termostato con salvataggio in sd

oggi mi sono messo a modificare il programma del mio termostato per inserire un sd per farlo funzionare come datalogger
ecco lo sketch

#include <SD.h>
#include <dht11.h>
dht11 DHT;
#define DHT11_PIN 8




const int buttonPin = 6;
const int buttonPin2 = 5;// the number of the pushbutton pin
int buttonState;  
int buttonState2;// the current reading from the input pin
int lastButtonState = LOW;
int lastButtonState2 = LOW;// the previous reading from the input pin
int olo = 25;
long lastDebounceTime = 0;
long lastDebounceTime2 = 0;// the last time the output pin was toggled
long debounceDelay = 50;
long debounceDelay2 = 50 ;// the debounce time; increase if the output flickers
File temperatura;
void setup() {

pinMode(buttonPin, INPUT);
pinMode(buttonPin2,INPUT);
pinMode(7,OUTPUT);
Serial.begin(9600);
SD.begin();}



void loop() {


  int reading = digitalRead(buttonPin);
  if (reading != lastButtonState) {
    lastDebounceTime = millis(); } 
  if ((millis() - lastDebounceTime) > debounceDelay) {
    if (reading != buttonState) {
      buttonState = reading;
      if (buttonState == HIGH) { (olo++);}}}
  lastButtonState = reading;


  int reading2 = digitalRead(buttonPin2);
  if (reading2 != lastButtonState2) {
    lastDebounceTime2 = millis(); } 
  if ((millis() - lastDebounceTime2) > debounceDelay2) {
    if (reading2 != buttonState2) {
      buttonState2 = reading2;
      if (buttonState2 == HIGH) { (olo--);  
  
       
      }
    }
  } int chk = DHT.read(DHT11_PIN);
  delay(18);

int temp =  DHT.temperature;delay(18);
  Serial.print( DHT.temperature);
  Serial.print("C' ");
  Serial.print(DHT.humidity);delay(18);
  Serial.print("%   ");
  Serial.print(olo);
  Serial.println("    ");
  if(temp>=olo){digitalWrite(7,LOW);}
  if(temp<=olo-3){digitalWrite(7,HIGH);}delay(20);
  
  
lastButtonState2 = reading2;
if(olo<100000)
{temperatura = SD.open("datilog.txt",FILE_WRITE);
temperatura.print ("temperatura");
temperatura.println(DHT.temperature);
temperatura.print("umidita");
temperatura.println(DHT.humidity);
temperatura.close();
delay(10000);
temperatura = SD.open("datilog.txt",FILE_WRITE);
temperatura.print ("temperatura");
temperatura.println(DHT.temperature);
temperatura.print("umidita");
temperatura.println(DHT.humidity);
temperatura.close();}
}

pero non va come dovrebbe ho inserito if(olo<100000) perche pensavo che stando la parte del salvataggio in sd in un if poteva contemporaneamente funzionare il termostato
invece la scrittura su seriale avviene ogni 10 secondi invece di essere continua e percio trovo difficoltoso cambiare il valore di olo

ce qualche funzioni che faccia fare le 2 cose contemporaneamente cioe fare da termostato regolabile con scrittura in seriale
e la scrittura in SD?

in futuro aggiungero un rtc un lcd e tutti i vari controlli dell hardware, potrebbe essere difficoltoso??

... non sei mica su un PC dove c'è un sistema operativo multi thread / multitask ... sei su una MCU e i pseudo-parallelismi te li devi fare da solo con la tecnica del millis() !

Nel codice tu usi una delay(10000) ... finché continui ad usare la delay() non ti puoi aspettare di riuscire a fare pseudo-parallelismi ... in casi come questi, è d'obbligo l'uso della millis() con i relativi IF ... :roll_eyes:

Guglielmo

visto che il termostato verra utilizzato in una camera calda per pappagalli e non vorrei rischiare ,la parte di salvataggio in SD sarebbe meglio farla gestire da un altro processore??
in tal caso quale mi consigli visto che io non ho mai programmato altri processori?

Scusa, senza che mi metto a cercare di interpretare cosa dovrebbe fare il codice che hai postato ...

... potresti descrivere esattamente cosa vuoi fare ? Ovvero le varie fasi step-by-step ? Magari si trova una soluzione più semplice ... :roll_eyes:

Guglielmo

In effetti nel tuo sketch modifichi il valore di olo utilizzandolo come setpoint. Con “if olo < 10000” gli fai compiere la scrittura su SD ogni volta che fa il loop finchè non avrai impostato un setpoint di 10000!
Secondo me dovresti salvare il valore del setpoint ogni volta che lo cambi, o meglio ancora, 30 secondi dopo che l’hai cambiato, in modo che se lo stai “sistemando” scriverai su SD solo una volta che hai finito di regolarlo…
Studia l’esempio “blink without delay” e usa la funzione millis(), togliendo i delay, come ha suggerito Guglielmo… vedrai che funzia sia la gestione dei tasti che il salvataggio ! :wink:

il programma dovrebbe leggere i dati provenienti da un dht11 temperatura e umidita
quando la temperatura arriva ad olo si disattiva un relay che controlla una lampada
olo si cambia con due pulsanti pero appena parte il programma olo è a 25 gradi
il termostato doverebbe anche salvare in sd ogni 20 minuti circa la temperatura l umidita e l ora

ho guardato la funzione millis pero ho visto che puo durare 50 gg ed rende un filino piu complicato il programma

in futuro se possibile vorrei inserire un altro pulsante per salvare la variabile olo

