Ich glaube ich werde das nie lernen mit den Variablen Typen.
Ich versuche gerade das Funkuhrsignal in eine RTC zu schreiben.
von der Funkuhr bzw der Time.h bekomme ich ja :
sekund() minute() hour() year() month() day()
Das sind int wenn ich mich nicht irre. Diese werden mir auch schön im seriellen Monitor angezeigt:
17.12.2012 16:31:02
So die RTC (ich habe hier eine softI2C) nimmt die Daten richtig an wenn ich sie so schreibe:
uint8_t d[4];
d[3]=0x12; // Jahr
d[2]=0x12; // Monat
d[1]=0x16; // Tag
d[0]=0x01; // Wochentag
Das ist HEX-Schreibweise wenn ich mich nicht irre.
Wenn ich jetzt einfach die ints versuche zu übergeben sieht meine ausgelesene RTC so aus;
RTC: 11.0C.2001 01:1F:01
Das ist irgendwie falsch!
Gehe ich recht in der Annahme das ich aus dem int ein HEX machen muss?
Und wenn ja, wie?
MueThoS:
Gehe ich recht in der Annahme das ich aus dem int ein HEX machen muss?
Und wenn ja, wie?
Nein, Du mußt nur Deine RTC-Library korrekt anwenden!
Dazu schaust Du nach, welche RTC-Library Du installiert hast (da gibt es wohl viel mehr als nur eine).
Dann lädst Du Dir das Beispielprogramm zu dieser RTC-Library in Deine Arduino-Software.
Dann studierst Du das Beispielprogramm.
Beispielprogramme sind kommentiert und in den Programmkommentaren stehen die notwendigen Hinweise, wie die Library angewendet wird.
Mit 0x beginnende Zahlen sind unter C die Hex-Schreibweise im 16er System
0x12 = 116 + 2 = 18
0x16 = 116 + 6 = 22
0x01 = 0*16 + 1 = 1
Ich habe, wie gesagt, die softi2c nennt sich i2cMaster.
Das Beispiel Programm habe ich offen.
Und dort ist folgendes interessant:
wenn ich die Zeit stellen will wird dies aufgerufen:
uint8_t bcdRead(uint8_t min, uint8_t max, uint8_t &n) {
uint16_t v;
if (!hexRead(v)) return false;
uint8_t d = 10 * (v >> 4) + (v & 0XF);
if ((v >> 4) > 9 || (v & 0XF) > 9 || d < min || d > max) {
PgmPrintln("Invalid");
return false;
}
n = v;
return true;
}
Was ich hier noch verstehe ist das hexRead aufgerufen wird.
dann kommt etwas was ich nicht verstehe. (uint8_t d = 10 * (v >> 4) + (v & 0XF)
Und dann wird geschaut ob die Werte gültig sind.
hexRead:
uint8_t hexRead(uint16_t &v) {
uint16_t n = 0;
while (!Serial.available());
while (Serial.available()) {
uint8_t c = Serial.read();
n <<= 4;
if ('a' <= c && c <= 'f') {
n += c - ('a' - 10);
}
else if ('A' <= c && c <= 'F') {
n += c - ('A' - 10);
}
else if ('0' <= c && c <= '9') {
n += c - '0';
}
else {
PgmPrintln("Invalid entry");
return false;
}
delay(10);
}
v = n;
return true;
}
es wird gewartet bis was über Seriell rein kommt.
Dann werden die kommenden Daten in c gelesen
dann wird geschaut ob die Werte Zahlen sind (so denke ich)
und der rest ist wieder Bahnhof.
Hier wird die RTC beschrieben:
uint8_t writeDS1307(uint8_t address, uint8_t *buf, uint8_t count) {
// issue a start condition, send device address and write direction bit
if (!rtc.start(DS1307ADDR | I2C_WRITE)) return false;
// send the DS1307 address
if (!rtc.write(address)) return false;
// send data to the DS1307
for (uint8_t i = 0; i < count; i++) {
if (!rtc.write(buf[i])) return false;
}
// issue a stop condition
rtc.stop();
return true;
}
Und wenn ich mir das anschaue würde ich sagen uint8_t *buf sollte mein Wert sein.
Also ein INT würde ich vermuten. Aber meine sekund() usw sind doch INTs
Und weil ich das nicht verstehe komme ich nicht weiter.
MueThoS:
Und weil ich das nicht verstehe komme ich nicht weiter.
Ich glaube, Du verhedderst Dich da in den Untiefen von Umrechnungen mit Zahlensystemen, von denen Du weder etwas verstehst noch dass Du sie benötigst.
BCD Zahlen sind Binary Coded Dezimals, binärcodierte Dezimalzahlen:
Damit kann man jede dezimale Ziffer von 0 bis 9 mit vier Bits darstellen.
Das wirst Du mit Sicherheit alles gar nicht benötigen.
Was Du immer benötigst, wenn es um Zeiten geht, das ist die Unix-Zeit.
Das ist ein long integer (32-Bit) Ganzzahlenwert mit der Anzahl der Sekunden seit dem 01.01.1970.
DAS ist es, womit Programmierer ihre Uhrzeiten handeln. Und wenn Du irgendeine Zeit-Library hast, dann gibt es einerseits bequeme Funktionen, um Tag, Monat, Jahr, Stunde, Minute, Sekunde in Unixzeit umzurechnen. Und umgekehrt genauso.
Und für Deine RTC-Library gibt es mit ziemlicher Sicherheit sowohl eine Schreibfunktion, der Du die Unixzeit übergeben kannst und auch eine Lesefunktion, von der Du die Unixzeit aus der Uhr geliefert bekommst.
Du hast es also im Endeffekt nur mit vier Funktionen zu tun, und die fressen allesamt Dezimalzahlen:
Eine Umrechenfunktion von Tag, Monat, Jahr, Stunde, Minute, Sekunde in Unixzeit
Eine Umrechenfunktion von Unixzeit in Tag, Monat, Jahr, Stunde, Minute, Sekunde
Eine Uhr-Stellen Funktion, die eine Unixzeit zum Stellen der RTC übergeben bekommt
Eine Uhr-Abfragen Funktion, die eine Unixzeit von der RTC geliefert bekommt
Wenn Du diese vier Funktionen bei Dir nicht findest, schreib mal genau, welche Time- und Realtime-Libraries Du installiert hast, dann schau ich mal in die Library rein!
Und Zahlensysteme wie Binärsystem, Hexadezimalsystem, und BCD-Zahlen kannst Du sicher getrost auf Lücke setzen, wenn Du nur eine Uhr stellen oder abfragen oder mit Zeiten rechnen möchtest, das sollte alles mit Dezimalzahlen zu erschlagen sein.
Unter "i2cmaster" finde ich nur eine Library, die was mit LCD-Displays zu tun hat, nicht mit RTC Uhren.
Die RTClib, die Du verlinkt hast, habe ich. Würde auch funktionieren. Möchte ich für meinen Anwendungsfall aber nicht nutzen.
Es sei denn ich kann sie auf andere PINs legen.
Die Lib die ich hier nutze (I2cMaster) Funktioniert mit dem Beispiel auch.
In meiner Umsetzung funktioniert es auch wenn ich die Daten mal zum Testen hard code:
...
d[1]=0x17;
...
writeDS1307(3, d, 4)
Für Heute den 17ten.
Nur leider ist zwischen day() der Time-Lib und 0x17 ein unterschied.
Das ist BCD
Binär Codierte Dezimal - Zahlen: 4 Bit Einerstelle, 2 bis 4 Bit Zehnerstelle.
pups-einfach: Schau auf Seite 5 dieses Datenblatts, http://www.sparkfun.com/datasheets/Components/DS1307.pdf
Da ist jedes Bit der 7 Datenbytes einer 1307 beschrieben.
(jedenfalls einfacher als auf einem Arduino mit Unix-Zeit rumzumachen)
Nur leider ist zwischen day() der Time-Lib und 0x17 ein unterschied.
byte day() {
byte ram = readDS1307Byte(3); // offset des DS1307 Bytes mit dem Kalendertag.
return (ram>>4)*10 + ram&0x0f;
}
OK, dann haken wir das Thema jetzt hier ab und ich frage was ganz anderes:
Ich möchte sozusagen ein Shield basteln welches nur eine Aufgabe hat:
DCF77 auswerten und in eine RTC schreiben.
Es soll dann möglich sein mit dem Arduino von dem Shield folgende Informationen zu bekommen:
Uhrzeit (aus der RTC)
Wann wurde zuletzt gesynct
Haben wir noch eine richtige Zeit
Es soll möglich sein den SQW/Out zu konfigurieren dieser soll an einen Pin anliegen
Solche Sachen halt. Einfach die Auswertung und Vorhaltung der aktuellen Zeit outsourcen.
Und da die Kommunikation zwischen RTC und uC unabhängig laufen sollte wollte ich diesen I2C-Bus auf anderen Pins haben.
Und die Hardware I2C soll dann später mit dem Arduino kommunizieren.
Die Frage ist wenn ich die Hardware-I2C nutze kann ich da nicht wild umher funken oder?
Die Frage ist wenn ich die Hardware-I2C nutze kann ich da nicht wild umher funken oder?
Wenn nur ein Master da ist, kann der "wild umher funken".
"DCF77 Auswertung in eine RTC schreiben" sollte dann der gleiche Arduino (?) machen, der auch den Rest macht.
Die gefilterte Zeit der DCF kommt doch immer noch mit nur ca. 1 bit / sek, oder hab ich da was nicht mitgekriegt ?
Das Shield kümmert sich um alles was mit Zeit zu tun hat, so mein Plan!
Ursprünglich hatte ich gehofft das man auf dem Shield nicht umbedingt einen 328 braucht sondern was kleineres.
mom ich versuch das mal zu krickeln....
Ein Kunstwerk, oder?
So, und jeder der Eine Uhr bauen will steckt dieses Modul auf und hat über I2C immer die aktuelle Uhrzeit.
Hatte ich jetzt noch nicht drüber nach gedacht aber Du hast recht!
Wir halten fest das Shield soll sich so verhalten wie die DS1307 RTC.
Ich glaube ich mach doch mal einen eigene Fred auf für das Dingen.
Die alte Version mit dem exponentiellen Filter ist nur noch ein Benchmark Der neue Filter wird Welten besser. Und natürlich werde ich auch noch eine fette Fehlerkorrektur hinterherschalten. Es kommen noch ein paar Ausbaustufen zu diesem Projekt.
Die Feldstärke in DB zu ermitteln ist mit den einfachen Modulen nicht möglich. Die finale Ausbaustufe meiner Uhr wird aber die Qualität des dekodierten Signals ermitteln. Aktueller Stand ist, daß ich jetzt auch die Sekunden dekodieren kann. Ich bin exakt im Plan
Die nächste Ausbaustufe ist fertig und dokumentiert: What time is it? | Blinkenlight. Decoding Time Data | Blinkenlight. Die aktuell in Entwicklung befindliche Ausbaustufe hat auch die Sommerzeitumstellung richtig hinbekommen, ist aber noch nicht fertig dokumentiert