DAU Transmitter Controller  Picaxe Basic Program

Declarations and Data

#rem DAU Controller.bas

This used to be the Environmental Monitor in 2006, but this chore is now taken over by Weather Logging System 

It now is a system of 3 units for transmitting measurements: Controller ("CON"),Battery Box ("Box"), and Probe 

The controller bax, and its regulators, audio amplifier, and analog circuits date back to 2006.

The Battery box replaces the BreakOut Box,which still exists and is compatible.

Alternativly the battery box has only some of the boB bpx onputs, but ads a battery

The D9P connector on the back of the controller is for the probe which has two cables

One has banana jacks for the+/- 15V input and for the +/- 500 mv floating input, with a switched 10 ohm shunt.

The other has a terminal strip for the relay and the mosfet.

Curent draw is 250 MA with backlight on, 90 off.

John Saunders 6/13/2021

#endrem


#picaxe 40X2

#rem

40X2 resources: bits 0-31, bytes 0 - 55, words 0 - 27

SRAM 56-255, can use @bptr. Scratchpad 0-1023, can use @ptr

EEPROM 0-255

pinsA,pinsB,pinsC,pinsD, 21 ADC. DS1307 RTC 8 - 63

SETFREQ k31, k250, k500,m1, m2, m4, m8;external em16, em32,em40

#endrem


rem --------------------------------- CONSTANTS ----------------------------------------


symbol NomRef        = 244

symbol RedZero        = 1500

symbol VioletZero        = 5065


symbol MaxSetupIndex    = 12

symbol MaxAnalogIndex    = 8


symbol AnalogStartAddr    = 70

symbol TxBufStartAddr    = 20


#rem

SRAM memory usage:

56-64 Indices for selected analog fields to transmit for a current message

54 bytes starting at AnalogStartAddr to store analog values converted to ASCII with commas

2 bytes before AnalogStartAddr to store a digital value in ASCII plus a comma


Scratchpad memory usage:

0-17 to store accumulated binary analog measurements 

32 bytes starting at TxBufStartAddr to store the current message being transmitted


Tables in EEPROM:

MaxAnalogIndex + 1 rows of 5 columns starting at AnalogTableAddr indexed by Analog Index

This is used both to measure analog values and to display them

The index also is used to locate fields in the ASCII analog area at AnalogStartAddr


MaxSetupIndex + 1 rows of 4 columns starting at RTCListStartAddr indexed by SetupIndex

This is used to display and modify time, date, and user preferences stored in the RTC

#endrem


rem --------------------------------- PORTS ----------------------------------------

rem Inputs

symbol Sig_Port    = C.5        'Serial Input from pin 2 of the Battery Box DA9P

symbol SwitchMux  = pinB.7    'Output of a 8:1 digital mux controlled by D.0, D.1, D.2

symbol Pin9       = pinB.6    



rem outputs

symbol Backlight    = C.0        'The backlight is controlled by a MOSFET to reduce power consumption

symbol RelayDir    = D.0        'HIGH connects DA9P pin 5 TO 9. HIGH pin5 to pin4

symbol RelayEn    = B.5        'This relay needs only neg-going pulses since it is bi-stable

symbol MOSFET    = B.4        'Low turns this MOSFET on. Its source can be up to 8V.

symbol Beep        = B.0

symbol GreenLED   = C.6        'Green LED, also transmitter signal

symbol RedLED    = C.7        'Red LED


rem --------------------------------- HARDWARE VARIABLES ----------------------------------------


symbol Switches    = b0        

symbol SETUPSW    = bit0    'Left switch is 0 up. The other 2 are momentary, center 1

symbol LESSSW    = bit1    'Switches make is 0. Middle switch down

symbol MORESW    = bit2    'Middle switch up

symbol PREVSW    = bit3    'Right switch down

symbol NEXTSW    = bit4    'Right switch up

symbol DOWNSW     = bit5    '0 is 40 range on yellow

symbol UPSW     = bit6    '0 is 5V range on yellow    

symbol COAXSW    = bit7    'Pin 6 on the Battery Box D-9 connector

symbol OldSecond  = bit8

symbol OLDSETUPSW    = bit16    'This is a SPDT, 1=Run.the others are momentary, center off

symbol BothCenter    = bit17    'Momentary switcjes centered

symbol SwAction    = bit18    'At least one momentary switch is closed

symbol RTCDataLSB = bit19

symbol Seconds    = b3        'Also bit24 - bit31

symbol SecondLSB  = bit24    'Part of Seconds


rem --------------------------------- DEDICATED VARIABLES ----------------------------------------


rem dedicated global


symbol Msg0TxEn        = bit10    '1 lets controller message transmit

symbol Msg1TxEn        = bit11    '1 lets box anog message transmit

symbol Msg2TxEn         = bit12    '1 lets controller message transmit


symbol SetupIndex        = b5        'The item in Setup to edit. Changed in SetupControl

symbol Page           = b6        '0=setting,1=Controller message,2=Box Analogs message,3=Probe message

symbol AnalogIndex    = b8        'Index into entries in the table starting at AnalogListStartAddr    

