Go Down

Topic: Erledigt Fragen zu DS1302 (Read 6083 times) previous topic - next topic

malerlein

Jan 13, 2015, 08:08 pm Last Edit: Jan 14, 2015, 11:12 am by malerlein
Hallo Freunde, ich habe in meinem Schatzkästchen noch ein RTC Modul gefunden das mit dem DS1302 Chip drauf. Jetzt wollte ich Schätzchen an einem Arduino Uno anschliessen nach dem Sketch aus dem Playground welcher extra für dem DS1307 dort eingestellt wurde. Jedoch obwohl ich alles so angeschlossen habe, Vcc an 5v pin, GND an GND pin; CLK an pin 6, Dat an Pin 7 und RST an pin 8. Obwohl ich nicht genau weis ob das mit dem RST an Pin 8 richtig ist, da in Playground beschrieben ist CE an pin 8, aber CE ist auf dem Modul nicht aufgeführt. Der Uno blinkt auch im Sekundentakt, jedoch bei der Seriellen Ausgabe wird mir auf dem Monitor alles angegeben nur nicht die Richtige Uhrzeit, obwohl ich diese in dem Sketch an der vorgesehene stelle eingegeben habe. mir wird immer folgendes angezeigt.
l.G.Jürgen

Verzeihe Deinen Feinden, aber vergesse nie Ihren Namen.

Doc_Arduino

Hallo,

so eine blöde RTC nimmt auch niemand.  :)

Google mal nach "arduino DS1302" und folge der Spur zu Github und teste die Librarys und Codes. Oder Deine Verdrahtung stimmt nicht.
Tschau
Doc Arduino '\0'

Messschieber auslesen: http://forum.arduino.cc/index.php?topic=273445
EA-DOGM Display - Demos: http://forum.arduino.cc/index.php?topic=378279

malerlein

DOC, ich habe mir ja schon andere bestellt, aber die war nun einmal da,Verdrahtet sollte es schon richtig sein, sie Läuft ja und zeigt jetzt auch die Uhrzeit, lediglich behäld sie jetzt die Uhrzeit nicht, wenn ich den uno vom Netz nehme und ihn wieder dran hänge fängt sie immer mit der alten Uhrzeit an obwohl sie eine neue Batterie hat. Naja muss ich noch was warten.
l.G.Jürgen

Verzeihe Deinen Feinden, aber vergesse nie Ihren Namen.

sschultewolter

Jürgen, setzt mal hier den Sketch rein.

Vermutlich ist dort eine Setzfunktion mit drin, damit die beim ersten Mal richtig eingestellt wird.
Orginal Atmel AVRISP mkII zu verkaufen. Anfrage per PN ;)

malerlein

#4
Jan 14, 2015, 09:28 am Last Edit: Jan 14, 2015, 10:41 am by malerlein
Stefan, Sie tickt und bringt die Uhrzeit, lediglich behält sie die Uhrzeit nicht, sobald ich den Arduino vom Strom nehme und ihn wieder anschalte fängt sie mit der gleichen Uhrzeit an wo ich den Sketch hochgeladen habe. Ich habe jetzt schon 3x die Batterie gewechselt aber es funktioniert nicht. Hier mal der Sketch. Den Sketch habe ich aus dem Playground übernommen.

Code: [Select]
]
#define DS1302_SCLK_PIN   6    // Arduino pin for the Serial Clock
#define DS1302_IO_PIN     7   // Arduino pin for the Data I/O
#define DS1302_CE_PIN     8   // Arduino pin for the Chip Enable

#define bcd2bin(h,l)    (((h)*10) + (l))
#define bin2bcd_h(x)   ((x)/10)
#define bin2bcd_l(x)    ((x)%10)

#define DS1302_SECONDS           0x80
#define DS1302_MINUTES           0x82
#define DS1302_HOURS             0x84
#define DS1302_DATE              0x86
#define DS1302_MONTH             0x88
#define DS1302_DAY               0x8A
#define DS1302_YEAR              0x8C
#define DS1302_ENABLE            0x8E
#define DS1302_TRICKLE           0x90
#define DS1302_CLOCK_BURST       0xBE
#define DS1302_CLOCK_BURST_WRITE 0xBE
#define DS1302_CLOCK_BURST_READ  0xBF
#define DS1302_RAMSTART          0xC0
#define DS1302_RAMEND            0xFC
#define DS1302_RAM_BURST         0xFE
#define DS1302_RAM_BURST_WRITE   0xFE
#define DS1302_RAM_BURST_READ    0xFF

