' -------------------------------------------------------------------------- ' ' DigiClock for DynaMite / Maxmite ' ' One Maximite drives one screen, three screens make one DigiClock ' Each screen is displaying two digits, either HH, MM or SS. ' ' This program uses V4.4B of the MMBasic language, so the DuinomMites have ' to be flashed with the most recent firmware. ' ' The clock is automatically set via DCF77 (Conrad Receiver) ' http://www.conrad.de/ce/de/product/641138/C-Control-DCF-Empfaengerplatine ' ' Wiring: The first device (SECOND) needs to receive the DCF signal on Pin 1 ' The other devices get their time via a UART connection on COM1. So connect Pin 16 ' of the SECOND board to pin 15 on the MINUTE and HOUR board. ' ' (External View) ' ' + GND for DCF Board ' | ' | ' | ' | 1 DCF In for SECOND module ' + + ' o o o o o o o o o o o o o ' ' o o o o o o o o o o o o o ' ^ ^ + ' | | 15 Rx Connect to Tx of SECOND Module ' | + ' | 16 Tx Connect to Rx of MINUTE and HOUR Module ' | ' + 3.3V for DCF Board ' ' You will need a 10 kOhm Pullup between Vcc and the non-inverting output of ' the DCF module (pulling high to 3.3V) as the module has open collector ' outputs. ' ' Take a look at "DuinoMite MMBasic ReadMe.pdf" for more info. ' ' The bitmaps and all basic files have to be copied to the SD card, change ' the DisplayMode variable for each board accordingly. ' ' You can of course replace the clock images by your own ones, but stick to ' the size and the BMP format - some BMP sizes make ugly bit noise at the end. ' ' v2.0 written in 2014 by Tim Hagemann (tim@way2.net) ' ' Use this code free of charge for private or educational uses. Ask for ' permission in case of commercial usage. ' ' -------------------------------------------------------------------------- DisplayMode = 2 ' 0: HH, 1: MM, 2:SS DigitY = 50 ' Y pos of both digits DigitLX = 53 ' X pos of left digit DigitRX = 250 ' X pos of right digit DCFPin = 1 ' Pin for the DCF77 signal SignalY = 300 ' Position of the search signal line SignalHeight = 20 ' Pulse height on screen ' ' ----------- initialization ' WaitingForTime = 1 FirstSyncFound = 0 OldSignalY = SignalY oldsignal = 1 Dim dcfbit(60) ' --- configure pin as input SetPin DCFPin, 2 cls ' ' ----------- welcome screen ' print "Welcome to DClock v2.0" print "----------------------" print print "Starting time sync." print if DisplayMode = 2 then print "This is the 'SECOND' and the DCF77 Unit" endif if DisplayMode = 1 then print "This is the 'MINUTE' Unit" endif if DisplayMode = 0 then print "This is the 'HOUR' Unit" endif ' ' ----------- main program ' if DisplayMode = 2 then DisplaySecondAndSendDCF else DisplayDigitAndReceiveDCF endif ' ----------------------------------------------------------------------- sub DisplaySecondAndSendDCF ' --- setup the ticker for the DCF signal SetTick 10, CheckDCF77 ' --- com1: Rx is pin 15, Tx is pin 16 OPEN "COM1:4800" AS #1 Do ' --- deferred actions if DoCls = 1 then cls DoCls = 0 endif if UpdateLastSync = 1 then print @(0,415) "Last synced: ";LastSync$;" "; UpdateLastSync = 0 endif currt$ = Time$ ' --- when time changed If currt$ <> oldt$ Then s1 = Val(Mid$(currt$,7,1)) s2 = Val(Mid$(currt$,8,1)) ' --- main program If WaitingForTime = 0 Then print #1,"TT";currt$ ' --- main display routine PrintDigit DigitLX, DigitY, s1 PrintDigit DigitRX, DigitY, s2 EndIf ' --- save time for compare oldt$ = currt$ EndIf ' --- wait a bit Pause 50 Loop end sub ' ----------------------------------------------------------------------- Sub DisplayDigitAndReceiveDCF ' --- com1: Rx is pin 15, Tx is pin 16 OPEN "COM1:4800" AS #1 do if LOC(#1) <> 0 then ' ---- read serial input a$ = input$(50,#1) ' ---- add to the receive uffer r$ = r$ + a$ 'print "'";r$;"'" ' ---- now process chr13 = instr(r$,chr$(13)) if chr13 <> 0 then ' ---- we found a CR command$ = left$(r$,chr13) cmd$ = left$(command$,2) param$ = mid$(command$,3) commandfound = 0 if cmd$="TT" then commandfound = 1 h1 = Val(Mid$(param$,1,1)) h2 = Val(Mid$(param$,2,1)) m1 = Val(Mid$(param$,4,1)) m2 = Val(Mid$(param$,5,1)) ' --- main display routine if FirstCLS = 0 then cls FirstCLS = 1 endif If DisplayMode = 0 Then PrintDigit DigitLX, DigitY, h1 PrintDigit DigitRX, DigitY, h2 Else PrintDigit DigitLX, DigitY, m1 PrintDigit DigitRX, DigitY, m2 EndIf endif if commandfound = 0 then 'print "Error: command ";command$;" is invalid" endif r$ = "" endif else Pause 50 endif loop end sub ' ----------------------------------------------------------------------- Sub PrintDigit (x,y,v) bitmapname$ = Str$(v) + ".bmp" LoadBMP bitmapname$, x, y End Sub ' ----------------------------------------------------------------------- Sub CheckDCF77 ' --- buffer the signal to avoid glitches signal = Pin(DCFPin) ' --- update the counters if signal = 1 or ignorepulse = 1 then highcount = highcount + 1 else lowcount = lowcount + 1 endif ' --- in search mode, display a fancy osci like graphic if WaitingForTime = 1 then ' --- clear old line Line (SignalX,SignalY) - (SignalX,SignalY-SignalHeight),0 ' --- draw new line NewSignalY = SignalY-signal*SignalHeight Line (SignalX,OldSignalY) - (SignalX,NewSignalY),1 OldSignalY = NewSignalY ' --- do the X warp around SignalX = SignalX + 1 if (SignalX > MM.HRES) then SignalX = 0 endif endif ' --- falling edge if oldsignal = 1 and signal = 0 then ' --- this is the falling edge 'print "Lowcnt";lowcount;" Highcnt";highcount ' --- filter out very small pulses if highcount < 7 then ignorepulse = 1 'print "Ignore pulse - too small" else if lowcount > 120 then 'print "Lowcount detected" ' --- two cases: we found the sync and completed the full datagram ' or we found the first sync having read only rubbish If FirstSyncFound = 1 Then ' --- the is then the 2nd, 3rd,... sync. ProcessDCFTime Else ' --- ok, now we got the first one! FirstSyncFound = 1 if WaitingForTime = 1 then print @(0,150) "First minute break found...now receiving time...";spc(40) endif EndIf ' --- the next bit will be bit 1, we ignore bit 60 --> anyway 0 bitindex = 1 else 'print "Pulse detected" ' --- only process, if we completed the first round If FirstSyncFound = 1 Then if WaitingForTime = 1 then print @(0,150) "Receiving bit number";bitindex;" of 58";spc(40) endif If bitindex <= 60 Then ' --- more than 100 ms? The this is a "1" If highcount > 10 Then dcfbit(bitindex) = 1 Else dcfbit(bitindex) = 0 EndIf 'Print "BIT :", dcfbit(bitindex) bitindex = bitindex + 1 Else if WaitingForTime = 1 then print @(0,150) "Lost sync. Try again.";spc(40) endif ' --- something was wrong. Restart sync FirstSyncFound = 0 EndIf EndIf endif lowcount = 0 highcount = 0 ignorepulse = 0 endif endif oldsignal = signal End Sub ' ----------------------------------------------------------------------- Sub ProcessDCFTime idx = 21 mm = dcfbit(idx) + dcfbit(idx+1)*2 + dcfbit(idx+2)*4 + dcfbit(idx+3)*8 + dcfbit(idx+4)*10 + dcfbit(idx+5)*20 + dcfbit(idx+6)*40 p1 = Party(21,28) idx = 29 hh = dcfbit(idx) + dcfbit(idx+1)*2 + dcfbit(idx+2)*4 + dcfbit(idx+3)*8 + dcfbit(idx+4)*10 + dcfbit(idx+5)*20 p2 = Party(29,35) idx = 36 dd = dcfbit(idx) + dcfbit(idx+1)*2 + dcfbit(idx+2)*4 + dcfbit(idx+3)*8 + dcfbit(idx+4)*10 + dcfbit(idx+5)*20 idx = 45 mo = dcfbit(idx) + dcfbit(idx+1)*2 + dcfbit(idx+2)*4 + dcfbit(idx+3)*8 + dcfbit(idx+4)*10 idx = 50 yy = dcfbit(idx) + dcfbit(idx+1)*2 + dcfbit(idx+2)*4 + dcfbit(idx+3)*8 + dcfbit(idx+4)*10 + dcfbit(idx+5)*20 + dcfbit(idx+6)*40 + dcfbit(idx+7)*80 p3 = Party(36,58) 'Print "//////////// time", hh , mm, dd,mo,yy,p1,p2,p3 ' --- now do some checks dcferr = 0 If Fix(p1/2) <> p1/2 Then dcferr = 1 EndIf If Fix(p2/2) <> p2/2 Then dcferr = 1 EndIf If Fix(p3/2) <> p3/2 Then dcferr = 1 EndIf If mo<1 Or mo>12 Then dcferr = 1 EndIf If dd<1 Or dd>31 Then dcferr = 1 EndIf If mm>59 Then dcferr = 1 EndIf If hh>23 Then dcferr = 1 EndIf If yy>25 Then dcferr = 1 EndIf ' --- now process If dcferr = 0 Then Time$ = Str$(hh)+":"+Str$(mm)+":00" if WaitingForTime = 1 then WaitingForTime = 0 ' --- deferred CLS - will otherwise get us out of sync DoCls = 1 endif ' --- deferred PRINT - will otherwise get us out of sync UpdateLastSync = 1 LastSync$ = time$ EndIf End Sub ' ----------------------------------------------------------------------- Function Party(idxa,idxe) p = 0 For i = idxa To idxe p = p + dcfbit(i) Next i Party = p End Function