Go Down

Topic: Tutto sui regolatori PID (e sulla PID_v1 library) (Read 11254 times) previous topic - next topic

marcowip

Ciao a tutti,
sono uno studente specializzando di ingegneria navale. Possiedo da un mese circa un Arduino UNO che sto imparando abbastanza velocemente ad utilizzare grazie anche agli esami di informatica ed elettrotecnica che ho sostenuto alla triennale :P . Proprio nel periodo in cui mi è stato regalato arduino stavo studiando, per un esame, i regolatori PID quindi questa è stata proprio la prima applicazione pratica che mi è venuta in mente per il mio arduino. Per intenderci, è il principio su cui si basa il controllo della velocità dei motori, dell'autopilota e di tantissime altre cose a bordo. Ho visto che c'è una apposita libreria che ho prontamente installato e che si chiama PID_v1. Il problema è che non capisco proprio come si usa. Per la precisione, non capisco come si impostano i coefficienti Kp, Ki e Kd e non riesco a capire per quale sensore e soprattutto per quale attuatore la libreria sia stata scritta di default. Ho intuito che probabilmente l'input (e quindi anche il set point) è in una scala da 0 a 1023 (come del resto lo sono gli input dei pin analogici) e che l'output è invece in una scala tra 0 e 255. Mi sbaglio?
Chi mi può spiegare meglio come si applica questa libreria per esempio nel caso di un semplice termostato?
Grazie!

PS: per puro "divertimento" ho provato a scrivere da solo il codice di un regolatore (per ora solo proporzionale) con display e con due potenziometri, uno per la regolazione del setpoint e l'altro per la regolazione del Kp. Il punto è che mi sembra più opportuno sfruttare la libreria che già c'è adattandola alle mie esigenze.

astrobeed


Ho visto che c'è una apposita libreria che ho prontamente installato e che si chiama PID_v1.


Stai parlando di questa libreria ?
Scientia potentia est

marcowip



Ho visto che c'è una apposita libreria che ho prontamente installato e che si chiama PID_v1.


Stai parlando di questa libreria ?



esattamente

testato

- [Guida] IDE - http://goo.gl/ln6glr
- [Lib] ST7032i LCD I2C - http://goo.gl/GNojT6
- [Lib] PCF8574+HD44780 LCD I2C - http://goo.gl/r7CstH


nid69ita



x iscrizione

che intendi scusa?


Intende che gli interessa l'argomento e perciò si "iscrive" al tuo thread. Ora rispondendoti, mi sono "iscritto" anche io.  :smiley-mr-green:

Io ho trovato questa come pagina di riferimento alla libreria:
http://playground.arduino.cc/Code/PIDLibrary
my name is IGOR, not AIGOR

marcowip

ok  XD (è evidente che non sono un abituale frequentatore dei forum!)

Grazie per il link. Quella pagina l'ho già letta però evidentemente non abbastanza bene……
infatti mi sono appena accorto che cliccando sulle funzioni si aprono le pagine che ne spiegano l'utilizzo!

Ecco… quindi per settare i parametri kp, ki e kd devo usare la funzione
Code: [Select]
SetTunings(Kp, Ki, Kd)

per settare invece i limiti di output c'è la funzione
Code: [Select]
SetOutputLimits(min, max)

(in effetti di default i limiti sono proprio 0-255 come avevo intuito)
Bene, bene. Ti ringrazio, sei stato immensamente utile. Stasera provo a realizzare il termostato che dicevo e vi faccio sapere. Qualche idea su cosa usare come attuatore?

PaoloP

Leggi gli esempi presenti nella stessa libreria --> https://github.com/br3ttb/Arduino-PID-Library/tree/master/PID_v1/Examples
Possono essere utili.

Se hai installato la libreria li trovi anche sul menu File --> Esempi nell'IDE di Arduino.

marcowip

Ciao a tutti,
ieri sera ho creato il mio regolatore PID. Non sapendo cosa regolare, ho creato un "regolatore di luce" utilizzando un fotoresistore come sensore e un LED come attuatore. Poiché volevo che avesse una funzione didattica, ho fatto in modo da poter impostare i coefficienti Kp, Ki e Kd nella fase iniziale attraverso un potenziometro e leggendo i valori sull'LCD. Lo stesso potenziometro l'ho usato poi per impostare nel ciclo loop il valore del setpoint. Appena posso poi sostituirò il fotoresistore con un TMP36 e il led con una ventola così da creare qualcosa di più sensato.
Per chi ci volesse provare ecco codice e immagine del circuito. Ciao a tutti e ancora grazie per le indicazioni.

Code: [Select]
#include <PID_v1.h>
#include <LiquidCrystal.h>

LiquidCrystal lcd(7, 6, 5, 4, 3, 2); //setto l'LCD
double Setpoint, Input, Output;
PID myPID(&Input, &Output, &Setpoint,2,5,1, DIRECT);
double letturaPot = 0;
double constkp = 0;
double constki = 0;
double constkd = 0;

//do un nome ai pin
const int misuraPin = A0; //questo pin è collegato al sensore di misura
const int attuatorePin = 9; //questo pin è collegato all'attuatore
const int potPin = A1; //questo pin legge il valore dato da un potenziometro
const int invioPin = 8;

void setup(){
  Serial.begin(9600); //apro una connessione seriale
  lcd.begin(16, 2);
  pinMode(attuatorePin, OUTPUT); //CONTROLLARE SE QUESTO SERVE
  pinMode(invioPin, INPUT);
 
  //splashscreen
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("CONTROLLORE PID");
  delay(2000);
 
  //inizializzo le variabili
  Input = analogRead(misuraPin);
  Setpoint = 0;
 
  //chiedo il Kp
  while(digitalRead(invioPin) == LOW){
    letturaPot = analogRead(potPin);
    letturaPot = letturaPot*(5 - 0)/1023 + 0; //NB: 5 e 0 sono il max e il min che puà assumere K
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("INSERIRE Kp:");
    lcd.setCursor(0, 1);
    lcd.print(letturaPot);
    delay(100);
  }
  constkp = letturaPot;
  letturaPot = 0;
  delay(300);
 
  //chiedo il Ki
  while(digitalRead(invioPin) == LOW){
    letturaPot = analogRead(potPin);
    letturaPot = letturaPot*(5 - 0)/1023 + 0; //NB: 5 e 0 sono il max e il min che puà assumere K
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("INSERIRE Ki:");
    lcd.setCursor(0, 1);
    lcd.print(letturaPot);
    delay(100);
  }
  constki = letturaPot;
  letturaPot = 0;
  delay(300);
 
  //chiedo il Kd
  while(digitalRead(invioPin) == LOW){
    letturaPot = analogRead(potPin);
    letturaPot = letturaPot*(5 - 0)/1023 + 0; //NB: 5 e 0 sono il max e il min che puà assumere K
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("INSERIRE Kd:");
    lcd.setCursor(0, 1);
    lcd.print(letturaPot);
    delay(100);
  }
  constkd = letturaPot;
  letturaPot = 0;
  delay(300);
 
  myPID.SetTunings(constkp, constki, constkd);
  myPID.SetMode(AUTOMATIC);
 
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Kp   Ki   Kd");
  lcd.setCursor(0, 1);
  lcd.print(constkp);
  lcd.print(" ");
  lcd.print(constki);
  lcd.print(" ");
  lcd.print(constkd);
  delay(3000);
}

void loop(){
  Setpoint = analogRead(potPin); //legge il setpoint
  Input = analogRead(misuraPin); //legge la misura
  myPID.Compute(); //effettua il calcolo
  analogWrite(attuatorePin, Output); //passa il risultato all'attuatore. NB: il risultato è comreso tra 0 e 255 di default
 
  //scrivo la situazione sull'lcd
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Misura ");
  lcd.print(Input);
  lcd.setCursor(0, 1);
  lcd.print("SetPoint ");
  lcd.print(Setpoint);
 
  //stampo sul serial monitor
  Serial.print("Misura: ");
  Serial.print(Input);
  Serial.print(" Setpoint: ");
  Serial.print(Setpoint);
  Serial.print(" Kp = ");
  Serial.print(constkp);
  Serial.print(" Ki = ");
  Serial.print(constki);
  Serial.print(" Kd ");
  Serial.print(constkd);
  Serial.print(" all'attuatore: ");
  Serial.println(Output);
 
  delay(100);
}

testato

la prossima volta invece di perdere tempo in fritzing, posta uno schema elettrico  :)
grazie della condivisione  :)
- [Guida] IDE - http://goo.gl/ln6glr
- [Lib] ST7032i LCD I2C - http://goo.gl/GNojT6
- [Lib] PCF8574+HD44780 LCD I2C - http://goo.gl/r7CstH

nid69ita


Ciao a tutti,
Appena posso poi sostituirò il fotoresistore con un TMP36 e il led con una ventola così da creare qualcosa di più sensato.


Grazie per la condivisione.
L'idea futura sarebbe quella di avere un setpoint che sò 20 gradi, misuri con il tmp36 la temperatura e con la ventola cerchi di mantenere i 20 gradi?
my name is IGOR, not AIGOR

marcowip



Ciao a tutti,
Appena posso poi sostituirò il fotoresistore con un TMP36 e il led con una ventola così da creare qualcosa di più sensato.


Grazie per la condivisione.
L'idea futura sarebbe quella di avere un setpoint che sò 20 gradi, misuri con il tmp36 la temperatura e con la ventola cerchi di mantenere i 20 gradi?


si è quello che pensavo di fare

gAs1

hai fatto il progetto con il sensore di temperatura?
sarei interessato!

gAs1


astrobeed

rispondi al più presto
Ti sei reso conto che è un topic del 2013 ?
Qua la prendiamo molto male quando arriva uno nuovo, senza presentarsi, e per giunta mette fretta.
Scientia potentia est

Go Up