Binäre DCF77 Uhr mit exponentiellem Filter und Blinkenlighty

MueThoS:
Aber dann macht er nichts mehr.

Wo denke ich falsch?

Wenn Du Dich auf den Original-Code beziehst:

const uint8_t dcf77_sample_pin = 19; // A5
const uint8_t dcf77_analog_sample_pin = 5;
...
//const uint32_t input = digitalRead(dcf77_sample_pin) * decimal_offset;
const uint32_t input = analogRead(dcf77_analog_sample_pin)>200? decimal_offset: 0;

Deklariert sind sowohl dcf77_sample_pin als auch dcf77_analog_sample_pin.

Die auskommentierte Codezeile bezieht sich auf dcf77_sample_pin und die ausgeführte Codezeile aber auf dcf77_analog_sample_pin.

Wenn Du den Code so verwendest, mußt Du entweder

  • die Deklaration für dcf77_analog_sample_pin ändern.
    oder
  • die Codezeile verwenden, in der dcf77_sample_pin verwendet wird und die andere auskommentieren.

Jetzt wo Du es sagst. :astonished:

Hab ich nicht gesehen.

Danke!

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 = 1
16 + 6 = 22
0x01 = 0*16 + 1 = 1

Dies versuche ich ja!

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):wink:
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:

  1. Eine Umrechenfunktion von Tag, Monat, Jahr, Stunde, Minute, Sekunde in Unixzeit
  2. Eine Umrechenfunktion von Unixzeit in Tag, Monat, Jahr, Stunde, Minute, Sekunde
  3. Eine Uhr-Stellen Funktion, die eine Unixzeit zum Stellen der RTC übergeben bekommt
  4. 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.

Also,
ich habe folgende Libraries die ich nutze:
softi2c von folgender Seite: (erster Beitrag)
http://forums.adafruit.com/viewtopic.php?f=25&t=13722
die Heißt dann I2cMaster

Time.h (Standard)

Hier aus diesem Fred:
DCF77.h
MsTimer2.h

Ich habe auch schon versucht die Libraries zu analysieren aber ich komme eben nicht weiter, deshalb frag ich.

MueThoS:
Also,
ich habe folgende Libraries die ich nutze:
softi2c von folgender Seite: (erster Beitrag)
http://forums.adafruit.com/viewtopic.php?f=25&t=13722
die Heißt dann I2cMaster

Time.h (Standard)

Hier aus diesem Fred:
DCF77.h
MsTimer2.h

Ich habe auch schon versucht die Libraries zu analysieren aber ich komme eben nicht weiter, deshalb frag ich.

Das ist jetzt aber nicht Dein Ernst, oder?

Du hast keine RTC-Library für Deine RTC in Verwendung?
Warum denn das nicht?

Als normaler Arduino-Anfänger macht man es so:

  1. Man schaut nach, was für ein Uhrenbaustein auf der RTC verbaut ist, z.B. ein Dallas 1307
  2. Dann sucht man eine Arduino-Library zur Ansteuerung, z.B. für einen Dallas 1307
  3. Dann verwendet man die Funktionen der Library zum Auslesen und Einstellen der Uhr

Was Du da vorhast, die Bit-Schubsereien über den I2C-Bus selbst zu codieren, ist absolut NICHT anfängergeeignet.

Anfängergeeignet zum Stellen und Auslesen einer RTC mit dem gängigen Dallas 1307 Chip wäre beispielsweise so eine Library:

Vielleicht passt's ja und Du hast eine RTC mit 1307, dann schau da mal rein!

Vielleicht drücke ich mich nur nicht richtig aus.

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 :wink:
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;
}

Dafür brauchst du wirklich keine Library :wink:

Es sei denn ich kann sie auf andere PINs legen.

I2C sollte man nicht auf andere Pins legen...

MueThoS:
Möchte ich für meinen Anwendungsfall aber nicht nutzen.

Wenn Du es auf die harte Tour tun willst, wirst Du nicht umhin kommen, Dich in das ganze Klein-Klein der Bit-Schubsereien gründlich einzuarbeiten.

MueThoS:
d[1]=0x17;
...
Für Heute den 17ten.

0x17 ist ja auch nicht 17, sondern 0x17 ist 1*16+7=23.
:wink:

jurs:
0x17 ist ja auch nicht 17, sondern 0x17 ist 1*16+7=23.
:wink:

Manchmal eben doch.
BCD ist einfach, das konnten MicroController schon, als sie noch nicht Mikro waren und noch aus Relais gebaut wurden :wink:

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:

  1. Uhrzeit (aus der RTC)
  2. Wann wurde zuletzt gesynct
  3. Haben wir noch eine richtige Zeit
  4. 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.

Auf dem Shield könnte evtl. softi2csinnvoll sein...

Soll das Shield sich zum Arduino genau wie eine DS1307 - RTC verhalten, damit alle Libraries gehen ?

"Wild umherfunken" ist natürlich nicht, da hast du Recht :wink:

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.

Zu meinem Thema geht es hier weiter.

Dann mülle ich den Wissenschaftlichen Teil hier nicht weiter voll. Den hab ich sowieso nicht verstanden :~

Ausbaustufe 1 meines DCF77 Projekts ist hier:

Die alte Version mit dem exponentiellen Filter ist nur noch ein Benchmark :wink: 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 :wink:

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 :slight_smile: