Ciao
Finalmente ho deciso di provare a fare un progetto con arduino
Il progetto prevede do mantenere constate un flusso di sabbia da un contenitore appeso ad una cella di carico
Controllero' una specie di valvola con un servo o uno stepper, indeciso
Ma quello che cerco in questo momento e' una libreria pid
Il gestore delle librerie di arduino mi da' questa
che credo sia usata anch da Aliverti mas il link mi manda al playground
Ho pero' trovato questo link
https://github.com/br3ttb/Arduino-PID-Library/blob/master/examples/PID_Basic/PID_Basic.ino
Voi avete altre librerie da suggerire?
grazie
Stefano
Probabilmente non serve un PID, ma è sufficiente un PI.
E probabilmente non serve neppure una libreria, sono quattro conti in croce
grazie per il riscontro
volevo provare a capirli e vedere che succede
E' un pid anche quello ho sbaglio? anche se solo pi
Si, è un regolatore PI.
X è il flusso desiderato, Y quello reale misurato all'uscita del sistema, dX è la correzione da dare a X per ottenere il valore di comando Z da dare al sistema per produrre Y = X.
Ad ogni passo di durata dt si calcola l'errore e, si accumula in i l'integrale dell'errore (che va limitato in ampiezza), ed infine si calcola il dX applicando Kp e Ki.
Alla partenza il termine integrativo è zero e quello proporzionale massimo.
A regime, raggiunto l'equilibrio e in assenza di perturbazioni, il termine proporzionale diventa zero e quello integrativo rimane costante e comanda il sistema.
In presenza di una perturbazione, ricompare il termine proporzionale che cerca di compensare, e quello integrativo si adatta per trovare un nuovo equilibrio.
Sbaglio o così l'ultima formula è sbagliata
Se all'uscita del PI ci sommi il valore reale è come se tu avessi un Kp maggiore di uno, che ci porta instabilità, o sbaglio?
Comunque manca invece un termine importante, precedente il regolatore:
Si vuole mantenere costante il flusso di sabbia, misurando però il peso erogato
Serve un derivatore sul peso per averne la variazione, cioè il suo flusso
Dubito comunque che tra bande morte, non linearità ed errori si possa ottenere qualcosa di funzionale
Credo di aver capito solo adesso
Mai scrivere prima del secondo caffè
Si, con Y > X il valore di e è negativo, e di conseguenza tutta la correzione porta verso un punto di equilibrio.
Per quanto riguarda il flussometro ottenuto derivando il peso, non ci ho neanche pensato. Come a tutto quello che riguarda le grandezze fisiche in gioco. Chiaro che "alle estremità" della catena di regolazione ideale, andranno fatte le opportune misurazioni e conversioni.
grazie per le repliche
sto' metendo insieme un po' di cose:
serbatoio
sabbia
tappo con un foro
al momento inizio a fare prove per vedere i valori di flusso
sketch non bloccante come insegnato e suggerito spesso sul forum
//
// FILE: HX_is_ready.ino
// AUTHOR: Rob Tillaart
// PURPOSE: HX711 demo
// URL: https://github.com/RobTillaart/HX711
#include "HX711.h"
HX711 scale;
// adjust pins if needed
uint8_t dataPin = 6;
uint8_t clockPin = 7;
//timer non bloccante
unsigned long t1;
int dt, interval;
float array[2] = { 0.00, 0.00 };
float FlowRate;
void setup() {
Serial.begin(115200);
Serial.println();
Serial.println(__FILE__);
Serial.print("HX711_LIB_VERSION: ");
Serial.println(HX711_LIB_VERSION);
Serial.println();
scale.begin(dataPin, clockPin);
// TODO find a nice solution for this calibration..
// load cell factor 20 KG
// scale.set_scale(127.15);
// load cell factor 10 KG
scale.set_scale(218.456375); // 2025 07 26 TODO you need to calibrate this yourself.
// reset the scale to zero = 0
scale.tare(20);
t1 = millis();
interval = 2500;
FlowRate = 0.00;
array[0] = 0.00;
}
void loop() {
dt = millis() - t1;
if (dt >= interval) {
Serial.print("dt ");
Serial.println(dt);
t1 = millis();
if (scale.is_ready()) {
array[1] = scale.get_units(10);
Serial.println(scale.get_units(10));
Serial.print("array[0]");
Serial.println(array[0]);
Serial.print("array[1]");
Serial.println(array[1]);
FlowRate = (array[1] - array[0]) * 1000.0 / dt;
Serial.print('\t');
Serial.print("FlowRate gr/sec ");
Serial.println(FlowRate);
array[0] = array[1];
}
}
}
Per tenere la misura del tempo più precisa direi di leggere millis una volta sola:
void loop() {
unsigned long now = millis();
dt = now - t1;
if (dt >= interval) {
Serial.print("dt ");
Serial.println(dt);
t1 = now;
Invece la scalatura (giustamente pensata per compensare intervalli di campionamento irregolari):
FlowRate = (array[1] - array[0]) * 1000.0 / dt;
...sarebbe corretta solo se interval fosse di un secondo. Bisognerebbe scrivere interval al posto di 1000, ma con interval 2500 la misura sarebbe in grammi ogni 2,5 secondi.
ciao
non sono sicuro di avere capito:
FlowRate = (array[1] - array[0]) * 1000.0 / dt;
il *1000 mi serve perche' dt sono millesimi
FlowRate = (array[1] - array[0]) / (dt/1000);
il valore piu' preciso per il quoziente non e' dt?
interval e' solo un valore con cui far scattare il primo IF
Si, ho scritto una muccata cosmica
1000/dt va benissimo
10 * 1000 / 1000 = 10
25 * 1000 / 2500 = 10