symbol RTCTableIndex    = b9        'Index into entries in the table starting at RTCListStartAddr

symbol MessageID        = b10        '0=Controller,1=Box,2=Probe. 

symbol MinSetupIndex    = b11        'Controls modifying time/date


rem dedicated gobal counters


symbol BLCount    = b17        'Countdown to backlight off, any switch tuns it back on, setup address 8

symbol Msg0Count     = b18        'Interval between controller message transmissions in 30-second units

symbol Msg1Count    = b19        'Interval between battery box message transmissions in 30-second units    

symbol Msg2Count    = b20        'Interval between probe message transmissions in 30-second units


rem --------------------------------- COUNTER AND General VARIABLES ----------------------------------------


symbol Iter        = b25        'Top level iteration

symbol Indx        = b26        'Second level iteration

symbol Scratch    = b27        'Use only in math. No GOSUBs while it contains valid data


rem --------------------------------- TOP-LEVEL SUBPROGRAM VARIABLES ----------------------------------------


rem general variables containing data

symbol TlVar1     = b30        'Multi-use variable for sunbroutines, mainly iteration

symbol TlVar2     = b31        'Multi-use variable for sunbroutines, mainly iteration

symbol TlVar3     = b32        'Multi-use variable for sunbroutines, mainly iteration

symbol TlVar4    = b33

symbol DecData    = b34        'Multi-use byte variable

symbol AccumulatorVal    = w27        'Multi-use word variable

symbol AnalogVal  = w26        'Analog measurement of the 1.2V reference diode


rem --------------------------------- SECOND-LEVEL SUBPROGRAM VARIABLES ----------------------------------------


symbol MlVar1     = b35        'Multi-use variable for sunbroutines, mainly iteration

symbol MlVar2     = b36        'Multi-use variable for sunbroutines, mainly iteration

symbol MlVar3     = b37        'Multi-use variable for sunbroutines, mainly iteration



rem --------------------------------- TRANSFER VARIABLES ----------------------------------------


rem addressing

symbol DispAddr   = b40        'A cursor position ot a LCD controller command

symbol RTCAddr    = b41        'An RTC address

symbol DataAddr    = b42        'Used to address an item in EEPROM

symbol ScratchAddr = b43        'An address in the scratchpad


rem contains information

symbol NewPage    = bit14

symbol MinusFlag    = bit15

symbol RTCData     = b44

symbol CharData    = b46        'Multi-use byte variable especially for ASCII data, subroutine transfer

symbol RefVal    = w25        'Value of the 1.2V reference diode in the battery Box


rem --------------------------------- EEPROM ----------------------------------------



DATA   0,($30,$30,$30,$38,$0C,$01,$06,$14,$80,0)'Display Init strings


rem RTC Variables for display and adjustment, ordered by RTC address

rem Type: 0=character, 1 = BCD, 2=Day string index, 3 = Delay Index (multiple of 30)

symbol RTCListStartAddr = 10     

rem    Location  Type    Minimum  Maximum

DATA 10,($83,     1,        0,       59)        '1-Minutes          

DATA 14,($80,     4,        0,       59)        '2-Hours          

DATA 18,($86,     2,        1,       7)        '3-Day of week         

DATA 22,($8d,     1,        1,       31)        '4-Date 

DATA 26,($8a,     1,        1,       12)        '5-Month          

DATA 30,($92,     1,        0,       99)        '6-Year

DATA 34,($e5,     3,        1,        8)        '8-Backlight Delay, multiplies of 30       

DATA 38,($cc,     0,      "q",      "z")        '9-Controller message key code

DATA 42,($c6,     3,        1,        8)        '10-Controller message interval      

DATA 46,($a0,     0,      "q",      "z")        '11-Box message key code  

DATA 50,($9a,     3,        1,        8)        '12-Box message interval

DATA 54,($e0,     0,      "q",      "z")        '13-Probe message key code

DATA 58,($da,     3,        1,        8)        '14-Probe message interval


rem day and month strings

symbol DayStringAddr = 59        'Sun is 1

DATA 62,("SUNMONTUEWEDTHUFRISAT")


rem Controller Analog page strings and locations

DATA 83,($c1,"SUPPLY")    

DATA 90,($94,"BATTERY")    

DATA 98,($84,"GRN")        


rem Box Analog page strings and locations (AnalogID 10 is 1.2V ref)

DATA 102,($80,"YEL")        

DATA 106,($8a,"BLU")    

DATA 110,($94,"Pin4")        

DATA 115,($c0,"COAX")        


rem Probe Analog page strings  and locations

DATA 120,($c3,"RED")        

DATA 124,($94,"VIOLET")        


symbol DigitalAddr = $a6

DATA 131,($a0,"Pin9")        'Digital input


rem Setup page strings

DATA 136,($d5,"MSG2")

DATA 141,($c1,"MSG0")

DATA 146,($95,"MCG1",$80)


DATA 159,($e2,"BL")

DATA 162,($ca,"K")

DATA 164,($9e,"K")

DATA 166,($de,"K")

