Go Down

Topic: Cercasi Volontari Per Automazione Camera Fermentazione "Birra" Con Arduino (Read 34206 times) previous topic - next topic

arzaman

Ho finalmente trovato il tempo per collegare il ponte di H da 43A al mio set up



Sto facendo qualche prova preliminare con il codice che avevo sviluppato per il controllo monodirezionale avvero singolo PID + pwm + h bridge usato in una sola direzione...giusto per adattare nuova unità di potenza che in realtà e costituita da due half bridge indipendenti che vanno gestiti in maniera diversa ris motor shield

Terminata questa fase mi dedico finalmente al codice del controllo bidirezionale  ;)

Stau tuned
Davide

saviothecnic

Terminata questa fase mi dedico finalmente al codice del controllo bidirezionale  ;)

Ottimo a me man mano stanno arrivando le varie parti ordinate :D
In settimana arrivano anche le serpentine inox il tedesco ha spedito ieri ordine fatto domenica superveloci :D
Dai anche un occhio a questo codice è sempre per una gestione camera di fermentazione ma tramite shield lan
la stessa che avevo proposto di inserire in questo progetto

http://www.birrandosiimpara.it/birrabirra/viewtopic.php?f=80&t=4513&p=46675#p46675


arzaman


Sto continuando a sperimentare il codice base e le librerie PID e al fine di rendere la situazione più reale ho inserito una delle due alette di raffreddamento + ventola all'interno di una scatola di polistirolo da gelato cercando di realizzare una mini cella termostatata.



all'interno la sonda LM35 legge la temperatura e per riscontro ho inserito anche una sonda indipendente connessa a termometro digitale



usando le librerie arduino PID con settaggio delle tre costanti Kp,Ki,Kd pari a 2,5,1 e usando la modalità DIRECT (frigo) faccio fatica a stabilizzare il sistema...

La temperatura rilevata dal LM35 oscilla anche di molto (pur facendo 5 rilevazioni e calcolando la media) e il valore letto "istantaneo" non corrisponde a quello reale misurato con un termometro digitale indipendente.



c'e' qualche cosa che non quadra..devo capire cosa o cambio sonda di temperatura..

allego il codice se qualcuno ci vuole dare un occhio ?

Code: [Select]
/*

Il programma misura la temperatura tramite il sensore LM35 e lo usa come ingresso
al PID
L'uscita del PID pilota la motor Shield (H-Bridge)

Vengono utilizzati i seguenti pin per LM35
Pin +5V         -> Alimentazione
Pin GND         -> Alimentazione
Pin Analogico 3 -> lettura LM35


La scala dell'LM 35 è T = K * V
dove:
K = 100 [°C/V] coeff.angolare della scala
V = tensione generata dall'LM35 (10mV/°C)
T = temperatura in °C


/* Numero del pin analogico sul quale è collegato l'LM35  */
#define LM35_pin 3

#include <PID_v1.h>

/* Definizioni globali */
float vref = 1.1;
double Setpoint, Input, Output;
                     // Vref dell'ADC (quell'interno è di 1,1V)
int SNS_A   = A0; // current read
int LPWM = 9; // H-bridge leg 1 ->LPWM
int enL = 8; // H-bridge enable pin 1 -> L_EN
int RPWM = 6; // H-bridge leg 2 ->RPWM
int enR = 7; // H-bridge enable pin 2 -> R_EN



/* Impostazione dell'hardware */

//Inizializzazione del PID, impostazione a DIRECT (frigo)
PID myPID(&Input, &Output, &Setpoint,2,5,1, REVERSE);

void setup()
{
  analogReference( INTERNAL );  // per l'ADC usiamo il Vref interno da 1,1V (migliore precisione)
  Input = analogRead( LM35_pin );       // Prima lettura "a vuoto" (serve per l'assestamento dell'ADC)
  Setpoint = 15;                    //definizione del set point
  Serial.begin(9600);
  Serial.println("Temperatura    PIDout    Corrente\n");
 
  //turn the PID on
  myPID.SetMode(AUTOMATIC);
 
  // Configurazione PIN direzione e freno
 
  pinMode(LPWM, OUTPUT);
  pinMode(RPWM, OUTPUT);
  pinMode(enL, OUTPUT);
  pinMode(enR, OUTPUT);
  digitalWrite(enL, HIGH);
  digitalWrite(enR, HIGH);

 
}

