Usare la libreria pid()

Ciao a tutti,

Sono nuovo del forum da poco mi sono anche presentato (spero del tipic corretto).

Volevo chiedervi una mano sul come usare la libreria pid(), ho gia letto le varie descrizioni, ma non riesco a capire come usare la funzione pid() e che valori dovrei mettere dentro alle variabili k

Non so se serve, io questa libreria dovrei usarla per controllare la temperatura nel modo più lineare possibile.

Riuscite per caso ad aiutarmi?

Spero di ricevere qualche risposta.

Grazie mille :slight_smile:

Ciao,

Provo a postare un codice per capire se sto andando nella direzione giusta ( sperando sempre in una risposta )

la temperatura viene letta dal sensore DS18B20 collegato al pin 2 e l’output viene gestito tramite un relè SSR collegato al pin3

/********************************************************
 *Reading analog input 2 to control analog PWM output 3 *
 ********************************************************/
#include <PID_v1.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <LiquidCrystal.h> //ancora da implementare

double Setpoint, Input, Output;
double Kp=2;
double Ki=5;
double Kd=1;
#define ONE_WIRE_BUS 2

OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
double soak = 150; //valore di prova fase soak ( in futuro lettura da sd )

PID myPID(&Input, &Output, &Setpoint, Kp, Ki, Kd, DIRECT);

/*
MEMO
    – Il parametro P è il parametro dominante. Sarà quello sul quale sarà necessario agire prima di tutto;
    – Il parametro I determina quanta forza deve essere applicata se l’inclinazione, rispetto al volo “livellato”, persiste;
    – Il parametro D viene usato per bloccare la correzione massima riguardante questa modalità
*/
void setup()
{
  Serial.begin(9600);
//attivo il sensore per rilvevare la temperatura
  sensors.begin();
//definisco il Setpoint
  Setpoint = soak;
  myPID.SetMode(AUTOMATIC);
}

void loop()
{
  // rilevo la temperaura
  sensors.requestTemperatures(); 
  Input = analogRead(sensors.getTempCByIndex(0));
  myPID.Compute();
  //gestisco l'uscita pid
  analogWrite(3,Output);
}

-L'uscita 3 non è PWM

-Un SSR non è pilotabile mediante PWM

In quanto al resto Non conosco la libreria in oggetto, ...mi sembra comunque corretto

per usare il PID controllando cose on/off e non proporzionali devi usare un controllo basato su Time Window; vedi qui http://playground.arduino.cc/Code/PIDLibraryRelayOutputExample

io ho fatto il porting della libreria su php e la sto usando su raspberry

-L’uscita 3 non è PWM

-Un SSR non è pilotabile mediante PWM

In quanto al resto Non conosco la libreria in oggetto, …mi sembra comunque corretto

a me l’uscita del pin 3 risulta un segnale PWM

0 e 1 sono tx e rx
dal 2 al 13 sono pwm.

scusa l’ssr che non è altro che un triak optoisolato, comandabile direttamente dall’arduino, in quanto basta 1v e qualche mA per eccitarlo. io on d’evitare problemi metto un transistor NPN bc547b ( esempio ) per comandarlo, oltre a quello l’ssr ha il circuito “zero cross detect”, quindi non va in conduzione finchè non rileva il passaggio per zero della sinusoide. Anche lo sgancio non avviene prima del passaggio per zero.

quindi dovrei riuscirlo a pilore in PWM, se non è cosi come dovrei fare?

blacktek:
per usare il PID controllando cose on/off e non proporzionali devi usare un controllo basato su Time Window; vedi qui http://playground.arduino.cc/Code/PIDLibraryRelayOutputExample

io ho fatto il porting della libreria su php e la sto usando su raspberry

guardando quel codice dovrebbe diventare cosi il mio, sbaglio?

/********************************************************
 *Reading analog input 6 to control analog PWM output 3 *
 ********************************************************/

#include <PID_v1.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <LiquidCrystal.h> //ancora da implementare
#include <SD.h> //ancora da implementare
#include <Wire.h> //ancora da implementare
 


double Setpoint, Input, Output;
double Kp=2;
double Ki=5;
double Kd=1;

#define ONE_WIRE_BUS 2
#define RelayPin 6

OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
int preheat = 150; //( in futuro lettura da sd )

PID myPID(&Input, &Output, &Setpoint, Kp, Ki, Kd, DIRECT);
/*
Per questo tuning è importante sapere quanto segue:

    – Il parametro P è il parametro dominante. Sarà quello sul quale sarà necessario agire prima di tutto;
    – Il parametro I determina quanta forza deve essere applicata se l’inclinazione, rispetto al volo “livellato”, persiste;
    – Il parametro D viene usato per bloccare la correzione massima riguardante questa modalità
*/