DATA 168,($d4,"Message ",$80)


rem analog calculation constants in order of AnalogID.

rem id 0-3 use ground loop correction from the 1.2V reference diode on A.3

symbol AnalogTableAddr = 180

rem       ADC Channel Multiply Divide Decimal Point Location   

DATA 180,(   1,         3,        2,     2,           $84)      '0-Yellow,15V default. UPSW0:5V,D=6.DP=1. DOWNSW0:40V,M=8.D=1 

DATA 185,(   7,         6,        4,     2,           $8e)        '1-Blue 15V

DATA 190,(   5,        10,        2,     1,           $99)      '2-Pin4      

DATA 195,(   2,        10,        2,     1,           $c5)      '3-Coax:5V 

DATA 200,(  10,         6,        4,     2,           $c8)      '4-12 V main power, 0-15V  

DATA 205,(   0,         6,        4,     2,           $9c)      '5-Battery 16V

DATA 210,(   9,         5,        2,     2,           $88)        '6-Green 25V    

DATA 215,(   6,         6,        6,     2,           $c7)        '7-Red: +/- 15V gain = 1/6 subtract ProbeZero

DATA 220,(   8,        10,        1,     3,           $9b)      '8-Violet: +/- 0.5V, gain 5, subtract VioletZero


symbol SetupFixedListAddr = 225

DATA 225,(141,162,146,164,136,166,159,0)

symbol Page0FixedListAddr = 233

DATA 233,(98,83,90,168,0)

symbol Page1FixedListAddr = 238

DATA 238,(102,106,115,110,131,168,0)

symbol Page2FixedListAddr = 245

DATA 245,(98,120,124,168,0)


rem 1.2V ref is channel 3


#rem RTC storage

Addresses  1 - 6 per DS1307 spec

Address      8         9         10      11      12      13      14           

Content  Backlight,Con Key,Con Int,Box Key,Box Int,Probe Key,Probe Int)

Address      16        17             18  - 23           

Content  Msg0 number, Digital     Message 0 indices    

Address      24        25             26  - 31           

Content  Msg1 number, Digital     Message 1 indices    

Address      32        33             34  - 47               

Content  Msg2 number, Digital     Message 2 indices    


#endrem

symbol BLDelayAddr = 8

symbol Msg0IKeyAddr = 9

symbol Msg0IntAddr = 10

symbol Msg1IKeyAddr = 11

symbol Msg1IntAddr = 12

symbol Msg2IKeyAddr = 13

symbol Msg2IntAddr = 14

Init and Main


rem --------------------------------- INIT & MAIN ----------------------------------------


init:

SETFREQ m8

lET ADCsetup = %0000011111101111

LET DirsB = %00110001

LET DirsC = %00011111

LET DirsD = $FF

HIGH MOSFET            'MOSFET off

HIGH Backlight        'Backlight on

HI2CSETUP I2Cmaster, %11010000, i2cslow_8, i2cbyte

PAUSE 1

'Hi2COUT 0,(0)        'Ensure RTC starts

Hi2cIN Msg0IntAddr,(Msg0Count)

Hi2cIN Msg1IntAddr,(Msg1Count)

Hi2cIN Msg2IntAddr,(Msg2Count)

Hi2cIN BLDelayAddr,(BLCount)

LET Msg0TxEn = 0

Hi2cIN Msg0IntAddr,(Msg0Count)

LET Msg1TxEn = 0

Hi2cIN Msg1IntAddr,(Msg1Count)

LET Msg2TxEn = 0

Hi2cIN Msg2IntAddr,(Msg2Count)

GOSUB GetSwitches

IF SETUPSW = 1 AND LESSSW = 0 THEN            'Allow time/Date modification

    LET MinSetupIndex = 0

    LET SetupIndex = 1

ELSE

    LET MinSetupIndex = 6

    LET SetupIndex = 6

ENDIF

IF SETUPSW = 1 AND MORESW = 0 THEN            'Load the RTC with default values

rem               BL 0key 0rate 1key 1rate 2key 2rate

    Hi2COUT 8 ,( 4, "x",  4,   "y",  2,   "w",  3)

rem             #flds  #digs      field locations

    Hi2COUT 16,(3,     0   ,       4,5,6)

    Hi2COUT 24,(6,     2,        5,0,1,2,3,6)

    Hi2COUT 32,(3,     0,           6,7,8)

ENDIF


LET SwAction = 1

LET BothCenter = 1

LET NewPage = 1

LOW C.2            'Idle level for display enable

HIGH RelayEn        'Idle level for Relay Enable

LOW RedLED

LOW GreenLED


rem Initialize Display

LET iter = 0

DO

    READ Iter,DispAddr

    IF DispAddr = 0 THEN Exit

    GOSUB DispCmd

    PAUSE 4

    INC Iter

LOOP

PAUSE 1

LET Page = 2


main:

rem ------------------ Main loop Operations ---------------------------------

rem ------------------------------ Switch-controlled operations -------------


GOSUB GetSwitches

LET Scratch = Switches & $1e

