RTC gegen Überschreiben schützen

Hallo,
ich habe eine RTC über den I2C-Bus mit dem Arduino verbunden.
Drücke ich "Reset" auf dem Mega, läuft die Uhr normal weiter.
Übertrage ich aber ein Programm, das die Uhr nicht nutzt, zerhackt es mir die Uhrzeit.
Es ist ein wenig lästig, die RTC immer wieder neu zu stellen.
Läßt sich eine RTC gegen Überschreiben schützen?
Gruß und Dank
Andreas

SkobyMobil:
Übertrage ich aber ein Programm, das die Uhr nicht nutzt, zerhackt es mir die Uhrzeit.

Von ganz alleine sicherlich nicht.

SkobyMobil:
Es ist ein wenig lästig, die RTC immer wieder neu zu stellen.

In welchem Sketch mußt Du die Uhrzeit immer wieder neu stellen?
Code?

SkobyMobil:
Läßt sich eine RTC gegen Überschreiben schützen?

Die I2C-Anschlüsse des Uhrenchips nicht an Deinen Arduino anschließen.
Und immer darauf achten, dass die Pufferbatterie nicht leer wird und nicht kurzgeschlossen wird.

Hallo jurs,
mit diesem Sketch setze ich die Uhrzeit manuell. (// Uhrzeit manuell setzen) Mit der ResetTaste am Board.
Habe ich aus "setTime und RTC.set" wieder den Kommentar hergestellt und übertrage es wieder, dann kommt es zum Problem.

/*
              Code für Grundfunktionen des EntwicklerBoard Vers. 2.0
              Projekt Energiemanagement/SmartMetering
              Vers. 3.7
              10/2013-1/2014, SkobyMobil
              
 */

#include <DS1307RTC.h>
#include <Time.h>
#include <Wire.h>
#include <LiquidCrystal.h>

const int inPin = 0;                        // Anschluss LM35 an Pin A0
const int LED = 13;                         // LED an Pin 13
const int LCDHB = 30;                       // LCD-H-Beleuchtung an Pin D-30
const int S1 = 25;                          // Taster (S1..S4) an Pin x
const int S2 = 26;
const int S3 = 27;
const int S4 = 28;
const int S5 = 24;                          // Taster LCD-H-Beleuchtung
const byte GradSym = B11011111;             // Grafiksymbol (Grad) aus DisplaySpeicher

 tmElements_t tm;
 
int LCDHBHL = LOW;                          // Status (high/low) von LCDH
int buttonState;                            // aktueller Wert von S5
int lastButtonState = LOW;                  // letzter Wert von S5
int value = analogRead(inPin);              // Wert von Pin A0

float MaxTemp=0;                            // Start Max/Min Temperaturen
float MinTemp=50;

long lastDebounceTime = 0;                  // letzte Prellzeit
long debounceDelay = 15;                    // Zeit bis Entprellen

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

void setup() {
  lcd.begin(20, 4);
  pinMode(LED, OUTPUT);                     // Ausgang für LED 13
  pinMode(LCDHB, OUTPUT);                   // Ausgang für LCD-H-Beleuchtung
  pinMode(S1, INPUT);                       // Taster (S1..S4) als Eingang
  pinMode(S2, INPUT);
  pinMode(S3, INPUT);
  pinMode(S4, INPUT);
  pinMode(S5, INPUT);                       // Taster LCD-H-Beleuchtung


  digitalWrite(LCDHB, LCDHBHL);             // LCD-Beleuchtung auf aus

//setTime(13,53,0,9,1,14);                  // Uhrzeit manuell setzen
//RTC.set(now());
//Serial.begin(19200);                      // +++ externe Kontrollfunktion +++
}

void loop() {                      
 //  serial.print(MinTemp,1);               // +++ externe Kontrollfunktion +++
  
  
                                            //### Temperatur lesen/schreiben ### 
 if (tm.Second == (0))                      // alle 60 sek. Temperatur holen
 
{int value = analogRead(inPin);
float millivolts = (value / 1024.0) * 5000;
  float celsius = millivolts / 9.765625;    // Faktor für 0.5 Grad = 9.765625
  lcd.setCursor(15, 0);                       
    lcd.print(celsius,1);                   // LCD-Ausgabe mit 1 Dezimalstelle
    lcd.write(GradSym);
    
    
    if (celsius > MaxTemp)                  // Wert für Max-Temperatur lesen/speichern/schreiben
  { 
   MaxTemp = celsius; 
    lcd.setCursor(15, 2);                       
    lcd.print(MaxTemp,1);
    lcd.write(GradSym);
    } 
    
    
      if (celsius < MinTemp)
  { 
   MinTemp = celsius; 
   lcd.setCursor(15, 3);                       
    lcd.print(MinTemp,1);
    lcd.write(GradSym);
    }  
    }
                                            //### Taster S1 bis S4 abfragen ###
                                           
{   int valS1 = digitalRead(S1);              // Taster lesen
  if (valS1 == HIGH)                          // ist Taster gedrückt
 {                                          // #### Reaktion Taster S1 ###
 digitalWrite(LED, HIGH);                   // wenn Taster gedrückt - LED ein
 lcd.setCursor(7, 3);                       // Status-Meldung S1
    lcd.print("S1-ein");    
 }
else {
  if (valS1 == LOW)                           // Taster-Eingabe löschen
 digitalWrite(LED, LOW);                    // und/oder andere Funktion                 
}                                           
}
{   int valS2 = digitalRead(S2);              // Taster lesen
  if (valS2 == HIGH)                          // ist Taster gedrückt
 {                                          // ### Reaktion Taster S2 ###
 digitalWrite(LED, HIGH);                   // wenn Taster gedrückt - LED ein
 lcd.setCursor(7, 3);                       // Status-Meldung S2
    lcd.print("S2-ein");
  }
else {   
// digitalWrite(LED, LOW);                  // Taster-Eingabe löschen
}                                           // und/oder andere Funktion
}
{   int valS3 = digitalRead(S3);              // Taster lesen
  if (valS3 == HIGH)                          // ist Taster gedrückt
 {                                          // ### Reaktion Taster S3 ###
 digitalWrite(LED, HIGH);                   // wenn Taster gedrückt - LED ein
 lcd.setCursor(7, 3);                       // Status-Meldung S3
    lcd.print("S3-ein");
 }
else {
// digitalWrite(LED, LOW);                  // Taster-Eingabe löschen
}                                           // und/oder andere Funktion
}
{   int valS4 = digitalRead(S4);              // Taster lesen
  if (valS4 == HIGH)                          // ist Taster gedrückt
 {                                          // ### Reaktion Taster S4 ###
 digitalWrite(LED, HIGH);                   // wenn Taster gedrückt - LED ein
 lcd.setCursor(7, 3);                       // Status-Meldung S4
    lcd.print("S4-ein");
 }
else {
// digitalWrite(LED, LOW);                  // Taster-Eingabe löschen
}                                           // und/oder andere Funktion                                         
}

                                            //### LCD-Hintergrundbeleuchtung ein/aus ###

{
  
  int reading = digitalRead(S5);            // Taste lesen
  if (reading != lastButtonState)           // Taste gedrückt
  {
    lastDebounceTime = millis();            // Timer setzen
  } 
  
  if ((millis() - lastDebounceTime) > debounceDelay)
  {
    if (reading != buttonState)
    {
      buttonState = reading;
// Serial.print(buttonState);               // +++ externe Kontrollfunktion +++
      if (buttonState == HIGH) {
        LCDHBHL = !LCDHBHL;
      }
    }
  }
  digitalWrite(LCDHB, LCDHBHL);             // LCD-Hintergrundbeleuchtung ein/aus
  lastButtonState = reading;                // Taste Zustand festhalten
}

//**********************************************************************************************
                                            // ### Zeit lesen ###
  if (RTC.read(tm)) {

lcd.setCursor(3, 1);                        // Zeit auf Display ausgeben
    print2digits(tm.Hour);
    lcd.print(":");
    print2digits(tm.Minute);
    lcd.print(".");
    print2digits(tm.Second);

lcd.setCursor(0, 2);

switch(tm.Wday)                             // Wochentag festlegen So ist 1
{
  case 1: 
    lcd.print("So");
    break;
  case 2: 
    lcd.print("Mo");
    break;
  case 3: 
    lcd.print("Di");
    break;
  case 4: 
    lcd.print("Mi");
    break;
  case 5: 
    lcd.print("Do");
    break;
  case 6: 
    lcd.print("Fr");
    break;
  case 7: 
    lcd.print("Sa");
    break;
  }
lcd.print(" ");

    print2digits(tm.Day);                    // führende 0 einfügen
    lcd.print('.');
    print2digits(tm.Month);
    lcd.print('.');
    lcd.print(tmYearToCalendar(tm.Year));
    lcd.setCursor(1, 3);
    lcd.print("            ");        // Status-Meldungen löschen


  }  else {
      lcd.setCursor(1, 3);
      lcd.print("RTC - Fehler");     // Status-Meldung RTC oder BUS Fehler
    }
 }
void print2digits(int number) {            // führende 0 festlegen
  if (number >= 0 && number < 10) {
    lcd.print('0');
  }
  lcd.print(number);
}

Gruß und Dank
Andreas

SkobyMobil:
Habe ich aus "setTime und RTC.set" wieder den Kommentar hergestellt und übertrage es wieder, dann kommt es zum Problem.

Also wenn Du in der setup-Funktion die Uhrzeit stellst, kann in der loop die laufende Uhrzeit korrekt ausgelesen werden, aber wenn die Uhrzeit zu Beginn nicht gestellt wird, kann in der loop nur eine falsche Uhrzeit ausgelesen werden?

In dem Fall würde ich mal die Pufferbatterie prüfen

  • Sitzt die Pufferbatterie fest, hat sie Kontakt?
  • Mit einem Multimeter ausmessen: Batteriespannung an VBat bei stromlosem Arduino?

Hallo jurs,
also:

setTime(13,53,0,9,1,14); // Uhrzeit manuell setzen
RTC.set(now());

übertrage ich, 2 sek vor Time- Reset, RTC ist gestellt

dann:


//setTime(13,53,0,9,1,14); // Uhrzeit manuell setzen
//RTC.set(now());

übertrage ich später (z.B. 14:00:00), dann ist Uhrzeit wieder "setTime"

Die Batterie hat 3,2v und die Spannung bricht auch nicht ein.

Ich kann die RTC stellen, Arduino über Nacht ohne Spannung- am nächsten Tag
genaue Zeit- keine Probleme.
Ich kann "Reset" am Arduino- keine Probleme.

Muß nach "RTC.set(now())" noch ein "RTC ist gestellt" in die RTC geschrieben
werden?
Gruß und Dank
Andreas

RTC Module mögen gerne eine kleinen Pufferelko auf der Betiebsspannung (nicht U batt), habe ich mal gelesen. Ansonsten gehen auch die sehr genauen DS3231 ungenau. Da mein kleines Chinaboard unten eine Stiftleiste und oben nochmal freie Löcher hat, habe ich dort vorsorglich einen 47µ Elko draufgebraten. Original ist nämlich keiner vorgesehen.
Vielleicht löst das ja dein Problem.

Gruß Gerald

Hallo nix_mehr_frei,
kann ich mir nicht vorstellen, wenn keine Versorgungsspannung anliegt schaltet die auf Batterie um.
Das funktioniert ja auch alles.
Aber-
ich stelle die Uhr wie oben beschrieben,
dann übertrage ich den Code wie oben beschrieben, die Uhrzeit wird wieder auf "setTime" gesetzt

Übertrage ich jetzt wieder, diesen oder andere Sketche passiert nichts mehr.
Der Fehler tritt also nur einmal auf.
Gruß und Dank
Andreas

Nachtrag:
Wenn ich beim zweiten Übertragen SDA/SCL abklemme, dann funktioniert es.
Keine Probleme mehr. Da wird wohl eine von den Lib´s etwas prüfen oder schreiben??