problema lettura secondi RTC

Se fai aspettare Arduino per un secondo é normale che non scrive in quel tempo i secondi sul display e percui salta dei numeri.
Ciao Uwe

Scusami ma non sono un esperto sto imparando da solo. Ho tolto il ritardo ma fa lo stesso, potresti indicarmi quale riga correggere e come?
Grazie

manda il nuovo codice.
Ciao Uwe

Perchè quello che ho postato non va bene? :frowning:

Hai detto che l' hai modificato e comunque non funziona. Manda quello modificato.
Ciao Uwe

Scusami se rompo il giorno di natale , anzi ne approfitto per farti gli auguri, ma la modica fatta era soltanto eliminare il DELAY tutto qui, sai dirmi tu che modifica fare? Grazie

danidiscus:
Scusami se rompo il giorno di natale , anzi ne approfitto per farti gli auguri, ma la modica fatta era soltanto eliminare il DELAY tutto qui, sai dirmi tu che modifica fare? Grazie

Tanti auguri anche a te.
io ho analizzato il codice ed effettivamente imho quello che rende l'aggiornamento ogni 2 secondi è al 99.99% solo il delay: lo togli e dovrebbe aggiornare correttamente.
C'è la remota possibilità che l'interrogazione dei sensori o dell'orologio per qualche motivo impieghi più di un secondo...ma non dovrebbe proprio...mi pare difficile... ma se tu dici che non cambia nulla io devo crederti:
Per ispezionare questa casistica bisogna che ci inventiamo un debug: possiamo usare il Serial.print ma possiamo usare anche il display.
Una possibile soluzione di debug è commentare la parte inerente la lettura dei sensori di temperatura e questo ci permette di capire se è la lettura della data che infastidisce.... commentanto la lettura della temperatura cambia qualcosa?

Un'alternativa "home made" è creare una variabile che viene incrementato ad ogni ciclo di loop e stamparla ad ogni ciclo: questo ci permette di capire quanto dura il ciclo loop (stampa veloce i numeri oppure lentamente) perchè c'è la remota possibilità che il ciclo loop in se duri poco ma che l'orologio per qualche motivo torni valori errati....
una cosa tipo
int cont;
cont ++;
cont = cont % 9;
lcd.print (cont);

ho fatto delle prove eliminando il DELAY ma noto che nello scorrere dei secondi ogni tot come se si inceppa, ho messo il DELAY (150) sembra andare meglio, ma anche in questo caso trova un inceppo ogni tanto meno del 150.
ho eliminato il sensore digitale e sembra funzionare bene, quindi l,intoppo è nel sensore digitale ma non capisco dove :frowning:

evidentemente i tempi di risposta sul dallas non sono certi. Io non so la logica in profondità del bus ma spesso nei bus le risposte vengono date a tempi appositamente "random" di modo da gestire eventuali risposte multiple/conflitti tra sensori.
Altra cosa il dallas l'hai attaccato con l'alimentazione parassita? (2 soli fili?): perchè con 2 fili è previsto un ritardo di "carica"... mi pare... devo averlo letto da qualche parte... boo forse mi sono inventato tutto...

andiamo ad una possibile soluzione: io toglierei questo delay: assolutamente.
Poi testerei "alla morte" (più velocemente possibile) l'orologio di modo da avere il più possibile letture al secondo e leggerei il sensore 1-wire (e a questo punto anche l'analogico) solo quando il secondo scatta...
uno "pseudocodice tipo":

void loop:

read dataora;
if second != oldSecond
lcd.print data ora
oldsecond = second
leggo dallas
leggo analogico.
lcd.print temperature
endif
end loop

In questo modo mi aspetto di intercettare il cambio del secondo appena succede ed avere un secondo netto per leggermi il sensore prima che ci sia bisogno di aggiornare di nuovo la data/ora... inoltre metti anche che non ce la facciamo in un secondo spaccato anche se diventa un secondo ed 1 decimo ben difficilmente ci accorgeremo di qualcosa.

L'alternativa è trovare un'altra libreria per il sensore che magari funzioni più velocemente.
Ho il panetto che mi viene su. :smiley:

...ho guardato la libreria che stai usando... di suo può aspettare fino a 750 millisecondi il dato di temperatura però ha delle funzioni che permettono di non bloccare il codice nei delay. per esempio c'è questa funzine che fa si che la funzione di lettura della temperatura non sia bloccante...

// sets the value of the waitForConversion flag
// TRUE : function requestTemperature() etc returns when conversion is ready
// FALSE: function requestTemperature() etc returns immediately (USE WITH CARE!!)
//                (1) programmer has to check if the needed delay has passed
//        (2) but the application can do meaningful things in that time
void DallasTemperature::setWaitForConversion(bool flag)
{
        waitForConversion = flag;
}

e con questa puoi vedere se il dato è diventato disponibile

bool DallasTemperature::isConversionAvailable(uint8_t* deviceAddress)
{
        // Check if the clock has been raised indicating the conversion is complete
        ScratchPad scratchPad;
        readScratchPad(deviceAddress, scratchPad);
        return scratchPad[0];
}

quindi sul setup setti il setwaitforconversion a false. fai requesttemperature normale (e questo non ti bloccherà) e solo quando troverai il isconversionavaiable a true farai il getTempC.

io vi ringrazio tutti di vero cuore ma come ho scritto sono alle prime armi, ora ho capito,
non ci capisco niente, stiamo entrando troppo nello specifico.
vi prego scusate ma sono inetto,
se posso chiedere ....
.... ho bisogno che qualcuno corregga il codice che ho impostato cosi da confrontarlo e cercare di capire.
grazie
Daniele

danidiscus:
io vi ringrazio tutti di vero cuore ma come ho scritto sono alle prime armi, ora ho capito,
non ci capisco niente, stiamo entrando troppo nello specifico.
vi prego scusate ma sono inetto,
se posso chiedere ....
.... ho bisogno che qualcuno corregga il codice che ho impostato cosi da confrontarlo e cercare di capire.
grazie
Daniele

non ti devi scusare e per quanto poco ti conosco non credo tu sia inetto se sei comunque riuscito a modificare un po' il codice soprastante.... è tuttavia molto difficile per me perchè non ho il dallas da attaccare... non mi funzionerebbe un tubo e non riuscirei a provare... pertanto potrei solamente postarti un codice "più o meno" funzionante e poi tu lo correggi e lo provi perchè se no non ce la faccio.
Devo però dirti che non è il miglior "approccio all'apprendimento"... nel senso che sarebbe bene che ti "spaccassi" letteralmente la schiena su questo problema di tuo in modo da imparare altrimenti alla fine otterremo un codice funzionante ma non otterremo la tua crescita che è ben più importante di un dallas che non risponde nei tempi.
Comunque dato che è Natale (e sono abbastanza disoccupato) mi offro di aiutarti... domani... :smiley:

Cavolo, mi dispiace per il disoccupato, purtroppo oggi è una parola che si sente sempre più spesso, specie per gente ingamba come te che meritano un lavoro piu di altri, ti capisco perche qualche anno fa ci sono passato pure io, costringendomi ad abbandonare la mia citta natale per trovare un posto di lavoro e cercare di farmi anche se a fatica un futuro.
Ti ringrazio di vero cuore per l'aiuto, hai perfettamente ragione per l'apprndimento, solo che in questo momento ho mille progettimper la testa che non riesco piu a capirci nulla. Sto riallestendo,il mio vecchio hobby che per i motivi sopra citati avevo mollato.
Grazie ancora qsecorf.

danidiscus:
Cavolo, mi dispiace per il disoccupato, purtroppo oggi è una parola che si sente sempre più spesso, specie per gente ingamba come te che meritano un lavoro piu di altri, ti capisco perche qualche anno fa ci sono passato pure io, costringendomi ad abbandonare la mia citta natale per trovare un posto di lavoro e cercare di farmi anche se a fatica un futuro.
Ti ringrazio di vero cuore per l'aiuto, hai perfettamente ragione per l'apprndimento, solo che in questo momento ho mille progettimper la testa che non riesco piu a capirci nulla. Sto riallestendo,il mio vecchio hobby che per i motivi sopra citati avevo mollato.
Grazie ancora qsecorf.