IF Scratch = $1e AND SwAction = 0 THEN

    LET BothCenter = 1

ENDIF

IF Scratch < $1e THEN

    LET SwAction = 1

    Hi2CIN BLDelayAddr,(BLCount)

    HIGH Backlight

ENDIF


IF BothCenter = 1 AND SwAction = 1 THEN  

    IF SETUPSW = 0 THEN

        GOSUB SetupControl

    ELSE

        GOSUB PageControl

    ENDIF

    GOSUB RefreshDisplay

    PAUSE 100

    LET SwAction = 0

ENDIF


IF SETUPSW <> OLDSETUPSW THEN

    GOSUB RefreshDisplay

    LET OLDSETUPSW = SETUPSW

ENDIF


rem ----------------------- Per-Second Operations -------------

Hi2cIN 0,(RTCData)        ;Seconds

LET RTCDataLSB = RTCData & $01

IF RTCDataLSB <> OldSecond THEN    'Per-second processing 

    LET OldSecond = RTCDataLSB

    INC Seconds

    IF Seconds> 29 THEN

        LET Seconds = 0

    ENDIF

    SELECT Seconds 

        CASE 15

            LET Scratch = "A"

            'GOSUB CommandTest

        CASE 22

            LET Scratch = "H"

            'GOSUB CommandTest

        CASE 24

            GOSUB RefreshDisplay    

        CASE 25

            GOSUB BacklightControl        'Dim backlight if delay has expired

        CASE 17

            LET MessageID = 0

            GOSUB TransmitControl

        CASE 20

            LET MessageID = 1

            GOSUB TransmitControl

        CASE 23

            LET MessageID = 2

            GOSUB TransmitControl

    ENDSELECT

    GOSUB GetAnalogs

    GOSUB GetDigital

ENDIF


GOTO Main

Sub-programs

rem ---------------------------- PROGRAM CONTROL SUBPROGRAMS CALLED FROM MAIN ----------------------------------------


RefreshDisplay:

LET DispAddr = $01

GOSUB DispCmd    

PAUSE 4

Hi2CIN BLDelayAddr,(BLCount)

HIGH Backlight

GOSUB DispPageFixed

IF SETUPSW = 0  THEN

    FOR RTCTableIndex = 0 TO MaxSetupIndex

        GOSUB DispRTCVal

    NEXT

    GOSUB DispPunct

ELSE

    GOSUB DispMeasurements

ENDIF    

RETURN


TransmitControl:    'Input is MessageID and asociated counts 

IF SETUPSW = 0 THEN

    RETURN

ENDIF

SELECT MessageID

    CASE 0

        IF Msg0Count > 0 THEN

            DEC Msg0Count

        ENDIF

        IF Msg0Count = 0 THEN

            IF Msg0TxEn = 1 THEN

                GOSUB Transmit

            ENDIF

            Hi2cIN Msg0IntAddr,(Msg0Count)

        ENDIF        

    CASE 1

        IF Msg1Count = 0 THEN

            DEC Msg1Count

        ENDIF

        IF Msg1Count > 0 THEN

            IF Msg1TxEn = 1 THEN

                GOSUB Transmit

            ENDIF

            Hi2cIN Msg1IntAddr,(Msg1Count)

        ENDIF        

    CASE 2

        IF Msg2Count = 0 THEN

            DEC Msg2Count

        ENDIF

        IF Msg2Count > 0 THEN

            IF Msg2TxEn = 1 THEN

                GOSUB Transmit

            ENDIF

            Hi2cIN Msg2IntAddr,(Msg2Count)

        ENDIF        


ENDSELECT

RETURN


BacklightControl:                'Input is BLCount

IF BLCount > 0 THEN

    DEC BLCount

ENDIF

IF BLCount = 0 THEN

    LOW Backlight

ENDIF

RETURN


PageControl:                'Input is switches and Page

rem any key press turns on the backlight


IF NEXTSW = 0  THEN        'Right switch RESET in RUN        '

    IF Page < 2 THEN

        INC Page

    ELSE

        LET Page = 0

    ENDIF

    LET NewPage = 1

ENDIF

IF PREVSW = 0 THEN        'Right switch ENTER in RUN

    IF Page > 1 THEN

        DEC Page

    ELSE

        LET Page = 2

    ENDIF

    LET NewPage = 1

ENDIF

IF MORESW = 0  OR LESSSW = 0    THEN    'Middle switch changes pages 1,2,3

    GOSUB GetTx    

ENDIF

RETURN


SetupControl:            'Input is switches and SetupIndex

rem any key press turns on the backlight

IF MORESW = 0  OR LESSSW = 0 THEN        'Middle switch MORE in page SETUP

    GOSUB Setup    

ENDIF

IF NEXTSW = 0  THEN        'Right switch RESET in SETUP page

    IF SetupIndex < MaxSetupIndex THEN

        INC SetupIndex

    ELSE

        LET SetupIndex = MinSetupIndex

    ENDIF

    LET NewPage = 1

ENDIF