#define DS1302_D0 0
#define DS1302_D1 1
#define DS1302_D2 2
#define DS1302_D3 3
#define DS1302_D4 4
#define DS1302_D5 5
#define DS1302_D6 6
#define DS1302_D7 7

#define DS1302_READBIT DS1302_D0 // READBIT=1: read instruction

#define DS1302_RC DS1302_D6

#define DS1302_CH DS1302_D7   // 1 = Clock Halt, 0 = start

#define DS1302_AM_PM DS1302_D5 // 0 = AM, 1 = PM
#define DS1302_12_24 DS1302_D7 // 0 = 24 hour, 1 = 12 hour

#define DS1302_WP DS1302_D7   // 1 = Write Protect, 0 = enabled

#define DS1302_ROUT0 DS1302_D0
#define DS1302_ROUT1 DS1302_D1
#define DS1302_DS0   DS1302_D2
#define DS1302_DS1   DS1302_D2
#define DS1302_TCS0  DS1302_D4
#define DS1302_TCS1  DS1302_D5
#define DS1302_TCS2  DS1302_D6
#define DS1302_TCS3  DS1302_D7

typedef struct ds1302_struct
{
  uint8_t Seconds:4;      // low decimal digit 0-9
  uint8_t Seconds10:3;    // high decimal digit 0-5
  uint8_t CH:1;           // CH = Clock Halt
  uint8_t Minutes:4;
  uint8_t Minutes10:3;
  uint8_t reserved1:1;
  union
  {
    struct
    {
      uint8_t Hour:4;
      uint8_t Hour10:2;
      uint8_t reserved2:1;
      uint8_t hour_12_24:1; // 0 for 24 hour format
    } h24;
    struct
    {
      uint8_t Hour:4;
      uint8_t Hour10:1;
      uint8_t AM_PM:1;      // 0 for AM, 1 for PM
      uint8_t reserved2:1;
      uint8_t hour_12_24:1; // 1 for 12 hour format
    } h12;
  };
  
};


void setup()
{      
  ds1302_struct rtc;


  Serial.begin(9600);
  Serial.println(F("DS1302 Real Time Clock"));
  Serial.println(F("Version 2, March 2013"));
  
  DS1302_write (DS1302_ENABLE, 0);
 
  DS1302_write (DS1302_TRICKLE, 0x00);

#define SET_DATE_TIME_JUST_ONCE
  
#ifdef SET_DATE_TIME_JUST_ONCE

  int seconds, minutes, hours;

  seconds    = 00;
  minutes    = 55;
  hours      = 23;


  memset ((char *) &rtc, 0, sizeof(rtc));

  rtc.Seconds    = bin2bcd_l( seconds);
  rtc.Seconds10  = bin2bcd_h( seconds);
  rtc.CH         = 0;      // 1 for Clock Halt, 0 to run;
  rtc.Minutes    = bin2bcd_l( minutes);
  rtc.Minutes10  = bin2bcd_h( minutes);
  
  rtc.h24.Hour   = bin2bcd_l( hours);
  rtc.h24.Hour10 = bin2bcd_h( hours);
  rtc.h24.hour_12_24 = 0; // 0 for 24 hour format
 

  DS1302_clock_burst_write( (uint8_t *) &rtc);
#endif
}

void loop()
{
  
  ds1302_struct rtc;
  char buffer[60];     // the code uses 70 characters.
  
  DS1302_clock_burst_read( (uint8_t *) &rtc);

    sprintf( buffer, "Time = %02d:%02d:%02d, ", \
    bcd2bin( rtc.h24.Hour10,rtc.h24.Hour), \
    bcd2bin( rtc.Minutes10, rtc.Minutes), \
    bcd2bin( rtc.Seconds10, rtc.Seconds));
    Serial.println(buffer);
  delay(1000);
}



void DS1302_clock_burst_read( uint8_t *p)
{
  int i;

  _DS1302_start();

  _DS1302_togglewrite( DS1302_CLOCK_BURST_READ, true);  

  for( i=0; i<8; i++)
  {
    *p++ = _DS1302_toggleread();
  }
  _DS1302_stop();
}


