Die Uhr funktioniert bis jetzt ohne Probleme.
In der Original Schaltung ist keine Möglichkeit vorgesehen die Uhr manuell oder
per DCF77 auf die aktuelle Uhrzeit zustellen.
Ich habe hier ein Funkuhr Modul von Pollin, das ich für diesen Zweck verwenden möchte.
Leider wurde mir gesagt das diese Module empfindlich auf Störfelder reagieren.
Das DCF77 Modul von Pollin (Best-Nr.: 810054) will eine Betriebssspannung von 1,2 bis 3,5V haben.
Der Adruino Uno Clone gibt auf einen der Pins 3,3V raus. Kann ich an diesen
das DCF77 Modul bedenkenlos besaften
->zoom
Das Bild wurde bei Zabex.de ausgeliehen.
Oder muss ich diese Wandlerschaltung von Zabex verwenden
Ich habe mal versucht als Adruino Anfäger dem Code anzupassen. Kann das so Funktionieren?
Code: Alles auswählen
#define A0 14 //ANALOG 0
#define A1 15
#define A2 16
#define INTERVAL 1000
//I/O Makros DCF77-Empfänger
#define DI_DCF77 9
//#define DO_DCF_DISABLE 8 //over 4K7 to PON. PON over 5K6 to GND
#define DO_DCF_POWERSUPPLY 7 //over 470R to VDD. VDD over white LED (2.8V) to GND.
//PINS SEKUNDEN MINUTEN STUNDEN
byte oneSecond[] = {0,1,2,3,4,5,6,7,8}; //No Serial on 0/1
byte tenSecond[] = {9,10,11,12,13}; //
byte theSwitch[] = {14,15,16}; //SEKUNDE MINUTE STUNDE
byte dcfSekunde; //0..59 - wird bei ausbleibendem Signal (59. Sekunde) auf 0 gesetzt
byte stoerung; //Unplausibler Empfang
byte zeitEmpfangen; //Schaltet auf Zeitanzeige statt Sekundenanzeige um
byte uhrHH; //Die interne Uhr (wird von DCF-Uhr gestellt)
byte uhrMM;
byte uhrSS;
int s10=0,s1=0; //ONESECOND TENSECOND BAND
int m10=5,m1=9;
int h10=2,h1=3;
unsigned long t,t0; //TIMEINIT
void INTITIME(void){t0=millis();}
unsigned long TIMEREAD(void){return millis()-t0;}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void decodeDCF77(void){ //Alle 5ms aufrufen
//------------------------------------------------------------------------------
static int iTic=0;
static int iTiefpass=0;
static bool bSteigend=0;
static byte nZeitumstellung=0;
static byte hs=0;
static byte hh=0;
static byte mm=0;
static byte ss=0;
static byte tag=0;
static byte wtag=0;
static byte monat=0;
static byte jahr=0;
static byte keinEmpfang=0;
static byte neuesDatum=0;
static bool bToggle;
static byte sommerzeit;
static byte winterzeit;
static byte startphase=1;
static byte bChecksum=0;
static byte zeitUebernehmen;
static byte bBit[60]; //die empfangenen Bits
static byte erfolgreichdecodiert;
static byte vorHH; //Die empfangene Zeit in der letzten Minute
static byte vorMM;
static byte vorJJ;
static byte ms50;
static long tries=0;
byte i;
iTic+=5; //5ms sind rum
if (iTic>3000){ //Kein Signal
iTic=3000;
}
//Eingang abfragen und filtern
if (digitalRead(DI_DCF77)){ //Signalabsenkung liefert High für 100ms oder 200ms
iTiefpass+=5;
digitalWrite(13, HIGH);
if (iTiefpass>200) iTiefpass=200; //auf 200ms begrenzen
}else{
digitalWrite(13, LOW);
iTiefpass-=5;
if (iTiefpass<0){
iTiefpass=0;
bSteigend=1;
}
}
//Minutenanfang erkennen
if (iTic > 1500){ //Minutensignal: mehr als 1s keine Absenkung
dcfSekunde=59;
}
else
//Signallänge bestimmen und im Bitfeld eintragen
if (160==iTic){ //160ms Tiefpass ist entweder +100-60=40 oder +100+60=160
//pulsdauer=iTiefpass;
if (iTiefpass > 90){
bBit[dcfSekunde]=1;
}else{
bBit[dcfSekunde]=0;
}
if ((iTiefpass < 5) || ((iTiefpass > 60) && (iTiefpass <100))){ //Unplausible Signaldauer
if (stoerung <4) stoerung++;
}else{
if (stoerung >0) stoerung--;
}
}
//Sekundenanfang erkennen
if ((60==iTiefpass) && bSteigend){ //60ms seit Pulsbeginn
bSteigend=0;
iTic=60;
dcfSekunde++;
if (dcfSekunde>59){ //Jetzt ist Minutenanfang
dcfSekunde=0;
if (0==startphase){ //beim 1. Minutenanfang nach Einschalten ist die Zeit noch nicht übertragen
zeitUebernehmen = 1;
}
//Auswertung zum Minutenanfang
if (zeitUebernehmen){
if (bBit[16]){
nZeitumstellung++;
}else{
if (nZeitumstellung) nZeitumstellung--;
}
if (bBit[17]){
if (sommerzeit < 60) sommerzeit++;
}else{
if (sommerzeit) sommerzeit--;
}
if (bBit[18]){
if (winterzeit < 60) winterzeit++;
}else{
if (winterzeit) winterzeit--;
}
bChecksum=bBit[21]+bBit[22]+bBit[23]+bBit[24]+bBit[25]+bBit[26]+bBit[27]+bBit[28]; //Minute
if (0==(bChecksum % 2)){ //P1
bChecksum=bBit[29]+bBit[30]+bBit[31]+bBit[32]+bBit[33]+bBit[34]+bBit[35]; //Stunde
if (0==(bChecksum % 2)){ //P2
if (bBit[20]){ //Startbit; immer gesetzt
bChecksum=0;
for (i=36; i<59; i++){ //Checksumme über Datum
bChecksum+=bBit[i];
}
if (0==(bChecksum % 2)){ //P3
neuesDatum=0;
keinEmpfang=0;
tag = bBit[36]+bBit[37]*2+bBit[38]*4+bBit[39]*8+bBit[40]*10+bBit[41]*20;
wtag = bBit[42]+bBit[43]*2+bBit[44]*4;
monat = bBit[45]+bBit[46]*2+bBit[47]*4+bBit[48]*8;
jahr = bBit[50]+bBit[51]*2+bBit[52]*4+bBit[53]*8+bBit[54]*10+bBit[55]*20+bBit[56]*40+bBit[57]*80;
if (zeitUebernehmen){
//Übernehme Zeit
zeitUebernehmen = 0;
hh = bBit[29]+bBit[30]*2+bBit[31]*4+bBit[32]*8+bBit[33]*10+bBit[34]*20;
mm = bBit[21]+bBit[22]*2+bBit[23]*4+bBit[24]*8+bBit[25]*10+bBit[26]*20+bBit[27]*40;
ss = 0;
//Ist diese Zeit genau eine Minute später als vor einer Minute? (zusätzliche Plausibilitätscheck)
vorMM++;
if (vorMM>59){
vorMM=0;
vorHH++;
if (vorHH >23) vorHH=0;
}
if ((vorHH == hh)
&& (vorMM == mm)
&& (vorJJ == jahr) //Beim Jahreswechsel muss die Uhr ja nicht um Mitternacht verdreht werden
&& (jahr>14)){ //Wir haben 2015 - und mehr als bis zum Jahr 2099 soll die Uhr gar nicht laufen
erfolgreichdecodiert=1;
}
vorHH=hh;
vorMM=mm;
vorJJ=jahr;
}
}//P3
}//Bit20
}//P2
}//P1
}//zeitUebernehmen
if (startphase) startphase=0;
for (i=0; i<60; i++){
bBit[i]=0;
}
}//(dcfSekunde>59)
//Interne Uhr feintunen
//Hundertstel Sekunden hs sollte auf 6 stehen , wenn die Uhr richtig läuft (60ms seit steigender Flanke)
//Nur machen, wenn Empfang OK
if ((keinEmpfang < 2) && (0==stoerung)){
if ((hs > 6) && (hs < 56)) {
hs --; //Uhr etwas zurückdrehen
}else{
if (hs != 6){
hs++; //Uhr etwas vor drehen. Überlauf wird weiter unten automatisch behandelt.
}
}
}
}//Sekundenanfang (60ms)
//Intere Uhr weiterdrehen
bToggle = !bToggle;
if (bToggle){ //10ms sind rum
hs++; //Hundertstel Sekunden
if (hs>99){ //1s ist rum
hs-=100; //Nicht auf 0 setzen, um Überlauf bei Uhr vordrehen (Feintuning) zu berücksichtigen
uhrSS++;
if (uhrSS > 59){
uhrSS=0;
uhrMM++;
if (keinEmpfang < 100){ //Wird bei Empfang mit korreten Prüfsummen auf 0 gesetzt
keinEmpfang++;
}
// if (!zeitEmpfangen && (keinEmpfang > 5)){
// displayEnable(0);
// }
if (zeitEmpfangen && (keinEmpfang > 15) && (uhrHH > 2) && (uhrHH < 6)) {
displayEnable(0);
}
if (uhrMM > 59){
uhrMM=0;
uhrHH++;
if (uhrHH > 23){
uhrHH=0;
neuesDatum=1; //Datum wird ja nicht angezeigt. Aber wenn ich das mal einbauen will, habe ich hiermit den Tagesbeginn.
}
//Zeitumstellung?
if ((nZeitumstellung > 45) && (uhrHH >=2) && (uhrHH <=3)){ //"nZeitumstellung" wurde in der Stunde vor der Umstellung jede Minute hochgezählt
if (sommerzeit > winterzeit){ //MESZ->MEZ
uhrHH--;
}else{ //MEZ->MESZ
uhrHH++;
}
}
}//uhrMM>59
anzeigen();
}//uhrSS>59
if (erfolgreichdecodiert){ //Zeit übernehmen (wenn vorhanden)
erfolgreichdecodiert=0;
zeitEmpfangen=1;
uhrHH=hh;
uhrMM=mm;
uhrSS=0;
displayEnable(1);
}
}//hs>99
if (!zeitEmpfangen){
ms50++;
if (ms50 > 4){ //50 ms sind rum
ms50 = 0;
//scope();
}
}
}//Toggle
}//decodeDCF77
//------------------------------------------------------------------------------
void displayEnable(byte en){
static byte oldEn=222;
if (oldEn != en){
oldEn=en;
led.shutdown(0,(en==0));
led.shutdown(1,(en==0));
}
}
void setup()
{int i;
for(i=0; i<sizeof(oneSecond);i++)pinMode(oneSecond[i],OUTPUT);
for(i=0; i<sizeof(tenSecond);i++)pinMode(tenSecond[i],OUTPUT);
for(i=0; i<sizeof(theSwitch);i++)pinMode(theSwitch[i],OUTPUT);
digitalWrite(A0, LOW);
digitalWrite(A1, LOW);
digitalWrite(A2, LOW);
}
void loop()
{int i;
t=TIMEREAD();
do
{for(i=0;i<sizeof(oneSecond);i++)digitalWrite(oneSecond[i],s1<=i?LOW:HIGH); //EINERBAND SEKUNDEN
for(i=0;i<sizeof(tenSecond);i++)digitalWrite(tenSecond[i],s10<=i?LOW:HIGH); //ZEHNERBAND SEKUNDEN
digitalWrite(A0, HIGH);//Masse an Sekunden
delay(1); //SHOWTIME SEKUNDEN
digitalWrite(A0, LOW);
for(i=0;i<sizeof(oneSecond);i++)digitalWrite(oneSecond[i],m1<=i?LOW:HIGH); //EINERBAND MINUTEN
for(i=0;i<sizeof(tenSecond);i++)digitalWrite(tenSecond[i],m10<=i?LOW:HIGH); //ZEHNERBAND MINUTEN
digitalWrite(A1, HIGH);//Masse an MINUTEN
delay(1); //SHOWTIME MINUTEN
digitalWrite(A1, LOW);
for(i=0;i<sizeof(oneSecond);i++)digitalWrite(oneSecond[i],h1<=i?LOW:HIGH); //EINERBAND STUNDEN
for(i=0;i<sizeof(tenSecond);i++)digitalWrite(tenSecond[i],h10<=i?LOW:HIGH); //ZEHNERBAND STUNDEN
digitalWrite(A2, HIGH);//Masse an STUNDEN
delay(1); //SHOWTIME STUNDEN
digitalWrite(A2, LOW);
}while(TIMEREAD()<(t+INTERVAL));
//---------------------------------
s1++; //s++;
if(s1>=10){s1=0;s10++;}
if(s10>=6){s10=0;m1++;} //m1++;
if(m1>=10){m1=0;m10++;}
if(m10>=6){m10=0;h1++;} //h1++;
if(h1>=10){h1=0;h10++;}
if(h10>=2 && h1>=4){h10=0;h1=0;}
}