IF PREVSW = 0  THEN        'Right switch ENTER in SETUP page

    IF SetupIndex > MinSetupIndex THEN

        DEC SetupIndex

    ELSE

        LET SetupIndex = MaxSetupIndex

    ENDIF

    LET NewPage = 1

ENDIF

RETURN


rem ---------------------------- MEASUREMENT SUBPROGRAMS CALLED FROM MAIN ----------------------------------------


symbol SwitchMask = TlVar1


GetSwitches:                'Input is switches. Relies on b0 overlays bit0 - bit7

LET Switches = 0

LET SwitchMask = 1

FOR Iter = 0 TO 7            

    LET OutpinsD = iter        'D pins also used for the LCD

    IF SwitchMux = 1 THEN

        LET Switches = Switches | SwitchMask

    ENDIF

    LET SwitchMask = 2 * SwitchMask

NEXT

RETURN


GetDigital:                    ;This originates in the Battery Box

LET bptr = AnalogStartAddr - 2

LET CharData = Pin9 + "0"

LET @bptrinc = CharData

LET CharData = ","

LET @bptr = CharData

RETURN


symbol Channel = TlVar1

symbol Multiply = TlVar2

symbol Divide = TlVar3

symbol DPLoc = TlVar4


GetAnalogs:

#rem

The processor has 9 active ADC ports. The signals for all pass through amplifiers, attenuators, and filters

which were made in 2006 for a fifferent application and have not been changed since.

However, the Battery Box contains additional circuitry in series.

The output of this sebprogram is measurements in engineering units.

Since Picaxe Basic does not do either floating point or negative values,

the ADC is designed to provide an exact 5 mv per count by designing the processor regulator to provide 5.12V

Measuring and displaying analog values therefore requires integer mathematics

including multiplication, division, and subtraction. These constants are provided in a table in EEPROM 

starting at.AnalogTableAddr, which has and is indexed by AnalogIndex and has 5 columns.

The values take into account the analog circuits, and for yellow, swith-controlled attenuation.

#endrem


rem Zero the accumulators in scratchpad starting at 0 if LoopCount = 0

rem alse measure the 1.2V reference diode for ground loop correction

IF Seconds = 29 THEN

    FOR Iter = 0 TO 35

        PUT Iter,0

    NEXT            

    READADC10 3,RefVal

'    SERTXD ("Ref=",#RefVal,13,10)

ENDIF


Rem Perform multiplication by measuring each analog multiple times and accumulate


FOR AnalogIndex = 0 TO 8                'Nine analogs

    LET ScratchAddr = 2 * AnalogIndex

    LET DataAddr = 5 * AnalogIndex + AnalogTableAddr

    READ DataAddr,Channel,Multiply,Divide,DPLoc

rem The table values for the analog channel are for the middle switch position

    IF AnalogIndex = 0 THEN

        IF DOWNSW = 0 THEN                'Yellow 40V range

            LET Multiply = 10

        ENDIF

        IF UPSW = 0 THEN            'Yellow 5V range

            LET Multiply = 10

            LET DpLoc = 1

        ENDIF

    ENDIF

    IF Seconds < Multiply THEN

        READADC10 Channel,AnalogVal

        IF AnalogIndex < 4 THEN        'Make ground loop correction

            LET AnalogVal = AnalogVal + NomRef

            IF AnalogVal > RefVal THEN            'Add a correction

                LET AnalogVal = AnalogVal - RefVal

            ELSE

                LET AnalogVal = 0

            ENDIF

        ENDIF            

        GET ScratchAddr, WORD AccumulatorVal

        LET AnalogVal = AnalogVal + AccumulatorVal

        PUT ScratchAddr, WORD AnalogVal

    ENDIF 

    

    IF Seconds = 14 THEN                        'Do division     

        GET ScratchAddr, WORD AnalogVal

        LET AnalogVal = AnalogVal / Divide

        LET MinusFlag = 0

        IF AnalogIndex = 7 THEN                    'Red jack in probe

            IF AnalogVal >= RedZero THEN

                LET AnalogVal = AnalogVal - RedZero

            ELSE

                LET AnalogVal = RedZero - AnalogVal

                LET MinusFlag = 1

            ENDIF 

        ENDIF

        IF AnalogIndex = 8 THEN                    'Violet jack in probe

            IF AnalogVal >= VioletZero THEN

                LET AnalogVal = AnalogVal - VioletZero

            ELSE

                LET AnalogVal = VioletZero - AnalogVal

                LET MinusFlag = 1

            ENDIF 

        ENDIF


rem Convert an analog binary to ASCII with decimal point in ordered location in RAM

rem Value to be converted is AnalogVal, Identified by AnalogID

