1. GetSwPos().
This 12-position rotary switch was inherited from the previous incarnation. It selects a massivly-overkill of contents of the 4 messages which are stored, and sets their transmit periods.
The parameters are stored in EEPROM and can be changed. Each message has two fields, which may be any of the nine measured. If the period is 0, then that message is not transmitted in that switch position.
2.ConvertAnalog()
Each of the analog inputs is converted during a portion of eleven loops. The number of samples which are accumulated depends on the engineering conversion factor, since it performs multiplication. At the end of the cycle the accumulated value is divided to complete conversion to engineering units, then converted to ASCII characters. The multiply and divide values are stored in EEPROM, as is the position of the decimal point.
3. XmitControl()
Since transmissions have a period in seconds, an interrupt driven by the one-Hz watch timer increments four counters, one per message. XmitControl responds to counting limits of these counters by calling Transmit(), which reads the field values for the two fields and assembles the message and calculates the two checksum characters. Then the message is sent to the transmitter module.
#rem
Standalone.bas Digitizes the analog inputs from the Signal Conditioner,
The resulting ascii characters are transmitted in RF messages.
John Saunders 10/10/2021
The 40X2 has 56 bytes of named storage and 56-255 of unnamed storage and 0-1024 bytes of scratchpad.
The unnamed are accessed using PEEK and POKE and the scratchpad by GET and PUT
If the variable name is preceded by WORD then a word variable may be used (using 2 locations)
Both unnamed and scratchpad can be indirectly addressed , the unnamed with @bptr and scratchpad with @ptr
Both also use the suffix inc and dec
#endrem
#PICAXE 40X2
rem Analog Signal Conditioner channels
symbol Grn = 11 'Scale 0 - 4V
symbol Yel = 17 'Scale 0 - 4V
symbol BNC_L_V = 1 'Scale 0 - 4,40V, 1 meg
symbol BNC_R_V = 0 'Scale 0 - 4,40V, 1 meg
symbol Bipolar = 8 'Scale -0.2 - + 0.2V 2.2 meg
symbol Diff_V = 9 'Scale 0 - 4,40V, 400 K
symbol Temp = 10 'Scale 1 mv/deg A
symbol D9P4 = 12 'Scale 0 - 4V
rem Analog ADC inputs
symbol Batt = 18 'Scale 0 - 4V
symbol Sw = 5
rem ADC external reference range
symbol PosRefVolt = 3
symbol NegRefVolt = 2
rem Range switch Inputs:
symbol BNC_L_R = PinB.7
symbol BNC_R_R = PinB.6
symbol Diff_R = PinD.2
rem interrupt
symbol CLkInt = PinC.3 '1 Hz clock pulse 3 milliChCycle
rem Serial output to transmitterr
symbol XmitPort = A.7
rem Pins on the D9s at the front of the Signal conditioner
symbol D9P3 = D.3
symbol D9P2 = C.4
rem Pins on the D9s at the back of the ADC
symbol DTRP4 = PinC.0 'protected input
symbol RTSP7 = PinC.2 'protected input
symbol ENP6 = C.1
symbol DATAP8 = D.0 '
rem Controls:
symbol DC_Out = D.4
symbol AC_Out = C.7
symbol DC_In = PinD.6
symbol AC_In = PinD.5
symbol BipolarZero = 1990
symbol AnalogStartAddr = 56 'In SRAM
symbol AnalogTableAddr = 0
symbol TxBufStartAddr = 16 'In the scratchpad
symbol MsgKey = "y"
symbol MsgTableStartAddr = 50
symbol MsgInterval = 40 'Minimum gap between messages
'EEPROM
'Analog parameter table, indexed by AnalogIndex * 5
rem ADC Mult Div DP Marker
DATA 0,(BNC_R_V, 8, 2, 3 , "R") 'AnalogIndex = 0, Adjust DPLoc for range
DATA 5,(BNC_L_V, 8, 2, 3 , "L") 'AnalogIndex = 1, Adjust DPLoc for range
DATA 10,(Diff_V, 8, 2, 3, "D") 'AnalogIndex = 2, Adjust DPLoc for range
DATA 15,(Grn, 8, 2, 3, "G") 'AnalogIndex = 3
DATA 20,(Yel, 8, 2, 3, "Y") 'AnalogIndex = 4
DATA 25,(D9P4, 8, 2, 3, "E") 'AnalogIndex = 5
DATA 30,(Batt, 8, 2, 3, "B") 'AnalogIndex = 6
DATA 35,(Bipolar, 8, 2, 1, "C") 'AnalogIndex = 7,Allow for negative, use lower case symbol
DATA 40,(Temp, 9, 5, 1, "T") 'AnalogIndex = 8,also * 4 then subtract 2079
rem Preset Message table of AnalogIndex of 2 fields per message, plus period in seconds
rem Rows are indexed bt swPos * 12
symbol TxDataStartAddr = 50
rem Msg 0 Msg 1 Msg 2 Msg 3
DATA 50 ,(1,4,20 , 3,0,0, 2,7,0, 6,8,120) 'Switch position A = 0
DATA 62 ,(1,4,40 , 3,0,0, 2,7,0, 6,8,120) 'Switch position B = 1
DATA 74 ,(1,4,60 , 3,0,0, 2,7,0, 6,8,120) 'Switch position C = 2
DATA 86 ,(0,3,20 , 3,0,0, 2,7,0, 6,8,120) 'Switch position D = 3
DATA 98 ,(0,3,40 , 3,0,0, 2,7,0, 6,8,120) 'Switch position E = 4
DATA 110,(0,3,60 , 3,0,0, 2,7,0, 6,8,120) 'Switch position F = 5
DATA 122,(1,4,60 , 0,3,64, 2,7,0, 6,8,120) 'Switch position G = 6
DATA 134,(2,7,40 , 5,4,44, 2,7,0, 6,8,200) 'Switch position H = 7
DATA 146,(4,1,30 , 3,0,34, 2,7,38, 6,5,200) 'Switch position J = 8
DATA 158,(4,1,60 , 3,0,63, 2,7,66, 6,8,200) 'Switch position X = 9
DATA 170,(4,1,120, 3,0,163, 2,7,177, 6,5,200) 'Switch position Y = 10
DATA 182,(4,1,240, 3,0,243, 2,7,247, 6,8,250) 'Switch position Z = 11
'Variables:
symbol Msg0En = bit0
symbol Msg1En = bit1
symbol Msg2En = bit2
symbol Msg3En = bit3
symbol IntFlag = bit4
symbol SendFlag = bit5
symbol ReadyFlag = bit6
rem Dedicated variables
symbol ChCycle = b2 '0-9 Main count
symbol AnalogIndex = b3 '0-8
symbol MsgIndex = b4
symbol SwPos = b5 '0-11 Switch position
symbol OldSwPos = b6
symbol Duration = b7 'The minimum number of ChCycle between transmissions
symbol Msg0Count = b8
symbol Msg1Count = b9
symbol Msg2Count = b10
symbol Msg3Count = b11
symbol Msg0Period = b12
symbol Msg1Period = b13
symbol Msg2Period = b14
symbol Msg3Period = b15
'Reusable -
symbol Scratch = b20
symbol DecData = b21
symbol Channel = b22
symbol Marker = b23
symbol Multiply = b24
symbol Divide = b25
symbol DPLoc = b26 'number of decimal places
symbol ScratchAddr = b27
symbol DataAddr = b28
symbol Indx = b29
symbol Iter = b30
symbol Chardata = b31
symbol CkSum = b32
symbol AnalogVal = w25
symbol AccumulatorVal = w26
Setup:
SETFREQ m8
LET DIRSA = %10010000
LET DIRSB = %00000000
LET DIRSC = %10010010
LET DIRSD = %00010001
LET ADCSETUP = %0001111100101111 '2,3 for ext ref, 4 not present, ext ref on a.3, + and A,2 -
LET ADCSETUP2 = %0000000000000110
LOW DC_Out
LOW AC_Out
LOW D9P2
LOW ENP6
LOW DATAP8
LET Msg0Count = 0
LET Msg0En = 0
LET Msg1Count = 0
LET Msg1En = 0
LET Msg2Count = 0
LET Msg2En = 0
LET Msg3Count = 0
LET Msg3En = 0
LET SendFlag = 0
LET ChCycle = 0
LET ReadyFlag = 0
SETINT %00001000,%00001000,C 'Interrupt on 1 Hz clock
main:
GOSUB GetSwPos 'Also sets the periods
GOSUB ConvertAnalog
LET bptr = 8 * SwPos + AnalogStartAddr
INC ChCycle
IF ChCycle > 10 THEN
LET ChCycle = 0
ENDIF
GOSUB XmitControl
PAUSE 1
GOTO main
GetSwPos:
READADC Sw,AnalogVal
FOR Scratch = 39 TO 231 STEP 16
IF Scratch > AnalogVal THEN EXIT
NEXT
LET SwPos = Scratch/16 - 3 'Switch position 0-11
LET DataAddr = 12 * SwPos + TxDataStartAddr + 2
READ DataAddr,Msg0Period
LET DataAddr = 12 * SwPos + TxDataStartAddr + 5
READ DataAddr,Msg1Period
LET DataAddr = 12 * SwPos + TxDataStartAddr + 8
READ DataAddr,Msg2Period
LET DataAddr = 12 * SwPos + TxDataStartAddr + 11
READ DataAddr,Msg3Period
IF SwPos <> OldSwPos THEN
LET Msg0Count = 0
LET Msg1Count = 0
LET Msg2Count = 0
LET Msg3Count = 0
LET ChCycle = 0
ENDIF
LET OldSwPos = SwPos
RETURN
#rem
SRAM memory usage:
64 bytes starting at AnalogStartAddr to store analog values.
2 bytes store a the symbol in ASCII plus a comma, followed by
5 bytes of data converted to ASCII with decimal point.
Finally a comma
Scratchpad memory usage:
0-15 to store accumulated binary analog measurements
20 bytes per message starting at TxBufStartAddr to store the current message being transmitted
#endrem
ConvertAnalog:
#rem
The processor has 8 active ADC ports.7 from The Signal Conditioner,plus the battery voltage
The output of this subprogram 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, some with modifications.
#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
Rem Perform multiplication by measuring each analog multiple times and accumulate
FOR AnalogIndex = 0 TO 8 '9 analogs
LET ScratchAddr = 2 * AnalogIndex 'Accumulators start at 0
LET DataAddr = 5 * AnalogIndex + AnalogTableAddr
READ DataAddr,Channel,Multiply,Divide,DPLoc, Marker
IF ChCycle < Multiply THEN
ADCCONFIG %0101
READADC10 Channel,AnalogVal
GET ScratchAddr, WORD AccumulatorVal
LET AnalogVal = AnalogVal + AccumulatorVal
PUT ScratchAddr, WORD AnalogVal
ENDIF
IF ChCycle = 10 THEN
GET ScratchAddr, WORD AnalogVal
LET AnalogVal = AnalogVal / Divide 'Do division
IF Channel = Temp THEN 'Bipolar
LET AnalogVal = 4* AnalogVal
LET AnalogVal = AnalogVal - 4597 '273.15*18 - 320 Go figure!
ENDIF
IF Channel = Bipolar THEN '200 mv input
SERTXD(",200mv=")
IF AnalogVal >= BipolarZero THEN
LET AnalogVal = AnalogVal - BipolarZero
ELSE
LET AnalogVal = BipolarZero - AnalogVal
LET AnalogVal = AnalogVal | $8000 'Set MSB
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
rem Inputs are in
IF AnalogVal > $7FFF THEN 'Minus
LET Marker = Marker + $20
LET AnalogVal = AnalogVal & $7FFF
ENDIF
IF Channel = BNC_L_V AND BNC_L_R = 1 THEN
DEC DPLoc
ENDIF
IF Channel = BNC_R_V AND BNC_R_R = 1 THEN
DEC DPLoc
ENDIF
IF Channel = Diff_V AND Diff_R = 1 THEN
DEC DPLoc
ENDIF '4 significant digits, plus decimal point and a comma
LET bptr = 8 * AnalogIndex + AnalogStartAddr
LET @bptrinc = Marker
LET @bptrinc = ","
LET DECData = AnalogVal/1000 'Digit #1
LET DECData = DECData + "0" 'Ascii
LET @bptrinc = DECData 'Digit 1 Pos
IF DpLoc = 3 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 = 1 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
LET ScratchAddr = 2 * AnalogIndex 'Zero Accumulators which start at 0
LET AccumulatorVal = 0
PUT ScratchAddr, 0,0
ENDIF
NEXT
RETURN
XmitControl:
IF Msg0En = 1 THEN
LET MsgIndex = 0
GOSUB Transmit
LET Msg0En = 0
RETURN
ENDIF
IF Msg1En = 1 THEN
LET MsgIndex = 1
GOSUB Transmit
LET Msg1En = 0
RETURN
ENDIF
IF Msg2En = 1 THEN
LET MsgIndex = 2
GOSUB Transmit
LET Msg2En = 0
RETURN
ENDIF
IF Msg3En = 1 THEN
LET MsgIndex = 3
GOSUB Transmit
LET Msg3En = 0
ENDIF
RETURN
Transmit: 'Transmits the data in the message pointed to by MsgIndex (0-3)
rem The message starts with msgKey, a comma, Then 2 data values.(AnalogIndex 0-8) followed by a checksum
rem The message is asembled in a buffer in the scratchpad starting at TxBufStartAddr
LET ptr = TxBufStartAddr
LET @ptrinc = MsgKey
LET @ptrinc = ","
LET @ptrinc = "K"
LET @ptrinc = ","
LET DataAddr = 12 * SwPos + TxDataStartAddr
LET DataAddr = 3 * MsgIndex + DataAddr
READ DataAddr,AnalogIndex
LET bptr = 8 * AnalogIndex + AnalogStartAddr 'Where the data comes from
FOR Indx = 0 TO 7 'Transfer the selected analog data to the transmit buffer
LET CharData = @bptrinc
LET @ptrinc = CharData
NEXT
INC DataAddr
READ DataAddr,AnalogIndex
LET bptr = 8 * AnalogIndex + AnalogStartAddr 'Where the data comes from
FOR Indx = 0 TO 7 'Transfer the selected analog data to the transmit buffer
LET CharData = @bptrinc
LET @ptrinc = CharData
NEXT
LET CkSum = 0
LET ptr = TxBufStartAddr + 4
FOR Iter = 0 to 14 'The last comma should not be included
LET CkSum = CkSum + @ptrinc
NEXT
INC ptr
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 XmitPort
PAUSE 40
LOW XmitPort
PAUSE 20
SEROUT XmitPort,N2400_8,("14L1776")
LET ptr = TxBufStartAddr
DO UNTIL @ptr = 10
SERTXD (@ptr)
SEROUT XmitPort,N2400_8,(@ptrinc)
LOOP
SEROUT XmitPort,N2400_8, (13,10)
SERTXD (13,10)
RETURN
interrupt:
IF Msg0Period > 0 THEN '0 is inhibit
INC Msg0Count
IF Msg0Count >= Msg0Period THEN
LET Msg0Count = 0
lET Msg0En = 1
ENDIF
ENDIF
IF Msg1Period > 0 THEN '0 is inhibit
INC Msg1Count
IF Msg1Count >= Msg1Period THEN
LET Msg1Count = 0
lET Msg1En = 1
ENDIF
ENDIF
IF Msg2Period > 0 THEN '0 is inhibit
INC Msg2Count
IF Msg2Count >= Msg2Period THEN
LET Msg2Count = 0
lET Msg2En = 1
ENDIF
ENDIF
IF Msg3Period > 0 THEN '0 is inhibit
INC Msg3Count
IF Msg3Count >= Msg3Period THEN
LET Msg3Count = 0
lET Msg3En = 1
ENDIF
ENDIF
SETINT %00001000,%00001000,C
RETURN