Red LED Message Display Receiver Picaxe Basic Program

Declarations and Data

#rem

Message_Display.bas Tests The Message Receiver is a small box with 4 1" red 7-segment LEDs which

displays selected fields received at 434 MHz.

Incoming messages are identified by the first character (Key_Code) which is in the range "q" to "z"

This determined where in the storage range $30-$CF they are stored in 10 blocks of 16 bytes

This is only valid in the interrupt subroutine

The numbers to be displayed are determined by a variable (Display_Code) which is global.

Its value is set by an incoming message with a Key_ code of "O".

This is followed by a comma, then a character range "A" to "Z".

This determines the number values indirectly from a table of pointers.

This table also indicates decimal points.

John Saunders 7/12/2015 moved spaces for s msg, max light reduced from 128

3/12/2017 added checksum

#endrem

#picaxe 14M2


'Decimal Points

symbol     Outport    = B.0        'Also DP4

symbol    DP3        = B.1

symbol    DP2        = B.2

symbol    DP1        = B.3


rem Interrupt only symbols

symbol    IntPort    = C.0

symbol    Rcvr_In    = C.3        'Idle low

symbol    Integrator = PinC.0

symbol    Checked    = bit0

symbol    Key_Code   = b1 

symbol    Key_Idx    = b2

symbol    Msg_End    = b3

symbol    Msg_Loc    = b4

symbol    Sto_Loc    = b5

symbol    I_tmp      = b6

symbol    ChckSum    = b7

symbol    ChckHex    = b8


rem Dimming Symbols

symbol    LEDControl = C.2

symbol    Photocell  = C.4

symbol    Light      = b10

symbol    Duty_Cycle = b11


rem Display symbols

symbol    Shft_Data  = C.1

symbol    Shft_Clk   = B.5

symbol    Latch_Clk  = B.4

symbol    Shft_Cnt   = b13

        

rem general variables

symbol    Iter       = b16

symbol    Temp       = b17

symbol    BCD_Data   = b19        'A binary value

symbol    ASC_Data   = b19        'A character

symbol    Data_Loc   = b20        'A pointer to an EEPROM location

symbol    S_Loc      = b21        'A pointer to a storage location    


rem global vatiable

symbol    Display_Code = b25    'Character in "O" message


rem constants

symbol    LEDPeriod     = 65

symbol    Min_Light     = 9

symbol    Max_Light     = 127

symbol    Age_Max       = 125

symbol    Disp_Code_Max = "F"        'Change to add more messages




DATA 0,(1,2,4,8)

#rem 

Display Code settings. The entries correspond to codes "A" through "Z".

The start address of each block of 5 values is 5*(Code - $40).

Each entry has 4 pointers to numbers, MSD - LSD, then decimal point control as follows:

Bit1 = DP1,Bit2 = DP2,Bit3 = DP2 (1=Off),bits 4-7 indicate which ageing timer controls DP4

Add entries to extend capability 

#endrem


DATA 5, ($60,$61,$62,$63,$31)            'A = Date, t message

DATA 10,($64,$65,$66,$67,$31)            'B = Time, t message

DATA 15,($50,$51,$52,29,$27)            'C = Temperature, s message

DATA 20,($53,$54,$55,29,$27)            'D = Humidity s message

DATA 25,($56,$57,$58,29,$27)            'E = Charging current s message

DATA 30,(29,$59,$5A,$5B,$25)            'F = Battery voltage s message

Init and  Main

Init:

SETFREQ m8

LOW Outport

LOW Shft_Clk

LOW Latch_Clk

LET Display_Code = "B"        'Time is default

POKE 28,"8"                'Fixed value for ;amp test

POKE 29,$3F                'Fixed value for padding blank

FOR S_Loc = $50 TO $63        'Initial display is time

    POKE S_Loc,$3F

NEXT

FOR S_Loc = $64 TO $67

    POKE S_Loc,$38

NEXT

POKE $67,$38

FOR Iter = 30 TO 39        'Initialize ageing

    POKE Iter,0

NEXT

SETINT %00000001,%00000001    'Interrupt when Rcvr_Int high


Main:

READADC Photocell,Light

IF Light < Min_Light THEN

    LET Duty_Cycle = Min_Light

ELSEIF Light >= Max_Light THEN

    LET Duty_Cycle = 2 * Max_Light

ELSE

    LET Duty_Cycle = 2 * Light

ENDIF

PWMOUT LEDControl,LEDPeriod,Duty_Cycle

PAUSE 2000

GOSUB Write_Out

FOR Iter = 30 TO 39        'Decrement all ageing counters to 0

    PEEK Iter,BCD_Data

    IF BCD_Data > 0 THEN

        DEC BCD_Data

    ENDIF