no no cosa hai capito: sono in ferie e sono disoccupato nel senso che non vado a lavorare e se non ho nulla da fare mi annoio...
...mi sto toccando i maroni... :grin: :blush:

dai domani a qualche ora...

Cavolo che figura, scusa!
Comunque ok, per domani :slight_smile:

come promesso questo è il primo codice: NOTE PRELIMINARI: NON HO LA TUA STESSA LIBRERIA RTC QUINDI NON HO MANCO POTUTO COMPILARLO... E NON HO L'RTC E NON HO IL DALLAS... quindi il codice E' DA COLLAUDARE /CORREGGERE.
(e sai cosa regalarmi per natale XD :grin:)

Questo codice testa a tutta birra l'RTC per vedere quando scatta il nuovo secondo. Quando scatta il nuovo secondo stampa sull'lcd la data/ora e poi fa subito la lettura del chip 1-wire di modo da avere circa 1 secondo a disposizione pieno per la lettura del dato... non è detto che vada ma dovrebbe andare...
Poi il pomeriggio facciamo l'altra soluzione

#include <DallasTemperature.h>
#include <OneWire.h>
#include <Wire.h>
#include <RTClib.h>
#include <LiquidCrystal.h>
#define ONE_WIRE_BUS 8


OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
float temperatura;

 
char buffer[10];
 
RTC_DS1307 RTC;
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
 
void setup () {
    sensors.begin();
    Wire.begin();
    RTC.begin();
    lcd.begin(20, 4);
 
    RTC.sqw(1);  // qsecofr: MI DA ERRORE: NON POSSO CORREGGERE IO
    if (! RTC.isrunning()) {
      RTC.adjust(DateTime(__DATE__, __TIME__));
    }
    
    
}
 
  
byte oldSecond =0;       //QSECOFR
 
void loop () {
    DateTime now = RTC.now();
    
 
    

 
//    delay(1000);        //QSECOFR

    if (oldSecond != now.second()) { //qsecofr sono cambiati i secondi...
      
           //stampa data ed ora
          sprintf(buffer,  "%02d/%02d/%d", now.day(), now.month(), now.year());
          lcd.setCursor(0, 1);
          lcd.print("Data  ");
          lcd.print( buffer );
      
          char buffer[10] = "";
      
          sprintf(buffer,  "%02d:%02d:%02d", now.hour(), now.minute(), now.second());
          lcd.setCursor(0, 0);
          lcd.print("Time   ");
          lcd.print( buffer );

          oldSecond = now.second();                //qsecofr: aggiorna i vecchi secondi
      
          // lettura analogica
          temperatura=analogRead(A0);
          lcd.setCursor(0, 2);
          lcd.print("Temp esterna ");
          lcd.print((5.0*temperatura*100.0)/1024.0);
          lcd.write(0b011011111);
          lcd.print("C");

      
          // lettura 1-wire...lenta ed in attesa. 
           sensors.requestTemperatures(); // Invia il comando di lettura delle temperatura
           lcd.setCursor(0, 3); 
           lcd.print("Temp H2o");
           lcd.setCursor(10, 3);
           lcd.print (sensors.getTempCByIndex(0));
           lcd.print (" C"); 
           lcd.write(0b11011111);
 
      }  //endif sono cambiati i secondi

  }

qsecofr:
come promesso questo è il primo codice: NOTE PRELIMINARI: NON HO LA TUA STESSA LIBRERIA RTC QUINDI NON HO MANCO POTUTO COMPILARLO... E NON HO L'RTC E NON HO IL DALLAS... quindi il codice E' DA COLLAUDARE /CORREGGERE.
(e sai cosa regalarmi per natale XD :grin:)

Questo codice testa a tutta birra l'RTC per vedere quando scatta il nuovo secondo. Quando scatta il nuovo secondo stampa sull'lcd la data/ora e poi fa subito la lettura del chip 1-wire di modo da avere circa 1 secondo a disposizione pieno per la lettura del dato... non è detto che vada ma dovrebbe andare...
Poi il pomeriggio facciamo l'altra soluzione