rem Character for the decimal point is denoted by DpLoc

        

        IF MinusFlag = 1 THEN            'Have to make do with one digit less precision

            LET AnalogVal = AnalogVal / 10

        ENDIF                        '4 significant digits, plus decimal point and a comma

        LET bptr = 6 * AnalogIndex + AnalogStartAddr    

        LET DECData  = AnalogVal/1000        'Digit #1

        IF MinusFlag = 1 THEN

            LET @bptrinc = "-"            'Digit 1 minus

        ELSE

            LET DECData  = DECData + "0"        'Ascii

            LET @bptrinc = DECData            'Digit 1 Pos

        ENDIF

        IF DpLoc = 1 THEN

            LET @bptrinc = "."            'Digit 2 if period

        ENDIF

        LET AccumulatorVal  = AnalogVal//1000        'AccumulatorVal for digit #1

        LET DECData  = AccumulatorVal/100        

        LET DECData  = DECData + "0"        'Ascii

        LET @bptrinc = DECData                'Digit #2 w/o period else digit 3    

        IF DpLoc = 2 THEN

            LET @bptrinc = "."            'Digit 3 if period

        ENDIF        

        LET AnalogVal  = AccumulatorVal//100        'AccumulatorVal for digit #2

        LET DECData  = AnalogVal/10        

        LET DECData  = DECData + "0"        'Ascii

        LET @bptrinc = DECData                'Digit #3 w/o period else digit 4        

        IF DpLoc = 3 THEN

            LET @bptrinc = "."            'Digit 4 if period

        ENDIF

        LET DecData  = AnalogVal //10        'Least significant digit

        LET DecData  = DecData + "0"        'Ascii

        LET @bptrinc = DecData                'Digit #4 w/o period else digit 5

        IF DpLoc = 0 OR DpLoc > 3 THEN

            LET @bptrinc = " "            'Digit 5 if no period

        ENDIF          

        LET @bptrinc = ","                'Digit 6

    ENDIF

NEXT

RETURN


GetTx:                'Input is Page and switches

SELECT Page

CASE 0

    IF MORESW = 0 THEN

        LET Msg0TxEn = 1

    ENDIF

    IF LESSSW = 0 THEN

        LET Msg0TxEn = 0

    ENDIF

CASE 1

    IF MORESW = 0 THEN

        LET Msg1TxEn = 1

    ENDIF

    IF LESSSW = 0 THEN

        LET Msg1TxEn = 0

    ENDIF

CASE 2

    IF MORESW = 0 THEN

        LET Msg2TxEn = 1

    ENDIF

    IF LESSSW = 0 THEN

        LET Msg2TxEn = 0

    ENDIF

ENDSELECT

RETURN


rem --------------------------- PAGE DISPLAY SUBPROGRAMS CALLED FROM MAIN -----------------------



symbol StringEntryAddr = TlVar1

symbol StringListAddr = TlVar2


DispPagefixed:                     'Input is page

rem Contents are in 4 lists which list addresses of strings per Page

rem These strings are in EEPROM

IF SETUPSW = 0 THEN

    LET StringListAddr = SetupFixedListAddr

ELSE

    LOOKUP Page,(Page0FixedListAddr,Page1FixedListAddr,Page2FixedListAddr),StringListAddr

ENDIF

LET Iter = 0

DO

    LET StringEntryAddr = StringListAddr + Iter        'Start of a fixed string

    READ StringEntryAddr,DataAddr

    IF DataAddr > 0 THEN

        GOSUB DispStr        

    ENDIF

    INC Iter

LOOP UNTIL DataAddr = 0

IF SETUPSW = 1 THEN

    LET DispAddr = $dd

    GOSUB DispCmd

    LET Chardata = Page + "0"

    GOSUB DispChar

    LET CharData = " "

    GOSUB DispChar

    LET CharData = "O"

    GOSUB DispChar

ENDIF

RETURN


symbol DispCode = TlVar1

symbol BlinkAddr = TlVar2


DispRTCVal:                'Displays the content of the input RTCTableIndex of the table starting at RTCListStartAddr

rem This table has a row for each RTC active address, including time (less seconds), date, and saved user preferences

rem It has 4 columns, of which only 2 are needed for this subprogram

LET DataAddr = 4 * RTCTableIndex + RTCListStartAddr

READ DataAddr,DispAddr,DispCode


LET BlinkAddr = DispAddr

GOSUB DispCmd

IF RTCTableIndex < 6 THEN

    LET RTCAddr = RTCTableIndex + 1        'Time and date less seconds

ELSE

    LET RTCAddr = RTCTableIndex + 2        'Preferences, skip over 7

ENDIF

Hi2CIN RTCAddr,(CharData)

'SERTXD ("Index=",#RTCTableIndex,",DispAddr=",#DispAddr,",Data=",#charData,13,10)


SELECT DispCode

    CASE 0            'A character

        GOSUB DispChar

    CASE 1            'A BCD value            '

        GOSUB DispBCD

    CASE 2            'Day of week

        GOSUB DispDOW

    CASE 3            'A time delay index

        GOSUB DispDelay    

    CASE 4            'Hour

        LET CharData = CharData & $3f

        GOSUB DispBCD

ENDSELECT

PAUSE 1

IF SetupIndex = RTCTableIndex AND SETUPSW = 0 AND SecondLSB = 0 THEN    

    LET DispAddr = BlinkAddr

    GOSUB DispCmd

    LET CharData = " "

    GOSUB DispChar

ENDIF

RETURN


symbol FirstIndex = TlVar1

