Datalogger: DS1307 überspringt Stunden

EDIT: Als Fazit kam raus es lag am Gerät die DS1307 ist wohl insgesamt unbeliebt und ich wechsele zur DS3231

Hallo liebes Forum,

nach benutzen der SUFU wende ich mich mit folgendem Problem an euch:

Ich verwende einen Datalogger shield für Arduino UNO, spricht ein shield mit SD-Slot und DS1307 RTC.

Mit ach und Krach habe ich mir einen Code zusammen gewurstet. Jetzt stehe ich vor dem Problem dass a) wenn ich die SD-Karte auslese merke dass alle geraden oder ungeraden Stunden fehlen, obwohl während jeder Stunde 6 Messungen passieren sollten.

b) Zusätzlich dazu hängt sich der MC hin und wieder auf und das LCD zeigt nur koreanische Nudelrezepte an.
Nach betätigen des Resetbuttons stimmen die Werte wieder, nur die Uhr geht danach falsch.
Normalerweise beeinflusst der reset die Uhr nicht. Also: was auch immer den Aufhänger verursacht brät auch die Uhr.
Hier könnt natürlich auch die Verkabelung mitspielen da sich dieses Arduino eine Stromquelle mit einem anderen Arduino teilt der 2 Relais schaltet. Ich wüsste allerdings nicht inwiefern das die Uhr beinflussen sollte.

Ich stell mal den Code hoch und falls für euch relevant skizzier ich die Schaltung auch gerne.

#include <OneWire.h>
#include <DallasTemperature.h>
#include <LiquidCrystal.h>
#include <SD.h>
#include <SPI.h>
#include <Wire.h>
#include <DS1307RTC.h>
#include <Time.h>
File dataFile ;

LiquidCrystal lcd(7, 6, 5, 4, 3, 2);

OneWire oneWire(8);
DallasTemperature sensors(&oneWire);
#define TEMPERATURE_PRECISION 9

DeviceAddress sensor1 = {0x28,0x6C,0xE4,0x3A,0x06,0x00,0x00,0xE7};              //SumpfL
DeviceAddress sensor2 = {0x28,0x54,0x99,0xDD,0x06,0x00,0x00,0xE5};                   //SumpfR
DeviceAddress sensor3 = {0x28,0xFF,0xA6,0x45,0x66,0x14,0x01,0x7B};                          //TankL
DeviceAddress sensor4 = {0x28,0xFF,0xA8,0x8B,0x54,0x14,0x00,0x3A};                                   //TankR
DeviceAddress sensor5 = {0x28,0xFF,0x8A,0x50,0x73,0x04,0x00,0xD6};                                                                    //Boden
DeviceAddress sensor6 = {0x28,0xDD,0x59,0x39,0x06,0x00,0x00,0xFC};                                                                      // Luft
DeviceAddress sensor7 = {0x28,0x43,0x97,0x39,0x06,0x00,0x00,0xDE};                                                                        //Aussen

const int chipSelect = 10;


 
void setup(void) {
  Serial.begin(9600);
  sensors.begin();
  lcd.begin(16, 2);
  Wire.begin();

  pinMode(10, OUTPUT);
  SD.begin(chipSelect);
}