void DS1302_clock_burst_write( uint8_t *p)
{
  int i;

  _DS1302_start();

 
  _DS1302_togglewrite( DS1302_CLOCK_BURST_WRITE, false);  

  for( i=0; i<8; i++)
  {
    
    _DS1302_togglewrite( *p++, false);  
  }
  _DS1302_stop();
}


uint8_t DS1302_read(int address)
{
  uint8_t data;

  // set lowest bit (read bit) in address
  bitSet( address, DS1302_READBIT);  

  _DS1302_start();
  // the I/O-line is released for the data
  _DS1302_togglewrite( address, true);  
  data = _DS1302_toggleread();
  _DS1302_stop();

  return (data);
}


void DS1302_write( int address, uint8_t data)
{
  // clear lowest bit (read bit) in address
  bitClear( address, DS1302_READBIT);  

  _DS1302_start();
  // don't release the I/O-line
  _DS1302_togglewrite( address, false);
  // don't release the I/O-line
  _DS1302_togglewrite( data, false);
  _DS1302_stop();  
}


void _DS1302_start( void)
{
  digitalWrite( DS1302_CE_PIN, LOW); // default, not enabled
  pinMode( DS1302_CE_PIN, OUTPUT);  

  digitalWrite( DS1302_SCLK_PIN, LOW); // default, clock low
  pinMode( DS1302_SCLK_PIN, OUTPUT);

  pinMode( DS1302_IO_PIN, OUTPUT);

  digitalWrite( DS1302_CE_PIN, HIGH); // start the session
  delayMicroseconds( 4);           // tCC = 4us
}


void _DS1302_stop(void)
{
  
  digitalWrite( DS1302_CE_PIN, LOW);

  delayMicroseconds( 4);           // tCWH = 4us
}


uint8_t _DS1302_toggleread( void)
{
  uint8_t i, data;

  data = 0;
  for( i = 0; i <= 7; i++)
  {
    
    digitalWrite( DS1302_SCLK_PIN, HIGH);
    delayMicroseconds( 1);

    
    digitalWrite( DS1302_SCLK_PIN, LOW);
    delayMicroseconds( 1);        // tCL=1000ns, tCDD=800ns
    
    bitWrite( data, i, digitalRead( DS1302_IO_PIN));
  }
  return( data);
}


void _DS1302_togglewrite( uint8_t data, uint8_t release)
{
  int i;

  for( i = 0; i <= 7; i++)
  {
    
    digitalWrite( DS1302_IO_PIN, bitRead(data, i));  
    delayMicroseconds( 1);     // tDC = 200ns

    
    digitalWrite( DS1302_SCLK_PIN, HIGH);    
    delayMicroseconds( 1);     // tCH = 1000ns, tCDH = 800ns

    if( release && i == 7)
    {
      
      pinMode( DS1302_IO_PIN, INPUT);

      
    }
    else
    {
      digitalWrite( DS1302_SCLK_PIN, LOW);
      delayMicroseconds( 1);       // tCL=1000ns, tCDD=800ns
    }
  }
}
l.G.Jürgen

Verzeihe Deinen Feinden, aber vergesse nie Ihren Namen.

malerlein

Stefan Danke für Dein Hilfsangebot, aber hat sich erledigt. Ich habe es gefunden, läuft auch alles super und die RTC hält auch die Zeit. das einzigste Manke bei der DS1307 ist das keine Sommer und Winterzeit berücksichtigt wird. aber damit kann ich lebe für den Kamin ob der nun um 18 0der 19 Uhr an geht spielt keine große Rolle. Danke noch einmal.
l.G.Jürgen

Verzeihe Deinen Feinden, aber vergesse nie Ihren Namen.

Doc_Arduino

Hallo,

und woran lag Dein Problem denn nun? Solche Antworten "hat sich erledigt" sind immer die besten. ;)

Das mit der Winterzeit/Sommerzeitumstellung hat nichts mit der RTC zu tun. Das muß man in der Software machen.

Dafür hat jurs was beigesteuert.   :)  Lies in dem Thread.
http://forum.arduino.cc/index.php?topic=234453.new;topicseen#new
Tschau
Doc Arduino '\0'

Messschieber auslesen: http://forum.arduino.cc/index.php?topic=273445
EA-DOGM Display - Demos: http://forum.arduino.cc/index.php?topic=378279