void loop()
{
  float temp = readTemp();  // legge il valore della temperatura e la memorizza nella var. temp.
  Input = temp;              //temperatura passata in ingresso a PID
  myPID.Compute();
 
  digitalWrite(LPWM, LOW);
  analogWrite(RPWM,Output); //PWM con segnale in uscita pari a uscita PID
   
  Serial.print( temp);    // invia i valori alla seriale
  Serial.print("\t");
  Serial.print((Output/255*100));
  Serial.print("\t");
  Serial.print(analogRead(SNS_A));
  Serial.print("\n");
 
  delay (3000);
}

/* Legge la temperatura */
float readTemp()
{
  float temp = 0.0;       // valore convertito in temperatura (°C)
  int val = 0;            // valore quantizzato dall'ADC [0..1023]
  int nread = 5;          // numero di letture (da 5 a 8)
  float somma = 0.0;      // somma delle letture
  for (int i=0; i<nread; i++)
  {
    val = analogRead( LM35_pin );              // legge il dato della tensione sul pin 'LM35_pin'
    temp = ( 100.0 *  vref * val ) / 1024.0;   // lo converte in °C
    somma += temp;                             // aggiunge alla somma delle temperature lette   
  }   
  return ( somma / nread );                     // ne calcola il valore medio
}


Davide

saviothecnic

La temperatura rilevata dal LM35 oscilla anche di molto (pur facendo 5 rilevazioni e calcolando la media) e il valore letto "istantaneo" non corrisponde a quello reale misurato con un termometro digitale indipendente.
c'e' qualche cosa che non quadra..devo capire cosa o cambio sonda di temperatura. Davide

Forse la lettura analogica viene disturbata dal PWM del modulo di potenza ?????
Prova ad usare un cavo antifurto schermato e los chermo collegato solo da un leto al negativo Alim

Se vuoi levaqrti il dubio a volo se non lo trovi veloce un DS18B20 digitale te lo posso mandare io

arzaman


Ho cambiato sensore e sono passato al DS18B20 con le libreire OneWire e DallasTemperature

come sempre faccio in questi casi vado per gradi...prima verificato che il sensore leggesse la temperatura correttamente e poi ho fatto il merge dei due Sketch dando in ingresso al PID la temperatura misurata e prendendo uscita del PID per pilotare ponte di H.

Misteri della programmazione ma quando faccio il merge la lettura della temperatura impazzisce...ho un valore fisso tipo 85...e se vario il delay nel loop varia anche questo valore.

Questo e' il codice stand alone che mi legge temperatura perfettamente

Code: [Select]
/*
Lettura_ds18b20.pde
Il programma permette la misurazione della temperatura
che viene mostrata su un display LCD

Vengono utilizzati i seguenti pin
Pin +5V         -> Alimentazione
Pin GND         -> Alimentazione
Pin Digital 2   -> Linea dati sensore DS18B20



*/

#include <OneWire.h>
#include <DallasTemperature.h>


// Il terminale data del sensore è connesso
// alla porta 2 di Arduino
#define ONE_WIRE_BUS 2

// Imposta la comunicazione oneWire per comunicare
// con un dispositivo compatibile
OneWire oneWire(ONE_WIRE_BUS);

// Passaggio oneWire reference alla Dallas Temperature.
DallasTemperature sensors(&oneWire);


void setup(void)
{
  Serial.begin(9600);
  // Start up the library
  sensors.begin();
}

void loop(void)
{

  sensors.requestTemperatures(); // Invia il comando di lettura delle temperatura
Serial.println("Temperatura di: ");
  Serial.print (sensors.getTempCByIndex(0));
  Serial.println (" C");
}



questo invece e' il codice completo dove non ho fatto altro che riportare la parte di lettura temperatura in ingresso al PID

Code: [Select]
/*
Il programma misura la temperatura tramite il sensore DS18B20 e lo usa come ingresso al PID
L'uscita del PID pilota un circuito H-bridge

Vengono utilizzati i seguenti pin per DS18B20
Pin +5V         -> Alimentazione
Pin GND         -> Alimentazione
Pin Digital 2   -> Linea dati sensore DS18B20

*/

#include <OneWire.h>
#include <DallasTemperature.h>
#include <PID_v1.h>

/* Definizioni globali */

// Il terminale data del sensore è connesso alla porta 2 di Arduino
#define ONE_WIRE_BUS 2

// Imposta la comunicazione oneWire per comunicare
// con un dispositivo compatibile
OneWire oneWire(ONE_WIRE_BUS);