#include <DallasTemperature.h>

#include <OneWire.h>
#include <Wire.h>
#include <RTClib.h>
#include <LiquidCrystal.h>
#define ONE_WIRE_BUS 8

OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
float temperatura;

char buffer[10];

RTC_DS1307 RTC;
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void setup () {
    sensors.begin();
    Wire.begin();
    RTC.begin();
    lcd.begin(20, 4);

RTC.sqw(1);  // qsecofr: MI DA ERRORE: NON POSSO CORREGGERE IO
    if (! RTC.isrunning()) {
      RTC.adjust(DateTime(DATE, TIME));
    }
   
   
}

byte oldSecond =0;       //QSECOFR

void loop () {
    DateTime now = RTC.now();

//    delay(1000);        //QSECOFR

if (oldSecond != now.second()) { //qsecofr sono cambiati i secondi...
     
           //stampa data ed ora
          sprintf(buffer,  "%02d/%02d/%d", now.day(), now.month(), now.year());
          lcd.setCursor(0, 1);
          lcd.print("Data  ");
          lcd.print( buffer );
     
          char buffer[10] = "";
     
          sprintf(buffer,  "%02d:%02d:%02d", now.hour(), now.minute(), now.second());
          lcd.setCursor(0, 0);
          lcd.print("Time   ");
          lcd.print( buffer );

oldSecond = now.second();                //qsecofr: aggiorna i vecchi secondi
     
          // lettura analogica
          temperatura=analogRead(A0);
          lcd.setCursor(0, 2);
          lcd.print("Temp esterna ");
          lcd.print((5.0temperatura100.0)/1024.0);
          lcd.write(0b011011111);
          lcd.print("C");

// lettura 1-wire...lenta ed in attesa.
           sensors.requestTemperatures(); // Invia il comando di lettura delle temperatura
           lcd.setCursor(0, 3);
           lcd.print("Temp H2o");
           lcd.setCursor(10, 3);
           lcd.print (sensors.getTempCByIndex(0));
           lcd.print (" C");
           lcd.write(0b11011111);

}  //endif sono cambiati i secondi

}

cavolo qsecofr, ho caricato il codice, sembra perfetto, non perde un attimo
ora lo testo bene bene, poi oggi ti daro la conferma, ho capito cosa hai fatto, ma da solo non ci sarei mai arrivato.
grazie
ps chiedi pure per il regalo di natale :slight_smile:

#include <DallasTemperature.h>
#include <OneWire.h>
#include <Wire.h>
#include <RTClib.h>
#include <LiquidCrystal.h>
#define ONE_WIRE_BUS 8


OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
float temperatura;

 
char buffer[10];
 
RTC_DS1307 RTC;
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
 
void setup () {
    sensors.begin();
    Wire.begin();
    RTC.begin();
    lcd.begin(20, 4);
 
    RTC.sqw(1);  // qsecofr: MI DA ERRORE: NON POSSO CORREGGERE IO
    if (! RTC.isrunning()) {
      RTC.adjust(DateTime(__DATE__, __TIME__));
    }
    
    
    
    // qsecofr: questa istruzione disattiva l'attesa della conversione
    
  sensors.setWaitForConversion(false);   
    
}
 
  
byte oldSecond =0;       //QSECOFR

byte richiestaTemperatura=0;   //Qsecofr
 
