Bins Alarm

cpedw

Senior Member
Where I live (Connel, Argyll), we have a simple but confusing system of bin collections: Recycling blue bins are collected fortnightly on Fridays and Landfill green bins are collected 3-weekly, also on Fridays. The algorithm is straightforward but remembering on Thursday (bins are emptied early in the morning) which part of the cycle applies is challenging.

I used an MSF based clock to tell the date and a simple bit of arithmetic using the Julian Date number (offset to a start date on which I know the bins state) to work out the states of the two bins. Green or Blue LEDs are lit on Thursday morning and stay lit until Friday night as appropriate. I used the Universal Solder MSF module.

I added a Red LED to warn if the MSF clock is not working. It sometimes loses the signal for a few minutes. The TIME variable is used to keep the clock moderately correct. It only needs to get the day of the week right. If the MSF clock has failed for over 24 hours, the Red LED flashes. I haven't noticed this happen in 2 years of operation. I am about 120 miles from the Anthorrn (Cumbria) MSF transmitter.

I am indebted to contributors to the forum:
Hippy's Show bits MSF decoder, http://www.picaxeforum.co.uk/showthread.php?11334-Decoding-UK-s-NPL-MSF-Time-Signal post 36
and
T.Ikeda's Julian day number (JDN) calculator https://picaxeforum.co.uk/threads/julian-date-code-for-picaxe.8674/

Code:
#PICAXE 08M2
#NO_DATA
' Bins alarm MSF self start
' DW 2/24
' Show when which bins should go out. Lights up on Wednesday midnight and stays on until Friday midnight

' Take date data from MSF clock, convert to JDN starting 24/3/23=0, calculate when Green or Blue bin goes out

' Uses MSF to find what date it is
'Receive MSF data based on:
'Hippy's Show bits as received and display date/time info from
'http://www.picaxeforum.co.uk/showthread.php?11334-Decoding-UK-s-NPL-MSF-Time-Signal post 36

' Red LED on C.0 flashing if no MSF for 12 hours or more. On steady if MSF not working but <12 hr since last time fix. Off when MSF working.

' Diagnotic output for LCD/OLED on C.4. 

'Julian day number (JDN) calculator
'Created: 2007-12-23 (T.Ikeda - KA1OS)
'Latest mod: 2008-01-27
'From https://picaxeforum.co.uk/threads/julian-date-code-for-picaxe.8674/

' Uses LCD/OLED to display diagnostics.

SYMBOL RedLight =C.0    ' Red LED on leg 7, along with Programming line
SYMBOL BlueLight=C.1    ' Blue LED on leg 6
SYMBOL GreenLight=C.2    ' Green LED on leg 5

Symbol SIGNAL      = pinC.3' Radio signal Input Pin (leg 4)
Symbol LCDout    = C.4    ' LCD diagnostics out (leg 3)

Symbol ACTIVE  = 1       ' Active level ( 0 or 1 )
Symbol INACTIVE = ACTIVE ^ 1

Symbol gapchar = "-"

Symbol bitest  = bit0        'Counts bits for parity tests
Symbol btyr       = bit1        'Parity test 17-24
Symbol btmd       = bit2        'Parity test 25-35
Symbol btdow   = bit3        'Parity test 36-38
Symbol bttim   = bit4        'Parity test 39-51
Symbol Paritycheck=bit5        'Overall parity result (1=good) 
Symbol bitA       = bit6
Symbol bitB       = bit7

SYMBOL GFlag = bit8        ' High when Green bin is due
SYMBOL BFlag = bit9        ' High when Blue bin is due
SYMBOL RFlag = bit10    ' High when red light is on or flashing
SYMBOL FlFlag= bit11    ' High if MSF hasn't worked for 12 hours