symbol LastIndex = TlVar2


DispMeasurements:            'Input is page which defines the                        

#rem AnalogIndex range which points to the values provided in a table in EEPROM 

starting at.AnalogTableAddr, which is indexed by AnalogIndex and has 5 columns,

The last column provides the screen address for the value which is in scratchpad

This is also the index for screen location in the table starting at AnalogStartAddr

It also provides the scratchadpad loation where the data resides.

#endrem

LOOKUP Page,(4,0,6),FirstIndex            'AnalogIndex for first value to be displayed            '

LOOKUP Page,(6,3,8),LastIndex                'AnalogIndex for last value to be displayed

FOR AnalogIndex = FirstIndex TO LastIndex    

    LET bptr = 6 * AnalogIndex + AnalogStartAddr

    LET DataAddr = 5 * AnalogIndex + AnalogTableAddr + 4

    READ DataAddr,DispAddr

    GOSUB DispCmd

    FOR Iter = 0 TO 4

        LET CharData = @bptrinc

        GOSUB DispChar

    NEXT

NEXT                    

LET DispAddr = $e0                'The transmit enable flaf display location

GOSUB DispCmd                    'All transmit status are on the bottom row

LET Chardata = "F"

SELECT Page

    CASE 0

        LET CharData = 8 * Msg0TxEn + CharData

        LET Scratch = 38 * Msg0TxEn

    CASE 1

        LET CharData = 8 * Msg1TxEn + CharData

        LET Scratch = 38 * Msg1TxEn

    CASE 2    

        LET CharData = 8 * Msg2TxEn + CharData

        LET Scratch = 38 * Msg2TxEn 

ENDSELECT

GOSUB DispChar

LET Chardata = "F" - Scratch

GOSUB DispChar


                'Display the digital measurement

LET DispAddr = DigitalAddr

GOSUB DispCmd

IF Page = 1 THEN    

    LET bptr = AnalogStartAddr - 2

    LET CharData = @bptr

ELSE

    LET CharData = " " 

ENDIF

GOSUB DispChar


RETURN


rem --------------------------------- FIELD DISPLAY PROGRAMS ---------------------------------------- 


symbol CharAddr = MlVar1


DispStr:                'Displays the string in DataAddr

READ DataAddr,DispAddr         'The first entry is the display location

GOSUB DispCmd

LET CharAddr = DataAddr

INC CharAddr

DO

    READ CharAddr,CharData

    IF CharData < "z" THEN

        GOSUB DispChar

    ENDIF

    INC CharAddr

LOOP WHILE CharData < "z" 

IF DataAddr < 168 THEN

    LET CharData = "="

ENDIF

GOSUB DispChar

RETURN


DispDelay:    'Displays a delay index in Chardata, leading zero blanked

rem Index is a multiple of 30

LET CharData = 30 * Chardata

LET Scratch = CharData // 100

LET CharData = CharData / 100 + "0"

GOSUB DispChar

LET CharData = Scratch / 10 + "0"

GOSUB DispChar

LET CharData = Scratch // 10 + "0"

GOSUB DispChar

RETURN


DispBCD:        'Displays a BCD value in CharData

LET Scratch = CharData 

LET CharData = Scratch / 16 + "0"

GOSUB DispChar

LET CharData = Scratch & $0f + "0"

GOSUB DispChar

RETURN


DispDOW:                    'Input is CharData 1-7

LET DataAddr = 3 * CharData + DayStringAddr

FOR Iter = 0 TO 2

    READ DataAddr, Chardata

    GOSUB DispChar

    INC DataAddr

NEXT

RETURN


rem --------------------------------- LCD DISPLAY SUBPROGRAMS ----------------------------------------


DispCmd:          'puts a command into the display from DispAddr

LOW C.1    'Display RS

LET OutpinsD = DispAddr

PULSOUT C.2,2

RETURN



DispChar:                'Writes CharData to the display

HIGH C.1

LET OutpinsD = CharData

PULSOUT C.2,2

RETURN


DispPunct:

FOR indx = 0 TO 6

    LOOKUP indx,($82,$85,$89,$8c,$8f,$90,$91),DispAddr

    GOSUB DispCmd

    LOOKUP indx,(":"," "," ","/","/","2","0"),Chardata

    GOSUB DispChar

NEXT

RETURN


rem --------------------------------- SETUP ----------------------------------------


symbol MinLimit = MlVar1

symbol MaxLimit = MlVar2


Setup:            'Adjusts field pointed to by SetupIndex according to MoreFlag and LessFlag

LET DataAddr = 4 * SetupIndex + RTCListStartAddr + 2

READ DataAddr,MinLimit,MaxLimit