if(olo<10000) era solo una prova olo non puo essere mai superiore a 10000(arrostirei i pappagalli :slight_smile: )

in realtà nel tuo sketch millis la usi diverse volte, per l'antirimbalzo :wink:
è vero che quando millis va in overflow può dare dei problemi, ma nel tuo caso faresti dei controlli solo in occasione di eventi (pressione di pulsante), quindi si potrebbe tollerare questo "errore" visto che si manifesterebbe solo se tu premi il pulsante proprio a cavallo dell'overflow (caso piuttosto raro direi !!). Comunque si può gestire facilmente facendo un confronto in valore assoluto (abs) invece che tout court.
Per salvare temperature ed umidità non c'è problema, basta fare un logger (ci sono 1000 esempi in rete) ma in ogni caso dovresti usare il riferimento al millis o all'RTC che vuoi implementare.
Anche salvare i setpoint con il pulsante potrebbe andar bene, basta che ti ricordi di farlo ogni volta che lo cambi!

michaelferrara:
ho guardato la funzione millis pero ho visto che puo durare 50 gg ed rende un filino piu complicato il programma

tapirinho:
è vero che quando millis va in overflow può dare dei problemi, ma nel tuo caso faresti dei controlli solo in occasione di eventi (pressione di pulsante), quindi si potrebbe tollerare questo "errore" visto che si manifesterebbe solo se tu premi il pulsante proprio a cavallo dell'overflow (caso piuttosto raro direi !!).

Quello della millis() che va in overflow è, salvo rarissimi casi, un falso problema dovuto al non aver capito come si usa !!!

Link da studiare ... QUESTO e poi QUESTO :wink:

Guglielmo

io in effetti ho sempre usato quella che viene indicata come seconda soluzione... solo che pensando (erroneamente come dice leo) che risultasse negativo, aggiungevo per l'appunto un abs.. :sweat_smile:

ok il salvataggio in sd va bene pero oggi mi sono accorto che la temperatura non è tanta giusta
ho preso un termoigometro professionale e mi dava 14.6 gradi e 55% di umidita
mentre il dht11 16 gradi e 36 di umità
ora mi chiedo se è il sensore che è troppo impreciso o bisogna fare delle tarature?
ci vogliono dei secondi di stabilizzazione fra una lettura e un altra ?
va bene salvare subito in SD o meglio fare 3-4 salvataggi in un buffer e poi salvare tt in sd??

ciao a tutti, scusate se mi intrometto in questa discussione, ho letto i documenti postati da guglielmo, molto chiaro e disponibile, avrei una piccola domanda molto banale ma non esplicitamente riportata sui documenti:
il timer che si occupa di millis che va in overflow ogiorni circa parte da alimento la scheda fin qui tutto ok se la stacco e la riattacco e carico il programma ovviamente riparte da zero.... giusto?(sono sicuro al 99% ma non vorrei fare errori che sto facendo un progettino per la maturità)(elettronico...... 8) 8) 8) )
grazie mille

superpeg:
il timer che si occupa di millis che va in overflow ogiorni circa parte da alimento la scheda fin qui tutto ok se la stacco e la riattacco e carico il programma ovviamente riparte da zero.... giusto?

Giusto .. i timer sono dento la MCU e sono volatili ...
... se togli l'alimentazione ... l'unica cosa che si salva sono :

  1. I FUSE
  2. ciò che è memorizzato nella Flash memory (i programmi)
  3. ciò che è memorizzato nella EEPROM

... tutto il resto ... bye bye XD

Guglielmo

michaelferrara:
oggi mi sono accorto che la temperatura non è tanta giusta
ho preso un termoigometro professionale e mi dava 14.6 gradi e 55% di umidita
mentre il dht11 16 gradi e 36 di umità

... hai già aperto un'altra discussione QUI per questa cosa e ti ci ho già risposto.

Ti ricordo che, da regolamento, il cross-posting è vietato !

Guglielmo

scusa ma visto che ero un po of topic mi sembrava giusto aprire un altra discussione
ho letto la guida linkata per evitare l overflow e da quanto ho capito il mio programma non ne dovrebbe soffrire ,o sbaglio?

la prima soluzione non l ho capita perche di numeri binari e di operatori logici non so molto

la parte If((long)(millis()-intervallo>=0)
quel long a che serve??

.

La differenza (convertita in una variabile di tipo signed) fra millis() e overflow,

com'è scritto nel tutorial di Leo, converte il risultato in un numero di tipo signed long, altrimenti il risultato tra due variabili unsigned darebbe come risultato un'altra grandezza unsigned

ok ho capito ,
ma il mio sketch usa la seconda soluzione giusto? o sbaglio?

michaelferrara:
...
la parte If((long)(millis()-intervallo>=0)
quel long a che serve??

Premesso che hai riportato male lo statement e che, quello giusto, è :

if ( (long)(millis() - intervallo) >= 0 ) {

quel (long) è un operatore di cast che serve a dire che, il risultato di (millis() - intervallo) deve essere considerato come un "long" ovvero un numero con segno.

Guglielmo

si ok ho capito
volevo la conferma che il mio sketch usasse il secondo metodo,
chiedo a voi ,il mio programma soffre di overflow ??

michaelferrara:
chiedo a voi ,il mio programma soffre di overflow ??

perché dovrebbe ??? :astonished: :astonished: :astonished:

Usi il classico :

if ((millis() - lastDebounceTime) > debounceDelay) {

... e, se hai ben studiato quanto scrive Leo, non dovresti avere dubbi :wink:

Guglielmo