Balancín con hélice y PID


          Aquí solo veremos un uso demostrativo de un balancín con hélice. Para uso en termostato ver aquí.

          Usaremos:
                   -Un Arduino (cualquiera)
                   -Un módulo L298 para alimentar el motor de la hélice.
                   -Un potenciómetro de 5kΩ
                   -Un motor con hélice.

           Por supuesto estos elementos pueden variarse. Como motor-hélice he usado uno de un cuadricóptero Eachine E58 que se vende suelto por menos de 4€ en AliExpress. Nada impide usar motores Brushless con su controladora.

           En un listón de 2x2cm y unos 40cm de largo fijamos el espárrago del potenciómetro en un taladro de 6mm.
           Lo siguiente es cargar el Sketch AnalogInput de los ejemplos de Arduino. Pondremos el listón horizontal y anotamos que valor da en el monitor serial. Es el valor que nos importa (nos da igual la resistencia real), ese será el Setpoint. En mi caso era 154, pero podría ser otro.

          El control PID (proporcional, integral y derivativo)  es un mecanismo de control que a través de un lazo de retroalimentación permite regular la velocidad, temperatura, presión y flujo entre otras variables de un proceso en general.
        
          El controlador PID calcula la diferencia entre nuestra variable real contra la variable deseada (Setpoint), pero lo hace teniendo en cuenta los tres parámetros antes mencionados de tal manera que el proporcional depende del error actual, el integral depende de los errores pasados y el derivativo es una predicción de los errores futuros. Esto nos proporciona un ajuste muy fino y estable del valor que queremos (Setpoint).

          Fundamental en industria para control de temperaturas, humedad, giro de un motor, etc.
          El módulo L298 lo alimento con 6,5v, es el mínimo para que el regulador integrado del módulo L298 proporcione 5v que sirven para alimentar al Arduino o puede hacer por el USB. Si se usa el USB los 6,5 pueden variarse. Si la hélice gira al revés, simplemente cambiar los cables.
int sensorPin = A0;    // select the input pin for the potentiometer
int sensorV = 0;  // variable to store the value coming from the sensor
int setpointS=160;   //Aprox 104 de pwm
int setpointI=148;
int IN3 = 5;    // Input3 conectada al pin 5
int IN4 = 4;    // Input4 conectada al pin 4
int ENB = 3;    // ENB conectada al pin 3 de Arduino
int pwm = 88;
void setup(){
Serial.begin(115200);
pinMode (ENB, OUTPUT);
pinMode (IN3, OUTPUT);
pinMode (IN4, OUTPUT);
digitalWrite (IN4, HIGH); //Preparamos la salida para que el motor gire en un sentido
digitalWrite (IN3, LOW);
}
void loop(){
  sensorV = analogRead(sensorPin);
  if (sensorV < setpointI){ pwm=pwm+4;}
  if (sensorV > setpointS){ pwm=pwm-4;}
    Serial.print("sensorV=");Serial.print(sensorV);
    Serial.print("  pwm=");Serial.println(pwm);
  analogWrite(ENB,pwm);
  delay(1000);
}
                    Para ver la diferencia, en un primer Sketch se intenta un control simple de aumentar potencia o disminuirla según sobrepasamos abajo o arriba el Setpoint.
                    El resultado es catastrófico como veremos en el video. 
           En el siguiente se usa la librería PID para Arduino. Fijamos el Setpoint que habíamos medido y el resultado es espectacular manteniendo la barra en perfecto equilibrio aún con fuertes alteraciones del equilibrio.
//www.jopapa.me  2021
//Control PID de balancin
#include <PID_v1.h>
#define Pot A0        //pin analogico lectura del potenciometro
#define PIN_OUT 3    //pin de salida pwm

//Define Variables
double Setpoint, Input, Output;

//Iniciar parametros
double Kp=1, Ki=0.1, Kd=0.2;   //por prueba y error
PID myPID(&Input, &Output, &Setpoint, Kp, Ki, Kd, DIRECT);

unsigned long previousMillis = 0;   //Actualiza gráfica
const long interval = 500;         //Gráfica cada 1/2''
int IN3 = 5;    // Input3 conectada al pin 5
int IN4 = 4;    // Input4 conectada al pin 4
int ENB = 3;    // ENB conectada al pin 3 de Arduino

void setup(){
  Serial.begin(115200);
  pinMode (ENB, OUTPUT);
  pinMode (IN3, OUTPUT);
  pinMode (IN4, OUTPUT);
  digitalWrite (IN4, HIGH); //El motor gire en un sentido
  digitalWrite (IN3, LOW); 
  Setpoint = 154;           //Que queremos mantener
  myPID.SetMode(AUTOMATIC);
}

void loop(){
  unsigned long currentMillis = millis();
  int value = analogRead(Pot);    //Valor del potenciometro
  Input = value;
  myPID.Compute();                //Calculo por el PID
  analogWrite(PIN_OUT, Output);   //Salida al motor
  if (currentMillis - previousMillis >= interval) {
   previousMillis = currentMillis;
   Serial.print(Output);   //PWM
   Serial.print(",");   
   Serial.print(154);      //linea SetPoint
   Serial.print(",");  
   Serial.println(Input);  // Linea potenciometro
  } 
}
          A la derecha la gráfica de tres parámetros. En rojo el Setpoint (154) que queremos alcanzar. En verde el balancín va subiendo y la resistencia del potenciómetro se iguala al Setpoint. En azul las variaciones de PWM para alcanzar el objetivo. También vemos las alteraciones provocadas por un golpe en el balancín y lo poco que tarda en estabilizarse.
 
Menu