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 ...
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?
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 !
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 )
in realtà nel tuo sketch millis la usi diverse volte, per l'antirimbalzo
è 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 !!!
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..
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 :
I FUSE
ciò che è memorizzato nella Flash memory (i programmi)
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 !
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
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.