void loop () {
    DateTime now = RTC.now();
    
 
    

 
//    delay(1000);        //QSECOFR

    if (oldSecond != now.second()) { //qsecofr sono cambiati i secondi...
      
           //stampa data ed ora
          sprintf(buffer,  "%02d/%02d/%d", now.day(), now.month(), now.year());
          lcd.setCursor(0, 1);
          lcd.print("Data  ");
          lcd.print( buffer );
      
          char buffer[10] = "";
      
          sprintf(buffer,  "%02d:%02d:%02d", now.hour(), now.minute(), now.second());
          lcd.setCursor(0, 0);
          lcd.print("Time   ");
          lcd.print( buffer );

          oldSecond = now.second();                //qsecofr: aggiorna i vecchi secondi
          
      
          // lettura analogica
          temperatura=analogRead(A0);
          lcd.setCursor(0, 2);
          lcd.print("Temp esterna ");
          lcd.print((5.0*temperatura*100.0)/1024.0);
          lcd.write(0b011011111);
          lcd.print("C");

      
      
          // lettura 1-wire...lenta ed in attesa. 
          if (richiestaTemperatura == 0) {
                 sensors.requestTemperatures(); // Invia il comando di lettura delle temperatura... non è più bloccante quindi il risultato si avrà fra 750 millisecondi.
                 richiestaTemperatura = 1;   // questa variabile indica che ho richiesto una lettura della temperatura
           }
           
   
      }  //endif sono cambiati i secondi
      
      
       bool temperaturaPronta = sensor.isConversionAvailable(0);   
      if ((richiestaTemperatura == 1) && (temperaturaPronta)) {
     
        richiestaTemperatura = 0;
            lcd.setCursor(0, 3); 
           lcd.print("Temp H2o");
           lcd.setCursor(10, 3);
           lcd.print (sensors.getTempCByIndex(0));
           lcd.print (" C"); 
           lcd.write(0b11011111);
        
        }
      
      
      

  };

allora questa è la versione 2.0... la chiameremo "ambiziosa" perchè usa la funzione sensor.isConversionAvailable(0); che non so manco se si compila...e non l'ho trovata usata neanche negli esempi...
In pratica questa versione dopo l'aggiornamento dell'ora lancia una richiesta al termometro: la richiesta non blocca il codice perchè ho specificato in "setup" che non ha da aspettare. Dopo aver lanciato la richiesta testa se il dato è disponibile e stampa la temperatura solo quando è disponibile... se non funziona proviamo anche il prossimo codice: la versione 3.0 "piedi per terra".

#include <DallasTemperature.h>
#include <OneWire.h>
#include <Wire.h>
#include <RTClib.h>
#include <LiquidCrystal.h>
#define ONE_WIRE_BUS 8


OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
float temperatura;

 
char buffer[10];
 
RTC_DS1307 RTC;
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
 
void setup () {
    sensors.begin();
    Wire.begin();
    RTC.begin();
    lcd.begin(20, 4);
 
    RTC.sqw(1);  // qsecofr: MI DA ERRORE: NON POSSO CORREGGERE IO
    if (! RTC.isrunning()) {
      RTC.adjust(DateTime(__DATE__, __TIME__));
    }
    
    
    
    // qsecofr: questa istruzione disattiva l'attesa della conversione
    
  sensors.setWaitForConversion(false);   
    
}
 
  
byte oldSecond =0;       //QSECOFR

byte richiestaTemperatura=0;   //Qsecofr
long oldMillis; //qsecofr
 