// Passaggio oneWire reference alla Dallas Temperature.
DallasTemperature sensors(&oneWire);

double Setpoint, Input, Output;
                   
int SNS_A   = A0; // current read
int LPWM = 9; // H-bridge leg 1 ->LPWM
int enL = 8; // H-bridge enable pin 1 -> L_EN
int RPWM = 6; // H-bridge leg 2 ->RPWM
int enR = 7; // H-bridge enable pin 2 -> R_EN

/* Impostazione dell'hardware */

//Inizializzazione del PID, impostazione a DIRECT (frigo)
PID myPID(&Input, &Output, &Setpoint,2,5,1, REVERSE);

void setup()
{

  Setpoint = 15;          //definizione del set point
  Serial.begin(9600);
  Serial.println("Temperatura    PIDout    Corrente\n");

  //turn the PID on
  myPID.SetMode(AUTOMATIC);
  // Start up the OneWire library
  sensors.begin();
  // Configurazione PIN direzione e freno H-bridge

  pinMode(LPWM, OUTPUT);
  pinMode(RPWM, OUTPUT);
  pinMode(enL, OUTPUT);
  pinMode(enR, OUTPUT);
  digitalWrite(enL, HIGH);
  digitalWrite(enR, HIGH);

}

void loop()
{
  double temp = sensors.getTempCByIndex(0);  // legge il valore della temperatura e la memorizza nella var. temp.
  Input = temp;              //temperatura passata in ingresso a PID
  myPID.Compute();
 
  digitalWrite(LPWM, LOW);
  analogWrite(RPWM,Output); //PWM con segnale in uscita pari a uscita PID
   
  Serial.print( temp);    // invia i valori alla seriale
  Serial.print("\t");
  Serial.print((Output/255*100));
  Serial.print("\t");
  Serial.print(analogRead(SNS_A));
  Serial.print("\n");

delay (1000);
 
}



sicuramente sbaglio qualche cosa...ma vorrei sapere cosa !  :0 :0

ora vado a dormire se no do di matto...

Davide

saviothecnic


Ho cambiato sensore e sono passato al DS18B20 con le libreire OneWire e DallasTemperature

Non ne so niente di programmazione aspettiamo gli esperti
Ma ricordo che in Birraduino si doveva anche specificare il tipo di sensore Dallas
#define OwType  1 /* 0 = 18s20 - 1= 18b20 */
Prova anche a cambiare PIN con brauduino e su birraduino sul 4 e 8 andava bene
ricordo che provai su altri pin perche mi serviva libero il 4 per via del shiel lan e non leggeva bene
Magari il PIN 2 che hai usato ora lo usa qualche libreria per qualche cosa e per questo sballa quando ci metti altro codice sotto

Io intanto vado avanti con assemblaggio meccanico :D

https://plus.google.com/photos/117096022619927896725/albums/5718015302058914513/5949578734407769298?banner=pwa&pid=5949578734407769298&oid=117096022619927896725

Grazie

arzaman

trovato errore... :smiley-red:
una banale dimenticanza nel loop del codice completo di un richiamo alla "sensors.requestTemperatures()"

ora legge temperatura corretta, questa sera collego H-Bridge e cella e provo a vedere se instabilita' che avevo con LM35 sparisce

Davide

saviothecnic

Ottimo mi fa piacere che hai trovato inghippo be in teoria questa essendo digitale
non dovrebbe soffrire di spurie PWM e interferenze sul alim

arzaman

Fermo restando che devo ancora completare i test nella configurazione "mono direzionale"  ovvero o frigo o stufa sto sempre ragionando su come impostare il codice del controllo bidirezionale/termostatico con inversione caldo/freddo

A parte l'approccio suggerito e discusso in qualche post precedente (che comunque proverò) di avere un controllo "esterno" che decide se si e' sopra o sotto set point e quindi decide la direzione del H-Bridge ho trovato un interessante articolo sui controlli PWM (di motori) con Locked Anti-phase

http://www.tmasi.com/robotica/pwmtut/pwmtut_2.htm

E' un approccio alternativo a quello Sign and Magnitude dove un pin di controllo pilota la direzione ovvero se il controllo lavora  frigo o stufa e il duty cycle del segnale PWM pilota la potenza da 0 a 100%

Per il controllo LAP può bastare anche solo un segnale di comando infatti l'onda quadra stabilisce sia la velocità che il verso di rotazione nel seguente modo:
1.Duty cycle a 0% : massima potenza in un verso (frigo)
2. Duty cycle al 50%: potenza applicata pari a 0
3.Duty cycle al 100%: massima potenza nel verso opposto (stufa)