void loop(void) {


 sensors.requestTemperatures();
float temp1 = sensors.getTempC(sensor1);
float temp2 = sensors.getTempC(sensor2);
float temp3 = sensors.getTempC(sensor3);
float temp4 = sensors.getTempC(sensor4);
float temp5 = sensors.getTempC(sensor5);
float temp6 = sensors.getTempC(sensor6);
float temp7 = sensors.getTempC(sensor7);
  
  tmElements_t tm;

  if (RTC.read(tm)) {
    Serial.print("Ok, Time = ");
    Serial.print(tm.Hour);
    Serial.write(':');
  Serial.print(tm.Minute);
    Serial.write(':');
    Serial.print(tm.Second);
    Serial.print(", Date (D/M/Y) = ");
    Serial.print(tm.Day);
    Serial.write('/');
    Serial.print(tm.Month);
    Serial.write('/');
    Serial.print(tmYearToCalendar(tm.Year));
    Serial.println();
    
    
  }else {Serial.print("Fehler");}

  
   if (tm.Minute %10 ==5)
  {
    File dataFile = SD.open("data2015.txt", FILE_WRITE);
    
    Serial.print(tm.Hour);
    Serial.write(':');
  Serial.print(tm.Minute);
    Serial.write(':');
    Serial.print(tm.Second);
    Serial.print(", Date (D/M/Y) = ");
    Serial.print(tm.Day);
    Serial.write('/');
    Serial.print(tm.Month);
    Serial.write('/');
    Serial.print(tmYearToCalendar(tm.Year));
    Serial.println();
    Serial.println ("Logging...");
    
dataFile.print(tmYearToCalendar(tm.Year));
dataFile.print('/');
dataFile.print(tm.Month);
dataFile.print('/');
dataFile.print(tm.Day);
dataFile.print(' ');
dataFile.print(tm.Hour-1);
dataFile.print(':');
dataFile.print(tm.Minute);
dataFile.print(':');
dataFile.print(tm.Second);
dataFile.print(" ");
dataFile.print("Sumpf Links ");
dataFile.print(temp1);
dataFile.print(" ");
dataFile.print("Sumpf Rechts ");
dataFile.print(temp2);
dataFile.print(" ");
dataFile.print("Tank Links ");
dataFile.print(temp3);
dataFile.print(" ");
dataFile.print("Tank Rechts ");
dataFile.print(temp4);
dataFile.print(" ");
dataFile.print("Boden ");
dataFile.print(temp5);
dataFile.print(" ");
dataFile.print("Luft");
dataFile.print(temp6);
dataFile.print(" ");
dataFile.print("Aussen ");
dataFile.print(temp7);
dataFile.println(" ");


dataFile.close();


delay(50000);
  } 
  
lcd.setCursor(0, 0);

lcd.print("SL ");
lcd.print(temp1);
lcd.print(" SR ");
lcd.print(temp2);

lcd.setCursor(0, 1);

lcd.print("TL ");
lcd.print(temp3);
lcd.print(" TR ");
lcd.print(temp4);

delay(3500);

lcd.clear();
lcd.setCursor(0, 0);

lcd.print("B ");
lcd.print(temp5);
lcd.print(" L ");
lcd.print(temp6);

lcd.setCursor(0, 1);

lcd.print("A ");
lcd.print(temp7);
lcd.print(" RH ");
lcd.print("x");


  delay(3500);
  
  lcd.print(tm.Hour);
  lcd.print(":");
  lcd.print(tm.Minute);
  lcd.print(":");
  lcd.print(tm.Second);
  
  delay(3000);
  lcd.clear();
  

}

Hallo,

kann ich Dir genau sagen was hier passiert. Glaskugel war nämlich bei der Reparatur. :slight_smile:

Deine Delayzeiten sind Dein Problem. Das sind genau 60sec - was genau eine Minute ist. Nun wird die RTC und der µC Quarz nicht ganz synchron laufen und damit dummweise eine ganze Weile lange dein Modulu %10 nie ausführen können, weil dein delay immer schön brav genau diese Minute die du brauchst blockiert hat.

Mach den Rest mit millis statt delay und es läuft.

Paar Schönheitsfehler mit 2x "File dataFile ..." kannste auch noch korrigieren und eine Abfrage einzügen vorm schreiben ob die Datei überhaupt existiert. Sind aber erstmal Schönheitsfehler. Delay muß weg.

Hey Danke erst mal für die Express-antwort!

Die delays dienen ja nur dem Zweck dass die Messung nur einmal in der besagten Minute ausgeführt wird.

Würdest du die delays durch millis ersetzen oder würdest du die If-Schleife für die Messung mit millis anstatt modulo tm.Minute machen?

Ich google das gerade, aber wenn du magst kannst du mich auch gerne erleuchten :slight_smile:

Ok, halt stop!
Irgendwas läuft definitiv nicht ganz rund mit meiner RTC.

Die Uhr überspringt einfach ganze Stunden, hier ein Auszug aus meinem Serial Monitor, der Code lief jetzt die ganze Zeit.

Ok, Time = 23:59:07, Date (D/M/Y) = 5/7/2015
Ok, Time = 23:59:17, Date (D/M/Y) = 5/7/2015
Ok, Time = 23:59:27, Date (D/M/Y) = 5/7/2015
Ok, Time = 23:59:37, Date (D/M/Y) = 5/7/2015
Ok, Time = 23:59:47, Date (D/M/Y) = 5/7/2015
Ok, Time = 23:59:58, Date (D/M/Y) = 5/7/2015
Ok, Time = 1:0:08, Date (D/M/Y) = 6/7/2015
Ok, Time = 1:0:18, Date (D/M/Y) = 6/7/2015
Ok, Time = 1:0:28, Date (D/M/Y) = 6/7/2015
Ok, Time = 1:0:38, Date (D/M/Y) = 6/7/2015
Ok, Time = 1:0:49, Date (D/M/Y) = 6/7/2015

Hallo,

nö. Das die Daten aller 10 Minuten (5, 15, 25, 35 ...) geschrieben werden und serial rausgehen, dafür sorgt alleine

if (tm.Minute %10 ==5)
{

und am Ende dieser if Abfrage blockierst Du satte 50sec. und dann nochmal 10sec. Das kann nicht funktionieren.
Deine Daten werden aller 10min geschrieben. Das paßt. Ohne die delay(50000). Das muß raus.
Und wenn Dein Display nicht flimmern soll durch ständige refresh's, dann nimmste dafür millis.
Wurde hier in den letzten Tagen und Wochen tausendmal erklärt. Du wirst fündig werden.

Edit:
wegen deinem Nachtrag. Das sind alles Nebeneffekte vom delay. Wenn Du den Code Zeile für Zeile durchgehst, weist Du warum und was passiert und warum es nicht funktioniert wie gewollt. Dein delay versaut dir alles.

Aber die Bedingung if(tm.Minute %10==5) ist doch 60 sekunden lang wahr, oder?

Also würde ich ohne den 1-Minütigen delay jedes mal soviele Messungen registrieren wie der Prozessor in einer Minute verarbeiten kann. Wie gesagt, darum blockierte ich genau 60 sekunden on purpose.

Die If-schleife an eine Minute UND eine exakte sekunde zu hängen klappt doch vorraussichtlich auch nicht.

Und nur damit wir uns klar verstehen: Der Auszug aus dem Serialmonitor sollte alle 10 sekunden die Zeit anzeigen, ich versteh nicht wie die fehlende Stunde zu Stande kommen sollte.

Aber gut, ich lass mal die delays weg und schau mich nach Alternativen um.

Hallo,

ähm ja, hast recht. Das habe ich vollkommen übersehen. Sorry. Morgen wieder.

Ok ich hab jetzt alles mit millis gelöst und die delays rausgenommen.
Nach jedem log wird eine long integer Messung= millis() aktualisiert.

Wenn das nächste mal die If schleife geprüft wird, wird abgefragt ob die differenz zwischen der aktuellen millis() und der fixierten zeit "Messung" größer als 60 sekunden ist. Klappt soweit.

ABER die Uhr springt immer noch randommäßig auf eine komplett andere uhrzeit. Die Uhr lief jetzt frisch eingestellt richtig( auf dem LCD display angezeigt) bis sie irgendwann auf einmal 21:34 anstatt 18.07 anzeigt.

Hallo,

irgendwas wird mit der RTC Lib nicht hinhauen. Hab mal was gebastelt zum testen auf Grundlage vom jurs Code.
Mal sehen ob das läuft, ohne RTC Lib.
Was hast du für ein Shield? Link bitte. Nicht das Pin 4 noch fest auf High muß.

Mr_Poopypants_RTC.ino (4.76 KB)

Allerschamlosester China-Import:

Merci, ich werd deinen Code heute Nacht mal testen, bin noch unterwegs.

Hallo,

okay, dann kannste den Code so testen, sollte erstmal laufen. Ich dachte nur vielleicht hast Du ein Netzwerkshield mit SD Slot. Aber das ist eins mit RTC & SD. RTC ist I2C Bus und SD ist alleine auf SPI Bus. Darum ging mir's.
Na dann, schauen wir mal ...

Bei acht Bibliotheken könnte es zu einer gegenseitigen Beeinflussung kommen. Um RTC zu testen, würde ich nur diese Hardware und einen Testsketch laufen lassen, ob die Uhr spinnt.

PS.: "Es spielt die RTC-Batterie, aber. Nun, die Geologie des Feuers zu Schweißen und Testen aller Komponenten, aber nicht installiert Kopf." Da jeder dritte Mensch ein Chinese ist, werden wir unsere Sprachgewohnheiten wohl etwas anpassen müssen. "Die Macht ist aus."

Hallo,

deswegen ist die RTC und Time Lib aus dem Rennen geworden wurden und wird "manuell" behandelt.
Wenn das funktionieren sollte, wovon ich ausgehe, kann er jurs neue Lib verwenden.

Doc_Arduino:
... aus dem Rennen geworden wurden ...

Du hast auch schon zu viel chinesisches Deutsch gelesen :confused: Sorry, paßt so schön :slight_smile:

Hallo,

schön, mich haut's weg. :slight_smile:
"genommen" sollte das werden.

Geologie des Feuers klingt aber auch sau-cool, ich glaube das benutz ich jetzt anstatt "löten".

Da hast du aber ne Menge getippt :open_mouth:

Ich hab den sketch mal hochgeladen und häng das Uno jetzt mal an den LCD und kuck morgen früh obs die Uhrzeit wieder zerrissen hat.

Angenommen die Uhr funktioniert unter diesen Umständen, dann wäre der nächste Schritt mir jurs library zu krallen und in meinen Code zu implementieren?? Hast du dir das so gedacht?

Edit: Was schon mal am Rande auffällt ist das Seriell 00:30 angegeben wurde, auf dem LCD aber 1:30.

Als ich mich damit beschäftigte, kannte ich RTC_DS3231_Register_012.ino "Doc Arduino - german Arduino Forrum" noch nicht. Daher verwende ich derzeit noch den Sketch von tronixlabs, der erweitert für ein LC-Display bislang gute Werte liefert. Kannst Du eventuell für einen Vergleich heranziehen.

Hallo,

seriell und LCD unterschiedlich? Das geht eigentlich nicht. Echt seltsam. Weil beide exakt die gleichen Variablen verwenden und zwischendurch auch nicht nochmal ausgelesen wird.
seriell wird optisch schön formatiert und das LCD bekommt die Variablen 1:1 zur Anzeige.
Ich guck mir das nachher nochmal an.

Ich war grad beim Display und es waren wieder nur vietnamesische Kreuzworträtsel zu sehen.

Als ich reset gedrückt hab kam auch wieder die korrekte (um 1 Stunde daneben liegende Uhrzeit).
Also was auch immer für das Springen der Uhr verantwortlich ist, mit diesem Code passiert es nicht.
Dann fang ich woh mal an diesen Code in meinen Logging-Code reinzuverwursten.

Ich würde ja mal behaupten dass der Wurm irgendwo in der Schaltung liegen muss, denn das einzige Ereignis zwischen gestern abend und heut morgen war das umschalten der Relais.

Hallo,

hab nochmal den Code abgespeckt und auf meinem Mega getestet, läuft wie erwartet. Den Code für Dich kann ich nicht nochmal testen, ist nur nach besten Wissen und Gewissen abgeändert für Deine Hardware. Wenn das wieder nicht gleich ist, mußte wirklich mal Deine Hardware prüfen. Hat die RTC auf dem I2C Bus Pullup Widerstände?

Kannste am abgezogenen nackten Shield messen. Zwischen + und SDA und zwischen + und SCL Pin. Irgendwas zwischen 5k und 2k Ohm sollten da sein.

Mr_Poopypants_RTC_002.ino (3.56 KB)