Compare commits

...

2 Commits

Author SHA1 Message Date
281f99da12 Merge branch 'main' of https://source.devloop.de/cederbach/Funkuhr 2025-05-03 18:21:09 +02:00
055f270397 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
2025-05-03 18:14:09 +02:00

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));
}