malerlein

#7
Jan 14, 2015, 02:53 pm Last Edit: Jan 14, 2015, 04:21 pm by malerlein
ja mit Winter und Sommer , da hast Du schon recht, aber das war auch nicht Massgeblich für mich. Es lag daran das ich immer über 5V gegangen bin, weil die angaben für den DS1302 3 - 5,5V waren. als ich es umgepoolt habe auf 3,3V  lief alles super. Und das mit dem Erledigt "LACH"  ist immer das schnellste und einfachste. Aber da Du , wenn Du das lesen solltest. Könntest Du mir eine kleine Hilfestellung geben.  Die Uhrzeit wird in buffer gespeichert. jetzt möchte ich eine abfrage erstellen.  

if ((buffer >= "17:00:00") and (buffer <= "1:00:00"))
{
Pixel auschalten
}
else
{
Pixel anschalten
}

oder kann man so nicht 2 Strings vergleichen ? muss ich eventuell die Strings wieder umwandeln. ?
l.G.Jürgen

Verzeihe Deinen Feinden, aber vergesse nie Ihren Namen.

malerlein

#8
Jan 14, 2015, 03:24 pm Last Edit: Jan 14, 2015, 04:22 pm by malerlein
DOC  hat sich schon wieder erledigt, die Lösung war:

Code: [Select]

if ((bcd2bin( rtc.h24.Hour10,rtc.h24.Hour) <= 17) and (bcd2bin( rtc.h24.Hour10,rtc.h24.Hour) >= 1))
   {

   for(int i = 0; i < NUM_LEDS; i++) leds[i] = CRGB(0, 0, 0);
   FastLED.show(); // display this frame
   Serial.print(" Aus ");
 }
 else
 {
   feuer();
   Serial.print("  An  ");
 }
l.G.Jürgen

Verzeihe Deinen Feinden, aber vergesse nie Ihren Namen.

michael_x

Quote
sobald ich den Arduino vom Strom nehme und ihn wieder anschalte fängt sie mit der gleichen Uhrzeit an wo ich den Sketch hochgeladen habe
Bist du nicht der Experte, der das gut findet, weil seine Uhr nie resetet wird, sondern höchstens mal einen neu kompilierten Sketch hochgeladen kriegt. Und der bei jedem Reset die Uhr absichtlich mit der Übersetzungszeit initialisiert ? 

--> http://forum.arduino.cc/index.php?topic=285443.msg2029807#msg2029807

Find ich gut, dass du dies hier als Problem stellst   ;)
Auch gut, dass du es schon selbst erkannt hast.

DS1302 und DS1307 sind übrigens leicht unterschiedlich ...

malerlein

Ja Michael, das bin ich. Aber bei dem Kamin mit der Befeuerung klappt das alles nicht so wie bei der Dezimal Uhr. Ich denke einmal da kommt sich etwas in die Quere. Komischer weise läuft bei dem Sketch für den Kamin die Software Uhr die ich bei der Dezimal Uhr verwende innerhalb einer Stunde um fast 20 Minuten nach, das kann ich auch nicht mehr mit den Millis() ausgleichen, was bei der Dezimal Uhr super geht. ich habe es nicht rausbekommen warum, deshalb bin ich auf die DS1302 gekommen und habe dann bemerkt das es echt ein Unterschied gegenüber der DS1307 ist. Schon beim verkabeln. Aber ich habe das Alter wo ich die Zeit und auch mittlerweile die Geduld habe um weiter zu kommen. Die DS1307 habe ich in meinem Aquariumcomputer verbaut und sie läuft und läuft und läuft :-)
l.G.Jürgen

Verzeihe Deinen Feinden, aber vergesse nie Ihren Namen.

Doc_Arduino

Hallo,

Du hast Dir zwar schon selbst geholfen, ich zeige dir dennoch meine Funktion um verschiedene Zeitbereiche auszuwerten. Ich habe verschiedene Meßintervalle je nach Uhrzeit festgelegt. Die Variable "_Intervallzeit" werte ich dann woanders aus.

