#rem
SerialVoltmeter.bas A cube measuring 2 voltages with a serial output
It has a 12=position rorary mode control with a 16-step voltage divider
The positions determine the output period ands whether the output is for hard-wired or RF connection.
The internal 4.096 voltage reference is used for two voltage inputs
The 4 volt range is sampled 4 times
The 10 volt range is 0.4, 1000 for 10V,accumulate 10 for 1 mv resolution ,
The 20 volt rnge is 0.2. 1000 for 20 volts, accumulate for 10 then multiply by 2 for 1 mv resolution
The basic cycle of 1 second is 14 phases: 0-9 for the 10/20-volt, 10-13 for the 4-volt.
As each input is measured the accumulated value is concerted to ASCII abs stored
The number of one-sevond cycles are varied to get the transmit period.
A checksum sums all of the variable message and the embedded commas and periods
but not the bracketed commas
After the key code and comma is added the number of bytes to sum + 60 ("<"), and another comma
At the end is a comma followed by the checksum in 2 hex
John Saunders 3/4/2017 9/18/2021 use v
#endrem
#PICAXE 08M2
'ports:
symbol OutPort = C.0 'Serial out
symbol ModePort = C.1 'Selector switch
symbol Volt4Port = C.2 '4 v range
symbol RangePort = PinC.3 '1 is 20 volt range
symbol Volt10Port = C.4 '10/20 volts
variables:
symbol RfTx = bit0 '1 is format for RF transmission, 0 for hard-wire transmission
symbol Mode = b1 '1 - 12
symbol SwitchVal = b2 'Mode selector potemtiometer count, starts at 32
symbol Phase = b3 'There are 14 phases, 0-13
symbol Cycle = b4 'The count of 14-phase sequences are counted to get the transmit period
symbol Scratch = b5 'Multi-use
symbol DataAddr = b6 'An address in data memory
symbol OldMode = b7
symbol PerVal = b8 'The lengtth of each phase in 1/10 sec
symbol PerMult = b9 'The number of 14-phase sequences to get the transmit period
symbol ChckSum = b10
symbol ChckHex = b11
symbol ADCVal = w11 'Count from the ADC
symbol Accum = w12 'ADCVal is accumulated
symbol Remdr = w13 'Remainder when calculating the ascill value
rem constants to correct timing for instructions
symbol PausePer = 123
#rem
The serial output pin (C.0) is not supposed to use SEROUT, only SERTXD, but the following combinations work:
m4 N2400_4; m8 N9600_8
#endrem
#rem baud rates
RfTx = 2400 baud RF with premble 14L1776r,H, and ending in a 2-hex checksym
HdTx = 9600 baud
#endrem
DATA 0,(255)
rem mode 1 2 3 4 5 6 7 8 9 10 11 12
rem Tx period 1min 2min 4m Stop 4m 2min 1min 30sec 15sec 5sec 2sec 1sec
DATA 1,( 60, 120, 240, 255, 240, 120, 60, 30, 15, 5, 2, 1)
DATA 13,( 153, 158, 163, 200, 143, 142, 140, 132, 128, 115, 84, 47)
DATA 25,( 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0)
init:
LET Phase = 0
LET Cycle = 0
LET Accum = 0
SETFREQ m8
main:
rem Measure during a cycle of 14 phases
rem Each loop is 19 ms w/o storage, 48 with storage plus pause
FVRSETUP FVR4096
ADCCONFIG %011
IF Phase < 10 THEN
READADC10 Volt10Port,ADCVal
ELSE
READADC10 Volt4Port,ADCVal
ENDIF
LET Accum = Accum + ADCVal
IF Phase = 9 THEN
IF RangePort = 1 THEN 'Double
LET Accum = Accum + Accum
ENDIF
GOSUB StoreMeas
ENDIF
IF Phase = 13 THEN
GOSUB StoreMeas
ENDIF
rem end of one second loop
LET Phase = Phase + 1
IF Phase > 13 THEN 'Check switch position
LET Cycle = Cycle + 1
ADCCONFIG 0
READADC ModePort,SwitchVal
LET Mode = 0
DO
INC Mode
LET Scratch = 16 * Mode + 23
LOOP WHILE Scratch < SwitchVal
'SERTXD (#SwitchVal,",M,",#Mode,",C,",#Cycle,13,10)
IF OldMode <> Mode THEN
LET OldMode = Mode
READ Mode,PerMult
LET DataAddr = Mode + 12
READ DataAddr, PerVal
LET DataAddr = Mode + 24
READ DataAddr,RfTx
IF PerMult = 255 THEN
LET Cycle = 0
ENDIF
ENDIF
LET Phase = 0
LET Accum = 0
IF Cycle >= PerMult THEN
LET Cycle = 0
ENDIF
#rem
IF Cycle <> 0 THEN
HIGH Outport
ENDIF
#endrem
PAUSE PerVal
rem LOW OutPort
IF PerVal < 255 AND Cycle = 0 THEN
GOSUB Transmit
ENDIF
ELSE
PAUSE PausePer
ENDIF
GOTO main
StoreMeas: 'Convert Accum to ASCII and store in message memory
rem 1 9 . 9 9 9 , 3 . 9 9 9 , A 9
rem 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
LET Scratch = Accum/10000
LET Scratch = Scratch + "0"
LET Remdr = Accum // 10000
IF Phase = 9 THEN
LET bptr = 28
LET @bptrinc = Scratch
ELSE
LET bptr = 34
LET @bptrinc = ","
ENDIF
LET Scratch = Remdr/1000
LET Scratch = Scratch + "0"
LET @bptrinc = Scratch
LET Accum = Remdr// 1000
LET @bptrinc = "."
LET Scratch = Accum/100
LET Scratch = Scratch + "0"
LET @bptrinc = Scratch
LET Remdr = Accum // 100
LET Scratch = Remdr/10
LET Scratch = Scratch + "0"
LET @bptrinc = Scratch
LET Scratch = Remdr//10
LET Scratch = Scratch + "0"
LET @bptrinc = Scratch
LET Accum = 0
LET ChckSum = 0
FOR bptr = 28 TO 39
LET ChckSum = ChckSum + @bptr
NEXT
LET bptr = 40
LET @bptrinc = ","
LET ChckHex = ChckSum / 16
IF ChckHex < 10 THEN
LET ChckHex = ChckHex + "0"
ELSE
LET ChckHex = ChckHex + "7"
ENDIF
LET @bptrinc = ChckHex
LET ChckHex = ChckSum & $F
IF ChckHex < 10 THEN
LET ChckHex = ChckHex + "0"
ELSE
LET ChckHex = ChckHex + "7"
ENDIF
LET @bptr = ChckHex
RETURN
Transmit:
LET bptr = 28
IF RfTx =0 THEN '33 ms
HIGH Outport
PAUSE 20
LOW Outport
PAUSE 10
rem 28 29 30 31 32 33 34 35 36 37 38 39
SEROUT Outport, N9600_8,("v,",@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptr,13,10)
ELSE 'Used with an RF link 140 ms
SETFREQ m4
HIGH Outport
PAUSE 20
LOW Outport
PAUSE 10
rem 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
SEROUT Outport, N2400_4,("14L1776v,H,",@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptr,13,10)
SETFREQ m8
ENDIF
RETURN