NEXT

GOTO Main

Sub-programs

Write_Out:        'Puts the 4 BCD in BCD_Data into the shift register

LET temp = Display_Code - $40

LET Data_Loc = 5 * temp + 4        'Points to the DP field of the selected display code

READ Data_Loc,b0                'Contains the DP bits

IF bit0 = 0 THEN

    LOW DP1

ELSE

    HIGH  DP1

ENDIF

IF bit1 = 0 THEN

    LOW DP2

ELSE

    HIGH  DP2

ENDIF

IF bit2 = 0 THEN

    LOW DP3

ELSE

    HIGH  DP3

ENDIF

LET S_Loc = b0/16 + 30            'Pointer to the counter for the message with this Display Code

PEEK S_Loc,BCD_Data

IF BCD_Data = 0 THEN

    LOW Outport

ELSE

    HIGH Outport

ENDIF

FOR Iter = 0 TO 3             'least significant digit first

    DEC Data_Loc

    READ Data_Loc,S_Loc

    PEEK S_Loc,ASC_Data

    IF ASC_Data < $30 OR ASC_Data > $39 THEN

        LET ASC_Data = $3F

    ENDIF

    FOR Shft_Cnt = 0 TO 3        'Least significant bit first

        READ Shft_Cnt,Temp    'Get the mask

        LET Temp = ASC_Data & Temp    '

        IF Temp = 0 THEN

            LOW Shft_Data

        ELSE

            HIGH Shft_Data

        ENDIF

        PULSOUT Shft_Clk,20

    NEXT Shft_Cnt

NEXT Iter

PULSOUT Latch_Clk,20

RETURN


Interrupt:

LET bptr=210

LET I_tmp = 0

DO WHILE Integrator = 1            'Noise interrupts are nearly always shorter

    INC I_tmp

    PAUSE 1

LOOP

IF I_tmp < 8 THEN End_Interrupt    'Minimises the time to recover from a noise interrupt

LET Key_Code = "Z"

SERIN [40,timeout],Rcvr_In,N2400_8,("14L1776"),Key_Code,I_tmp,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptr

GOTO End_Interrupt            'A long message from an intefering device

timeout:

IF Key_Code  = "Z" THEN End_Interrupt    'A foreign message

IF Key_Code = "O" THEN            'A display control message

    PEEK 210,I_tmp

    IF I_Tmp >= "A" AND I_tmp <= Disp_Code_Max THEN

        LET Display_Code = I_tmp

    ENDIF

ENDIF

IF Key_Code < "q" OR Key_Code = "O" THEN    End_Interrupt 'Not a data message

LET Checked = 0

PEEK 210, I_tmp 

SERTXD ("Key_Code = ",Key_Code,",Length Code = ",I_tmp,",")

LET Msg_End = bptr - 1                'Default for no checksum

IF I_tmp > 60 THEN                'A message lengyh for checksum

    LET Msg_End = I_tmp + 151        'Last message byte 

    LET Chcksum = 0

    FOR I_tmp = 212 TO Msg_End

        LET bptr = I_tmp

        LET ChckHex = @bptr    

        LET ChckSum = ChckSum + ChckHex

    NEXT

    LET bptr = Msg_End + 2                    'Address of first checksun byte

    LET ChckHex = ChckSum / 16

    IF ChckHex  < 10 THEN

        LET ChckHex = ChckHex + "0"

    ELSE

        LET ChckHex = ChckHex + "7"

    ENDIF

    LET I_tmp = @bptrinc                    'first Checksum character

    IF ChckHex <> I_tmp THEN End_Interrupt

    LET ChckHex = ChckSum & $F

    IF ChckHex  < 10 THEN

        LET ChckHex = Chckhex + "0"

    ELSE

        LET ChckHex = ChckHex + "7"

    ENDIF

    LET I_tmp = @bptr                    'first Checksum character

    IF ChckHex <> I_tmp THEN End_Interrupt

    LET Checked = 1

ENDIF    

LET Key_Idx = Key_Code - "q"

LET Sto_Loc = Key_Idx * $10 + $30

LET ChckHex = 2 * Checked + 210

FOR Msg_Loc = ChckHex TO Msg_End                'Copy numbers to storage

    PEEK Msg_Loc,I_tmp

SERTXD (I_Tmp)

    IF I_tmp >= "0" AND I_tmp <= "9" THEN

        POKE Sto_Loc,I_tmp

        INC Sto_Loc

    ENDIF    

NEXT

SERTXD (13,10)

LET Sto_Loc = 30 + Key_Idx

POKE Sto_Loc,Age_Max

End_Interrupt:

SETINT %00000001,%00000001    'Interrupt when Rcvr_Int high


RETURN