Menu

time code transmissions

2022-08-25
2022-08-29
  • David Stephenson

    As they were very cheap I bought a DCF77 receiver from aliexpress. It receives the time code transmissions from Mainflingen in Germany on 77.5 kHz (VLF)
    https://en.wikipedia.org/wiki/DCF77
    The unit comes with a ferrite rod aerial an amplifier chip with a crystal filter (77.5 kHz I suppose) and very little other information. So I have got it to work; here is the code...
    I have also attached a picture.

    #chip 12F1840,.25
    #config osc=intosc,wdte=off,mclr=off,boren=off
    ' Define HI2C settings
    #define HI2C_BAUD_RATE 25
    #define HI2C_DATA PORTA.2
    #define HI2C_CLOCK PORTA.1
    Dir HI2C_DATA in
    Dir HI2C_CLOCK in
    HI2CMode Master
    wait 100 ms
    dir porta.3 in 'data pin
    dir porta.0 out 'not used
    dir porta.4 out 'not used
    dir porta.5 out 'not used
    set porta.0 off 'pon off=on
    set porta.4 off
    set porta.5 off
    option_reg.7=0
    wpua=b'00000110' 'HI2C pins
    SL=0x7C 'DISPLAY ID
    COMSEND=0x00 'display COMMAND send
    DS=0X40      'display DATA send
    wait 10 ms
    onetwoline 'initialize LCD
    wait 10 ms
    j=0
    kmin1=0:kmin=0
    khour1=0:khour=0
    kday1=0:kday=0
    kmonth1=0:kmonth=0
    kyear1=0:kyear=0 'initialize constants
    
    t1con=b'00000100' 't1con.0 timer1 is on/off
    pir1.0=0 'set interrupt flag off
    intcon.6=1 'enable peripheral interrupts
    t1gcon.7=0 'timer1 continuous counting
    tmr1l=0
    tmr1h=0
    t1con.0=1 'timer on
    pie1.0=1 'timer1 overflow Interrupt
    'start of main loop...
    do
    xyz:
      do
      if porta.3=1 then exit do
      if pir1.0=1 then exit do
      loop
    
    if pir1.0=1 then 'detected missing pulse at 59 sec
    j=59
    screen3
    pir1.0=0
    tmr1l=0
    tmr1h=0
    goto xyz
    end if
    
    if j=59 and pir1.0=0 then
    j=0
    khour1=khour 'update on minute roll-over
    kmin1=kmin
    kday1=kday
    kmonth1=kmonth
    kyear1=kyear
    khour=0
    kmin=0
    kday=0
    kmonth=0
    kyear=0
    end if
    
    tmr1l=0
    tmr1h=0
    screen3
    j=j+1 'j is the second count
      do
      if porta.3=0 then exit do
      loop
    
    id7=tmr1h 'id7=37 is about 150 ms
    
    jj=j-1 'one second ahead!
    'binary coded decimal (arrgh!!)
    if id7>37 then
    if jj=21 then kmin=kmin+1
    if jj=22 then kmin=kmin+2
    if jj=23 then kmin=kmin+4
    if jj=24 then kmin=kmin+8
    if jj=25 then kmin=kmin+10
    if jj=26 then kmin=kmin+20
    if jj=27 then kmin=kmin+40
    
    if jj=29 then khour=khour+1
    if jj=30 then khour=khour+2
    if jj=31 then khour=khour+4
    if jj=32 then khour=khour+8
    if jj=33 then khour=khour+10
    if jj=34 then khour=khour+20
    
    if jj=36 then kday=kday+1
    if jj=37 then kday=kday+2
    if jj=38 then kday=kday+4
    if jj=39 then kday=kday+8
    if jj=40 then kday=kday+10
    if jj=41 then kday=kday+20
    
    if jj=45 then kmonth=kmonth+1
    if jj=46 then kmonth=kmonth+2
    if jj=47 then kmonth=kmonth+4
    if jj=48 then kmonth=kmonth+8
    if jj=49 then kmonth=kmonth+10
    
    if jj=50 then kyear=kyear+1
    if jj=51 then kyear=kyear+2
    if jj=52 then kyear=kyear+4
    if jj=53 then kyear=kyear+8
    if jj=54 then kyear=kyear+10
    if jj=55 then kyear=kyear+20
    if jj=56 then kyear=kyear+40
    if jj=57 then kyear=kyear+80
    end if
    
    pir1.0=0 'make sure!
    tmr1l=0
    tmr1h=0
    loop
    end 'should never get here
    
    sub screen3
    hi2cstart
    hi2csEND(Sl)
    hi2csEND(Comsend)
    hi2csend(0x80) 'first line
    hi2cstop
    j1=j/10
    j2=j%10
    hi2cstart
      hi2csend(Sl)
      hi2csend(DS)
    hi2csend(khour1/10+48)
    hi2csend(khour1%10+48)
    hi2csend(32)
    hi2csend(58)
    hi2csend(32)
    hi2csend(kmin1/10+48)
    hi2csend(kmin1%10+48)
    hi2csend(32)
    hi2csend(58)
    hi2csend(32)
    hi2csend(j1+48)
    hi2csend(j2+48)
    hi2csend(32)
    hi2cSTOP
    
    hi2cStart
    hi2cSEND(Sl)
    hi2cSEND(Comsend)
    hi2csend(0xC0) 'second line
    hi2cstop
    hi2cstart
    hi2cSEND(Sl)
    hi2cSEND(DS)
    hi2csend(kday1/10+48)
    hi2csend(kday1%10+48)
    hi2csend(32)
    hi2csend(47)
    hi2csend(32)
    hi2csend(kmonth1/10+48)
    hi2csend(kmonth1%10+48)
    hi2csend(32)
    hi2csend(47)
    hi2csend(32)
    hi2csend(50)
    hi2csend(48)
    hi2csend(kyear1/10+48)
    hi2csend(kyear1%10+48)
    hi2csend(32)
    hi2cstop
    end sub
    
    sub onetwoline 'initialize display
    SL=0x7C 'DISPLAY ID
    COMSEND=0x00 'display COMMAND send
    DS=0X40      'display DATA send
    chht=0x38 'two lines
    hi2cStart
    hi2cSEND(Sl)
    hi2cSEND(Comsend)
    hi2cSEND(chht) 'initialize 16x1or2
    hi2cSEND(COMSEND)
    hi2cSEND(chht+1) '16x1or2
    hi2cSEND(0x10) 'osc set to slowest
    hi2cSEND(0x77) 'contrast low byte=3 now 5 now 7
    hi2cSEND(0x54) 'pwr booster on
    hi2cSEND(0x6F) 'follower
    hi2cSEND(0x0C) 'on/off
    hi2cSEND(0x01) 'clear
    hi2cstop
    end sub
    
     
  • David Stephenson

    So what about the UK time signals (MSF on 60 kHz)?
    Aliexpress offer a dual frequency (40 and 60 kHz) VLF receiver (the 40 kHz is for the Japanese VLF transmissions). The problem (as ever) is there is little to no information supplied. I tried all possible combinations of pins high and low and could not get it to work. So the solution was to remove the 60kHz crystal and put it onto a DCF77 board (I also swapped the ferrite inductors, but this made little difference).
    UK VLF time signals used to be broadcast from Rugby - a nice central location. Now they are broadcast from Anthorn in Cumbria (almost in Scotland) . This is a long way from me in fact the German one is probably nearer (and is definitely more powerful 50kW versus 17kW).

    As is to be expected the coding is different. Rather than a missing pulse on the minute MSF60 has an extra long pulse (500ms) on the minute. Other than that it is a mixture of long (200ms) and short pulses (100ms) to give the BCD time (except near the minute there can be 300ms pulses "as a parity check"). The code is below. I used a 12LF1552 (as I have no 12F1840's left). It only has a 8-bit counter (timer0), but with the prescaler (256:1) it is essentially 16-bit (with only the high byte accessible).

    #chip 12LF1552,.25
    #config osc=intosc,wdte=off,mclr=off,boren=off
    ' Define HI2C settings
    #define HI2C_BAUD_RATE 25
    #define HI2C_DATA PORTA.2
    #define HI2C_CLOCK PORTA.1
    Dir HI2C_DATA in
    Dir HI2C_CLOCK in
    HI2CMode Master
    wait 20 ms
    dir porta.3 in 'mclr pin
    dir porta.0 out 'pon=power on
    dir porta.4 in 'time pulses
    dir porta.5 out 'out n/c
    set porta.0 off 'pon off=on
    set porta.5 off
    option_reg=b'00000111'
    wpua=b'00000110' 'HI2C pins
    wait 20 ms
    onetwoline 'initialize LCD
    wait 20 ms
    jj=0
    kmin1=0:kmin=0
    khour1=0:khour=0
    kday1=0:kday=0
    kmonth1=0:kmonth=0
    kyear1=0:kyear=0 'initialize constants
    tmr0=0
    'start of main loop...
    do
      do
      if porta.4=1 then exit do 'start of pulse
      loop
    tmr0=0
      do
      if porta.4=0 then exit do 'end of pulse
      loop
    jj=jj+1
    id7=tmr0 'id7=37 is about 150 ms
    if id7<110 then screen3
    tmr0=0
    if id7>110 then 'found minute marker
    jj=0
    khour1=khour 'update on minute roll-over
    kmin1=kmin
    kday1=kday
    kmonth1=kmonth
    kyear1=kyear
    khour=0
    kmin=0
    kday=0
    kmonth=0
    kyear=0
    screen3
    end if
    'binary coded decimal (arrgh!!)
    if id7>37 and id7<72 then
    if jj=51 then kmin=kmin+1
    if jj=50 then kmin=kmin+2
    if jj=49 then kmin=kmin+4
    if jj=48 then kmin=kmin+8
    if jj=47 then kmin=kmin+10
    if jj=46 then kmin=kmin+20
    if jj=45 then kmin=kmin+40
    
    if jj=44 then khour=khour+1
    if jj=43 then khour=khour+2
    if jj=42 then khour=khour+4
    if jj=41 then khour=khour+8
    if jj=40 then khour=khour+10
    if jj=39 then khour=khour+20
    
    if jj=35 then kday=kday+1
    if jj=34 then kday=kday+2
    if jj=33 then kday=kday+4
    if jj=32 then kday=kday+8
    if jj=31 then kday=kday+10
    if jj=30 then kday=kday+20
    
    if jj=29 then kmonth=kmonth+1
    if jj=28 then kmonth=kmonth+2
    if jj=27 then kmonth=kmonth+4
    if jj=26 then kmonth=kmonth+8
    if jj=25 then kmonth=kmonth+10
    
    if jj=24 then kyear=kyear+1
    if jj=23 then kyear=kyear+2
    if jj=22 then kyear=kyear+4
    if jj=21 then kyear=kyear+8
    if jj=20 then kyear=kyear+10
    if jj=19 then kyear=kyear+20
    if jj=18 then kyear=kyear+40
    if jj=17 then kyear=kyear+80
    end if
    tmr0=0
    loop
    end 'should never get here
    
    sub screen3
    hi2cstart
    hi2csEND(Sl)
    hi2csEND(Comsend)
    hi2csend(0x80) 'first line
    hi2cstop
    j1=jj/10
    j2=jj%10
    hi2cstart
      hi2csend(Sl)
      hi2csend(DS)
    hi2csend(khour1/10+48)
    hi2csend(khour1%10+48)
    hi2csend(32)
    hi2csend(58)
    hi2csend(32)
    hi2csend(kmin1/10+48)
    hi2csend(kmin1%10+48)
    hi2csend(32)
    hi2csend(58)
    hi2csend(32)
    hi2csend(j1+48)
    hi2csend(j2+48)
    hi2csend(32)
    hi2cSTOP
    
    hi2cStart
    hi2cSEND(Sl)
    hi2cSEND(Comsend)
    hi2csend(0xC0) 'second line
    hi2cstop
    hi2cstart
    hi2cSEND(Sl)
    hi2cSEND(DS)
    hi2csend(kday1/10+48)
    hi2csend(kday1%10+48)
    hi2csend(32)
    hi2csend(47)
    hi2csend(32)
    hi2csend(kmonth1/10+48)
    hi2csend(kmonth1%10+48)
    hi2csend(32)
    hi2csend(47)
    hi2csend(32)
    hi2csend(50)
    hi2csend(48)
    hi2csend(kyear1/10+48)
    hi2csend(kyear1%10+48)
    hi2csend(32)
    hi2cstop
    end sub
    
    sub onetwoline 'initialize display
    SL=0x7C 'DISPLAY ID
    COMSEND=0x00 'display COMMAND send
    DS=0X40      'display DATA send
    chht=0x38 'two lines
    hi2cStart
    hi2cSEND(Sl)
    hi2cSEND(Comsend)
    hi2cSEND(chht) 'initialize 16x1or2
    hi2cSEND(COMSEND)
    hi2cSEND(chht+1) '16x1or2
    hi2cSEND(0x10) 'osc set to slowest
    hi2cSEND(0x77) 'contrast low byte=3 now 5 now 7
    hi2cSEND(0x54) 'pwr booster on
    hi2cSEND(0x6F) 'follower
    hi2cSEND(0x0C) 'on/off
    hi2cSEND(0x01) 'clear
    hi2cstop
    end sub
    
     

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.