IF SetupIndex < 6 THEN 

    LET RTCAddr = SetupIndex + 1

    Hi2cIN RTCAddr,(RTCData)         'This is BCD, Convert to binary            

    LET Scratch = RTCData & $F0

    LET DecData = Scratch/16

    LET Scratch = RTCData & $0F

    LET DecData = 10*DecData + Scratch

    IF MORESW = 0 THEN

        IF DecData < MaxLimit THEN

            INC DecData

        ELSE

            LET DecData = MinLimit

        ENDIF

    ENDIF

    IF LESSSW = 0 THEN

        IF DecData > MinLimit THEN

            DEC DecData

        ELSE

            LET DecData = MaxLimit

        ENDIF

    ENDIF

    LET Scratch = DecData / 10            'Convert back to BCD

    LET CharData = DecData // 10

    LET RTCData = 16*Scratch + CharData

    Hi2COUT RTCAddr,(RTCData)

ELSE

    LET RTCAddr = SetupIndex + 2

    Hi2cIN RTCAddr,(RTCData)         

    IF MORESW = 0 THEN

        IF RTCData < MaxLimit THEN

            INC RTCData

        ELSE

            LET RTCData = MinLimit

        ENDIF

    ENDIF

    IF LESSSW = 0 THEN

        IF RTCData > MinLimit THEN

            DEC RTCData

        ELSE

            LET RTCData = MaxLimit

        ENDIF

    ENDIF

    Hi2COUT RTCAddr,(RTCData)

ENDIF

    ' SERTXD ("Page=",#page,",SetupIndex=",#SetupIndex,",RTCAddr=",#RTCAddr,",Min=",#MinLimit,",Max=",#MaxLimit,13,10)


RETURN


rem --------------------------------- SERIAL CALLED FROM SETUPCONTROL ----------------------------------------


symbol MessageSize    = TlVar1

symbol CkSum        = TlVar2

symbol DigitalSize    = TlVar3

symbol NumFields        = TlVar4


Transmit:            'Input is MessageID

rem The message is assembled in the scratchpad statrting at 100

rem Get the message content, first the keycode

rem Get the key code from the RTC


LET ptr = TxBufStartAddr

LOOKUP MessageID,(9,11,13),RTCAddr

Hi2cIN RTCAddr,(CharData)

LET @ptrinc = Chardata

LET Chardata = ","

LET @ptrinc = Chardata

rem Get the message content, next the number of analog fields

LOOKUP MessageID,(16,24,32),RTCAddr    'get the number of analog fields

Hi2CIN RTCAddr,(NumFields)

LET MessageSize = 6 * NumFields

rem Add for a digital value

LOOKUP MessageID,(17,25,33),RTCAddr

Hi2CIN RTCAddr,(DigitalSize)

LET MessageSize = MessageSize + DigitalSize - 1        ;The last comma is not included

LET Chardata = MessageSize + 60    'The length code

'SERTXD ("Size Code=",chardata,",") 

LET @ptrinc = Chardata

LET Chardata = ","

LET @ptrinc = Chardata

LET Cksum = 0

rem Get the analog content of the message as a list of AnalogIndex in the RTC

LET DecData = 8 * MessageID + 18 

LET Scratch = NumFields - 1

FOR Iter = 0 TO Scratch

    LET RTCAddr = DecData + Iter

    Hi2CIN RTCAddr, (AnalogIndex)

PAUSE 2

    LET bptr = 6 * AnalogIndex + AnalogStartAddr    'Where the data comes from

'    SERTXD (",Index=",#AnalogIndex,",")

    PAUSE 2    

    FOR Indx = 0 TO 5            'Transfer the selected analog data to the transmit buffer

        LET CharData = @bptrinc

        PAUSE 2

        LET @ptrinc = CharData    

            SERTXD (CharData)    

PAUSE 2

        LET Cksum = Cksum + CharData

    NEXT

NEXT

IF DigitalSize > 0 THEN                        'Add digitals to the end

    LET bptr = AnalogStartAddr - DigitalSize

    FOR Iter = 1 TO DigitalSize

        LET CharData = @bptrinc

        LET @ptrinc = CharData

        LET Cksum = Cksum + CharData

    NEXT

ENDIF

LET Chardata = ","

LET Cksum = Cksum - CharData                    'The last comma should not be included

rem convert the checksum into hex

LET Scratch = Cksum / 16 + "0"

IF Scratch > "9" THEN

    LET Scratch = Scratch + 7

ENDIF

LET @ptrinc = Scratch

LET Cksum = Cksum & $0f + "0"

IF Cksum > "9" THEN

    LET Cksum = Cksum + 7

ENDIF

LET @ptrinc = Cksum

LET @ptrinc = 13

LET @ptrinc = 10

LET @ptrinc = 0


HIGH GreenLED

PAUSE 40

LOW GreenLED

PAUSE 20

SEROUT GreenLED,N2400_8,("14L1776")

LET ptr = TxBufStartAddr

DO UNTIL @ptr = 10

     ' LET CharData = @ptrinc

    ' SEROUT GreenLED,N2400_8,(CharData)

 ' SERTXD (@ptr)

        SEROUT GreenLED,N2400_8,(@ptrinc)

LOOP 

SERTXD (13,10)

RETURN


CommandTest:

HIGH GreenLED

PAUSE 40

LOW GreenLED

PAUSE 20

SEROUT GreenLED,N2400_8,("14L1776",scratch,13,10)

RETURN