Code: [Select]
void Messintervall ()
{   // Reihenfolge spät nach früh
    static byte alter_Zeitbereich = 0;
    byte Zeitbereich = 0;  // default
   
    if ( _Stunde == 21 && _Minute <= 30 ) {   // zwischen 21:00 - 21:30 Uhr
      Zeitbereich = 5;   
    }
    if ( _Stunde == 18 && _Minute <= 30 ) {   // zwischen 18:00 - 18:30 Uhr
      Zeitbereich = 4;   
    } 
    if ( _Stunde == 15 && _Minute <= 30 ) {   // zwischen 15:00 - 15:30 Uhr
      Zeitbereich = 3;   
    } 
    if ( _Stunde ==  13 && _Minute <= 30 ) {   // zwischen 13:00 - 13:30 Uhr
      Zeitbereich = 2;
    } 
    if ( _Stunde ==  5 && _Minute <= 30 ) {   // zwischen 5:00 - 5:30 Uhr
      Zeitbereich = 1;
    }
       
    switch (Zeitbereich)  {
       case 1 : _Intervallzeit =  3; break;  //  3 _Minute
       case 2 : _Intervallzeit =  5; break;  //  5 _Minuten
       case 3 : _Intervallzeit =  7; break;  //  7 _Minuten
       case 4 : _Intervallzeit =  8; break;  //  8 _Minuten
       case 5 : _Intervallzeit =  9; break;  //  9 _Minuten
      default : _Intervallzeit =  15;        // 15 _Minuten
    }   

    if ( Zeitbereich != alter_Zeitbereich && Zeitbereich == 0 )  {  // hat sich das Messintervall geändert?
      alter_Zeitbereich = Zeitbereich;
    } 
    else if ( Zeitbereich != alter_Zeitbereich && Zeitbereich != 0 )  {  // hat sich das Messintervall geändert?
      _RTC_Alarmflagcounter = 99;               // kurzzeitige Erhöhung, damit wird eine syncronisierte Messung zum Zeitbereichsanfang erzwungen
      alter_Zeitbereich = Zeitbereich;
    }
   
}       
Tschau
Doc Arduino '\0'

Messschieber auslesen: http://forum.arduino.cc/index.php?topic=273445
EA-DOGM Display - Demos: http://forum.arduino.cc/index.php?topic=378279

malerlein

Danke Doc, ja so habe ich das ungefähr auch bei meiner Dezimaluhr, zwar etwas aufwendiger, da dort die Sommer/Winterzeit und Schaltjahre mit eingerechnet sind. Aber wo es mir drum ging war, das auswerten von einem String der die Uhrzeit enthält zu einer Variablen.  also ungefähr so  if (String == Variable) {ausführung}   ich habe es anders gelöst, aber ich wollte bei der Uhrzeit die als String in buffer steht, nur die Stunden zur Zahl umwandeln um sie in unter if zu vergleichen.
l.G.Jürgen

Verzeihe Deinen Feinden, aber vergesse nie Ihren Namen.

malerlein

#13
Jan 15, 2015, 04:48 pm Last Edit: Jan 15, 2015, 04:52 pm by malerlein
So der Kamin ist soweit fertig, die DS1302 schaltet auch so wie ich es wollte 18 Uhr Kamin an 1 Uhr Kamin aus.
Hier mal 2 Bilder vom Kamin die Keramik Scheite leuchten schön wie bei brennenden Hulzscheiten und es gibt einen Schein auf der Hunterfront als wenn der Kamin richtig brennen würde.
l.G.Jürgen

Verzeihe Deinen Feinden, aber vergesse nie Ihren Namen.

Serenifly

Strings lexikalisch miteinander vergleichen geht mit strcmp(). Da muss man aber genau auf das Format aufpassen.

strcmp(str1, str2) gibt -1 zurück wenn das erste unterschiedliche Zeigen in str1 kleiner ist als in str2. 0 bei Gleichheit. Und 1 wenn str1 > str2

Das hier würde also gehen:
Code: [Select]

char str[] = "15:00:00";
int cmp = strcmp_P(str, PSTR("16:00:00"));

Liefert -1

Das hier liefert aber 1:
Code: [Select]

char str[] = "1:00:00";
int cmp = strcmp_P(str, PSTR("16:00:00"));

Da ':' = 58 und '6' = 54

Die Uhrzeit müsste also führende Nullen haben:
Code: [Select]

char str[] = "01:00:00";
int cmp = strcmp_P(str, PSTR("16:00:00"));

Liefert -1

Go Up