I made this device to measure the total daily charge of a portable solar panel with a 5V output via a USB-A socket. Each of several was tested for weeks. Another solar panel keeps the included battery charged.
After this use it is presently unused but could be used for another test, perhaps with a modified program.
#rem SolarCurrentMonitor.bas Transparent box with a
DC-9S for the Universal Transmitter and programming
5.5 x 2.1 coax socket for an external shunt
The multipliers (11*61) + (30*59) + padding = reference diode in mv
LM385 measured at 2.482V
John Saunders 3/19/2021
#endrem
#picaxe 08M2
rem ports
symbol refPort = 2 'Reference diode LM385 nominal 2.5V
symbol refDrive = 1 'LM385 only turned on during measurement
symbol currPort = 4 'Connects to external shunt resistor of 10 ohms
rem variables
symbol iter = b1 'For FOR..NEXT loops
symbol indx = b2 'To distinguish between current and battery voltage measurements
symbol digit = b3
symbol ChckSum = b4
symbol ChckHex = b5
symbol fudge = w8 'To compensate, on average for not measuring the fractionals
symbol vRef = w9 'Measured only once a period since it is stable
symbol Vcc = w10 'Accumulated to get required multil\plier
symbol curr = w11 'Measured at 42 equal intervals per period for averaging and multiplication
symbol genVal = w12
symbol remdr = w13
rem constants
symbol VccPad = 41
symbol currPad = 9 'Modified value to compensate for 10 ohm shunt inaccuracy
symbol keyCode = "p" 'Logged as
symbol interval = 56 'To get 90-second period
init:
SETFREQ k125 'To reduce battery current drain to 200 microamps
LOW refDrive
LET Vcc = 0
LET curr = 0
main:
HIGH refDrive
PAUSE 1
READADC10 refPort,vRef
LOW refDrive
LET fudge = vRef / 2 'One-half
#rem The measurement is made in steps for these reasons:
1. The solar current changes frequently in cloudy days
2. Limited to 16-bit variables and no floating point
3. Generates a multiplication for the reference voltage
#endrem
rem Once a period calculation makes up tje sum and then transmits
LET genVal = 1024 * VccPad + fudge
LET Vcc = genVal/vRef + Vcc 'Final accumulation for battery voltage
READADC10 currPort,genVal 'Then for solar current
LET genVal = currPad * genVal + fudge
LET curr = genVal / vRef + curr
LET indx = 0 'Just a flag
GOSUB store
LET indx = 4
GOSUB store
GOSUB transmit
LET Vcc = 0
LET curr = 0
PAUSE interval
#rem The first of 2 multiplication steps.
The multipliers are chosen to be prime,
to be near to 63 (the limit) for 16 bits
to be the same for both Vcc and current
to be within 63 for both Vcc and current
#endrem
FOR iter = 1 TO 30
READADC10 currPort,genVal
LET genVal = 59 * genVal + fudge
LET curr = genVal / vRef + curr
LET genVal = 59 * 1024 + fudge
LET Vcc = genVal / vRef + Vcc
PAUSE interval
NEXT
FOR iter = 1 TO 11
READADC10 currPort,genVal
LET genVal = 61 * genVal + fudge
LET curr = genVal / vRef + curr
LET genVal = 61 * 1024 + fudge
LET Vcc = genVal / vRef + Vcc
PAUSE interval
NEXT
GOTO main
store: 'Imaging the transmitter message in ram
IF indx = 0 THEN
LET bptr = 28
LET genVal = curr
ELSE
LET bptr = 34
LET genVal = Vcc
ENDIF
LET digit = genVal/1000 'Digit #3
LET digit = digit + "0" 'Ascii
LET @bptrinc = digit
IF indx = 4 THEN
LET @bptrinc = "."
ENDIF
LET remdr = genVal//1000 'Remainder for digit #3
LET digit = remdr/100 'Digit #2
LET digit = digit + "0" 'Ascii
LET @bptrinc = digit
LET genVal = remdr//100 'Remainder for digit #2
LET digit = genVal/10 'Digit #1
LET digit = digit + "0" 'Ascii
LET @bptrinc = digit
IF indx = 0 THEN
LET @bptrinc = "."
ENDIF
LET digit = genVal //10 'Least significant digit
LET digit = digit + "0" 'Ascii
LET @bptrinc = digit
LET @bptrinc = ","
RETURN
transmit:
rem calculate the checksum and add to message
LET ChckSum = 0
FOR bptr = 28 TO 38
LET ChckSum = ChckSum + @bptr
NEXT
LET bptr = 39
LET @bptrinc = "," '37
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
SETFREQ m4
rem transmit by UHF radio with sync pulse, message type character (p) and message length code (G)
LET bptr = 28
HIGH C.0
PAUSE 20
LOW C.0
PAUSE 10
rem length char = ASCII of 60 + chars between and not including the bracketing end commas
rem curr3 curr2 curr1 period curr0 | comma | Vcc3 | period | Vcc2 Vcc1 Vcc0 | comma | ChckSum |
rem 28 29 30 31 32 33 34 35 36 37 38 39 40 41
SEROUT C.0, N2400_4,("14L1776",keyCode,",G,",@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc, @bptrinc,@bptrinc,@bptr, 13, 10)
SETFREQ k125
RETURN