#include <PID_v1.h>
#include <LiquidCrystal.h>
double dispKp; // Valores de `Kp` para visualización.
double dispKi; // Valores de `Ki` para visualización.
double dispKd; // Valores de `Kd` para visualización.
// Definir pines
const int potPin = 34; // Pin del potenciómetro
const int motorPin = 25; // Pin PWM para el motor
const int irPin = 26; // Pin del sensor de infrarrojos
// Pines para la pantalla LCD (RS, E, D4, D5, D6, D7)
const int rs = 15, en = 2, d4 = 5, d5 = 4, d6 = 18, d7 = 19;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
// Variables para el control PID
double Setpoint, Input, Output;
double Kp = 2, Ki = 100.0, Kd = 0;
PID myPID(&Input, &Output, &Setpoint, Kp, Ki, Kd, DIRECT);
// Simulación de RPM
double simulatedRPM = 0;
double motorResponseFactor = 0.1; // Ajusta según la respuesta del motor
// Variables para el cálculo de RPM mediante infrarrojos
volatile unsigned int irCount = 0;
unsigned long lastTime = 0;
double irRPM = 0;
const int pulsesPerRevolution = 4; // Ajustar según el número de pulsos por revolución
void IRAM_ATTR isr() {
irCount++;
}
void setup() {
Serial.begin(115200);
// Configurar pines
pinMode(potPin, INPUT);
pinMode(motorPin, OUTPUT);
pinMode(irPin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(irPin), isr, RISING);
// Inicializar PID
myPID.SetMode(AUTOMATIC);
myPID.SetOutputLimits(0, 255); // Salida PWM de 0 a 255
// Inicializar LCD
lcd.begin(16, 2);
lcd.print("Iniciando...");
delay(2000); // Mostrar mensaje de inicio por 2 segundos
}
void loop() {
// Leer el valor del potenciómetro
int potValue = analogRead(potPin);
Setpoint = map(potValue, 0, 4095, 0, 20000); // Ajustar el rango según el motor
double potVoltage = potValue * (3.3 / 350.0); // Calcular el voltaje del potenciómetro
// Simulación de RPM
simulatedRPM += (Output - simulatedRPM) * motorResponseFactor;
Input = simulatedRPM;
// Calcular la salida del PID
myPID.Compute();
// Aplicar la salida del PID al motor
analogWrite(motorPin, Output);
// Calcular las RPM usando el sensor de infrarrojos
unsigned long currentTime = millis();
if (currentTime - lastTime >= 1000) { // Actualizar cada segundo
irRPM = (irCount * 60) / pulsesPerRevolution;
irCount = 0;
lastTime = currentTime;
}
// Mostrar los valores para monitoreo en el Serial
Serial.print("Setpoint: ");
Serial.print(potVoltage);
Serial.print("V");
Serial.print(" RPM-Simulated: ");
Serial.print(Input);
Serial.print(" RPM: ");
Serial.print(irRPM);
Serial.print(" PWM: ");
Serial.println(Output);
// Mostrar los valores en la pantalla LCD
lcd.setCursor(0, 0);
lcd.print("Set:");
lcd.print(potVoltage*0.1,1);
lcd.print(" V");
lcd.setCursor(0, 1);
lcd.print("RPM: ");
lcd.print(irRPM);
lcd.setCursor(10, 1);
lcd.print("Kp:");
lcd.print(Ki); // Valores de `Ki` para visualización.
lcd.setCursor(10, 0);
lcd.print("Kd:");
lcd.print(Kd);
delay(100); // Pequeño retardo para estabilizar la simulación
}