#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:
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
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