avevo prospettato questo approccio all'inizio ma poi scartato perche' la maggior parte dei ponti di H (tipo L298)  funziona in modalita' SM

Ho trovato tuttavia un integrato LMD18200 che supporta anche la modalita' LAP  e questo ponte di H sembra interessante.

http://www.droids.it/cmsvb4/content.php?237-990-009-H-Bridge-TANK-3A-HP-Motor-Controller-IT



peccato solo per i soliti 3 A max di potenza
da capire se semplifica algoritmo di controllo rispetto all'approccio SM
Davide

saviothecnic

Scusa questo non fa la stessa cosa ? o non è un vero LAP ? Locked Anti-Phase

http://www.ebay.it/itm/MODULO-PID-50A-SINGLE-BRIDGE-PONTE-SINGOLO-PER-ARDUINO-AUTO-INTELLIGENTI-NUOVO-/141043351527?pt=Componenti_elettronici_attivi&hash=item20d6d6bfe7

RPWM Forward PWM input, high active.
LPWM Reverse PWM input, active high.

arzaman

Direi di no....in un LAP il segnale PWM e' unico e non c'e' un pin high/low per fare il reverse...

Davide

arzaman

Ora ci siamo ..funziona !
sostitutito LM35 con DS18B20 e la rilevazione della temperatura e' stabile

Come si vede dal grafico la catena Sensore temperatura -> PID -->PWM -> Hbridge  e' stabile e impostato un set point di 16C partendo dalla temperatura ambiente in poco tempo algoritmo converge e temperatura dentro la scatola di polistirolo rimane stabile al set point.
Per contro la potenza applicata alla cella (uscita del PID = duty cycle del PWM ) si riduce via via fino a stabilizzarsi anch'essa intorno all' 80%



abbiamo messo un punto fermo !


  • prossimi passi provare algoritmo PID  inverso per generare calore e verificare la stabilità come "stufa"

  • mettere insieme i due algoritmi e verificare la stabilità della cella termostatica



stay tuned
Davide

arzaman

Anche la prova nella direzione opposta ovvero usando il lato caldo della cella all'interno del contenitore che funge da camera termosatata ho raggiunto un discreto risultato.
Sono partito da temperatura ambiente e ho impostato set point 30C
Ho cambiato la direction nel PID da reverse a DIRECT e invertito h-bridge

Sotto trovate risultati..come si vede lentamente PID converge anche se le sovra elongazioni rispetto al set point sono maggiori rispetto al caso frigo. Probabilmente il set di parametri Ki Kp Kd  usato non è ottimizzato x le caratteristiche termodinamiche del mio set up di prova



Direi che con i limiti di un ambiente di prova la catena nelle due direzioni fa il suo lavoro ora si tratta di mettere tutto insieme e vedere se il sistema rimane stabile

Stay tuned
Davide


Etemenanki

Solo un'appunto (non sulla birra, che sono "quasi astemio" :P XD) sulla cella di Peltier, che ne ho usate a decine ...

Noto dall'ultimo grafico che l'alimentazione della cella la togli completamente, se interpreto correttamente (pid output) ... le celle di Peltier, non sono isolanti termici, anzi, senza alimentazione hanno una discreta conducibilita' termica in entrambe le direzioni, quindi il tuo insieme, quando la cella si spegne, diventa in pratica un dissipatore all'interno collegato termicamente ad un dissipatore all'esterno, e questo ti sottrae calore piu velocemente ... potrebbe essere per quel motivo che hai quell'oscillazione piu ampia ...

In genere nei sistemi di refrigerazione si prevede sempre un minimo di alimentazione per la cella, per fare in modo che non riconduca all'interno il calore appena sottratto ... con i dovuti limiti (perche' il riscaldamento e' piu efficente della refrigerazione) potresti fare lo stesso ... ovvero prevedere una soglia minima al di sotto della quale l'alimentazione della cella non scende mai, in modo che rimanga sempre "in funzione" (magari anche solo all'1 o 2 %), in modo che non si trasformi da pompa di calore a conduttore indifferenziato di calore, sottraendolo dal lato caldo quando si spegne ...
"Sopravvivere" e' attualmente l'unico lusso che la maggior parte dei Cittadini italiani,
sia pure a costo di enormi sacrifici, riesce ancora a permettersi.

Go Up