int WindowSize = 5000;
unsigned long windowStartTime;

void setup()
{
  Serial.begin(9600);
  //sensor soak
  sensors.begin(); // libreria del sensore
  
   //for test
   Setpoint = preheat;
  
  //tell the PID to range between 0 and the full window size
   myPID.SetOutputLimits(0, WindowSize);
  
  //turn the PID on
  myPID.SetMode(AUTOMATIC);
}

void loop()
{
  // Send the command to get temperatures
  sensors.requestTemperatures();  
  Input = digitalRead(sensors.getTempCByIndex(0));
  
  myPID.Compute();
  /************************************************
   * turn the output pin on/off based on pid output
   ************************************************/
  unsigned long now = millis();
  if(now - windowStartTime>WindowSize){
    //time to shift the Relay Window
    windowStartTime += WindowSize;
  }if(Output > now - windowStartTime) digitalWrite(RelayPin,HIGH);
  else digitalWrite(RelayPin,LOW);

}

che se non ho capito male se diminuisco la variabile WindowSize = 5000 a 500ms l’apertura e la chiusura del relè dovrebbe essere piu frequente quindi (0.5s), giusto?

fate conto che vorrei fare una cosa del genere

il mio unico problema è capire come comandare l’SSR con la libreria in oggetto per creare una curva ideale di saldatura

luca120:
a me l'uscita del pin 3 risulta un segnale PWM

