Buona sera a tutti. Ho un problema di stampa a intervalli regolari con rtc.
Nello specifico devo stampare alcune informazioni a intervalli di 15 minuti e altre informazioni a intervalli di 1 secondo. Se le due parti le scrivo su due sketch separati funzionano. Se invece le unisco inizia la stampa a intervalli di 1 secondo, arriva al 15mo minuto, stampa le informazioni del 15mo minuto e si blocca la stampa.
Come posso risolvere?
senza vedere il programma è un po' difficile...
Scusate il ritardo. Vi giro il codice semplificato. Il codice stampa a intervalli di 1 secondo l'ora, minuti e secondi. Poi se l'orario è compreso tra "StartTimeWork" e "FinishTimeWork"
fa un'altra stampa, se arriva al 15mo minuto fa la successiva stampa, ma poi si blocca.
A dopo!!!
void loop() {
DateTime now = rtc.now();
if (correntMillis - previousMillis >= intervalRead) {
previousMillis = correntMillis;
Serial.print(now.hour(), DEC);
Serial.print(':');
Serial.print(now.minute(), DEC);
Serial.print(':');
Serial.print(now.second(), DEC);
Serial.println(" ");
if (now.hour() >= StartTimeWork && now.hour() < FinishTimeWork) {
Serial.print(" ");
if(now.hour()>=0 && now.minute()==0 | now.minute() ==15 | now.minute() ==30 | now.minute() ==45 && now.second()==0) {
Serial.print(" ");
}
}
}
scusa ma questo non è il codice che ti da il problema che riporti...questo codice è incompleto e sbagliato per altri motivi.
posta quello "corretto" o non ne usciamo.
In realtà è questo il codice con la differenza che ho tolto le letture del sensore di temperatura e le ho sostituite con un semplice serial print. Il problema è proprio nella stampa dell'ultima parte. Mi spunta un punto interrogativo sul serial monitor.
Ci sono alcuni errori, tra i quali l'uso dello or sbagliato e il mancato aggiornamento di currentmillis
Dubito che quel programma abbia i problemi che dici, ne ha altri peggiori
Inoltre siamo convinti che tu abbia copiato in tutto o in parte da vecchi siti o pubblicazioni
Comunque dato che quel programma non può dare gli errori che descrivi ti consiglierei di controllare bene i messaggi di errore in compilazione e trasferimento
Buongiorno, io non sono un programmatore quindi sto cercando di imparare da quello che trovo sulla rete incluso il forum.
Nel codice ho dimenticato a copiare "unsigned long currentMillis = now.unixtime() * 1000;" prima del primo if.
Per quanto riguarda errori di compilazione non ne da. Lo sketch viene caricato su Arduino, parte ma poi si blocca.
Non saprei!!
Invece di impegolarsi con i millisecondi io controllerei quando cambia il secondo:
if (now.second() != previousSecond) {
previousSecond = now.second();
}
Adesso si comincia a ragionare
E per quanto riguarda la condizione sbagliata?
Perfetto questo mi semplifica il codice!!!!
Se lo provi ti funziona? Cioè riesci a vedere l'ultimo serial print?
Non lo so
Non lo provo di certo
E' incompleto e certamente sbagliato
Il debug si fa su programmi completi e che dovrebbero funzionare
Su quelli che sono certamente sbagliati "prima" si tolgono gli errori conosciuti, "dopo" si vede cosa fanno
Riassumendo: metti a posto la condizione
Ricompila il programma
Vedi come va
E poi casomai postalo con una descrizione completa e dettagliata di cosa dovrebbe fare e di cosa fa
E mi raccomando: completo, compilabile e formattato
Quel if non può funzionare senza ulteriori parentesi
tuo originale:
now.hour()>=0 && now.minute()==0 | now.minute() ==15 | now.minute() ==30 | now.minute() ==45 && now.second()==0
corretto:
now.hour()>=0 && (now.minute()==0 || now.minute() ==15 || now.minute() ==30 || now.minute() ==45) && now.second()==0
senza parentesi ogni test viene valutato da sx a dx, quindi ora>=0 e minuto=0, poi oppure minuto=15, etc. Inoltre or logico è || e non | (solo uno è or sui bit)
P.S. a che serve chiedere se hour() >= 0 ?? ti risulta possa essere negativo ??
Edit: corretto "or logico", grazie @Salvorhardin
Buona sera, ringrazio tutti per le correzioni e mi scuso per il ritardo nella risposta. Ho aggiunto alcune righe di codice e lo condivido in modo da poterlo sistemare. Il codice viene compilato, il seriale restituisce quello che deve ma appena tolgo lo Slash della riga 269 e i successivi serial print il monitor seriale si blocca. Grazie a dopo!!!
//RTC+SD
#include <RTClib.h>
#include <SPI.h>
#include <SD.h>
#define SD_CS_PIN 10 //pin CS del modulo SD
File dataFile;
RTC_DS1307 rtc;
char daysOfTheWeek[7][4] = {"Dom","Lun","Mer","Mer","Gio","Ven","Sab",};
// valore dell'igrometro che attiva il relè
const int valore_limite = 990;
// costanti per il calcolo del VPD. La formula è stata presa dal file excel del calcolo del VPD
float avpd = 0;
float a = 0;
// costanti per il calcolo della media delle letture dell'igrometro
float valori [10];
float media =0.0;
//costanti igrometro
float igro = 0;
float umdtrr = 0;
//costanti light sensor e attivazione attuatori
int StartTimeWork = 6;
int FinishTimeWork = 22;
int TimeBuffer = 1;
long PPFD_micro_watt_cmq = 0;
long PPFD_watt_mq = 0;
int soglia_PPFD_watt_mq = 400;
unsigned long DLI_micromoli_mq_giornaliero = 0;
long soglia_DLI_micromoli_mq_giornaliero = 20000; //scegliere un valore in moli e convertirlo in micromoli(es: 100 moli/mq/day * 1000000)
DateTime PPFD_firstOverThresholdTime;
bool PPFD_OverThreshold = false;
bool DLI_OverThreshold = false;
//costanti per stampare a intervalli regolari
unsigned long correntMillis;
unsigned long previousMillis = 0;
const long intervalRead = 1000;
//DGT11 sensor:
#include "DHT.h"
#define DHTPIN 6 //sensore collegato al pin 6
#define DHTTYPE DHT11 //DHT 11
DHT dht(DHTPIN, DHTTYPE);
//I2C LCD:
#include <Wire.h> // Libreria Wire
#include <LiquidCrystal_I2C.h> //Libreria LCD I2C
//LCD Address
LiquidCrystal_I2C lcd = LiquidCrystal_I2C (0x27, 20, 4);//da cambiare se si ha un modello diverso
//Libreria Light Sensor
#include <Wire.h>
#include "Adafruit_AS726x.h"
//create the object
Adafruit_AS726x ams;
//buffer to hold raw values
uint16_t sensorValues[AS726x_NUM_CHANNELS];
//buffer to hold calibrated values (not used by default in this example)
//float calibratedValues[AS726x_NUM_CHANNELS];
void setup() {
Serial.begin(9600);
// Pin 4 al relè - IN4
pinMode(4, OUTPUT);
// Pin 3 al relè - IN3
pinMode(3, OUTPUT);
// Pin 2 al relè - IN2
pinMode(2, OUTPUT);
//I2C LCD
lcd.init ();
lcd.backlight();
lcd.clear();
//Serial.print ("Serra Domotizzata");
lcd.print("Serra Domotizzata");
lcd.clear();
//Avvio Sensore DHT11
dht.begin();
//Avvio RTC+SD
if (!rtc.begin()) {
Serial.println("Error");
return;
}
if (!rtc.isrunning()) {
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}
// initialize digital pin LED_BUILTIN as an output light sensor
pinMode(LED_BUILTIN, OUTPUT);
//begin and make sure we can talk to the light sensor
if(!ams.begin()){
Serial.println("could not connect to sensor! Please check your wiring.");
while(1);
}
//begin SD card
if (!SD.begin(SD_CS_PIN)) {
Serial.println("inizializzazione SD fallita");
while (1)
;
}
}
void loop() {
//RTC+SD
DateTime now = rtc.now();
correntMillis = now.unixtime() * 1000; //conversione del tempo in millisecondi
if (correntMillis - previousMillis >= intervalRead) { //Confronta il tempo corrente rispetto all'ultima lettura del tempo e se la differenza è maggiore o uguale allintervallo allora...
previousMillis = correntMillis; //il tempo precedente dell'ultima lettura è uguale alla lettura del tempo corrente, quindi essendo uguali la sequanza del loop avverrà a cadenza dell'intervallo prefissato.
Serial.print(now.day(), DEC);
Serial.print('/');
Serial.print(now.month(), DEC);
Serial.print('/');
Serial.print(now.year(), DEC);
Serial.print(" (");
Serial.print(daysOfTheWeek[now.dayOfTheWeek()]);
Serial.print(") ");
Serial.print(now.hour(), DEC);
Serial.print(':');
Serial.print(now.minute(), DEC);
Serial.print(':');
Serial.print(now.second(), DEC);
Serial.println(" ");
//Stampa su SD
dataFile = SD.open("datalog.txt", FILE_WRITE);
if (dataFile) {
dataFile.print(now.hour(), DEC);
dataFile.print(" : ");
dataFile.print(now.minute(), DEC);
dataFile.print(" : ");
dataFile.print(now.second(), DEC);
dataFile.println(" ");
dataFile.close();
} else {
Serial.println("Errore scrittura su SD");
}
if (now.hour() >= StartTimeWork && now.hour() < FinishTimeWork) {
//read the device temperature
uint8_t temp = ams.readTemperature();
//ams.drvOn(); //uncomment this if you want to use the driver LED for readings
ams.startMeasurement(); //begin a measurement
//wait till data is available
bool rdy = false;
while (!rdy) {
//delay(5);
rdy = ams.dataReady();
}
//ams.drvOff(); //uncomment this if you want to use the driver LED for readings
//read the values!
ams.readRawValues(sensorValues);
//ams.readCalibratedValues(calibratedValues);
Serial.print("Temp: ");
Serial.print(temp);
Serial.print(" Violet: ");
Serial.print(sensorValues[AS726x_VIOLET]);
Serial.print(" Blue: ");
Serial.print(sensorValues[AS726x_BLUE]);
Serial.print(" Green: ");
Serial.print(sensorValues[AS726x_GREEN]);
Serial.print(" Yellow: ");
Serial.print(sensorValues[AS726x_YELLOW]);
Serial.print(" Orange: ");
Serial.print(sensorValues[AS726x_ORANGE]);
Serial.print(" Red: ");
Serial.print(sensorValues[AS726x_RED]);
Serial.print(" PPFD: ");
PPFD_micro_watt_cmq = (sensorValues[AS726x_VIOLET]) + Serial.print(sensorValues[AS726x_BLUE]) + (sensorValues[AS726x_GREEN]) + (sensorValues[AS726x_YELLOW]) + (sensorValues[AS726x_ORANGE]) + (sensorValues[AS726x_RED]);
Serial.print(PPFD_micro_watt_cmq);
Serial.print(" microwatt/cq ");
Serial.print(" PPFD: ");
PPFD_watt_mq = (PPFD_micro_watt_cmq / 100);
DLI_micromoli_mq_giornaliero += (PPFD_watt_mq * 2); //1 watt/mq = 2 micromoli/mq/s. La moltiplicazione x 2 serve a fare la conversione. Vedi slide Stanghellini.
Serial.print(PPFD_watt_mq);
Serial.print(" watt/mq ");
Serial.print(" DLI: ");
Serial.print(DLI_micromoli_mq_giornaliero);
Serial.println(" micromole/m2/s");
//Serial.println();
if (DLI_micromoli_mq_giornaliero <= soglia_DLI_micromoli_mq_giornaliero) {
if (PPFD_watt_mq < soglia_PPFD_watt_mq) {
if (!PPFD_OverThreshold) { //prima volta che la soglia della luce è stata superata in positivo o in negativo in base alle impostazioni
PPFD_firstOverThresholdTime = rtc.now(); //salva l'ora corrente
PPFD_OverThreshold = true; //la soglia è stata superata
} else {
DateTime now = rtc.now();
TimeSpan elapsed = now - PPFD_firstOverThresholdTime;
if (elapsed.totalseconds() >= TimeBuffer) {
Serial.println("Accesa");
}
}
}
else { //la luce è sopra la soglia, reset
PPFD_OverThreshold = false;
Serial.println("spenta");
}
}
}
}
//Fotoresistore
int Lumen = analogRead (A0); //Lettura della fotoresistenza dal pin A0
if (Lumen > 750)
digitalWrite (2, HIGH); //se il valore di Lumen è maggiore di 750 attiva relè
else
digitalWrite (2, LOW); //altrimenti spegni il relè
//Livello acqua
int water = analogRead(A1);
if (water >=300) {
lcd.setCursor(0,3);
lcd.print("Livello Acqua: OK");
}
else
{
lcd.setCursor(0,3);
lcd.print("Livello Acqua: BASSA");
//alarm();
//flash();
}
//lettura Umidità e Temperatura e calcolo AVPD
float h = dht.readHumidity();
float t = dht.readTemperature();
a = 610.78 * exp( t/(t + 237.3) * 17.2594 )/1000.0;
avpd = a * (1.0 - h/100.0);
//Lettura valori dei sensori a intervalli prestabiliti
if(now.hour()>=0 && (now.minute()==00 || now.minute() ==56 || now.minute() ==30 || now.minute() ==45) && now.second()==0) {
//Igrometro
igro = analogRead (A2);
umdtrr = 0; //Variabile umidità suolo
umdtrr = map (igro, 100, 990, 100, 0); //converte il valore analogico in percentuale
//Serial.println(" Valore puntuale umidità del suolo: ");
//Serial.println(umdtrr);
for (int a =0; a<10; a++){
valori [a] = umdtrr;
media = media + valori [a];
//Serial.print("Valore delle 10 letture per fare la media dell'umidità del suolo: ");
//Serial.println(valori [a] );
}
media = media /10;
//Serial.print("Media di 10 letture umidità del suolo: ");
//Serial.println(media);
//Stampa valore sensore crepuscolare
//Serial.print ("Sensore crepuscolare: ");
//Serial.println (Lumen, DEC); //stampa un valore decimale del fotoresistore
//Stampa valore sensore di livello acqua
//Serial.print ("Sensore di livello: ");
//Serial.println(water, DEC); //stampa il valore decimale del livello dell'acqua
//Stampa valore sensore T e U
//Serial.print ("Temp: ");
//Serial.print (t);
//Serial.println (" C");
//Serial.print ("Umid: ");
//Serial.print (h);
//Serial.println (" %");
}
}
Che sarebba dalla riga //Serial.println(" Valore puntuale umidità del suolo: ");
Non ci vedo nulla di strano, mi sembra corretto come codice.
Hai provato a togliere i commenti a solo UNA di quelle Serial.print ?
P.S. quel giro di 10 col for non ha senso. Leggi solo 1 volta analogRead(A2) e lo scrivi in igro
essendo fuori dal for... umdtrr vale sempre lo stesso valore. Non serve un vettore visto che calcoli subito, non azzeri mai media.
//Igrometro
media = 0 ;
for (int a =0; a<10; a++)
{ igro = analogRead (A2);
media = media + map (igro, 100, 990, 100, 0); //converte il valore analogico in percentuale
}
media = media / 10.0;
269Ciao.
"Che sarebba dalla riga `//Serial.println(" Valore puntuale umidità del suolo: ");" Semplicemente è il valore di umidità nel momento della lettura. Per quanto riguarda la media dell'umidità, ha avuto solo lo scopo di verificare se il sensore leggeva correttamente, comunque andrà tolta. La modificherò per come mi hai consigliato.
"Hai provato a togliere i commenti a solo UNA di quelle Serial.print ?"
ho fatto diverse prove:
1)Stampa con serial print esclusa la riga 269 e successive: Tutto funziona correttamente
11/7/2024 (Gio) 17:27:45
Temp: 29 Violet: 265 Blue: 292 Green: 377 Yellow: 335 Orange: 229 Red: 197 PPFD: 2921406 microwatt/cq PPFD: 14 watt/mq DLI: 28 micromole/m2/s
11/7/2024 (Gio) 17:27:46
Temp: 28 Violet: 265 Blue: 292 Green: 377 Yellow: 335 Orange: 230 Red: 197 PPFD: 2921407 microwatt/cq PPFD: 14 watt/mq DLI: 56 micromole/m2/s
Accesa
11/7/2024 (Gio) 17:27:47
Temp: 29 Violet: 265 Blue: 293 Green: 377 Yellow: 335 Orange: 230 Red: 197 PPFD: 2931407 microwatt/cq PPFD: 14 watt/mq DLI: 84 micromole/m2/s
Accesa
11/7/2024 (Gio) 17:27:48
Temp: 29 Violet: 265 Blue: 292 Green: 377 Yellow: 335 Orange: 230 Red: 197 PPFD: 2921407 microwatt/cq PPFD: 14 watt/mq DLI: 112 micromole/m2/s
- Stampa con aggiunta della riga 269: Questo il risultato
11/7/2024 (Gio) 17:38:36
Temp: 30 Violet: 257 Blue: 287 Green: 372 Yellow: 333 Orange: 229 Red: 200 PPFD: 2871394 microwatt/cq PPFD: 13 watt/mq DLI: 26 micromo11/7/2024 (Gio) 17:38:38
Temp: 30 Violet: 257 Blue: 288 Green: 372 Yellow: 333 Orange: 229 Red: 200 PPFD: 2881394 microwatt/cq PPFD: 13 watt/mq DLI: 26 micromole/�
-
stampa senza la riga 269 ma con la riga 270: funziona correttamente
11/7/2024 (Gio) 17:40:6
Temp: 30 Violet: 256 Blue: 288 Green: 373 Yellow: 334 Orange: 229 Red: 201 PPFD: 2881396 microwatt/cq PPFD: 13 watt/mq DLI: 158 micromole/m2/s
Accesa
11/7/2024 (Gio) 17:40:7
Temp: 30 Violet: 257 Blue: 288 Green: 373 Yellow: 334 Orange: 230 Red: 202 PPFD: 2881399 microwatt/cq PPFD: 13 watt/mq DLI: 184 micromole/m2/s -
stampa senza la riga 269 ma con la riga 270 e quando arrivo al minuto specifico dichiarato nella riga 263 questo è il risultato:
11/7/2024 (Gio) 17:42:0
Temp: 30 Violet: 257 Blue: 290 Green: 376 Yellow: 337 Orange: 232 Red: 205 PPFD: 2901410 microwatt/cq PPFD: 14 watt/mq DLI: 980 micromole/m2/s
Accesa
0.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.0011/7/2024 (Gio) 17:42:1
Che Arduino stai utilizzando? ... perché ricorda problemi di mancanza di memoria ... ![]()
Guglielmo
arduino 1
ho provato a mettere una parola al posto della lettura del sensore e a fatto 13 stampe invece che 1. Mi sembra un problema legato all'RTC ma comunque è strano perchè quando questa parte di codice era in un altro sketch funzionava bene.
17:54:05.916 -> 11/7/2024 (Gio) 18:0:59
17:54:06.232 -> Temp: 30 Violet: 254 Blue: 298 Green: 392 Yellow: 358 Orange: 250 Red: 230 PPFD: 2981487 microwatt/cq PPFD: 14 watt/mq DLI: 1764 micromole/m2/s
17:54:06.396 -> Accesa
17:54:06.396 -> ciao
17:54:06.396 -> ciao
17:54:06.428 -> ciao
17:54:06.473 -> ciao
17:54:06.515 -> ciao
17:54:06.515 -> ciao
17:54:06.584 -> ciao
17:54:06.584 -> ciao
17:54:06.617 -> ciao
17:54:06.650 -> ciao
17:54:06.682 -> ciao
17:54:06.715 -> ciao
17:54:06.748 -> ciao
17:54:06.828 -> ciao
17:54:06.874 -> ciao
17:54:06.905 -> ciao
17:54:06.905 -> 11/7/2024 (Gio) 18:1:0
17:54:07.227 -> Temp: 30 Violet: 253 Blue: 298 Green: 391 Yellow: 357 Orange: 250 Red: 230 PPFD: 2981484 microwatt/cq PPFD: 14 watt/mq DLI: 1792 micromole/m2/s
Ho fatto alcune prove.
Togliendo alcune etichette dai valori letti dai sensori la stampa non si blocca.
Se però tolgo tutte le etichette si blocca comunque
... per me, al 90% è un problema di memoria ... usi librerie che sono delle vere mangia memoria, se ci aggiungi tutte le stringhe delle Serial.print() ... ecco fatto che vai fuori. ![]()
Puoi provare, come ultima ratio, ad usare la macro F() per le stringhe che stampi spostandole così in flash invece che in SRAM ... vedi in fondo a QUESTA pagina.