In der Variante 3 hat die Funkuhr zwei Controller,

einen für die flimmerfreie Anzeige und einen für
die störungsfreie Erfassung des DCF Signals.
Die Datenübertragung erfolg seriell von TX nach RX
This commit is contained in:
2025-05-03 18:14:09 +02:00
parent a733c347b6
commit 055f270397
2 changed files with 478 additions and 0 deletions

145
Coprozessor_DCF77.ino Normal file
View File

@ -0,0 +1,145 @@
/* Das Programm dekodiert die DCF77 Zeit,
macht die Paritätsprüfung und
schickt die vier benötigten Ziffern für die Zeitanzeige
als serielle Daten über den TX Pin 1 an den Anzeigecontroller.
Datengeschwindigkeit: 9600 Baud
Wenn ein gültiges Signal gesendet wurde, gibt es eine Pause von 30 Minuten,
in dieser Zeit wird der DCF Empfänger an Pin 6 abgeschaltet.
mit Hilfe von: https://wolles-elektronikkiste.de/dcf77-funkuhr
30.04.2025
*/
#include <util/parity.h> //comment out if you don't use an AVR MCU
#define dcfOnOut 6
int interruptPin = 2;
volatile unsigned long lastInt = 0;
volatile unsigned long long currentBuf = 0;
volatile byte bufCounter;
volatile bool parityStat = 0;
volatile byte dcf77MinuteEiner = 0;
volatile byte dcf77MinuteZehner = 0;
volatile byte dcf77HourEiner = 0;
volatile byte dcf77HourZehner = 0;
void setup() {
Serial.begin(9600);
pinMode(dcfOnOut, OUTPUT);
digitalWrite(dcfOnOut, HIGH);
pinMode(interruptPin, INPUT);
attachInterrupt(digitalPinToInterrupt(interruptPin), DCF77_ISR, CHANGE);
}
void loop() {
if (parityStat == 1) {
delay(100);
Serial.print(dcf77HourZehner);
Serial.print(",");
Serial.print(dcf77HourEiner);
Serial.print(",");
Serial.print(dcf77MinuteZehner);
Serial.print(",");
Serial.print(dcf77MinuteEiner);
delay(100);
digitalWrite(dcfOnOut, LOW);
parityStat = 0;
delay(1800000); // 30 Minuten, 15 Minuten Wartezeit: 900000
digitalWrite(dcfOnOut, HIGH);
}
}
/*************************************************************************
lesen des dcf Signals am Pin 2
**************************************************************************/
void DCF77_ISR() { //
unsigned int dur = 0;
dur = millis() - lastInt;
if (digitalRead(interruptPin)) {
if (dur > 1500) {
unsigned long highBuf = (currentBuf >> 32) & 0x7FFFFFF;
unsigned long lowBuf = (currentBuf & 0xFFFFFFFF);
bufCounter = 0;
evaluateSequence();
currentBuf = 0;
}
}
else {
if (dur > 150) {
currentBuf |= ((unsigned long long)1 << bufCounter);
}
bufCounter++;
}
lastInt = millis();
}
/**************************************************************************
Umwandlung Binärcode in Ziffern
*************************************************************************/
void evaluateSequence() {
parityStat = 1;
byte dcf77Year = (currentBuf >> 50) & 0xFF; // year = bit 50-57
byte dcf77Month = (currentBuf >> 45) & 0x1F; // month = bit 45-49
byte dcf77DayOfWeek = (currentBuf >> 42) & 0x07; // day of the week = bit 42-44
byte dcf77DayOfMonth = (currentBuf >> 36) & 0x3F; // day of the month = bit 36-41
byte dcf77Hour = (currentBuf >> 29) & 0x3F;
dcf77HourEiner = (currentBuf >> 29) & 0xF; // hour = bit 29-34, 6 bit
dcf77HourZehner = (currentBuf >> 33) & 0x3; // hour = bit 29-34, 6 bit
byte dcf77Minute = (currentBuf >> 21) & 0x7F;
dcf77MinuteEiner = (currentBuf >> 21) & 0xF; // minute = 21-27, 7 bit
dcf77MinuteZehner = (currentBuf >> 25) & 0x7; // minute = 21-27, 7 bit
bool parityBitMinute = (currentBuf >> 28) & 1;
bool parityBitHour = (currentBuf >> 35) & 1;
bool parityBitDate = (currentBuf >> 58) & 1;
/***************************************************************************
Paritätsprüfung
***************************************************************************/
if ((parity_even_bit(dcf77Minute)) != parityBitMinute) {
parityStat = 0;
}
if ((parity_even_bit(dcf77Hour)) != parityBitHour) {
parityStat = 0;
}
if (((parity_even_bit(dcf77DayOfMonth) + parity_even_bit(dcf77DayOfWeek)
+ parity_even_bit(dcf77Month) + parity_even_bit(dcf77Year)) % 2) != parityBitDate)
{
parityStat = 0;
}
if (dcf77MinuteEiner > 9) {
parityStat = 0;
}
if (dcf77MinuteZehner > 5) {
parityStat = 0;
}
if (dcf77HourEiner > 9) {
parityStat = 0;
}
if (dcf77HourZehner > 2) {
parityStat = 0;
}
if (dcf77Hour == 0 && dcf77Minute == 0) {
parityStat = 0;
}
}
unsigned int rawByteToInt(byte raw) {
return ((raw >> 4) * 10 + (raw & 0x0F));
}