- Akku Tests und Balkonkraftwerk Speicher         
Ergebnis 1 bis 7 von 7

Thema: RTC per Arduino einstellen

  1. #1
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    17.02.2009
    Ort
    Aachen
    Beiträge
    1.176

    RTC per Arduino einstellen

    Anzeige

    Powerstation Test
    Hallo zusammen,

    ich bin grade seit Stunden am suchen, aber ich kann einfach kein aufschlußreiches Tutorial finden, wie ich ein RTC per Arduino, also ohne PC, einstellen kann.
    Ich würde gerne, falls meinem Arduino und meinem RTC der Saft ausgehen, einfach beide Akkus wechseln und per Arduino ohne PC Zeit und Datum eingeben können.

    In sämtlichen Tutorials wird die Eingabe der Zeit via

    Code:
    DateTime now = RTC.now();
    und

    Code:
    RTC.adjust(DateTime(__DATE__, __TIME__));
    beim Aufspielen des Arduino-Sketchs vorgenommen.
    Ich würde mich über ein paar Suchbegriffe oder vielleicht sogar ein hilfreiches Tutorial sehr freuen.


    //Edit:

    Scheinbar ist das gar nicht so schwer.
    Mit der Lib
    Code:
    #include <DS1307RTC.h>
    Mit diesem Befehl wird dem Arduino die gewünschte Zeit mitgeteilt:
    Code:
    setTime(hr,min,sec,day,month,yr);
    und danach hiermit ins RTC geschrieben:
    Code:
    RTC.set(now());
    Jetzt muss ich nur noch die Lib finden und testen
    Geändert von Cysign (05.06.2015 um 04:24 Uhr)

  2. #2
    Erfahrener Benutzer Roboter Genie Avatar von oderlachs
    Registriert seit
    17.05.2010
    Ort
    Oderberg
    Alter
    73
    Beiträge
    1.175
    Blog-Einträge
    1
    nach der Lib, die Du auf GitHub findest solltest Du mal googlen, habe die URL jetzt nicht im Kopfe...arbeite gerade auch mit RTC und drum herrrum..

    Viel Spass

    Gerhard

    PS: Hier mein Schaffen, inc.LIB als Download
    Arduinos, STK-500(AVR), EasyPIC-40, PICKIT 3 & MPLABX-IDE , Linux Mint

  3. #3
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    17.02.2009
    Ort
    Aachen
    Beiträge
    1.176
    Was macht deine Lib? (ohne sie jetzt runtergeladen und reingeschaut zu haben...)

  4. #4
    Erfahrener Benutzer Roboter Genie Avatar von oderlachs
    Registriert seit
    17.05.2010
    Ort
    Oderberg
    Alter
    73
    Beiträge
    1.175
    Blog-Einträge
    1
    Diese Lib ist für den RTC Baustein mit DS1307, also Zeit, Datum, Tag lesen oder setzen...
    Arduinos, STK-500(AVR), EasyPIC-40, PICKIT 3 & MPLABX-IDE , Linux Mint

  5. #5
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    17.02.2009
    Ort
    Aachen
    Beiträge
    1.176
    Hast du ne Projektseite zu der Lib? Und n Anwendungsbeispiel?
    Und ist sie auch mit DS3231 kompatibel?

  6. #6
    Erfahrener Benutzer Roboter-Spezialist Avatar von schorsch_76
    Registriert seit
    25.03.2012
    Ort
    Kurz vor Neuschwanstein
    Alter
    47
    Beiträge
    456
    Hier hab ich meine RTC Funktionen bzw die Statemachine.

    Code:
    // -----------------------------------------------------
    // RTC
    // -----------------------------------------------------
    #include "rtc.h"
    
    #include "util.h"
    #include "project.h"
    #include "i2c.h"
    
    extern avr::project sys;
    extern avr::i2c twi;
    
    extern bool check_twi(unsigned char& state);
    
    namespace rtc {
    unsigned char state = 0;
    avr::util::timeout rtc_timeout;
    
    bool
    handle()
    {
        using namespace avr::util;
    
        switch (state)
        {
        // step 0 to 9 are init. >= 10 are regular stuff
        case 0:
           // try to read from the rtc
           twi.read_from_slave(avr::rtc_address,nullptr,0, 1);
           state++;
           return false;
        case 1:
            if (check_twi(state))
            {
                unsigned char i = 0;
                while (twi.rx_size() > 0)
                {
                    twi >> g_buffer[i];
                    ++i;
                }
                // is the Clock Halt bit active?
                if (g_buffer[0] & 0x80)
                {
                    // bit is set. We need to enable the clock
                    sys.LED_141.toggle();
                }
                else
                {
                    // bis is cleared. Clock is running
                    state = 4;
                }
                return true;
            }
            return false;
        case 2:
            // enable the clock
            g_buffer[0] = 0x00;
            g_buffer[1] = to_bcd(sys.dt.sec);
            g_buffer[2] = to_bcd(sys.dt.min);
            g_buffer[3] = to_bcd(sys.dt.hour);
            g_buffer[4] = sys.dt.dow;
            g_buffer[5] = to_bcd(sys.dt.day);
            g_buffer[6] = to_bcd(sys.dt.month);
            g_buffer[7] = to_bcd(sys.dt.year);
            g_buffer[8] = 0;
    
            twi.write_to_slave(avr::rtc_address, g_buffer, 8);
            state++;
            return false;
        case 3:
            return check_twi(state);
        case 4:
            // clock is running. poll it only every second
            rtc_timeout.start(1000);
            state++;
            return true;
        case 5:
            if (rtc_timeout.elapsed())
            {
                if (sys.rtc_change_in_progress)
                {
                    state = 10;
                }
                else
                {
                    state++;
                }
            }
            return true;
        case 6:
           // try to read from the rtc
           g_buffer[0] = 0x00;
           twi.read_from_slave(avr::rtc_address,g_buffer,1, 8);
           state++;
           return false;
        case 7:
            if (check_twi(state))
            {
                unsigned char i = 0;
                while (twi.rx_size() > 0)
                {
                    twi >> g_buffer[i];
                    ++i;
                }
                if (i == 8)
                {
                sys.LED_142.toggle();
    
                // update the sys variables from the RTC values
                sys.dt.sec   = from_bcd(g_buffer[0] & 0x7F);
                sys.dt.min   = from_bcd(g_buffer[1] & 0x7F);
                sys.dt.hour  = from_bcd(g_buffer[2] & 0x3F);
                sys.dt.dow   = g_buffer[3] & 0x07;
                sys.dt.day   = from_bcd(g_buffer[4] & 0x7F);
                sys.dt.month = from_bcd(g_buffer[5] & 0x1F);
                sys.dt.year  = from_bcd(g_buffer[6] & 0xFF);
                }
                // jump back to timeout
                state = 4;
                return true;
            }
            break;
        case 10:
            // wait unti user is done
            if (!sys.rtc_change_in_progress)
            {
                state = 2;
            }
            return true;
        default:
            break;
        }
    
        return true;
    }
    
    }; // namespace rtc
    Das ist die Komplette Schrittkette.
    0-> Init und Check ob die Uhr passt
    2->5 Ist das setzen der Uhr
    6-10: Ist das pollen der Uhr

    Das ganze wird Zyklisch aus einem Scheduler aufgerufen.

    EDIT: In meinem Fall läuft das alles in einem Timer IRQ. Damit kann ich Laufzeiten wie bei einer SPS garantieren. Ich darf mir aber keine Zeitscheibenverletzungen erlauben Auch habe ich hier ganz klar den Schwerpunkt auf Trennung der Anwendungslogik von der TWI logik getrennt. Wiederverwendung und Wartbarkeit!
    Geändert von schorsch_76 (05.06.2015 um 21:36 Uhr)

  7. #7
    Erfahrener Benutzer Robotik Einstein Avatar von Rabenauge
    Registriert seit
    13.10.2007
    Ort
    Osterzgebirge
    Alter
    55
    Beiträge
    2.198
    Keine Lib nötig, diesen Code hat User Jurs mal im Arduino-Forum veröffentlicht. Alles da, was man _wirklich_ braucht.


    Code:
    #include <Wire.h>
    // I2C Adresse der RTC ist 0x68 für DS1307 und DS3231
    #define RTC_I2C_ADDRESS 0x68
    
    int jahre,monate,tage,stunden,minuten,sekunden;
    // wochentag bleibt in diesem Test-Sketch unberücksichtigt
    
    void rtcReadTime(int &jahre, int &monate, int &tage, int &stunden, int &minuten, int &sekunden)
    // aktuelle Zeit aus RTC auslesen
    {
    // Reset the register pointer
      Wire.beginTransmission(RTC_I2C_ADDRESS);
      Wire.write(0);
      Wire.endTransmission();
      Wire.requestFrom(RTC_I2C_ADDRESS, 7);
      // A few of these need masks because certain bits are control bits
      sekunden    = bcdToDec(Wire.read() & 0x7f);
      minuten     = bcdToDec(Wire.read());
      stunden     = bcdToDec(Wire.read() & 0x3f);  // Need to change this if 12 hour am/pm
      /*wochentag   = */bcdToDec(Wire.read());
      tage        = bcdToDec(Wire.read());
      monate      = bcdToDec(Wire.read());
      jahre       = bcdToDec(Wire.read())+2000;  
    }
    
    void rtcWriteTime(int jahre, int monate, int tage, int stunden, int minuten, int sekunden)
    // aktuelle Zeit in der RTC speichern
    {
      Wire.beginTransmission(RTC_I2C_ADDRESS);
      Wire.write(0);
      Wire.write(decToBcd(sekunden));    // 0 to bit 7 starts the clock
      Wire.write(decToBcd(minuten));
      Wire.write(decToBcd(stunden));      // If you want 12 hour am/pm you need to set
                                       // bit 6 (also need to change readDateDs1307)
                                      
      Wire.write(decToBcd(0)); // Wochentag unberücksichtigt
      Wire.write(decToBcd(tage));
      Wire.write(decToBcd(monate));
      Wire.write(decToBcd(jahre-2000));
      Wire.endTransmission();  
    }
    
    byte decToBcd(byte val) // Hilfsfunktion zum Lesen/Schreiben der RTC
    // Convert decimal number to binary coded decimal
    // Hilfsfunktion für die Echtzeituhr
    {
      return ( (val/10*16) + (val%10) );
    }
    
    byte bcdToDec(byte val)  // Hilfsfunktion zum Lesen/Schreiben der RTC
    // Convert binary coded decimal to decimal number
    // Hilfsfunktion für die Echtzeituhr
    {
      return ( (val/16*10) + (val%16) );
    }
    
    
    int getIntFromString (char *stringWithInt, byte num)
    // input: pointer to a char array
    // returns an integer number from the string (positive numbers only!)
    // num=1, returns 1st number from the string
    // num=2, returns 2nd number from the string, and so on
    {
      char *tail; 
      while (num>0)
      {
        num--;
        // skip non-digits
        while ((!isdigit (*stringWithInt))&&(*stringWithInt!=0)) stringWithInt++;
        tail=stringWithInt;
        // find digits
        while ((isdigit(*tail))&&(*tail!=0)) tail++;
        if (num>0) stringWithInt=tail; // new search string is the string after that number
      }  
      return(strtol(stringWithInt, &tail, 0));
    }  
    
    
    void setup()
    {
      Wire.begin();       // initialisiert die Wire-Library
      Serial.begin(9600); // Serielle Kommunikation starten
      while (!Serial);    // wait for serial port to connect. Needed for Leonardo only
      Serial.println("\r\nRTC Demo Sketch by jurs for German Arduino Forum");
      Serial.println("Dieser Sketch zeigt die aktuelle Zeit alle 10 Sekunden im 'Serial Monitor'.");
      Serial.println("Du kannst die Zeit mit einem 'set' Befehl im 'Serial Monitor' neu setzen.");
      Serial.println("\r\nBeispiel:");
      Serial.println("set 28.08.2013 10:54\r\n");
    }
    
    
    void machsAlle10Sekunden(){
      static unsigned long prevMillis=-20000;
      char linebuf[30];
      if (millis()-prevMillis<10000) return; // Zeit noch nicht erreicht, Funktion abbrechen
      prevMillis=millis();
      // RTC Uhr auslesen
      rtcReadTime(jahre,monate,tage,stunden,minuten,sekunden);
      // Zeit für Ausgabe formatieren
      snprintf(linebuf,sizeof(linebuf),"%02d.%02d.%04d %02d:%02d:%02d Uhr",tage,monate,jahre,stunden,minuten,sekunden);
      // Zeit auf serieller Schnittstelle ausgeben
      Serial.println(linebuf);
    }
    
    void behandleSerielleBefehle()
    {
      char linebuf[30];
      byte counter;
      if (Serial.available())
      {
        delay(100); // Warte auf das Eintreffen aller Zeichen vom seriellen Monitor
        memset(linebuf,0,sizeof(linebuf)); // Zeilenpuffer löschen
        counter=0; // Zähler auf Null
        while (Serial.available())
        {
          linebuf[counter]=Serial.read(); // Zeichen in den Zeilenpuffer einfügen
          if (counter<sizeof(linebuf)-1) counter++; // Zeichenzähler erhöhen
        }
        // Ab hier ist die Zeile eingelesen
        if (strstr(linebuf,"set")==linebuf) // Prüfe auf Befehl "set" zum Setzen der Zeit
        { // Alle übermittelten Zahlen im String auslesen
          tage=getIntFromString (linebuf,1);
          monate=getIntFromString (linebuf,2);
          jahre=getIntFromString (linebuf,3);
          stunden=getIntFromString (linebuf,4);
          minuten=getIntFromString (linebuf,5);
          sekunden=getIntFromString (linebuf,6);
        }
        else
        {
          Serial.println("Befehl unbekannt.");
          return;
        }
        // Ausgelesene Werte einer groben Plausibilitätsprüfung unterziehen:
        if (jahre<2000 || monate<1 || monate>12 || tage<1 || tage>31 || (stunden+minuten)==0)
        {
          Serial.println(linebuf);
          Serial.println("\r\nFehlerhafte Zeitangabe im 'set' Befehl");
          Serial.println("\r\nBeispiel:");
          Serial.println("set 28.08.2013 10:54\r\n");
          return;
        }
        rtcWriteTime(jahre, monate, tage, stunden, minuten, sekunden);
        Serial.println("Zeit und Datum wurden auf neue Werte gesetzt.");
      }
    }
    
    
    void loop()
    { 
      machsAlle10Sekunden();
      behandleSerielleBefehle();
    }
    Grüssle, Sly
    ..dem Inschenör ist nix zu schwör..

Ähnliche Themen

  1. Arduino vs. Arduino: Kampf um die Arduino IDE
    Von Roboternetz-News im Forum Neuigkeiten / Technik-News / Nachrichten / Aktuelles
    Antworten: 0
    Letzter Beitrag: 04.04.2015, 17:21
  2. Rtc ds3231
    Von simonelein im Forum C - Programmierung (GCC u.a.)
    Antworten: 10
    Letzter Beitrag: 15.08.2012, 17:27
  3. [ERLEDIGT] [ARDUINO] 2 Motoren + Servo mit dem Arduino Uno steuern
    Von Torrentula im Forum C - Programmierung (GCC u.a.)
    Antworten: 0
    Letzter Beitrag: 31.08.2011, 16:31
  4. RTC
    Von Kampi im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 6
    Letzter Beitrag: 21.01.2010, 22:04
  5. RTC für CCRP5
    Von solo im Forum Robby CCRP5
    Antworten: 3
    Letzter Beitrag: 07.04.2006, 06:40

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

Solar Speicher und Akkus Tests