Symbol bcd     = b2        ' MSF workspace
Symbol bitVal  = b3        ' MSF workspace
SYMBOL JDN     = w2        'b4,b5 Julian date number
SYMBOL JDtest=w3        'b6,b7 JDN or JDN+1 so we score a hit on Thursday and Friday
SYMBOL test = b8        ' 0 on Thursday/Friday

SYMBOL hour        = b14
SYMBOL mins        = b15
SYMBOL dow        = b16
SYMBOL yr        = b17
SYMBOL mon        = b18
SYMBOL date        = b19
Symbol bits        = b22
SYMBOL putPtr    = b23

SYMBOL mn        = w13    ; b26, b27 minutes after midnight

SYMBOL p50 = 50        'For default freq M4
Symbol p100= 100
Symbol p200=200
SYMBOL tmax=43200        ' 12hrs in seconds for TIME. For 4MHz
SYMBOL baudmode = N2400_4 

    LOW BlueLight         ' All bin lights off to start
    LOW GreenLight
    HIGH RedLight        ' MSF Clock not working yet
    FlFlag = 0            ' Set after tmax without MSF, flashing red
    TIME = 0

    BFlag = 0
    GFlag = 0
    RFlag = 1

 Do                        ' Wait for the MSF clock to get started
    Gosub ReadBit
 Loop
Paritycheck=0

WaitForMinute:

    IF Paritycheck=1 THEN            ' If MSF is working, use its time; reset error flags
        LOW RedLight
        FlFlag = 0            ' No Flashing or steady Red light
        RFlag = 0
        TIME = 0
        hour = mn/60
          mins = mn//60
        Paritycheck=0
serout LCDout, baudmode, (254,128," using MSF ")
    ELSEIF RFlag=0 THEN    ' MSF Clock not working 
        RFlag = 1    ' MSF was working but now it's not
        HIGH RedLight
        TIME = 0
    ELSEIF TIME>tmax THEN
        FlFlag = 1 ' MSF hasn't worked for 12 hours so start flashing
        TIME = 0
        RFlag = 1
    ELSEIF FlFlag=1 THEN
        IF TIME>0 THEN
            Toggle RedLight        ' MSF not working>12hrs, keep flashing
            RFlag = 1
            TIME = 0
        ENDIF
    ENDIF

    IF mins<10 THEN            
        serout LCDout, baudmode, (254,139,#hour,":0",#mins,"   ")
    ELSE
        serout LCDout, baudmode, (254,139,#hour,":",#mins,"   ")
    ENDIF
    serout LCDout, baudmode, (254,192,#BFLag," ",#GFlag,"    ",#DOW,"        ")
    
'  Correct time has been established.        

'Julian day number (JDN) calculator by T.Ikeda
'From https://picaxeforum.co.uk/threads/julian-date-code-for-picaxe.8674/
'Works with dates from 2000-01-01 to 2178-12-31
'
'Original program had 2000-01-01, JDN = 0 (Epoch: 2000-01-01) 
' To extend usefulness, moved Epoch to 2023-03-24 has JDN=0.

JDN = 0
If mon > 2 Then
    JDN = 1
End If

JDN = yr + JDN * 7 / 4
JDN = 367 * yr - JDN
JDN = mon * 3912 / 128 + date - 31 + JDN

'Add correction for 2100 not being a leap year...
If JDN > 36584 Then
    JDN = JDN -1
End If

    JDN = JDN - 8483        'JDN epoch moved to 2023-03-24=day0.  Blue bin next week Green in 2 weeks.    
    JDtest     = JDN + 1
    test = JDtest//7
    test = JDN//7 * test    ' Is Zero on Thursdays & Fridays
    
    IF test=0 THEN
        BFlag     = JDtest // 14 / 7    ' Every 2 weeks
        GFlag    = JDtest // 21 / 14    ' Every 3 weeks 
    ELSE
        BFlag = 0
        GFlag = 0
    ENDIF    


    IF BFLag=1 THEN    'This is a Blue week
        HIGH BlueLight
    ELSE
        LOW BlueLight
    ENDIF

    IF GFlag=1 THEN    'This is a Green week
        HIGH GreenLight
    ELSE
        LOW GreenLight
    ENDIF
serout LCDout, baudmode, (254,192,#JDN, "   ",#BFlag, "   ",#GFlag,"       ")
  
  Do                    ' Back to MSF clock
    Gosub ReadBit
  Loop
END

StartMinute:

 putPtr  = $50
  bits = 16 :              Gosub ReadBcd ' $50,$51 Unused bits  16
  bits = 8  : bitVal = 8 : Gosub ReadBcd : btyr = bitest ' $52,$53 Year bits    4+4
  bits = 5  : bitVal = 1 : Gosub Readbcd : btmd = bitest ' $54,$55 Month bits   1+4
  bits = 6  : bitVal = 2 : Gosub ReadBcd : btmd = btmd + bitest ' $56,$57 Day bits     2+4
  bits = 3  : bitVal = 4 : Gosub Readbcd : btdow = bitest ' $58,$59 DOW bits     3    
  bits = 6  : bitVal = 2 : Gosub ReadBcd : bttim = bitest' $5A,$5B Hour bits    2+4
  bits = 7  : bitVal = 4 : Gosub Readbcd : bttim = bttim + bitest ' $5C,$5D Minutes bits 3+4   
  bits = 2  :              Gosub ReadBcd ' Unused bits  2
  bits = 1  :              Gosub ReadBcd : btyr = btyr + bitB ' Year parity check bit 54B
  bits = 1  :              Gosub ReadBcd : btmd = btmd + bitB ' Month/day parity check bit 55B
  bits = 1  :              Gosub ReadBcd : btdow= btdow+ bitB ' DOW parity check bit 56B
  bits = 1  :              Gosub ReadBcd : bttim= bttim+ bitB ' Time parity check 57B
 
IF btyr=1 AND btmd=1 AND btdow=1 AND bttim=1 THEN
    Paritycheck = 1

    putPtr = $52
    DO
        Peek putPtr,bcd

        IF putPtr = $52 THEN
            yr = bcd
        ENDIF
        IF putPtr = $54 THEN
            mon = bcd
        ENDIF
          IF putPtr = $56 THEN
            date = bcd
        ENDIF
            IF putPtr = $58 THEN
            dow = bcd
        ENDIF
          IF putPtr = $5A THEN
            mn = bcd*60
        Endif
        IF putPtr = $5C THEN
            mn = mn + bcd
        ENDIF
         putPtr = putPtr+1
        Peek putPtr,bcd
         putPtr = putPtr+1
      Loop until putPtr>$5C

  ENDIF
  
  Goto WaitForMinute

ReadBcd:
  bcd = 0                                'Accumulate data into bcd bit by bit
  bitest = 0
  Do 
    Gosub ReadBit
    bcd = bitVal * BitA + bcd            'Add next bit
    bitest = bitest + bitA
    bitVal = bitVal / 2                    'Define next bit's value
    bits = bits - 1                        'Keep count of bits
    If bits = 4 Then                        'If it's a 2 digit result, this is the tens
      bcd = bcd * 10
      bitVal = 8
    End If
  Loop Until bits = 0
  Poke putPtr,bcd
  putPtr = putPtr+1
  Poke putPtr,gapChar
  putPtr = putPtr+1
  Return

ReadBit:
  Do : Loop Until SIGNAL IS INACTIVE
  Do : Loop Until SIGNAL IS ACTIVE
  Pause  p50
  If SIGNAL IS INACTIVE Then WaitForMinute
  Pause p100
  bitA = SIGNAL ^ INACTIVE
  Pause p100
  bitB = SIGNAL ^ INACTIVE
  Pause p200
  If SIGNAL IS ACTIVE Then StartMinute
'sertxd( #bitA )
  Return
 
Back
Top