#rem
Controller.bas This program runs on the base unit of a system for displaying and logging environmental and security information.
This unit is the Environmental Display. It has the following connections:
* A photocell, a temperature sensor, a pair of banana jacks no longer monitoring a gate via X-10
* An output to the Logging Terminal, an input from the Adapter.
The Adapter has the following:
* An RF receiver for messages from the Alpha LED Clock and the Solar Transmitter.
* An interface for the receiver of the wireless-connected Driveway Patrol sensor pair
* An interface to monitot the presence of line voltage (The system is run from a UPS)
* An interface to measure DC voltage range 0 - 20
* An interface to the Patio Sensor Box.
The Patio Sensor Box has the following"
* Internal temperature and humidity sensors.
* External connections for the Patio and Back photocells and the spa heater gas valve.
The Alpha LED Clock transmits date and tie values once a minute.
The Solar Transmitter transmits the following once per minute:
* Thmperature and Humidity.
* Solar panel charging current and battery voltage.
Program via the pigtail to the logger using Editor V5.
John Saunders 8/16/2016 RF gate switch 3/11/17 added checksum calculation
1/11/2019 Gate sense correction. 2021 send out keycode and comma
#endrem
#Picaxe 40X1
#rem
Controls:
1. The toggle switch at the rear controls power to the Controller, Adapter, Logging Terminal, Driveway Patrol receiver and the Sensor Box,
2. The rotary switch has 12 mechanical positions, but only the first 7 from CCW are decoded and can be used by the program.
The first 5, labelled O,A B,C D affect only the items displayed, not the program operation.
The next P, allows parameter setting.
Position r is hard-wired to the 40X1 reset pin. Do not use any other positions.
3. The ENT and CLR buttons control backlighting in switch positions O - D.
In switch position P both advance the selected parameter to , the difference is that SET stores the parameter value in EEPROM before advancing.
4. The encoder in switch positions O - D turns pn backlighting.
In switch position P it adjusts the selected parameter.
Timing:
* The main loop executes continuously about 40 times a secomd.
* It generates 14 phases, 13 of which are devoted to specific inputs.
* The 14th. generates a. Event message when one has ocurred.
* The controls are checked each loop. The 1/2 Hz clock is polled each loop to generate a separate seconds timebase.
* This is used to once a minute to send the Weather Message.
* The internal temperature sensor is also read only once a minute because it takes 700 ms.
* Incoming RF messages are stored temporally in the interrupt proflage generated.
* At the next main loop the message is copied to its specific location.
* The daylight flag and midnight operation are message-dependent and so are handles when the message arrives.
* Switch position 5 (P-setting) is handled every loop.
Memory Usage:
This program buffers analog values in Scratchpad; isolating acquisition from display and logging.
The measurements are stored in the scratchpad exaclly as they will be output to the Logging Terminal.
Each item is in ASCII and has a specific address in Scratchpad as follows:
SOLAR 85 - 99: Temperature,Humidity,Milliamperes,Voltage (each 3 characters plus a comma)
PATIO BOX: 101 - 112: Temperature, 101 - 103: Humidity, Patio Photocell, Back Photocell (each 2)
INTERNAL: 114 - 127:Temperature, 114 - 116: Photocell, 118 - 119: External Voltage 121 - 125
The RAM is also used with binary values. It is allocated as follows:
80,81: word Patio Temperature accumulation, 82,83 word Ext BNC accumulation
84 byte Patio light value, 86 byte Back light value
90 Parameter while setting
Acquisition differs depending on the source:
* The RF inputs need no engineering conversion. They are input in the interrupt procedure into scratchpad
which is used brcause because it supports the @ptrinc designation. The data is transferred into scratchpad
just as it comes out of the interrupt sub-program.
* The hard-wired analogs are sampled and accumulated multiple times in scratchpad,
both to smooth noise and for engineering unit conversion.This is periodic.
* The local tmperature sensor is digital. Because it is very slow, it is input infrequently.
Displaying is split into pages. The items in the selected page are updated from scratchpad at the end of each acquisition cycle.
Logging is periodic at a selected interval in seconds. It does not include a time-tag - this is added in the Logging Terminal.
The discretes are checked frequently and displayed and logged at each change in a different file.
#endrem
rem Bit variables:
rem Specific flags
symbol tMesgFlag = bit0 'A time message has been received
symbol sMesgFlag = bit1 'A solar message has been received
symbol BacklightFlag = bit2 'Backlight is on
symbol Pending = bit3 'Backlight has been on for about a minute
symbol Phase = bit4 'Flag indicates that clock interrupt has been detected
symbol Daylight = bit5 'One if the solar cells are producing
symbol Midnight = bit6 'One if the hour MSB is not 0
symbol TxFlag = bit7 'A transmission is in process
rem Event Flags, also b1 A 1 in each is the asserted state, not necessarily the voltage level
symbol BackFlag = bit8
symbol PatioFlag = bit9
symbol GateFlag = bit10 'From RF input, 1 = open, 0 = closed
symbol LineFlag = bit11
symbol IRFlag = bit12
symbol SpaFlag = bit13
symbol BananaFlag = bit14 'Used formally for the gate, now spare
symbol GateEvent = bit15
rem word variables - uses bytes 27 down
symbol Remainder = w13 'Output of an ADC read
symbol DECData = w12 'Numeric value to be displayed
rem byte variables - uses bytes 2 and up
rem variables with specific meanings
symbol Seconds = b2 'Incremented by the clock, not used except for output and DS18B20
symbol SwPos = b3 'Position of rotary switch: 0..6
symbol OldSwPos = b4 'To detect a change
symbol LoopCount = b5 'The main loop is cyclic on this
symbol OldEvents = b6 'To detect a change
symbol SettingIndex = b7
rem pointer variables
symbol DataAddr = b9 'Usually used to point to an EEPROM entry
symbol ScreenLoc = b10 'A location on the screen or a command
symbol SPAddr = b11 'Used to point to an address in scratchpad memory
rem Used only in interrupt
symbol I_Char = b12
symbol Key_Code = b13
symbol ChckHex = b14
symbol I_Tmp = b15
symbol ChckSum = b16
rem Other variables
symbol DispMode = b17 'Controls displaying a field. Bits 0,1:length 1-4, bits 2,3 Decimal pos from left
symbol Index = b18 'Multi-use variable
symbol Iter = b19 'Multi-use variable
symbol CharData = b20 'Byte variable
symbol Temp = b21 'General use
rem EEPROM
rem Magic numbers
DATA 0,($30,$30,$30,$38,$0C,$01,$06,$14,$80) 'Display Init strings
rem Patio floodlight is 65 when on, Back is 85
DATA 9,(40,50,20) 'Selectable: Patio min, Back min, hysteresis
rem Fixed strings for display formatting
rem Data values
DATA 12,("PATIO",0)
DATA 18,("BACK",0)
DATA 23,("SOLAR",0)
DATA 29,("GARAGE",0)
DATA 36,("EXT BNC",0)
rem Events
DATA 44,("IR",0)
DATA 47,("SPA",0)
DATA 51,("GATE",0)
DATA 56,("LINE",0)
rem page Headings
DATA 61,("SETTING",0)
DATA 69,("HUMIDITY",0)
DATA 78,("TEMPERATURE",0)
DATA 90,("LIGHT",0)
DATA 96,("VOLTS",0)
rem Units
DATA 102,(":",0)
DATA 104,($DF,"F",0)
DATA 107,("%",0)
DATA 109,("MA",0)
DATA 112,("V",0)
rem String locations and addresses First=location, second = EEPROM address
DATA 114,($8D,102,0) 'Page0="O" Colon
DATA 117,($82,78,$C0,23,$C9,104,$94,12,$9D,104,$D4,29,$DE,104,0) 'Page1="A' temperatures
DATA 132,($84,69,$C0,23,$C9,107,$94,12,$9C,107,0) 'Page2="B" humidity
DATA 143,($86,90,$C0,12,$C8,107,$CB,18,$D2,107,$94,29,$9D,107,$D4,23,$DD,109,0) 'Page3="C" Light
DATA 162,($88,96,$C0,23,$C9,112,$94,36,$A1,112,0) 'Page4="D" Volts
DATA 173,("DELTA=",0)
rem Field locations and scratchpad addresses
DATA 180,($C6,85,$9A,101,$DB,114,0) 'Page1="A' temperatures
DATA 187,($C6,89,$9A,105,0) 'page2="B" humidity
DATA 192,($C6,108,$D0,111,$9B,118,$DA,93,0) 'Page3="C" Light
DATA 201,($C6,97,$9C,121,0) 'Page4="D" Volts
rem Field locations and EEPROM addresses
DATA 206,($C9,18,$C0,12,$94,51,$9D,56,$D4,44,$DD,47,0) 'Page0="O" Events
DATA 219,($86,61,$C0,12,$94,18,$D4,173,0) 'Page5="P" Setting
DATA 228,(" ",0)
Init:
SetFREQ m8
LOW portc 7 'LCD Enable
HIGH Portc 5 'backlight on
rem Initialize Display
FOR DataAddr = 0 TO 8
READ DataAddr,ScreenLoc
GOSUB DispCmd
PAUSE 100
NEXT
GOSUB ClearScreen
rem Prepare the scratchpad for transmission
LET CharData = "0"
FOR SPAddr = 41 TO 67
PUT SPAddr, CharData
NEXT
rem Put commas into the scratchpad for recording
LET CharData = ","
FOR Iter = 0 TO 7
LOOKUP Iter,(100,104,107,110,113,117,120,126),SPAddr
PUT SPAddr, CharData
NEXT
LET Seconds = 0
LET OldSwPos = $FF
LET SettingIndex = 0
LET GateFlag = 0
LET GateEvent = 0
READ 9, CharData
POKE 90,CharData
PUT 33,"1"
rem Set initial interrupt on either RF or encoder
SETINT OR %01000001,%01000001
looping: 'Main loop is asynchronous, 320 ms
IF tMesgFlag = 1 THEN 'A message has been received from the Green LED Clock.
IF SwPos = 0 THEN
LET ScreenLoc = $82 'It's not stored, only displated in switch position O
GOSUB DispCmd
FOR SPAddr = 2 TO 12
LET Index = 8
LOOKDOWN SPAddr,(4,7,10),Index 'Locations of commas to be converted
IF Index < 8 THEN
LOOKUP Index,("/"," ",":"),CharData
ELSE
GET SPAddr,CharData
ENDIF
GOSUB DispChar
NEXT
ENDIF
GET 8, Index 'The hour MS digit to determine midnight
IF Index = "0" and Midnight = 1 THEN
GOSUB TxHeading
ENDIF
IF Index = "0" THEN
LET Midnight = 0
ELSE
LET Midnight = 1
ENDIF
LET tMesgFlag = 0
ENDIF
IF sMesgFlag = 1 THEN 'Transfer the Solar Transmitter message to the scratchpad at 25
FOR SPAddr = 2 TO 16 'First character is 2 of the incoming message
GET SPAddr,CharData
LET Index = SPAddr + 83
LET CharData = CharData & $7F
PUT Index,CharData
NEXT
LET Daylight = 0 'Used in getting light events
FOR SPAddr = 93 TO 95 'Solar panel charging current
GET SPAddr, Chardata
IF CharData > "0" THEN
LET Daylight = 1
ENDIF
NEXT
LET sMesgFlag = 0
ENDIF
IF LoopCount >= 13 THEN
LET LoopCount = 0
ELSE
INC LoopCount
ENDIF
GOSUB ReadSwitch
GOSUB ReadAnalogs
GOSUB ReadDigitals
GOSUB BacklightControl
IF Pin4 <> Phase THEN 'A clock pulse has been detected, each second
IF Seconds >= 59 THEN
LET Seconds = 0
ELSE
INC Seconds
ENDIF
rem Display the seconds in switch position 0
IF SwPos = 0 THEN
LET ScreenLoc = $8E 'After the date and time
GOSUB DispCmd
LET CharData = Seconds/10 + "0"
GOSUB DispChar
LET CharData = Seconds//10 + "0"
GOSUB DispChar
ENDIF
IF Seconds = 41 THEN
GOSUB TxWeather
ENDIF
IF Seconds = 5 THEN
READTEMP12 1,Remainder
PAUSE 10
LET DecData = 9*Remainder/80 + 32 'Convert to Farenheit
LET DispMode = 2
LET SPAddr = 114
GOSUB StoreAnalog
ENDIF
LET Phase = Pin4
ENDIF
rem Display the selected parameter and blank the other in switch position 5 every loop
IF SwPos = 5 THEN
FOR Iter = 0 TO 2
IF Iter <> SettingIndex THEN 'Blank it out
LET Index = 2 * Iter + 221 'Using indirect addressing
READ Index,ScreenLoc
LET ScreenLoc = ScreenLoc + 6
GOSUB DispCmd
LET ChaRData = " "
GOSUB DispChar
LET ChaRData = " "
GOSUB DispChar
ENDIF
NEXT
LET Index = 2 * SettingIndex + 221 'Using indirect addressing
READ Index, ScreenLoc
LET ScreenLoc = ScreenLoc + 6
GOSUB DispCmd
PEEK 90,Temp 'Volatile: adjusted in interrupt by the encoder
LET CharData = Temp/10 + "0"
GOSUB DispChar
LET CharData = Temp//10 + "0"
GOSUB DispChar
ENDIF
GOTO looping
#rem Classification of Subprograms:
Group A: Modify no variables
Group B. Modify only Chardata and Index
Group C: Modify only CharData & Iter & temp
#endrem
rem Group C
ReadAnalogs:
SELECT LoopCount
CASE 0
GOSUB DispData 'Depends on page
CASE 1
READADC10 6,DecData 'Patio Temperature, 1st of 3
READADC10 7,Remainder 'Ground reference
LET DecData = DecData - Remainder
POKE 80, WORD DecData
CASE 2
READADC10 3,DecData 'Ext BNC, 1st of 2
POKE 82, WORD DecData
CASE 3
READADC10 5,DecData 'Garage Photocell
LET DecData = DecData / 10
LET DispMode = 1
LET SPAddr = 118
GOSUB StoreAnalog
CASE 4
READADC10 2,DecData 'Patio Humidity
READADC10 7,Remainder 'Ground reference
LET DecData = DecData - Remainder LET DecData = DecData / 10
LET DispMode = 1
LET SPAddr = 105
GOSUB StoreAnalog
CASE 5
READADC10 6,DecData 'Patio Temperature, 2nd of 3
READADC10 7,Remainder 'Ground reference
LET DecData = DecData - Remainder
PEEK 80, WORD Remainder
LET DecData = Decdata + Remainder
POKE 80, DecData
CASE 6
READADC10 0,DecData 'Patio Photocell
' READADC10 7,Remainder 'Ground reference
' LET DecData = DecData - Remainder 'Commented out-was going negative on interference
LET DecData = DecData / 10
POKE 84,DecData 'Save for flag determination
LET DispMode = 1
LET SPAddr = 108
GOSUB StoreAnalog
CASE 7
READADC10 1,DecData 'Back Photocell
' READADC10 7,Remainder 'Ground reference
' LET DecData = DecData - Remainder 'Commented out-was going negative
LET DecData = DecData / 10
POKE 86,DecData 'Save for flag determination
LET DispMode = 1
LET SPAddr = 111
GOSUB StoreAnalog
CASE 8
PEEK 82, WORD Remainder
READADC10 3,DecData 'Ext BNC #2 0f 2
LET DecData = Decdata + Remainder
LET DispMode = 11
LET SPAddr = 121
GOSUB StoreAnalog
CASE 9
READADC10 6,DecData 'Patio Temperature, 3rd of 3
READADC10 7,Remainder 'Ground reference
LET DecData = DecData - Remainder
PEEK 80, WORD Remainder
LET DecData = Decdata + Remainder
LET DecData = DecData /20 + 12 '1 count per deg F
LET DispMode = 2
LET SPAddr = 101
GOSUB StoreAnalog
ENDSELECT
RETURN
ReadDigitals:
SELECT LOOPCOUNT
CASE 10
PEEK 84,Decdata 'Patio Analog photocell volts
READ 9,CharData 'Less than the value when the floodlights are on
READ 11,Temp 'This will stabilize the operation
LET Temp = CharData + Temp
IF DecData > Temp THEN
LET PatioFlag = 1
ENDIF
IF DecData < CharData OR Daylight = 1 THEN
LET PatioFlag = 0
ENDIF
CASE 11
PEEK 86,Decdata 'Back Analog photocell volts
READ 10,CharData
READ 11,Temp
LET Temp = CharData + Temp
IF DecData > Temp THEN
LET BackFlag = 1
ENDIF
IF DecData < CharData OR Daylight = 1 THEN
LET BackFlag = 0
ENDIF
CASE 12
IF Portc pin4 = 0 THEN 'Get the events to the scratchpad for both messages
LET BananaFlag = 0
ELSE
LET BananaFlag = 1
ENDIF
IF Portc pin0 = 0 THEN
LET LineFlag = 1
ELSE
LET LineFlag = 0
ENDIF
LOW 7
LET SpaFlag = Pin3
IF Portc pin2 = 0 THEN
LET IRFlag = 1
ELSE
LET IRFlag = 0
ENDIF
CASE 13
IF OldEvents <> b1 THEN 'Transmit an event message
GOSUB TxEvent
ENDIF
LET OldEvents = b1
ENDSELECT
RETURN
ReadSwitch:
HIGH 7 'B selection: Clear PB, Set PB, Mode 0
LET Iter = Pin7
LOW 7 'A selection: pin 4,Mode1,Mode2
LET CharData = 2 * Pin2 + Iter
LET SwPos = 4 * Pin7 + CharData
IF OldSwPos <> SwPos THEN 'Display the headings. This uses indirect addressing
GOSUB ClearScreen
LOOKUP SwPos,(114,117,132,143,162,219,219),Iter 'Location of the first string location
DO
READ Iter,ScreenLoc
IF ScreenLoc = 0 THEN EXIT
INC Iter
READ Iter,DataAddr
GOSUB DispFixed
INC Iter
LOOP
HIGH Portc 5
LET BacklightFlag = 1
ENDIF
LET OldSwPos = SwPos
RETURN
DispData: '68 ms
IF SwPos < 5 THEN
LOOKUP SwPos,(206,180,187,192,201),Iter 'Location of the first field location
LET Temp = 1
DO
READ Iter,ScreenLoc
IF ScreenLoc = 0 THEN EXIT
INC Iter
IF SwPos = 0 THEN 'Display the string only if the flag is 1
LET CharData = b1 & Temp 'Read the event flage in sequence LS first
IF Chardata > 0 THEN 'Flag is set
READ Iter,DataAddr 'Correspomding name of event
ELSE
LET DataAddr = 228 'Blank string
ENDIF
GOSUB DispFixed
LET Temp = 2 * Temp
ELSE
READ Iter,SPAddr
GOSUB DispField
ENDIF
INC Iter
LOOP
ENDIF
RETURN
rem Group B
rem Did not wish to use BINTOASCII - slow and needs more variables
StoreAnalog: 'Stores DecData in the scratchpad starting at SPAddr
BRANCH DispMode,(OneDigit,TwoDigit,ThreeDigit)
rem 4 digit by default
LET Chardata = DecData / 1000 + "0" MAX "9"
PUT SPAddr,Chardata
INC SPAddr
LET Remainder = DecData // 1000
LET DecData = Remainder
ThreeDigit:
LET Chardata = DecData / 100 + "0"
PUT SPAddr,Chardata
INC SPAddr
LET Remainder = DecData // 100
LET DecData = Remainder
IF DispMode = %00001011 OR DispMode = %00001010 THEN '11 or 10
LET CharData = "."
PUT SPAddr,Chardata
INC SPAddr
ENDIF
TwoDigit:
LET Chardata = DecData / 10 + "0" MAX "9"
PUT SPAddr,Chardata
INC SPAddr
LET Remainder = DecData // 10
LET DecData = Remainder
OneDigit:
LET Chardata = DECData // 10 + "0" MAX "9"
PUT SPAddr,Chardata
IF SPAddr < 127 THEN
INC SPAddr
LET Chardata = ","
PUT SPAddr,Chardata
ENDIF
RETURN
ClearScreen: 'There is a Hitachi command but I did not want to use it
LET ScreenLoc = $80
GOSUB DispCmd
LET Chardata = " "
FOR Iter = 0 TO 39
GOSUB DispChar
NEXT Iter
LET ScreenLoc = $C0
GOSUB DispCmd
LET Chardata = " "
FOR Iter = 0 TO 39
GOSUB DispChar
NEXT Iter
RETURN
TxDigital: 'Spa,IR,Line,Gate,Patio,Back
LET Temp = 32 'Store MS first $20 bit 5= 13 - 8 (spa Flag)
FOR Iter = 0 TO 5
LET CharData = b1 & Temp
IF CharData > 0 THEN
LOOKUP Iter,("S","I","L","G","P","B"),CharData
ELSE
LET Chardata = "0"
ENDIF
LET Temp = Temp / 2
SERTXD (",",CharData)
NEXT Iter
RETURN
DispFixed: 'Displays the zero-terminated string in EEPROM at DataAddr at ScreenLoc
GOSUB DispCmd
LET Index = DataAddr
DO
Read Index,CharData
INC Index
IF CharData > $1F THEN
GOSUB DispChar
ENDIF
LOOP WHILE CharData > $1F
IF SwPos > 0 AND DataAddr < 44 THEN
LET CharData = "="
GOSUB DispChar
ENDIF
RETURN
DispField: 'Displays the field at SPAddr at CharData until a ",".
GOSUB DispCmd
LET Index = SPAddr
DO
GET Index,CharData
INC Index
IF CharData > "," THEN
GOSUB DispChar
ENDIF
LOOP WHILE CharData > ","
RETURN
rem Group A
BacklightControl:
HIGH 7
IF Pin2 = 0 THEN 'ENT pushbutton Turn on backlight
IF SwPos < 5 THEN
HIGH Portc 5
LET BacklightFlag = 1
ELSE 'Cycle through the parameters
PEEK 90, CharData
LET Index = 9 + SettingIndex
WRITE Index,CharData
IF SettingIndex >= 2 THEN
LET SettingIndex = 0
ELSE
INC SettingIndex
ENDIF
LET Index = 9 + SettingIndex
READ Index,CharData
POKE 90, CharData
DO
PAUSE 1
LOOP UNTIL Pin2 = 1
ENDIF
ENDIF
IF Pin3 = 0 THEN 'CLR Poshbutton Turn off backlight
IF SwPos < 5 THEN
LOW Portc 5
LET BacklightFlag = 0
LET Pending = 0
ELSE
IF SettingIndex >= 2 THEN
LET SettingIndex = 0
ELSE
INC SettingIndex
ENDIF
LET Index = 9 + SettingIndex
READ Index,CharData
POKE 90, CharData
DO
PAUSE 1
LOOP UNTIL Pin3 = 1
ENDIF
ENDIF
rem The backlight turns off in less than 2 minutes
IF Seconds < 5 AND BacklightFlag = 1 THEN
LET Pending = 1
ENDIF
IF Seconds > 50 AND Pending = 1 AND SwPos < 5 THEN
LOW Portc 5
LET Pending = 0
LET BacklightFlag = 0
ENDIF
RETURN
DispCmd: 'Puts a command into the display
LOW portc 6 'instruction function is low,
LET outpins = ScreenLoc
IF ScreenLoc < $80 THEN 'It seems necessary to make sure bit 7 is set correctly
LOW 7
ELSE
HIGH 7
ENDIF
HIGH portc 7 'clocks the instruction and the function into the display
LOW portc 7
RETURN
DispChar: 'writes CharData to the display
HIGH portc 6 'data function is high
LET outpins = CharData
HIGH portc 7 'clocks the character into the display
LOW portc 7
RETURN
TxWeather: '53 chars + w, and 10, 13
LET TxFlag = 1
LET GateFlag = GateEvent
LET ptr = 85
SETFREQ K500
SERTXD (0) 'Makes a positive pulse
SETFREQ M8
PAUSE 12
rem scratchpad locations
rem 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
SERTXD ("n",",",@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptr)
GOSUB TxDigital
SERTXD (13,10)
LET TxFlag = 0
LET GateFlag = 0
LET GateEvent = 0
RETURN
TxEvent:
LET TxFlag = 1
SETFREQ K500
SERTXD (0) 'Makes a positive pulse
SETFREQ M8
PAUSE 12
SERTXD ("o")
GOSUB TxDigital
SERTXD (",")
rem Add the string for the changed event
LET Temp = OldEvents ^ b1 'Will have a 1 bit for each changed event
LET Index = NCD Temp - 1 'Identifies the changed event (0 = patio flag)
LET DataAddr = 47
LOOKUP Index, (18,12,51,56,44,47),DataAddr
LET Index = DataAddr
DO
READ Index,CharData
IF CharData > $1F THEN
SERTXD (CharData)
ENDIF
INC Index
LOOP WHILE CharData > $1F
SERTXD (13,10)
LET TxFlag = 0
RETURN
TxHeading:
LET TxFlag = 1
SETFREQ K500
SERTXD (0) 'Makes a positive pulse
SETFREQ M8
PAUSE 12
SERTXD ("n,STemp,SHum,MA,Batt,PTemp,PHum,PLight,BLight,GTemp,GLight,EXT,Spa,IR,Line,Gate,PF,BF",13,10)
LET TxFlag = 0
RETURN
interrupt:
IF Pin0 = 1 THEN 'Receiver interrupt, from hardware integrate and dump circuit
LET I_Tmp = 0
DO WHILE Pin0 = 1 AND I_Tmp < 28 'Noise interrupts are nearly always shorter
LET I_Tmp = I_Tmp + 1 'Twice as fast as INC Usual count is 15
LOOP
rem Avoid messing up ptr and bad copy if messages are too close together
IF I_Tmp < 8 OR tMesgFlag = 1 OR sMesgFlag = 1 OR TxFlag = 1 THEN EndInterrupt 'Minimises the time to recover from a noise interrupt
LET ptr=0
PUT 0,"z"
PUT 2,0
rem 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
SERIN [40,timeout],5,N2400_8,("14L1776"),@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc
GOTO EndInterrupt 'A long message from an intefering device
timeout:
GET 0,Key_Code
IF Key_Code = "z" THEN
LET ptr = 0
GOTO EndInterrupt
ENDIF
GET 2,I_tmp
IF I_tmp < 61 OR I_tmp > 110 THEN NoChecksum 'Can be a message, get the checksum
LET ChckSum = 0
LET ChckHex = I_tmp - 57 'Address of the last message byte
FOR I_tmp = 4 TO ChckHex
LET ptr = I_tmp
LET I_Char = @ptr
LET ChckSum = ChckSum + I_Char
LET ptr = I_tmp - 2 'Move message back for compatinility
LET @ptr = I_Char
NEXT
LET I_tmp = ChckHex - 1
PUT I_tmp,13,10 'Replace comma with newline
LET ptr = ChckHex + 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_Char = @ptrinc 'first Checksum character
IF ChckHex <> I_Char THEN EndInterrupt
LET ChckHex = ChckSum & $F
IF ChckHex < 10 THEN
LET ChckHex = Chckhex + "0"
ELSE
LET ChckHex = ChckHex + "7"
ENDIF
LET I_Char = @ptr
IF ChckHex <> I_Char THEN EndInterrupt
LET ptr = 0 'To enable recording on different filenames 3/30/2021
NoChecksum:
GET 0,Key_Code
SELECT Key_Code
CASE "t"
LET tMesgFlag = 1
IF Seconds > 1 AND Seconds < 58 THEN 'Synchronize
LET Seconds = 0
ENDIF
CASE "s"
LET sMesgFlag = 1
CASE "Q"
LET GateFlag = 1
LET GateEvent = 1
CASE "B"
LET GateFlag = 0
ELSE ;Re-transmit the message
SETFREQ K500
SERTXD (0) 'Makes a positive pulse
SETFREQ M8
PAUSE 12
DO
LET I_tmp = @ptrinc
LET I_tmp = I_tmp & $7F
SERTXD(I_tmp)
LOOP WHILE I_tmp > 10
ENDSELECT
LET Key_Code = "z"
ELSE 'An encoder 1ms interupt
IF SwPos = 5 THEN
PEEK 90,I_tmp
IF Portc Pin3 = 0 THEN 'Direction
INC I_tmp
ELSE
DEC I_tmp
ENDIF
POKE 90,I_tmp
ELSE
HIGH Portc 5 'Turn on backlight
LET BacklightFlag = 1
ENDIF
ENDIF
EndInterrupt:
SETINT OR %01000001,%01000001 'Re-enable the encoder and receiver interrupts again
RETURN