A DCF77 Atomic Clock (Mainflingen/Frankfurt)
|
10 REM K8055_DCF_4_0 20 REM Decode and display the DSF77 clock 30 REM Caters for an inverted or a non-inverted signal 40 REM 50 REM Output of clock should be connected to analogue input A1 60 REM of a Velleman K8055 USB interface booard 70 REM (c) Jochen Lueg 80 REM http://roevalley.com/newsbrowser/v-projects/v-index.htm 90 REM Limavady, September 2013 100 REM Vers 4.0 110 REM Uses digital input 4 120 130 140 ON ERROR PRINT REPORT$;" at line ";ERL : END 150 PROCK8055_init 160 ON ERROR PROCerror 170 ON CLOSE PROCclose 180 PROCport_setup 190 PROCinit 200 PROCcheck_for_inversion 210 PRINTTAB(21,1);"Waiting for the beginning of the sequence" 220 230 IF Invert%=1 THEN 240 PROCK8055_start_inverted 250 PROCprint_info 260 PROCdecode_inverted 270 ENDIF 280 290 IF Invert%=0 THEN 300 PROCK8055_start_non_inverted 310 PROCprint_info 320 PROCdecode_non_inverted 330 ENDIF 340 PROCclose 350 END 360 370 380 DEFPROCclose 390 SYS K8055_ClearAllDigital% 400 SYS K8055_CloseDevice% 410 SYS "FreeLibrary",K8055_Board% 420 QUIT 430 ENDPROC 440 450 460 DEFPROCprint_info 470 COLOUR Col3% 480 PRINTTAB(21,8);"Incoming DCF77 binary coded decimal bits " 490 PRINTTAB(21,Tab5%)" " 500 PRINTTAB(20,10)"| Variable internal codes |R ! S N L -| Minute |P| Hour |P| Day | DoW | Month | Year |P|" 510 PRINTTAB(49,11)" |R = Reserve antenna | S = Summertime | ! = S announce |" 520 PRINTTAB(49,12)" |N = Normal time | L = leap second | P = Parity bit |" 530 ENDPROC 540 550 560 DEFPROCdecode_non_inverted 570 LOCAL Low%,High%,C%,State% 580 C%=0 590 REPEAT 600 COLOUR Col1% 610 REPEAT 620 SYS K8055_ReadDigitalChannel%,Port% TO State% 630 IF G%=1 X%+=1:PLOT 5,X%/S%,State%*222 :IF X%/S%>2900 X%=0:CLG:MOVE 0,0 640 UNTIL State%=1 AND TIME>5 650 Low%=TIME 660 SYS K8055_WriteAllDigital%,128 670 TIME=0 680 REPEAT 690 SYS K8055_ReadDigitalChannel%,Port% TO State% 700 IF G%=1 X%+=1:PLOT 5,X%/S%,State%*222 :IF X%/S%>2900 X%=0:CLG:MOVE 0,0 710 UNTIL State%=0 AND TIME>5 720 High%=TIME 730 SYS K8055_WriteAllDigital%,64 740 TIME=0 750 IF Low%<15 Time%(C%)=0 760 IF Low%>15 Time%(C%)=1 770 PROCdecode(C%) 780 IF High%>130 C%=-1:SWAP Col1%,Col2% 790 C%+=1 800 PROCcheck_keyboard 810 UNTIL FALSE 820 ENDPROC 830 840 850 DEFPROCdecode_inverted 860 LOCAL Low%,High%,C%,Col1%,Col2%,State% 870 Col1%=15 : REM White 880 Col2%=6 : REM Cyan 890 C%=0 900 REPEAT 910 COLOUR Col1% 920 REPEAT 930 SYS K8055_ReadDigitalChannel%,Port% TO State% 940 IF G%=1 X%+=1:PLOT 5,X%/S%,State%*222 :IF X%/S%>2900 X%=0:CLG:MOVE 0,0 950 UNTIL State%=0 AND TIME>4 960 High%=TIME 970 SYS K8055_WriteAllDigital%,128 980 TIME=0 990 REPEAT 1000 SYS K8055_ReadDigitalChannel%,Port% TO State% 1010 IF G%=1 X%+=1:PLOT 5,X%/S%,State%*222 :IF X%/S%>2900 X%=0:CLG:MOVE 0,0 1020 UNTIL State%=1 AND TIME>4 1030 Low%=TIME 1040 SYS K8055_WriteAllDigital%,64 1050 TIME=0 1060 IF High%<15 Time%(C%)=0 1070 IF High%>15 Time%(C%)=1 1080 PROCdecode(C%) 1090 IF Low%>130 C%=-1:SWAP Col1%,Col2% 1100 C%+=1 :IF C%>60 C%=1 1110 PROCcheck_keyboard 1120 UNTIL FALSE 1130 ENDPROC 1140 1150 1160 DEFPROCcheck_keyboard 1170 IF INKEY(-84) G%=G% EOR 1 1180 IF INKEY(-49) S%=1 :CLG:MOVE 0,0 :X%=1 1190 IF INKEY(-50) S%=2 :CLG:MOVE 0,0 :X%=1 1200 IF INKEY(-18) S%=3 :CLG:MOVE 0,0 :X%=1 1210 IF INKEY(-19) S%=4 :CLG:MOVE 0,0 :X%=1 1220 ENDPROC 1230 1240 1250 DEFPROCK8055_start_non_inverted : REM Find beginnming of sequence 1260 LOCAL State%,Low%,State% 1270 REPEAT 1280 SYS K8055_ReadDigitalChannel%,Port% TO State% 1290 IF G%=1 X%+=1:PLOT 5,X%/S%,State%*222 :IF X%/S%>2900 X%=1:CLG:MOVE 0,0 1300 UNTIL State%=1 AND TIME>4 1310 REPEAT 1320 SYS K8055_ReadDigitalChannel%,Port% TO State% 1330 IF G%=1 X%+=1:PLOT 5,X%/S%,State%*222 :IF X%/S%>2900 X%=1:CLG:MOVE 0,0 1340 UNTIL State%=0 AND TIME>4 1350 TIME=0 1360 REPEAT 1370 REPEAT 1380 SYS K8055_ReadDigitalChannel%,Port% TO State% 1390 IF G%=1 X%+=1:PLOT 5,X%/S%,State%*222 :IF X%/S%>2900 X%=1:CLG:MOVE 0,0 1400 UNTIL State%=1 AND TIME>4 1410 Low%=TIME 1420 SYS K8055_WriteAllDigital%,128 1430 TIME=0 1440 REPEAT 1450 SYS K8055_ReadDigitalChannel%,Port% TO State% 1460 IF G%=1 X%+=1:PLOT 5,X%/S%,State%*222 :IF X%/S%>2900 X%=1:CLG:MOVE 0,0 1470 UNTIL State%=0 AND TIME>4 1480 High%=TIME 1490 SYS K8055_WriteAllDigital%,64 1500 PRINTTAB(21,Tab5%)"High: ";High%;" Low: "; 1510 IF Low%<10 PRINT" "; 1520 PRINT;Low%;" Both: ";High%+Low%;" " 1530 TIME=0 1540 PROCcheck_keyboard 1550 UNTIL High%>130 1560 C%=0 1570 ENDPROC 1580 1590 1600 DEFPROCK8055_start_inverted : REM Find beginnming of sequence 1610 LOCAL State%,Low% 1620 REPEAT 1630 SYS K8055_ReadDigitalChannel%,Port% TO State% 1640 IF G%=1 X%+=1:PLOT 5,X%/S%,State%*222 :IF X%/S%>2900 X%=1:CLG:MOVE 0,0 1650 UNTIL State%=0 AND TIME>6 1660 REPEAT 1670 SYS K8055_ReadDigitalChannel%,Port% TO State% 1680 IF G%=1 X%+=1:PLOT 5,X%/S%,State%*222 :IF X%/S%>2900 X%=1:CLG:MOVE 0,0 1690 UNTIL State%=1 AND TIME>6 1700 TIME=0 1710 REPEAT 1720 REPEAT 1730 SYS K8055_ReadDigitalChannel%,Port% TO State% 1740 IF G%=1 X%+=1:PLOT 5,X%/S%,State%*222 :IF X%/S%>2900 X%=1:CLG:MOVE 0,0 1750 UNTIL State%=0 AND TIME>6 1760 High%=TIME 1770 SYS K8055_WriteAllDigital%,128 1780 TIME=0 1790 REPEAT 1800 SYS K8055_ReadDigitalChannel%,Port% TO State% 1810 IF G%=1 X%+=1:PLOT 5,X%/S%,State%*222 :IF X%/S%>2900 X%=1:CLG:MOVE 0,0 1820 UNTIL State%=1 AND TIME>50 1830 Low%=TIME 1840 SYS K8055_WriteAllDigital%,64 1850 PRINTTAB(21,Tab5%)"High: ";High%;" Low: "; 1860 IF Low%<10 PRINT" "; 1870 PRINT;Low%;" Both: ";High%+Low%;" " 1880 TIME=0 1890 PROCcheck_keyboard 1900 UNTIL Low%>130 1910 C%=0 1920 ENDPROC 1930 1940 1950 DEFPROCdecode(C%) 1960 REM Minute 1970 IF C%=27 THEN 1980 Minute%=40*Time%(27)+20*Time%(26)+10*Time%(25)+8*Time%(24)+4*Time%(23)+2*Time%(22)+Time%(21) 1990 PRINTTAB(78,Tab4%);"Minute: ";Minute% 2000 ENDIF 2010 2020 REM hour 2030 IF C%=34 THEN 2040 Hour%=20*Time%(34)+10*Time%(33)+8*Time%(32)+4*Time%(31)+2*Time%(30)+Time%(29) 2050 PRINTTAB(67,Tab4%);"Hour: ";Hour% 2060 ENDIF 2070 2080 REM Day 2090 IF C%=41 THEN 2100 Day%=20*Time%(41)+10*Time%(40)+8*Time%(39)+4*Time%(38)+2*Time%(37)+Time%(36) 2110 PRINTTAB(46,Tab4%);"Day: ";Day%;" " 2120 ENDIF 2130 2140 REM Day of week 2150 IF C%=44 THEN 2160 DoW%=4*Time%(44)+2*Time%(43)+Time%(42) 2170 IF DoW%<8 PRINTTAB(56,Tab4%);Weekday$(DoW%) 2180 ENDIF 2190 2200 REM Month 2210 IF C%=49 THEN 2220 Month%=10*Time%(49)+8*Time%(48)+4*Time%(47)+2*Time%(46)+Time%(45) 2230 IF Month%<13 THEN PRINTTAB(33,Tab4%);Month$(Month%) 2240 ENDIF 2250 2260 REM The year 2270 IF C%=57 THEN 2280 Year%=2000+80*Time%(57)+40*Time%(56)+20*Time%(55)+10*Time%(54)+8*Time%(53)+4*Time%(52)+2*Time%(51)+Time%(50) 2290 PRINTTAB(21,Tab4%);"Year: ";Year% 2300 ENDIF 2310 2320 PRINTTAB(21+C%*2,Tab2%);Time%(C%);" " 2330 IF C%=58 PRINTTAB(138,Tab2%)" " 2340 PRINTTAB(90,Tab4%);"Second: ";C%;" " 2350 ENDPROC 2360 2370 2380 DEFPROCcheck_for_inversion 2390 LOCAL Low%,High% 2400 Low%=0: High%=0 2410 PRINTTAB(21,0)"Please wait for 3 seconds to check for signal inversion" 2420 SYS K8055_CloseDevice% 2430 SYS K8055_OpenDevice%,Board% 2440 PRINT 2450 REPEAT 2460 SYS K8055_ReadDigitalChannel%,Port% TO State% 2470 UNTIL State%=1 AND TIME>4 2480 FOR J%=1 TO 3 2490 TIME=0 2500 REPEAT 2510 SYS K8055_ReadDigitalChannel%,Port% TO State% 2520 UNTIL State%=0 AND TIME>4 2530 High%+=TIME 2540 TIME=0 2550 REPEAT 2560 SYS K8055_ReadDigitalChannel%,Port% TO State% 2570 UNTIL State%=1 AND TIME>4 2580 Low%+=TIME 2590 NEXT 2600 CLS 2610 IF Low%>High% Invert%=1 ELSE Invert%=0 2620 IF Invert%=1 PRINTTAB(21,0)"Inverted signal" 2630 IF Invert%=0 PRINTTAB(21,0)"Non-inverted signal" 2640 ENDPROC 2650 2660 2670 DEFPROCport_setup 2680 PROCwindow(1500,520,"DCF77 atomic clock decoder") 2690 VDU 28,0,16,185,0 2700 VDU 24,40;40;2940;390; 2710 COLOUR12,60,60,60 2720 GCOL 140 2730 CLG 2740 ORIGIN 40,50 2750 VDU5 2760 MOVE 0,330 2770 PRINT" To stop or start plotting press 'G' for possibly up to a second" 2780 PRINT" Press 1 to 5 to change the time-base" 2790 2800 VDU 23,23,1;0;0;0; :REM Lines double thickness 2810 GCOL11 2820 MOVE 0,0 2830 X%=1 2840 OFF 2850 VDU4 2860 ENDPROC 2870 2880 2890 DEFPROCinit 2900 Tab1% = 10 2910 Tab2% = 9 2920 Tab3% = 8 2930 Tab4% = 6 2940 Tab5% = 4 2950 Tab6% = 13 2960 Bit%=5 2970 Port%=4 2980 Board%=0 2990 G%=1 3000 S%=4 3010 Col1%=15 : REM White 3020 Col2%=6 : REM Cyan 3030 Col3%=3 3040 DIM Time%(100) 3050 DIM Weekday$(7) 3060 Weekday$(1)="Monday " 3070 Weekday$(2)="Tuesday " 3080 Weekday$(3)="Wednesday" 3090 Weekday$(4)="Thursday " 3100 Weekday$(5)="Friday " 3110 Weekday$(6)="Saturday " 3120 Weekday$(7)="Sunday " 3130 3140 DIM Month$(12) 3150 Month$(1)="January " 3160 Month$(2)="February " 3170 Month$(3)="March " 3180 Month$(4)="April " 3190 Month$(5)="May " 3200 Month$(6)="June " 3210 Month$(7)="July " 3220 Month$(8)="August " 3230 Month$(9)="September" 3240 Month$(10)="October " 3250 Month$(11)="November " 3260 Month$(12)="December " 3270 3280 ENDPROC 3290 3300 3310 DEFPROCwindow(WindowWidth%,WindowHeight%,Wt$) 3320 MODE 30 3330 SYS "SetWindowPos",@hwnd%,0,0,0,WindowWidth%,WindowHeight%,6 3340 COLOUR 128 3350 CLS 3360 COLOUR 15 3370 VDU 26 3380 SYS "SetWindowText",@hwnd%,Wt$ 3390 ENDPROC 3400 3410 3420 DEFPROCerror 3430 PRINT REPORT$;" at line ";ERL : 3440 SYS K8055_ClearAllDigital%,1 3450 SYS K8055_ClearAllAnalog%,1 3460 SYS K8055_CloseDevice%,1 3470 SYS "FreeLibrary",K8055_Board% 3480 END 3490 ENDPROC 3500 3510 3520 DEFPROCK8055_init 3530 REM Typing errors in routine name do not generate an error message - they just hang up the program. 3540 REM These are all the system calls in the order found in the manual 3550 SYS"LoadLibrary","K8055D.dll" TO K8055_Board% 3560 SYS"GetProcAddress",K8055_Board%,"OpenDevice" TO K8055_OpenDevice% 3570 SYS"GetProcAddress",K8055_Board%,"CloseDevice" TO K8055_CloseDevice% 3580 SYS"GetProcAddress",K8055_Board%,"ReadAnalogChannel" TO K8055_ReadAnalogChannel% 3590 SYS"GetProcAddress",K8055_Board%,"ReadAllAnalog" TO K8055_ReadAllAnalog% 3600 SYS"GetProcAddress",K8055_Board%,"OutputAnalogChannel" TO K8055_OutputAnalogChannel% 3610 SYS"GetProcAddress",K8055_Board%,"OutputAllAnalog" TO K8055_OutputAllAnalog% 3620 SYS"GetProcAddress",K8055_Board%,"ClearAnalogChannel" TO K8055_ClearAnalogChannel% 3630 SYS"GetProcAddress",K8055_Board%,"ClearAllAnalog" TO K8055_ClearAllAnalog% 3640 SYS"GetProcAddress",K8055_Board%,"SetAnalogChannel" TO K8055_SetAnalogChannel% 3650 SYS"GetProcAddress",K8055_Board%,"SetAllAnalog" TO K8055_SetAllAnalog% 3660 SYS"GetProcAddress",K8055_Board%,"WriteAllDigital" TO K8055_WriteAllDigital% 3670 SYS"GetProcAddress",K8055_Board%,"ClearDigitalChannel" TO K8055_ClearDigitalChannel% 3680 SYS"GetProcAddress",K8055_Board%,"ClearAllDigital" TO K8055_ClearAllDigital% 3690 SYS"GetProcAddress",K8055_Board%,"SetDigitalChannel" TO K8055_SetDigitalChannel% 3700 SYS"GetProcAddress",K8055_Board%,"SetAllDigital" TO K8055_SetAllDigital% 3710 SYS"GetProcAddress",K8055_Board%,"ReadDigitalChannel" TO K8055_ReadDigitalChannel% 3720 SYS"GetProcAddress",K8055_Board%,"ReadAllDigital" TO K8055_ReadAllDigital% 3730 SYS"GetProcAddress",K8055_Board%,"ResetCounter" TO K8055_ResetCounter% 3740 SYS"GetProcAddress",K8055_Board%,"ReadCounter" TO K8055_ReadCounter% 3750 SYS"GetProcAddress",K8055_Board%,"SedtCounterDebouceTime" TO K8055_SetCounterDebounceTime% 3760 ENDPROC 3770 |
|