Tutto sui regolatori PID (e sulla PID_v1 library)

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 :stuck_out_tongue: . 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.

marcowip:
Ho visto che c'è una apposita libreria che ho prontamente installato e che si chiama PID_v1.
[/quote]
Stai parlando di questa libreria ?

astrobeed:

marcowip:
Ho visto che c'è una apposita libreria che ho prontamente installato e che si chiama PID_v1.
[/quote]
Stai parlando di questa libreria ?
[/quote]
esattamente

x iscrizione

Testato:
x iscrizione

che intendi scusa?

marcowip:

Testato:
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. :grin:

Io ho trovato questa come pagina di riferimento alla libreria:
http://playground.arduino.cc/Code/PIDLibrary

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

SetTunings(Kp, Ki, Kd)

per settare invece i limiti di output c'è la funzione

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?

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.

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.

#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);
}

la prossima volta invece di perdere tempo in fritzing, posta uno schema elettrico :slight_smile:
grazie della condivisione :slight_smile:

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?

nid69ita:

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

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

a marcowip!
rispondi al più presto

gAs1:
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.

Che ne so, tiro ad indovinare...

Maturità?

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

Ti invitiamo a presentarti (dicci quali conoscenze hai di elettronica e di programmazione) qui: Presentazioni
e a leggere il regolamento: Regolamento

scusami tanto astrobeed!
ero di fretta e molto irritato!
mi scuso con tutti e nella fretta non ho guardato la data!

mi presento: sono davide e non ho una grandissima esperienza con arduino
lo sto usando per finire il mio progetto per l'esame sulla casa domotica.
mi scuso ancora.