... e secondo te come facciamo noi a sapere su quale board sei visto che NON lo hai specificato ? >:(

Dalla tua affermazione qui sopra, si può solo suppore che tu sia su una MEGA2560 ... o su cosa d'altro ?

Guglielmo

gpb01:
... e secondo te come facciamo noi a sapere su quale board sei visto che NON lo hai specificato ? >:(

Dalla tua affermazione qui sopra, si può solo suppore che tu sia su una MEGA2560 ... o su cosa d'altro ?

Guglielmo

ciao io non voglio criticare ma allora prima di dire che non è PWM non sarebbe stato meglio dire... puoi specificare la scheda che stai usando?

Detto questo penso sia meglio evitare di partire in quarta come stai facendo te e darmi la colpa su come IO ho risposto...

purtroppo è vero mi sono dimenticato di segnalarlo la prossima volta non ometterò questo particolare importante!!!!

comunque si sto lavorando con un mega2560.

grazie per il tuo intervento Guglielmo....

spero che a parte questo tuo appunto su una mia affermazione che ho fatto, tu sia venuto qua anche per aiutarmi in una mia difficoltà

Luca

luca120:
ciao io non voglio criticare ma allora prima di dire che non è PWM non sarebbe stato meglio dire... puoi specificare la scheda che stai usando?

... il 85% di quelli nuovi che arrivano, arrivano con Arduino UNO e quindi, normalmente, se non si specifica altro, si da per scontato che si stia parlando di quella scheda che, come giustamnete ha segnalato icio, NON ha il PWM sul pin 3 ... da qui il suo intervento. :slight_smile:

E io ... come lui, non conosco quella libreria ... dovrai pazientemente attendere qualcuno che l'abbia già usata ... ::slight_smile:

Guglielmo

Il mondo è bello perché è vario,che noia sarebbe se fossimo tutti uguali...

aspetterò, speriamo che ci sia qualcuno che l'abbia usata..

Luca

Comunque ti ripeto che un SSR non si può comandare in PWM, inutile che fai tanto il saputello, ti sgamiamo in quattro e quattrotto

se diminuisci WindowSize l'apertura e chiusura dei relè è più frequente; quindi più WindowSize è piccolo, prima il tuo relè crepa :slight_smile:

Il "time proportioning control" che ti ho linkato è semplicemente un modo di dire: "nel lasso di tempo che sto specificando stai x% del tempo in stato on 100%-x% del tempo in stato off. Il pid cercherà di trovare l'X di equilibrio per cui si ha la convergenza al setpoint.

Il pid non comanda niente, da solo un output numerico che poi va adattato al sistema di controllo.

Anche i valori di Kp, Kd e Ki sono puramente di esempio. Ti suggerisco di partire da alcuni valori e loggarti poi l'andamento dell'output per plottarlo in excel e vedere cosa sta combinando. All'inizio prima che lo facessi non ci stavo capendo nulla e sembrava che non funzionasse nulla. dopo aver fatto il plotting è stato tutto chiaro e ho capito che per la mia applicazione i valori K* erano circa 1/10 di quelli del'esempio.

Il PID è tutt'altro che un algoritmo plug and play, è un'algoritmo non deterministico (euristica) che cerca di approssimare il risultato tentando di diminuire l'errore tra la variabile target e la variabile misurata.

Aiutati con excel altrimenti è difficile uscirne :slight_smile:

icio:
Comunque ti ripeto che un SSR non si può comandare in PWM, inutile che fai tanto il saputello, ti sgamiamo in quattro e quattrotto

adesso giochiamo anche a nascondino? io non sono qua per essere insultato o far vedere che sono una saputello, ho studiato elettronica, sono un responsabile elettronica, quindi penso di sapere UN MINIMO DI ELETTRONICA, poi non me ne frega xx xxxxx di fare il saputello in questo forum, invece di dire quello che non si può fare, forse sarebbe meglio spiegare anche il perché non si può, te invece di fare il saputello senza dare una spiegazione ad un mio problema che ho posto è meglio che non rispondi!!!!

detto questo sai spiegarmi il perché non si può ?
sai darmi una possibile soluzione al mio problema?

blacktek:
se diminuisci WindowSize l'apertura e chiusura dei relè è più frequente; quindi più WindowSize è piccolo, prima il tuo relè crepa :slight_smile:

Il "time proportioning control" che ti ho linkato è semplicemente un modo di dire: "nel lasso di tempo che sto specificando stai x% del tempo in stato on 100%-x% del tempo in stato off. Il pid cercherà di trovare l'X di equilibrio per cui si ha la convergenza al setpoint.

Il pid non comanda niente, da solo un output numerico che poi va adattato al sistema di controllo.

Anche i valori di Kp, Kd e Ki sono puramente di esempio. Ti suggerisco di partire da alcuni valori e loggarti poi l'andamento dell'output per plottarlo in excel e vedere cosa sta combinando. All'inizio prima che lo facessi non ci stavo capendo nulla e sembrava che non funzionasse nulla. dopo aver fatto il plotting è stato tutto chiaro e ho capito che per la mia applicazione i valori K* erano circa 1/10 di quelli del'esempio.

Il PID è tutt'altro che un algoritmo plug and play, è un'algoritmo non deterministico (euristica) che cerca di approssimare il risultato tentando di diminuire l'errore tra la variabile target e la variabile misurata.

Aiutati con excel altrimenti è difficile uscirne :slight_smile:

ok grazie mille blacktek, volevo chiederti un'ultima cosa, la variabile WindowSize interviene solo quando raggiunge la temperatura di setpoint corretto?, quindi "teoricamente" piu aperture/chiusure più linearità nel mantenimento della temperatura giusto?

--- luca120, modera il linguaggio, oltre ad essere una questione di educazione, sul forum ci sono anche parecchi ragazzi giovanissimi. Grazie. - gpb01

la WindowSize interviene sempre; sei sei lontano dal setpoint sicuramente l'errore è grande (in positivo o negativo) e quindi è sempre on o sempre off.

Corretto che più è piccolo window size più c'è linearità (corrisponde a diminuire l'isteresi)

Io mi sono già fatto una brutta opinione su di te per cui ti darò solo una semplice risposta come si darebbe a un ragazzo di 15 anni che si è appena avvicinato all'elettronica in quanto i tuoi commenti denotano una totale ignoranza in materia.

Il PWM , che è quello che prelevi da arduino, si usa per regolare la potenza in carichi in DC,

Invece la parzializzazione di fase che è quella che intendi tu, si usa per regolare carichi in AC mediante TRIAC o SCR, per funzionare ha bisogno che comunichi ad arduino un segnale di zero crossing e poi arduino genera un segnale di eccitazione ritardato di un tempo da 0 a 10 mSec scarsi dal zero crossing per eccitare il tiristore,

se dai un PWM ad un TRIAC con o senza zc interno quello che ottieni è che resterà sempre eccitato
Ti invito per l'ultima volta a rivolgerti con educazione, non sei autorizzato a negare la parola a nessuno, siamo in un forum dove chiunque ha diritto a parlare

mi inserisco anche io in questa "discussione". Premetto che le mie conoscenze di elettronica sono scarse. Ho realizzato comunque un termostato che regoli la temperatura del mosto di birra. Questo termostato, con arduino uno, ha due uscite con due relè: uno pilota un cavo riscaldante da 40W e l'altra un gruppo frigo che raffredda, in modo tale da tenere una temperatura entro un range. Tralasciando la sezione raffreddamento (il gruppo frigo necessita di riposo prima di una riaccensione), è possibile abbinare un comportamento Pid al mio sistema? Ho una seconda scheda relè che, diversamente da quella classica a due che uso ora, ha 4 relè ssr. Onestamente non ci ho capito nulla sullo zc, sinusoidi pari ecc.. nel mio caso sarebbe possibile riscaldare con arduino uno e librerie pid?
grazie delle preziose "lezioni"

ciao. ci sono esempi di pid per il controllo del ph che sono analoghi alla tua applicazione. prova a cercare.