Klok op een data logging shield niet juist

Allen

Ik heb een paar jaar geleden een simpel programma geschreven om elke minuut temperatuur en vochtigheid weg te schrijven naar een data logging shield. Die heeft een ingebouwd klok.

Om de een of andere reden loopt de klok vanaf 09/05 niet meer juist en staat die op 2000/1/1.

Ik snorde het programma op en ik probeer de klok juist te zetten, maar dat lukt me niet.

Dit is mijn programma

// https://github.com/adafruit/Light-and-Temp-logger/blob/master/lighttemplogger.ino
// https://learn.adafruit.com/adafruit-data-logger-shield/using-the-real-time-clock-2

// Date and time functions using a DS1307 RTC connected via I2C and Wire lib


// datum en tijd die op de data logger shield zit
#include "RTClib.h"


// The Wire library allows you to communicate with I2C devices, often also called "2 wire" or "TWI" (Two Wire Interface).
#include <Wire.h>

// bibliotheek voor DHT22
#include "DHT.h"
#define DHTPIN 3
#define DHTTYPE DHT22  
DHT dht(DHTPIN, DHTTYPE);

// include the SD library - om met SD te communiceren
#include <SPI.h>
#include <SD.h>


// set up variables using the SD utility library functions:
Sd2Card card;
SdVolume volume;
SdFile root;

//deze poort moet op 10 staan
const int chipSelect = 10;


// how many milliseconds between grabbing data and logging it. 1000 ms is once a second
#define LOG_INTERVAL  1000 // mills between entries (reduce to take more/faster data)
// how many milliseconds before writing the logged data permanently to disk
// set it to the LOG_INTERVAL to write each time (safest)
// set it to 10*LOG_INTERVAL to write all data every 10 datareads, you could lose up to 
// the last 10 reads if power is lost but it uses less power and is much faster!
#define SYNC_INTERVAL 1000 // mills between calls to flush() - to write data to the card
uint32_t syncTime = 0; // time of last sync()


// the logging file
File logfile;

// dit is het type clock
RTC_DS1307 rtc;


char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};


void error(char *str)
{
  Serial.print("error: ");
  Serial.println(str);

// dit is een oneindige lus en nu wordt niets meer gedaan tot programma onderbroken wordt
  while(1);
}





void setup () {
//  Returns true if the specified serial port is available.
// kan volgende regel weg ??
  while (!Serial); // for Leonardo/Micro/Zero

  Serial.begin(57600);
  if (! rtc.begin()) {            // if(! ... betekent als aan deze conditie niet is voldaan
    Serial.println("Couldn't find RTC");
    while (1);
  }

  if (! rtc.isrunning()) {
    Serial.println("RTC is NOT running!");
    // following line sets the RTC to the date & time this sketch was compiled
// rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
    // This line sets the RTC with an explicit date & time, for example to set
    // January 21, 2014 at 3am you would call:
 rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
  }

   // initialize the SD card
  Serial.print("Initializing SD card...");
  // make sure that the default chip select pin is set to
  // output, even if you don't use it:
  pinMode(10, OUTPUT);
  
  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
    error("Card failed, or not present");
  }
  Serial.println("card initialized.");


//onderstaande betekent volgens mij het volgende
// je begint met een bestandsnaam te geven
// de eerste positie is positie0
// en dan ga je positie 7 en 8 (filename[6] en [7]) veranderen door 01,02,03etc...
// / betekent geheel deel van deling
// % is rest van de deling
// + '00' is om van een karakter een cijfer te maken of zoiets

   // create a new file
  char filename[] = "LOGGER00.TXT";
  for (uint8_t i = 0; i < 100; i++) {   // uint8_t is zelfde als byte
    filename[6] = i/10 + '0';
    filename[7] = i%10 + '0';
    if (! SD.exists(filename)) {
      // only open a new file if it doesn't exist
      logfile = SD.open(filename, FILE_WRITE); 
      break;  // leave the loop!
    }
  }
  
  if (! logfile) {
    error("couldnt create file");
  }
  
  Serial.print("Logging to: ");
  Serial.println(filename);

  
  logfile.println("datetime, hum, temp");    
#if ECHO_TO_SERIAL
  Serial.println("datetime, hum, temp");
#endif //ECHO_TO_SERIAL
  delay(3000);
}







