Eines de l'usuari

Eines del lloc


Barra lateral

ControlOnLine.net

controlonline.net@gmail.com

public:automatismes:arduino:regulacio:pid_led:pid_led_tut

Tutorarial LED-LDR-PID pas a pas

Connexió

Programes de comprovació

Modificant el blink i posant la visualització del valor del LDR. Desprès es tractarà de fixar una mesura encara que es moguin.

led_ldr_blinck.ino
/*
  Blink
  Turns on an LED on for one second, then off for one second, repeatedly.
 
  This example code is in the public domain.
 */
 
// Pin 13 has an LED connected on most Arduino boards.
// give it a name:
int led = 9;
 
 
// the setup routine runs once when you press reset:
void setup() {                
  // initialize the digital pin as an output.
  pinMode(led, OUTPUT);
  pinMode(A0, INPUT);
  Serial.begin(9600);  
}
 
// the loop routine runs over and over again forever:
void loop() {
  digitalWrite(led, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);  // wait for a second
  Serial.println(analogRead(A0));
  digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW
  delay(1000);   // wait for a second
  Serial.println(analogRead(A0));
}

Al següent programa en compte de tot res i cada segon controlarem el LED des de el port serie enviant el valor de 0 a 255, byte de sortida PWM.

El programa es el següent:

led_ldr_pwm.in0
 
int led = 9;
int sortidaPWM;
 
void setup() {                
  // initialize the digital pin as an output.
  pinMode(led, OUTPUT);
  pinMode(A0, INPUT);
  Serial.begin(9600);  
}
 
void loop() {
 
         if (Serial.available() > 0) {                
               sortidaPWM = Serial.parseInt();
               Serial.print("SortidaPWM=");
               Serial.println(sortidaPWM);
               analogWrite(9,sortidaPWM);
         }
  Serial.print("lectura LDR= ");
  Serial.println(analogRead(A0));
  delay(2000);
}

La sortida del monitor serie es la següent quan canviem el valor de la sortidaPWM de 225 a 0 canvia el valor de l'entrada de 62 a 670.

Quin valor de PWM caldria posar per tenir 300 a la lectura?
lectura LDR= 670
SortidaPWM=225
lectura LDR= 481
lectura LDR= 63
lectura LDR= 63
lectura LDR= 67
lectura LDR= 62
SortidaPWM=0
lectura LDR= 67
lectura LDR= 670
lectura LDR= 670
lectura LDR= 670
lectura LDR= 671
lectura LDR= 673
SortidaPWM=220
lectura LDR= 482
lectura LDR= 64
lectura LDR= 66
lectura LDR= 63
lectura LDR= 69
lectura LDR= 63

Per tenir un valor de 300 en el LDR en el meu cas es cal un PWM=10 però si canvia l'orientació i posició del LED-LDR serà altre valor, si els separe 1cm en compte de PWM=10 es PWM=25 i la lectura torna a ser de 300 aprox.

En un PID sempre tinguem una sortida a fixar, en aquest cas la lectura del LDR a 300 i un accionador sobre el que podem actuar en aquest cas el PWM del LED. I un error, entre el valor que volem i el que tinguem. El PID es el programa que permet mantenir aquest valor el més prop possible a 300 i que enfront qualsevol canvi extern(canvi posició LDR, LED) pugui reaccionar el més ràpid possible.

Programa regulació proporcional Kp

led_ldr_kp.ino
int led = 9;
int sortidaPWM=0;
int setPoint=300;
float error=0;
float Kp=0.1;
 
void setup() {                
  // initialize the digital pin as an output.
  pinMode(led, OUTPUT);
  pinMode(A0, INPUT);
  Serial.begin(9600);  
}
void loop() {
// entrada setPoint
         if (Serial.available() > 0) {                
               setPoint= Serial.parseInt();
               Serial.print("setPoint=");
               Serial.println(setPoint);
              }
 
Serial.print("lectura LDR= ");
Serial.println(analogRead(A0));
 
 
error=analogRead(A0)-setPoint;
Serial.print("error=");
Serial.println(error);
 
sortidaPWM=int((sortidaPWM+error*Kp));
 
analogWrite(9,sortidaPWM);
Serial.print("sortidaPWM=");
Serial.println(sortidaPWM);
Serial.println("---------------");
 
delay(2000);
 
}

Podem provar valors de setPoint entre 100 i 400, amb Kp=0.1 tingem un sistema prou estable però lent si augmentem tindrem un sistema menys estable però mes ràpid. També el 2000ms el fan més lent.

Podem jugar camviant els valors setPoint, Kp, delay(), per exemple un Kp=0.5 pot fer un sistema oscilant inestable.

Un Kp mal regulat pot crea un sistema que tardi moltíssim fins aconseguir el valor desitjat setPoint, o fer un sistema inestable oscil·lant entre màxim o saturat que mai arriba al valor desitjat. Per això s'utilitzen a més del proporcional el D(derivada=sistema mes ràpid) i el I(integral=sistema més precís, error final més petit). El PID.

the proportional action is the main control, while the integral and derivative actions refine it.

Pel que fa al ús:

  • P :el bàsic, molt utilitzat
  • PD :rapid pero inestable, poc utilitzat
  • PI :com el P però més precís a la llarga, molt utilitzat
  • PID :el més complet ben ajustat ràpid i precís

Una de les qüestions d'aquest PID es que es invers un pujada de la sortida PWM provoca una baixada del valor a controlar il·luminació al LDR:

setPoint=LecturaLDR - soritdaPWM
        150         -    52
        200         -    25
        250         -    19
        300         -    13
        100         -    96

Per solucionar-ho canvie el error, que el normal es error=setPoint-lectura i com es invers faig error=lectura-setPoint quan utilitzem PID industrial i llibreries, cal indicar que si es invers, com a mínim els paràmetres d'un PID serien PID myPID(&Input, &Output, &Setpoint, Kp, Ki, Kd, DIRECT);

També podem utilitzar les llibreries que calculen el output i que després cal aplicar a la sortidaPWM

ProcessValue = ProcessValue + output

On l'output es calcula:

previous_error = 0
integral = 0 
 start:
 error = setpoint - measured_value
 integral = integral + error*dt
 derivative = (error - previous_error)/dt
 output = Kp*error + Ki*integral + Kd*derivative
 previous_error = error
 wait(dt)
 goto start
Pot ser que la llibreria ja tingui output=output+……

Podem veure el resultat de la regulació al plot del IDE del arduino:

Es el mateix programa d'abans però només enviant el valor de la lectura del LDR:

Serial.println(analogRead(A0));
public/automatismes/arduino/regulacio/pid_led/pid_led_tut.txt · Darrera modificació: 2018/05/08 16:42 per crevert