Hi,
The CALIBADC command is perhaps the nearest thing to a "free lunch" with a PICaxe. It can indicate the supply rail voltage (on the Program Editor's Terminal) using only a few lines of code, with absolutely NO external hardware or PICaxe pins required. Often, I now include code similar to the following at the top of my development programs, to check that the battery is good (and also indicate if the program restarts unexpectedly for any reason).
Code to report the voltage to one decimal place has been described previously and is generally "good enough" when using Alkaline cells (whose voltage falls drastically over their full discharge life). I couldn't find it with a quick forum search but it's basically:
However, particularly when using only 2 x rechargeable NiMH cells, or most lithium types, a resolution of 100 mV is hardly sufficient to give a good indication of their state of charge. The "magic number" (10500) cannot be multiplied by 10 (because it would overflow the word variable), but it can be multiplied by 5, then the division performed, then the result multiplied by 2. This gives a result in tens of millivolts, but the final digit will always be even. Therefore, I devised the following code which resolves the Vdd to 10 mV, at least for lower voltages (at higher voltages the ADC and PICaxe's limited division resolution let us down).
Just a few comments on this implementation. Firstly, CALVDD is a nominal, theoretical, calculated value. But if a reasonably "accurate" indication of the supply voltage is required, then the code must be loaded into the specific PICaxe chip, the actual Vdd measured with a multimeter and then this constant modified accordingly.
Secondly, I have not used the normal BINTOASCII command because it is rather inefficient (in Program and Variable memory space). Strictly, it requires 5 bytes for the ASCII values (in practice 3 appear to be accepted, or the first two can be "dummy" or repeated variables) and the Program Editor does not permit the ASCII output variables to re-use the input word. My alternative routine uses only 3 bytes (a "temporary byte" and a "temporary word"), but the byte value will overflow if Vdd > 5.11 volts. Also, it relies on the "overlay" of b2 and b3 on w1.
Finally, the "trick" used to obtain the increased resolution assumes that the integer result from CALIBADC10 is truncated, so that incrementing it may actually produce a more "accurate" result. However, the base PIC data sheet suggests that the ADC might already give a "rounded" (up or down) result. Also it's arguable whether CALVDD should be based on a value of 1023 or 1024 (ADC steps). But these are only theoretical considerations which will be "corrected" by the necessary calibration procedure already mentioned.
Cheers, Alan.
The CALIBADC command is perhaps the nearest thing to a "free lunch" with a PICaxe. It can indicate the supply rail voltage (on the Program Editor's Terminal) using only a few lines of code, with absolutely NO external hardware or PICaxe pins required. Often, I now include code similar to the following at the top of my development programs, to check that the battery is good (and also indicate if the program restarts unexpectedly for any reason).
Code to report the voltage to one decimal place has been described previously and is generally "good enough" when using Alkaline cells (whose voltage falls drastically over their full discharge life). I couldn't find it with a quick forum search but it's basically:
Code:
calibadc10 w1
b1 = 10500 / w1
bintoascii b1,b4,b5,b6
sertxd ("Vdd= ",b5,".",b6," Volts",cr,lf)
Code:
symbol CALVDD = 52429 ; 1024 * 1.024 * 1000 / 20 (DAC steps * Ref V / Resolution in mV)
ShowVdd:
calibadc10 w1 ; Measure FVR (nominal 1.024 v) relative to Vdd (1024 steps)
b1 = CALVDD / w1 ; Result fits into a single byte if Vdd < 5 volts
inc w1
w1 = CALVDD / w1 + b1 ; Average Vdd in tens of mV - then fall into Show2dp routine
Show2dp:
b1 = w1 / 100 ; Integer volts
w1 = w1 // 100 ; Decimal part (remainder)
b3 = b2 // 10 ; Hundredths digit
b2 = b2 / 10 ; Tenths digit
sertxd("Vdd=",#b1,".",#b2,#b3," Volts",cr,lf)
; return
Secondly, I have not used the normal BINTOASCII command because it is rather inefficient (in Program and Variable memory space). Strictly, it requires 5 bytes for the ASCII values (in practice 3 appear to be accepted, or the first two can be "dummy" or repeated variables) and the Program Editor does not permit the ASCII output variables to re-use the input word. My alternative routine uses only 3 bytes (a "temporary byte" and a "temporary word"), but the byte value will overflow if Vdd > 5.11 volts. Also, it relies on the "overlay" of b2 and b3 on w1.
Finally, the "trick" used to obtain the increased resolution assumes that the integer result from CALIBADC10 is truncated, so that incrementing it may actually produce a more "accurate" result. However, the base PIC data sheet suggests that the ADC might already give a "rounded" (up or down) result. Also it's arguable whether CALVDD should be based on a value of 1023 or 1024 (ADC steps). But these are only theoretical considerations which will be "corrected" by the necessary calibration procedure already mentioned.
Cheers, Alan.