void loop () {

    DateTime now = rtc.now();

 // delay for the amount of time we want between readings
  delay((LOG_INTERVAL -1) - (millis() % LOG_INTERVAL));
  
    Serial.print(now.year(), DEC);
    Serial.print('/');
    Serial.print(now.month(), DEC);
    Serial.print('/');
    Serial.print(now.day(), 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();

 

   

// zelf toegevoegd lezen van DHT22
    float temp = dht.readTemperature();
    float hum = dht.readHumidity();

    if (isnan(hum) || isnan(temp)) {
    Serial.println("Sensor niet correct uitgelezen!");
    return;}


 Serial.print("Humiditeit: ");   // laat tekst Humiditeit: verschijnen
 Serial.print(hum, 1);      // geef de waarde van de humiditeit, op 1 decimaal nauwkeurig
 Serial.print(" %\t");      // voeg een tab in na teken %
 Serial.print("Temperature: ");    // laat tekst Temperature verschijnen
 Serial.println(temp, 1);      // geef de waarde van de variabele temp, op 1 decimaal nauwkeurig
Serial.println();


    logfile.print(now.year(), DEC);
    logfile.print('/');
    logfile.print(now.month(), DEC);
    logfile.print('/');
    logfile.print(now.day(), DEC);
    logfile.print(" (");
    logfile.print(daysOfTheWeek[now.dayOfTheWeek()]);
    logfile.print(") ");
    logfile.print(now.hour(), DEC);
    logfile.print(':');
    logfile.print(now.minute(), DEC);
    logfile.print(':');
    logfile.print(now.second(), DEC);
    logfile.println();
logfile.print(hum); 
logfile.print(", ");
logfile.print(temp); 
logfile.print(", ");




//delay(1000);

// Now we write data to disk! Don't sync too often - requires 2048 bytes of I/O to SD card
  // which uses a bunch of power and takes time
  if ((millis() - syncTime) < SYNC_INTERVAL) return;
  syncTime = millis();
  
  // blink LED to show we are syncing data to the card & updating FAT!
  
  logfile.flush();
 
  
// einde zelf toegevoegd lezen DHT22

}

Ik merk wel dat als ik de arduino loskoppel van stroom, hij de tijd onthoud. Dus de batterij werkt nog. Enig idee wat fout kan lopen ? Zie ik iets over het hoofd ?

Ik heb ook dit eens geupload

// Date and time functions using a DS1307 RTC connected via I2C and Wire lib
#include <Wire.h>
#include "RTClib.h"
RTC_DS1307 rtc;
char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
void setup () {
 while (!Serial); // for Leonardo/Micro/Zero
 Serial.begin(57600);
 if (! rtc.begin()) {
   Serial.println("Couldn't find RTC");
   while (1);
 }
 if (! rtc.isrunning()) {
   Serial.println("RTC is NOT running!");
   // following line sets the RTC to the date & time this sketch was compiled
  // rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
   // This line sets the RTC with an explicit date & time, for example to set
   // January 21, 2014 at 3am you would call:
rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
 }
}
void loop () {
 DateTime now = rtc.now();
 Serial.print(now.year(), DEC);
 Serial.print('/');
 Serial.print(now.month(), DEC);
 Serial.print('/');
 Serial.print(now.day(), 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();
 Serial.print(" since midnight 1/1/1970 = ");
 Serial.print(now.unixtime());
 Serial.print("s = ");
 Serial.print(now.unixtime() / 86400L);
 Serial.println("d");
 // calculate a date which is 7 days and 30 seconds into the future
 DateTime future (now + TimeSpan(7, 12, 30, 6));
 Serial.print(" now + 7d + 30s: ");
 Serial.print(future.year(), DEC);
 Serial.print('/');
 Serial.print(future.month(), DEC);
 Serial.print('/');
 Serial.print(future.day(), DEC);
 Serial.print(' ');
 Serial.print(future.hour(), DEC);
 Serial.print(':');
 Serial.print(future.minute(), DEC);
 Serial.print(':');
 Serial.print(future.second(), DEC);
 Serial.println();
 Serial.println();
 delay(3000);
}

Maar ook hier blijft de datum op 2000/1/1 staan (het uur loopt wel door).

Iemand die me wat kan helpen ?

Misschien maakt er iets niet goed contact of is de batterij leeg.

De tijd onthouden is iets anders dan dat de tijd doorloopt op de batterij. Kun je specifieker zijn met je beschrijving ?
Als de RTC het maar een beetje half doet, dan lijkt het de batterij te zijn die bijna leeg is. Maar het kan ook een goedkope module zijn waarbij de contacten zijn geoxideerd en slecht contact maken met de batterij.

Als de batterij goed is, dan kun je misschien een I2C Scanner sketch een tijdje laten lopen om te kijken of dat stabiel is.

Wel, het lijkt er op dat de tijd doorloopt. De module loopt nu al een paar uur, ik heb ze al diverse malen losgekoppeld van stroombron (enkel dus nog de batterij er in) en de tijd loopt verder. Ze staat nu ergens op 2000/1/1 2:49

Ik heb de batterij eens uitgehaald en die meet nog 2.79V (dit lijkt me toch voldoende te zijn, niet)?
De contacten zien me er niet geoxideerd uit …

Ik heb een IC2 scanner geupload en dan krijg ik dit.

I2C Scanner
Scanning…
I2C device found at address 0x68 !
done

Als je die I2C Scanner laat lopen, blijft het dan stabiel als je wat duwt tegen de spullen en draden ?

De batterijspanning lijkt me voldoende, maar misschien heb je een namaak chip.

Ik begrijp niet waarom het jaartal niet te wijzigen is.
Misschien kun je een andere RTC module proberen.
Helaas weet ik het verder niet :cry: misschien heeft iemand anders een goed idee.

Geen idee of een RTC met een tabel werkt, dat moet in een datasheet terug te vinden zijn.
Maar bijvoorbeeld GPS werkt wel met een dergelijke oplossing (de almanak).
Bij GPS gebeurt het regelmatig (letterlijk) dat de almanak over loopt.
Dan wordt de datum verkeerd weergegeven.
Kun je eens proberen of je wel een datum van een paar jaar geleden kunt instellen ?
Wanneer dat wel lukt, is het waarschijnlijk dat dit je probleem is.
In dat geval zul je er weinig aan kunnen doen, want het is niet heel eenvoudig om dit dan even om te rekenen (schrikkeljaren zijn heel vervelend bijvoorbeeld).

Bij de GPS is het updaten van de firmware (met nieuwe almanak dus) dan een oplossing, maar vaak biedt de fabrikant dat niet en moet je maar een nieuwe kopen.

Allen,

Na heel veel geprobeerd te hebben (misschien wel 50x) het programma up te loaden, zag ik dat plots de datum wel gewijzigd was. Ik heb ze dan opnieuw geprobeerd te wijzigen, en dat lukte weer tientallen keren niet, en dan plots wel - zonder dat ik ook maar 1 zaak wijzigde ... vreemd ... maar de datum staat nu in elk geval juist.

Groeten
Diederik