void loop () {
    DateTime now = RTC.now();
    
 
    

 
//    delay(1000);        //QSECOFR

    if (oldSecond != now.second()) { //qsecofr sono cambiati i secondi...
      
           //stampa data ed ora
          sprintf(buffer,  "%02d/%02d/%d", now.day(), now.month(), now.year());
          lcd.setCursor(0, 1);
          lcd.print("Data  ");
          lcd.print( buffer );
      
          char buffer[10] = "";
      
          sprintf(buffer,  "%02d:%02d:%02d", now.hour(), now.minute(), now.second());
          lcd.setCursor(0, 0);
          lcd.print("Time   ");
          lcd.print( buffer );

          oldSecond = now.second();                //qsecofr: aggiorna i vecchi secondi
          
      
          // lettura analogica
          temperatura=analogRead(A0);
          lcd.setCursor(0, 2);
          lcd.print("Temp esterna ");
          lcd.print((5.0*temperatura*100.0)/1024.0);
          lcd.write(0b011011111);
          lcd.print("C");

      
      
          // lettura 1-wire...lenta ed in attesa. 
          if (richiestaTemperatura == 0) {
                 sensors.requestTemperatures(); // Invia il comando di lettura delle temperatura... non è più bloccante quindi il risultato si avrà fra 750 millisecondi.
                 richiestaTemperatura = 1;   // questa variabile indica che ho richiesto una lettura della temperatura
                 oldMillis = millis();
           }
           
   
      }  //endif sono cambiati i secondi
      
      
      long ciccio = millis();
      if ((richiestaTemperatura == 1) 
       {
         if (ciccio-oldMillis > 750) {
           {
           richiestaTemperatura = 0;
           lcd.setCursor(0, 3); 
           lcd.print("Temp H2o");
           lcd.setCursor(10, 3);
           lcd.print (sensors.getTempCByIndex(0));
           lcd.print (" C"); 
           lcd.write(0b11011111);
          }
        }
      
 
  };

in questo caso viene inviata la richiesta e poi sono attesi 750 millisecondi (che sono i millisecondi richiesti per la prontezza del dato a 12 bit)... chissà... adesso tocca a te collaudare il tutto.

prima di tutto grazie per il tempo dedicatomi,
ho provato i codici:
2.0 "ambiziosa"
dopo aver trovato un errore di battitura ho caricato il codice anche questo caso risponde bene, sia in termini di tempo che in quelli di lettura temo.
3.0 "piedi per terra"
anche in questo caso non rilevo alcuna differenza su lcd quindi visiva, ma leggendo la compilazione ritengo questa più precisa.
conclusione, i codici ricompilati da te sono perfetti all'uso che ne devo fare, avrai capito che mi servono in campo acquariofilo, il mio progetto con arduino e acquario è molto più che la semplice lettura di data ora e temp
vorrei fare un sistema con lampade t5 dimmerabili con potenza da 0 a 100% nell'arco del fotoperiodo.
in più vorrei aggiungere un menu che mi dia la possibilita di attivare relay e modificare l'ara di accensione lampade con le varie %li,
credi sia possibile tutto ciò.
se si avrei da proporti un interessante progetto stimolante :slight_smile:

danidiscus:
prima di tutto grazie per il tempo dedicatomi,
ho provato i codici:
2.0 "ambiziosa"
dopo aver trovato un errore di battitura ho caricato il codice anche questo caso risponde bene, sia in termini di tempo che in quelli di lettura temo.
3.0 "piedi per terra"
anche in questo caso non rilevo alcuna differenza su lcd quindi visiva, ma leggendo la compilazione ritengo questa più precisa.
conclusione, i codici ricompilati da te sono perfetti all'uso che ne devo fare, avrai capito che mi servono in campo acquariofilo, il mio progetto con arduino e acquario è molto più che la semplice lettura di data ora e temp
vorrei fare un sistema con lampade t5 dimmerabili con potenza da 0 a 100% nell'arco del fotoperiodo.
in più vorrei aggiungere un menu che mi dia la possibilita di attivare relay e modificare l'ara di accensione lampade con le varie %li,
credi sia possibile tutto ciò.
se si avrei da proporti un interessante progetto stimolante :slight_smile:

Sono contento che vada... ed anche piuttosto stupito dato che di solito il primo tentativo non va mai...
Posso dirti che pochi gg fa ho visto che un utente ha finito una nuova versione di una libreria per fare i menu sugli lcd: francamente non ricordo il nome anche perchè sono iscritto da pochissimo e non conosco ancora tutti.... questa è da ritirare fuori dal cilindro perchè ti servirà.
Poi queste lampade t5... oddio io non so come funzionino ma di gestione "acquario" con arduino penso non mancheranno gli esempi quindi sono altamente fiducioso... però non ho studiato come funziona la dimmerizzazione delle lampade fluorescenti...
Per i relay non c'è problema ma io ti consiglio di usare fotoaccoppiatori ed eventualmente triac se possibile.
per il progetto: io non so se sarà sempre in grado di aiutarti per via del tempo e per via delle mie conoscenze ma se potrò ti aiuterò: devo però avvisarti che la mia conoscenza in materia di pesce comincia da quando il pesce è morto e lo devo mangiare :smiley: