termostato non aggiorna la temperatura (Arduino uno)

Ciao, sono un semplice amatore di Arduino e piuttosto scarso nella programmazione; sto realizzando un termostato per un fornetto molto semplice con Arduino uno ed il Max6675, cercando pezzi di programma qua e la e cerco di dare un senso a tutto.

il mio problema è questo:
riesco a visualizzare la temperatura, il set point impostato e lo cambio con due pulsanti (+ e -), riesco ad attivare l’uscita che comanderà un relè SSD e la visualizzo sempre nel display con ON e OFF ma la temperatura letta dalla termocoppia K del modulo 6675 rimane sempre la stessa nel display finché non premo uno dei due pulsanti per variare il set.
a quel punto si aggiorna.

Purtroppo la mia inesistente esperienza nel linguaggio di programmazione mi ha bloccato qui.

un grazie a chi vorrà e potrà aiutarmi.

ciao!

termostato_fornetto_v2.ino (2.23 KB)

Si vedo, ma non riesco a seguire la debounce, comunque c'è quel while che potrebbe essere bloccante.

Prova a rimuovere il delay(500) che è dentro il corpo della if

if (debounce(tempM) == LOW) {

Per debounce puoi aiutarti con un circuito RC, tipo questo:

Prova anche a implementare una "macchina a stati finiti", comunque documentati, se non riesci posta e in qualche modo si fa.

Ciao.

comunque c'è quel while che potrebbe essere bloccante.

Quel while può essere bloccante se i pulsanti utilizzati sono dei normalmente chiusi.
Questo può spiegare i sintomi! ;D
Prova cosi':

  if (debounce(tempP) == HIGH) {
    set = set + 1; //incrementa di 1 se il pulsante è premuto
    while (debounce(tempP) == HIGH) {
      delay(5);  //attendi il rilascio del pulsante
    }
  }

  if (debounce(tempM) == HIGH) {
    set = set - 1; //decrementa di 1 se il pulsante è premuto
    while (debounce(tempM) == HIGH) {
      delay(5);  //attendi il rilascio del pulsante
    }
  }

Prova anche a implementare una "macchina a stati finiti"

è quasi un'urgenza!

è quasi un'urgenza!

Concordo, però scrive che:

Purtroppo la mia inesistente esperienza nel linguaggio di programmazione mi ha bloccato qui.

Per i pulsanti usa le pull-up interne, qui:

pinMode(tempP, INPUT_PULLUP);
pinMode(tempM, INPUT_PULLUP);

Quindi quando il pulsante è rilasciato legge HIGH, quando premuto legge LOW.

Ciao.

Quindi quando il pulsante è rilasciato legge HIGH, quando premuto legge LOW.

OK se i pulsanti sono dei normalmente aperti.
Ma se usa dei normalmente chiusi?

OK se i pulsanti sono dei normalmente aperti.

Ragione non ci avevo pensato, ma sono così comuni i pulsanti NC?

Aspettiamo l'utente, così ci (e si) chiarisce alcuni punti.

Ciao.

digitalWrite(A0, HIGH); //accendo retroilluminazione lcd

E' inutile che stia nel loop, ripetuto continuamente.
Inoltre sarebbe opportuno prevedere un'isteresi, in modo che il relè non possa eccitarsi e diseccitarsi in continuazione. Ad esempio, potrebbe eccitarsi quando la temperatura scende 0,5°C al di sotto di quella impostata e diseccitarsi quando sale 0,5°C al di sopra se vuoi essere pignolo, ma l'isteresi può anche essere maggiore.

ciao a tutti e grazie, purtroppo le mie lacune sono evidenti.
I pulsanti funzionano, aumentano e diminuiscono il set point, quella parte di programma non mi da problemi.
Il problema è la lettura\visualizzazione della temperatura: anche se aumenta di 20 gradi (scaldo la sonda) il display non si aggiorna finchè non agisco su uno dei due pulsanti.
In quel momento mi fa vedere la variazione della temperatura letta dalla sonda K.
Sto "studiando" l'uso dei millis, ho capito la teoria anche della macchina a stati finiti ma non credo di avere le basi per portarlo avanti.
Mi serve un semplice termostato che visualizzi la temperatura attuale nella riga 1 ed il set point nella riga 2, modificandolo con i due pulsanti appunto.
L'idea dell'isteresi sarebbe ottimale, provo a studiarci.

Ancora:
questo nel loop è inutile, perché è già presente in readtemp():
float temp = tc.readCelsius();
int t = tc.readCelsius();

Fatto ciò che ti ho detto e riordinato e compattato un po’:

#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
#include <AverageThermocouple.h>
#include <MAX6675_Thermocouple.h>
MAX6675_Thermocouple tc = MAX6675_Thermocouple(SCK_PIN, CS_PIN, SO_PIN);
#include <SmoothThermocouple.h>
#include <Thermocouple.h>

#define SCK_PIN 10
#define CS_PIN 9
#define SO_PIN 8

#define tempP 7
#define tempM 6
#define relay_PIN 13

int set = 20;
int previous_set;
int debounceDelay = 20;

boolean debounce(int pin)
{
boolean state;
boolean previousState;
previousState = digitalRead(pin);
for (int counter=0; counter<debounceDelay; counter++)
  {
  delay(1);
  state = digitalRead(pin);
  if (state != previousState)
    {
    counter = 0;
    previousState = state;
    }
  }
return state;
}

void setup()
{
pinMode(A0, OUTPUT);
pinMode(tempP, INPUT_PULLUP);
pinMode(tempM, INPUT_PULLUP);
Serial.begin(9600);
lcd.begin(16, 2);

lcd.setCursor(0, 0); lcd.print("TEMP:");
lcd.setCursor(10, 0); lcd.print((char)223); lcd.print('C');
lcd.setCursor(0, 1); lcd.print("SET:");
lcd.setCursor(10, 1); lcd.print((char)223); lcd.print('C');
}

void readtemp()
{
float temp = tc.readCelsius();
int t = tc.readCelsius();
lcd.setCursor(7, 0); lcd.print(t);
}

void loop()
{
readtemp();
lcd.setCursor(7, 1); lcd.print(set);
if (t<=set)
  {
  lcd.setCursor(13, 1); lcd.print("ON");
  digitalWrite(13, HIGH); //attivo uscita relè
  }
else
  {
  digitalWrite(13, LOW);
  lcd.setCursor(13, 1); lcd.print("OFF"); //disattivo uscita relè
  }

if (debounce(tempP)==LOW)
  {
  set = set+1; //incrementa di 1 se il pulsante è premuto
  while (debounce(tempP)==LOW) {delay(5);}  //attendi il rilascio del pulsante
  }

if (debounce(tempM)==LOW)
  {
  set = set-1; //decrementa di 1 se il pulsante è premuto
  while (debounce(tempM)==LOW) {delay(5);}  //attendi il rilascio del pulsante
  delay(500);
  }
}

Ma che cos’è quel delay(500) nell’ultimo if?..

Togli tutti i debounce e metti 220nF, eventualmente con 100 Ohm in serie, in parallelo a ogni pulsante e vedi se (che :slight_smile: ) funziona.

I pulsanti funzionano, aumentano e diminuiscono il set point, quella parte di programma non mi da problemi.
Il problema è la lettura\visualizzazione della temperatura: anche se aumenta di 20 gradi (scaldo la sonda) il display non si aggiorna finchè non agisco su uno dei due pulsanti.

Questo non esclude il fatto che i tuoi pulsanti non siano dei NC.

Se così fosse, però, l'incremento avverrebbe nel momento in cui si lascia il pulsante. Comunque esistono anche pulsanti che hanno sia i contatti NA che NC.

l’incremento avverrebbe nel momento in cui si lascia il pulsante.

Come diceva anche Maurotec, il codice si blocca da qualche parte e quei due while possono essere la causa.
Penso che sia una pista facilmente smentibile cambiando i LOW per dei HIGH; giusto per aver il cuore in pace!
Anche se:

riesco ad attivare l’uscita che comanderà un relè SSD e la visualizzo sempre nel display con ON e OFF

questo smantella di netto la mia ipotesi.

Comunque inserendo uno o due Serial.println la cosa si risolverebbe in un baleno.

void readtemp () {
  float temp = tc.readCelsius();
  int t = tc.readCelsius();
  Serial.println(t);
  lcd.setCursor(7, 0);
  lcd.print(t);

}

boolean debounce(int pin)
{
  boolean state;
  boolean previousState = digitalRead(pin);
  Serial.println(previousState)
  for (int counter = 0; counter < debounceDelay; counter++) {
    delay(1);
    state = digitalRead(pin);
    if ( state != previousState) {
      counter = 0;
      previousState = state;
    }
  }
  return state;

}

per esempio.