Gestione relè tramite termoresistore

Ciao,
sto realizzando un piccolo circuito con il quale andrò a comandare un relè sulla base di quattro valori letti di un termoresistore. Il circuito è composto da n°4 led che ne identificano la fase, un pulsante per cambiare la fase, un termoresistore e un relè che piloterà il carico.

Il sistema deve, ad ogni pressione del pulsante, cambiare la fase e, in base alla lettura del termoresistore, eccitare o meno il relè; quindi:

  • FASE 1: Standby, imposto temperatura molto bassa in maniera di non eccitare il relè;
  • FASE 2: Minimo, imposto temperatura bassa (relè eccitato ad una temperatura minima);
  • FASE 3: Medio, imposto temperatura media (relè eccitato ad una temperatura media);
  • FASE 4: Massimo, imposto temperatura massima (relè eccitato ad una temperatura massima);
  • Ripremo pulsante e ritorno alla FASE 1.

Premetto che con un termoresistore a seriale non ho la lettura della temperatura ma un valore x in base alla resistenza condizionata dalla temperatura.

Circuito realizzato sulla breadboard con Arduino UNO e tutti i componenti sopraindicati.
Sketch realizzato:

const byte LED1[]={ 9, 10, 11, 12 };
const int P1=2;                       //Pulsante cambio di stato
const int debaunceDelay=100;
const int PW=8;
const int v=A0;
const int THRS = 135;                 //valore termoresistore posizione Standby
const int THRL = 140;                 //valore termoresistore posizione Low
const int THRM = 145;                 //valore termoresistore posizione Medium
const int THRH = 150;                 //valore termoresistore posizione High
byte stato=1; 


void setup() {
  Serial.begin(9600);
  pinMode(v, INPUT);        //vlaore registrato termoresistore
  pinMode(LED1[0], OUTPUT); //led standby
  pinMode(LED1[1], OUTPUT); //led LOW
  pinMode(LED1[2], OUTPUT); //led MIDIUM
  pinMode(LED1[3], OUTPUT); //led HIGH    
  pinMode(P1, INPUT);       //Pulsante
  pinMode(PW, OUTPUT);      //Relè
}

void loop() {

  if(digitalRead(P1))

  {

    if(stato<4) stato=stato+1;

    else stato=1;

  }
  

     
switch(stato)
{ case 1:
    
    analogRead(v);
    Serial.println(v);
    delay(500);
    digitalWrite(LED1[0],HIGH);
    if (v < THRS) {
    digitalWrite(PW, HIGH);
    }
    digitalWrite(LED1[1],LOW);
    digitalWrite(LED1[2],LOW);
    digitalWrite(LED1[3],LOW);
    digitalWrite(PW, LOW);
    break;

    
  case 2:
    analogRead(v);
    Serial.println(v);
    delay(500);
    digitalWrite(LED1[0],LOW);
    digitalWrite(LED1[1],HIGH);
    if (v < THRL) {
    digitalWrite(PW, HIGH);
    }
    digitalWrite(LED1[2],LOW);
    digitalWrite(LED1[3],LOW);
    digitalWrite(PW, LOW);
    break;

    
  case 3:
    analogRead(v);
    Serial.println(v);
    delay(500);
    digitalWrite(LED1[0],LOW);
    digitalWrite(LED1[1],LOW);
    digitalWrite(LED1[2],HIGH);
    if (v < THRM) {
    digitalWrite(PW, HIGH);
    }
    digitalWrite(LED1[3],LOW);
    digitalWrite(PW, LOW);
    break;

    
  case 4:
    analogRead(v);
    Serial.println(v);
    delay(500);
    digitalWrite(LED1[0],LOW);
    digitalWrite(LED1[1],LOW);
    digitalWrite(LED1[2],LOW);
    digitalWrite(LED1[3],HIGH);
    if (v < THRH) {
    digitalWrite(PW, HIGH); 
    }
    digitalWrite(PW, LOW);    
    break;
} 

  while (digitalRead(P1) == LOW)
  {
    delay(10);
  }

  delay(debaunceDelay);

}

Sono sincero; Sono un neofita di Arduino ed ho realizzato alcuni progetti sempre con il prezioso aiuto del forum.
Qui c'è farina del mio sacco insieme a qualche ricerca su internet, quindi avrò fatto sicuramente un po' di casino.

Il circuito funziona sulla commutazione della fase visibile tramite i led ma non per quanto riguarda l'eccitazione del relè sulla base della lettura del valore del termoresistore.

Grazie a tutti!!

A parte la gestione del pulsante un po' fantasiosa, ma se dici che funziona tralasciamo...
Per come hai scritto gli if accendi il relè e subito dopo lo spegni. Il digitalWrite con low credo vada nell'else.

Grazie mille per la risposta!!
Spero di aver capito quello che intendevi dire e quindi ho apportato delle modifiche allo sketch:

const byte LED1[]={ 9, 10, 11, 12 };
const int P1=2;                       //Pulsante cambio di stato
const int debaunceDelay=500;
const int PW=8;                       //Relè
const int THRS = 100;                 //valore termoresistore posizione Standby
const int THRL = 170;                 //valore termoresistore posizione Low
const int THRM = 180;                 //valore termoresistore posizione Medium
const int THRH = 190;                 //valore termoresistore posizione High
byte stato=1; 


void setup() {
  Serial.begin(9600);

  pinMode(LED1[0], OUTPUT); //led standby
  pinMode(LED1[1], OUTPUT); //led LOW
  pinMode(LED1[2], OUTPUT); //led MIDIUM
  pinMode(LED1[3], OUTPUT); //led HIGH    
  pinMode(P1, INPUT);       //Pulsante
  pinMode(PW, OUTPUT);      //Relè
}

void loop() {
   int v = analogRead(A0);
   Serial.println(v);
   
   
  if(digitalRead(P1))

  {

    if(stato<4) stato=stato+1;

    else stato=1;

  }
  
   
     
switch(stato)
{ case 1:
    digitalWrite(LED1[0],HIGH);
    digitalWrite(LED1[1],LOW);
    digitalWrite(LED1[2],LOW);
    digitalWrite(LED1[3],LOW);
    {
    if (v > THRS) digitalWrite(PW, HIGH); 
    else digitalWrite(PW, LOW);
    }    
    break;

    
  case 2:
    digitalWrite(LED1[0],LOW);
    digitalWrite(LED1[1],HIGH);
    digitalWrite(LED1[2],LOW);
    digitalWrite(LED1[3],LOW);
    {
    if (v > THRL) digitalWrite(PW, HIGH);
    else digitalWrite(PW, LOW);   
    }    
    break;

    
  case 3:
    digitalWrite(LED1[0],LOW);
    digitalWrite(LED1[1],LOW);
    digitalWrite(LED1[2],HIGH);
    digitalWrite(LED1[3],LOW);
    {
    if (v > THRM) digitalWrite(PW, HIGH); 
    else digitalWrite(PW, LOW);
    }    
    break;

    
  case 4:
    digitalWrite(LED1[0],LOW);
    digitalWrite(LED1[1],LOW);
    digitalWrite(LED1[2],LOW);
    digitalWrite(LED1[3],HIGH);
    {
    if (v > THRH) digitalWrite(PW, HIGH);  
    else digitalWrite(PW, LOW);
    }
    
    
       
    break;
} 

  while (digitalRead(P1) == LOW)
  {
    delay(10);
  }

  delay(debaunceDelay);

}

Quello che adesso mi manda in bestia e che sto facendo un sacco di confusione con i delay e non riesco a dare una continuità cadenzata alla lettura della termoresistenza. Se apro il monitor seriale la lettura viene effettuata solo alla pressione del pulsante ed a una frequenza dettata dal delay.

Grazie

Il problema è come gestisci il pulsante.
Cerca qualche esempio di debounce software e cerca di capire come funziona.

Visto che sei un neofita a questo punto ti consiglio un debounce hardware. È più semplice e ti elimini un po di problemi di programmazione.

Sergio_A:
un sacco di confusione con i delay e non riesco a dare una continuità cadenzata alla lettura della termoresistenza. Se apro il monitor seriale la lettura viene effettuata solo alla pressione del pulsante ed a una frequenza dettata dal delay

Confronta il design logico del tuo codice del post #3 (flowchart a sinistra) con un altro possibile design (a destra). Il flusso del tuo disegno è bloccato sia dal while (che attende finché il pulsante non viene premuto), sia dal successivo delay di mezzo secondo. A destra invece c'è solo un piccolo delay da 40ms che fa da debounce (certo rallenta il loop a circa 25 cicli al secondo, ma in questo caso vanno benissimo). Di più c'è solo la variabile flag 'giaprem' (indicatore di pulsante già rilevato premuto al ciclo precedente). In qualsiasi caso partendo dall'alto fino alla fine non c'è niente che possa bloccare l'esecuzione e causare ritardi o comportamenti non progettati/previsti. Per questo dico sempre che la logica prima si pensa/progetta/disegna già funzionante su carta, e solo poi si traduce in istruzioni, è molto più semplice ed evita un sacco di "mi manda in bestia" :wink:

nello79:
Visto che sei un neofita a questo punto ti consiglio un debounce hardware. È più semplice e ti elimini un po di problemi di programmazione.

Anche io, quando vedo un debounce software, ho dei conati di vomito.
Ma vedo che continua ad essere consigliato...

Eh ma qui i "problemi" sono tre contemporaneamente (sempre gli stessi :roll_eyes:), debounce, edge detect e logica bloccante. Tutti presenti nel flow di sinistra, tutti risolti in quello di destra. Stesso Arduino, stessi componenti, stesso linguaggio, solo due "disegni" diversi :wink:

1 Like

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.