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.
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.
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.
Jürgen, setzt mal hier den Sketch rein.
Vermutlich ist dort eine Setzfunktion mit drin, damit die beim ersten Mal richtig eingestellt wird.
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.
]
#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
}
}
}
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.
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
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. ?
DOC hat sich schon wieder erledigt, die Lösung war:
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 ");
}
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 ?
--> Offener Kamin für die Terrasse - #24 by malerlein - Deutsch - Arduino Forum
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 ...
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
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.
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;
}
}
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.
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.
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:
char str[] = "15:00:00";
int cmp = strcmp_P(str, PSTR("16:00:00"));
Liefert -1
Das hier liefert aber 1:
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:
char str[] = "01:00:00";
int cmp = strcmp_P(str, PSTR("16:00:00"));
Liefert -1
Danke Serenifly, wieder etwas dazu gelernt. Ich habe es ja auch so geschafft, aber das ist schön das Du mir das gesendet hast, das kann ich gut gebrauchen.