Picaxe Program Declarations

#rem PortableReadout.bas

This is for the grey box with the 3" TfT colour display.

The main processor is a Tensy 3.6 which is not always on

Its power is controlled by this Picaxe which is always on at low power.

It has 2 modes "Active" and "Standby"

It is on active if C.3 is high and the battery voltage is above minimum, else Standby

On standby it is mostly napping.

The two processors exchange serial data for these purposes:

1. The Picaxe provide battery voltage measurement in a message.

2. The Arduino sends one message with 2 characters:

    No 1: "D" if on battery, "C" if charging

    No 2: "B" if the SD drive is busy, "R if safe to turn off the Teensy power

The message format is the same both ways.

1. A "<"

2. The message data

3. A ">"    

John Saundes 9/21/2023

#endrem

#picaxe 08M2


symbol txPort    = C.0            'Connecte to Teensy Serial5 via an inverter with 3.3V pullup

symbol convEn    = C.1            'A HIGH powers the Teensy and the receiver

symbol refPort    = C.2            'A 1.2V ref diode indirectly measures the battery voltage

symbol rxPort    = C.4            

symbol contPort    = pinC.3        'Connected to the push-on, push-off button

                        'If this pin is used for an interrupt, the program crashes


rem general vriables

symbol decDP    = b2

symbol decData     = b3

symbol remdr    = b4

symbol temp        = b5

symbol charData    = b6            

symbol battVolt    = w12


rem state machine status flags

symbol contFlag    = bit0        'Same as contPort

symbol msgFlag    = bit1        'A message has beenreceived before msgCount gets to zero

symbol busyFlag    = bit2        'Message received with a "B" due to SD activity in progress

symbol battFlag    = bit3        'Battery Voltage is better than minimum

symbol Status    = b0

symbol prevStatus    = b1

symbol sysState    = b7            'S,B, R, or O


rem global variables

symbol battCount    = b10

symbol loopCount    = b11

symbol msgsCount    = b12

symbol pwrState    = b13

symbol chgVolt    = b14        'first character of the charge voltage in the message received

symbol bootCount    = b15

symbol diag        = b16

symbol bdiag    = b17


symbol rawADC    = w13


'Interrupt Variable

symbol iTemp    = b20

symbol chgStatus    = b21

symbol sdBusy    = b22


rem constants

symbol voltNum        = 63130            'based on reference voltage of 1.233V

symbol minBattVolt    = 395            'ref count for 3.2 V,

symbol outMsgCount    = 30

symbol msgMin        = 150

symbol napTime        = 5

symbol pauseTime        = 800

symbol battMax        = 30    

symbol bootMax        = 4

Picaxe Program Init and Main

init:

OUTPUT convEn

LOW convEn                        'Default off

LET decDP = 2

LET loopCount    = 1

DISABLEBOD

LET sysState = "S"

GOSUB getBattFlag

LET battCount = battMax

LET chgVolt = "0"

LET sdBusy = "N"


main:

LET contFlag = contPort


if battCount > 0 THEN

    DEC battCount

ELSE

    LET battCount = battMax

    GOSUB getBattFlag

ENDIF


IF sysState = "O" OR sysState = "R" THEN

    IF msgsCount > 0 THEN

        DEC msgsCount

    ELSE

        msgFlag = 0

    ENDIF

ENDIF


IF sysState = "O" OR sysState = "B" THEN

    IF bootCount > 0 THEN

        DEC bootCount

    ENDIF

ENDIF




IF sysState = "S" THEN

    LOW convEn

ELSE

    HIGH convEn

ENDIF


IF sysState = "R" THEN

    IF loopCount > 0 THEN

        DEC loopCount

    ELSE

        loopCount = outMsgCount

        GOSUB Transmit;

        

    ENDIF

    SETINT %00010000, %00000000

ELSE

    SETINT OFF

ENDIF


IF sysState = "O" AND bootCount > 2 THEN

    GOSUB Transmit

ENDIF


IF sysState = "B" AND bootCount < 3 THEN

    GOSUB Transmit

ENDIF


IF Status <>  prevStatus OR bootCount = 0 OR loopCount = 0 THEN

    GOSUB CheckStatus    

        

ENDIF


prevStatus = Status

LET diag = b0 + "A"

LET bdiag = bootCount + "0"

IF sysState = "S" THEN

    SETFREQ M16

    SEROUT txPort,N9600_16,("<",diag,"-",bdiag,"-",chgVolt,",",sysState,">",13,10)

    SETFREQ K31

    NAP napTime

ELSE

    SETFREQ M16

    SEROUT txPort,N9600_16,("<",diag,"_",bdiag,"_",chgVolt,",",sysState,">",13,10)

    SETFREQ M4

    PAUSE pauseTime

ENDIF


goto main

Picaxe Program Sub-programs and Interrupt

CheckStatus:

SELECT sysState

    CASE "S"

        IF contFlag = 1 AND battFlag = 1 THEN

            LET bootCount = bootMax

            LET sysState = "B"

        ENDIF

    CASE "B"

        IF bootCount = 0 THEN

            LET sysState = "R"

        ENDIF

    CASE "R"

        'IF contFlag = 0 OR battFlag = 0 OR msgFlag = 0 THEN

        IF contFlag = 0  THEN

            LET sysState = "O"

            LET bootCount = bootMax

        ENDIF

    CASE "O"

        IF bootCount = 0 THEN

            LET sysState = "S"

        ENDIF

        IF msgFlag = 0 OR busyFlag = 0 THEN

            LET sysState = "S"

        ENDIF

ENDSELECT

RETURN


getBattFlag:

SETFREQ m4

READADC10 refPort,rawADC

SETFREQ K250

IF rawADC < minBattVolt THEN

    LET battFlag = 1

ELSE

    LET battFlag = 0

ENDIF

SETFREQ K31

RETURN


transmitChar:            'Input is charData            

SEROUT txPort,N9600_8,(charData)

RETURN


Transmit:        'Input is battVolt and decDP (no of decimals)

SETFREQ m8    

LET battVolt = voltNum / rawADC    'in units of 2mv+++

LET battVolt = 2 * battVolt

LET charData = "<"

GOSUB transmitChar

LET decData = battVolt / 100

LET charData = decData + "0"

GOSUB transmitChar

IF decDP = 2 THEN

    LET charData = "."

    GOSUB transmitChar

ENDIF

remdr = battVolt // 100

decData = remdr / 10

LET charData = decData + "0"

GOSUB transmitChar

IF decDP = 1 THEN

    LET charData = "."

    GOSUB transmitChar

ENDIF

decData = remdr // 10

LET charData = decData + "0"

GOSUB transmitChar

LET charData = ">"

GOSUB transmitChar

LET charData = sysState

GOSUB transmitChar

LET charData = 13

GOSUB transmitChar

LET charData = 10

GOSUB transmitChar

SETFREQ K250

RETURN


INTERRUPT:

SETFREQ m16

PAUSE 5

SERIN [50],rxPort,T9600_16,("<"),chgVolt,iTemp,sdBusy,iTemp

IF sdBusy = "B" THEN

    LET busyFlag = 1

ELSE

    LET busyFlag = 0

ENDIF

SETFREQ K250

LET msgsCount = msgMin

LET msgFlag = 1

SETINT %00010000, %00000000

RETURN