CALIBADC to calculate voltage: problem @ 32mHz

lbenson

Senior Member
I've often used this code to calculate voltage times 10:

calibadc b4
b4 = 2611 / b4 ' 1.024 * 255 * 10 / calibADC value: V*10

I have a design which needs to run at 32mHz and 3V to accomodate a Nokia 5110 LCD, but have found that CALIBADC doesn't return the right value for this calculation, whereas it is correct for 4mHz, 8mHz, and 16mHz.

Here's my test code. I first display the calculated voltage at 4mHz, and then again after SETFREQ M32.
Code:
' 20calibadc ' trys to calculate voltage @ 4mHz & 32mHz
#picaxe 20M2
#terminal 4800

pause 2000
  calibadc b4
  sertxd("calib: ",#b4," ")
  b4 = 2611 / b4 ' 1.024 * 255 * 10 / calibADC value: V*10
  sertxd(#b4,cr,lf)
  b5 = b4 // 10
  b4 = b4 / 10
  sertxd("Supply Voltage @ 4mHz = ",#b4,".",#b5,cr,lf)
  pause 1000

  setFreq M32
  pause 16000
  calibadc b4
  b6 = b4
  b4 = 2611 / b4 ' 1.024 * 255 * 10 / calibADC value: V*10
  b7 = b4
  b5 = b4 // 10
  b4 = b4 / 10
  pause 16000

  setFreq M4
  pause 2000
  sertxd("calib: ",#b6," ")
  sertxd(#b7,cr,lf)
  sertxd("Supply Voltage @ 32mHz = ",#b4,".",#b5,cr,lf)
  pause 2000
Powering with 2 AAs I get a DVM reading of 3.16
Code:
calib: 83 31
Supply Voltage @ 4mHz = 3.1
calib: 99 26
Supply Voltage @ 32mHz = 2.6
With DVM reading of 4.48, the following:
Code:
calib: 58 45
Supply Voltage @ 4mHz = 4.5
calib: 86 30
Supply Voltage @ 32mHz = 3.0
As mentioned, with SETFREQ M8 and SETFREQ M16 I get correct answers.

(I tried switching to SETFREQ M4 to do the voltage calculation, but that causes the LCD to clear.)
 

Technical

Technical Support
Staff member
We suspect the adc acquisition delay time is being violated at the higher speed. Should be no reason why not to slow down for the calibadc and then speed up again, changing setfreq should not affect any LCD?
 

PhilHornby

Senior Member
I've often used this code to calculate voltage times 10:
...
...
As mentioned, with SETFREQ M8 and SETFREQ M16 I get correct answers.
By strange coincidence, I mentioned this issue in another thread :-

http://www.picaxeforum.co.uk/showthread.php?30557-Issue-with-PICAXE-and-Instrumental-Amplifier-AD623&p=317256&viewfull=1#post317256

(I know, for example, that attempts to read the Supply Voltage @ 32MHz gives the wrong answer).
 

marks

Senior Member
Hi Ibenson,
Most problems are decouplin related but this does just seem to be a slight code error somewhere..
perhaps try the following code.
Code:
 [color=Navy]#picaxe [/color][color=Black]20M2 
 [/color][color=Navy]#no_data
 #terminal 38400
 [/color][color=Blue]SETFREQ M32

      SYMBOL [/color][color=Purple]CALIB_ADC   [/color][color=DarkCyan]= [/color][color=Purple]b3
      [/color][color=Blue]SYMBOL [/color][color=Purple]Supply      [/color][color=DarkCyan]= [/color][color=Purple]b4
      [/color][color=Blue]SYMBOL [/color][color=Purple]D0          [/color][color=DarkCyan]= [/color][color=Purple]b5 
      [/color][color=Blue]SYMBOL [/color][color=Purple]D1          [/color][color=DarkCyan]= [/color][color=Purple]b6 
      
   [/color][color=Black]Main: 
   
      [/color][color=Blue]CALIBADC [/color][color=Purple]CALIB_ADC [/color][color=Black]: [/color][color=Blue]Sertxd([/color][color=Red]"CalibADC = "[/color][color=Black],#[/color][color=Purple]CALIB_ADC[/color][color=Blue]) 
      
  [/color][color=Purple]Supply [/color][color=DarkCyan]= [/color][color=Navy]26112 [/color][color=DarkCyan]/  [/color][color=Purple]CALIB_ADC [/color][color=DarkCyan]/[/color][color=Navy]10                  
  [/color][color=Blue]BinToAscii [/color][color=Purple]Supply [/color][color=Black],[/color][color=Purple]D1[/color][color=Black],[/color][color=Purple]D1[/color][color=Black],[/color][color=Purple]D0 [/color][color=Black]: [/color][color=Blue]Sertxd([/color][color=Red]"  Supply  "[/color][color=Black],[/color][color=Purple]D1[/color][color=Black],[/color][color=Red]"."[/color][color=Black],[/color][color=Purple]D0[/color][color=Black],[/color][color=Red]" V"[/color][color=Black],[/color][color=Blue]cr[/color][color=Black],[/color][color=Blue]lf) 
  
    GOTO [/color][color=Black]Main[/color]
 

hippy

Technical Support
Staff member
The odd thing is that when I try it on my 18M2 and 20M2 everything is fine at 3V, 4V and 5V, at 4, 8, 16 and 32MHz. I tested going up in frequency and down, to test a 4MHz to 32MHz jump.

The raw values returned are roughly the same, perhaps differing +/-2 across them and on consecutive readings but that's not enough to alter the 2611/adc result greatly.

There was no pattern of a particular operating speed always reading higher or lower than others

Code:
#Picaxe 20M2
#Terminal 4800
Do
  SetFreq M32 : Pause 8000 : CalibAdc b4
  SetFreq M16 : Pause 4000 : CalibAdc b3
  SetFreq M8  : Pause 2000 : CalibAdc b2
  SetFreq M4  : Pause 1000 : CalibAdc b1
  SerTxd( #b1, TAB, #b2, TAB, #b3, TAB, #b4, CR, LF )
Loop
Results are ...

Code:
5V   53 52 52 53   2611/52 = 50.2   2611/53 = 49.2   5.0   4.9
4V   65 66 65 66   2611/65 = 40.1   2611/66 = 39.5   4.0   3.9
3V   87 88 89 87   2611/87 = 30.0   2611/89 = 29.3   3.0   2.9
 

hippy

Technical Support
Staff member
I also tried this test program to see what variances there were at 4MHz and 32MHz ...

Code:
#Picaxe 20M2
#Terminal 4800
Do
  SetFreq M32 : Pause 8000 : Gosub Sample
  b3 = b1 
  b4 = b2
  SetFreq M4  : Pause 1000 : Gosub Sample
  SerTxd( #b1, "..", #b2, TAB, #b3, "..", #b4, CR, LF )
Loop

Sample:
  CalibAdc b0
  b1 = b0
  b2 = b0
  For b9 = 1 To 200
    CalibAdc b0
    b1 = b1 Max b0 ; Lowest
    b2 = b2 Min b0 ; Highest
  Next
  Return
That showed it to be pretty much the same at 3V at 4MHz and 32MHz.

But there was one anomaly on the first reading shown after download where the 32MHz reading showed "87..139" rather than the subsequent "87..89" which it generally was; 2611/139 = 18.7 => 1.8V

That may be because of the first switching of the ADC input selector to the Vref from something else. I vaguely recall something similar in the past and I believe the solution there was to perform consecutive CALIBADC commands and use the last reading. A double CALIBADC at the start of the Sample: routine fixed my anomalous reading.
 

marks

Senior Member
Hi Ibenson,
after relooking at your code ,i became more interested and luckily have a 20m2 at the moment to try.
and did get similiar results to what you reported.i still think this could be a decouplin issue
microchip always recommends 10uf and 0.1uf as minimum and at speeds above 10mhz to add 0.01 uf .
I did not try improving decouplin but as a workaround found adding a second calibrateADC to work.

Hi Hippy,
I did try your code (20m2 V8.A @ 3.3v) I also needed a second 'CalibAdc b4' at M32 to correct that result.
my 20m2 probably been around abit
79 79 79 117
79 79 79 90
79 79 79 90
Code:
[color=Green]' 20calibadc ' trys to calculate voltage @ 4mHz & 32mHz[/color]
[color=Navy]#picaxe [/color][color=Black]20M2[/color]
[color=Navy]#terminal 4800[/color]
[color=Black]main:[/color]
[color=Blue]pause [/color][color=Navy]2000
  [/color][color=Blue]calibadc [/color][color=Purple]b4
  [/color][color=Blue]sertxd([/color][color=Red]"calib: "[/color][color=Black],#[/color][color=Purple]b4[/color][color=Black],[/color][color=Red]" "[/color][color=Blue])
  [/color][color=Purple]b4 [/color][color=DarkCyan]= [/color][color=Navy]2611 [/color][color=DarkCyan]/ [/color][color=Purple]b4 [/color][color=Green]' 1.024 * 255 * 10 / calibADC value: V*10
  [/color][color=Blue]sertxd([/color][color=Black]#[/color][color=Purple]b4[/color][color=Black],[/color][color=Blue]cr[/color][color=Black],[/color][color=Blue]lf)
  [/color][color=Purple]b5 [/color][color=DarkCyan]= [/color][color=Purple]b4 [/color][color=DarkCyan]// [/color][color=Navy]10
  [/color][color=Purple]b4 [/color][color=DarkCyan]= [/color][color=Purple]b4 [/color][color=DarkCyan]/ [/color][color=Navy]10
  [/color][color=Blue]sertxd([/color][color=Red]"Supply Voltage @ 4mHz = "[/color][color=Black],#[/color][color=Purple]b4[/color][color=Black],[/color][color=Red]"."[/color][color=Black],#[/color][color=Purple]b5[/color][color=Black],[/color][color=Blue]cr[/color][color=Black],[/color][color=Blue]lf)
  pause [/color][color=Navy]1000

  [/color][color=Blue]setFreq M32
  [/color][color=Green]'  pause 16000  'remove
   [/color][color=Blue]calibadc [/color][color=Purple]b4
  [/color][color=Blue]calibadc [/color][color=Purple]b4     [/color][color=Green]'2nd command required check decouplin
  [/color][color=Purple]b6 [/color][color=DarkCyan]= [/color][color=Purple]b4
  b4 [/color][color=DarkCyan]= [/color][color=Navy]2611 [/color][color=DarkCyan]/ [/color][color=Purple]b4 [/color][color=Green]' 1.024 * 255 * 10 / calibADC value: V*10
  [/color][color=Purple]b7 [/color][color=DarkCyan]= [/color][color=Purple]b4
  b5 [/color][color=DarkCyan]= [/color][color=Purple]b4 [/color][color=DarkCyan]// [/color][color=Navy]10
  [/color][color=Purple]b4 [/color][color=DarkCyan]= [/color][color=Purple]b4 [/color][color=DarkCyan]/ [/color][color=Navy]10
  [/color][color=Blue]pause [/color][color=Navy]16000

  [/color][color=Blue]setFreq M4
  pause [/color][color=Navy]2000
  [/color][color=Blue]sertxd([/color][color=Red]"calib: "[/color][color=Black],#[/color][color=Purple]b6[/color][color=Black],[/color][color=Red]" "[/color][color=Blue])
  sertxd([/color][color=Black]#[/color][color=Purple]b7[/color][color=Black],[/color][color=Blue]cr[/color][color=Black],[/color][color=Blue]lf)
  sertxd([/color][color=Red]"Supply Voltage @ 32mHz = "[/color][color=Black],#[/color][color=Purple]b4[/color][color=Black],[/color][color=Red]"."[/color][color=Black],#[/color][color=Purple]b5[/color][color=Black],[/color][color=Blue]cr[/color][color=Black],[/color][color=Blue]lf)
  pause [/color][color=Navy]2000
  
  [/color][color=Blue]goto [/color][color=Black]main[/color]
as a note the code in post #4 works ok at 32mhz but the first value read is high you need a second command when changing frequency to M32 within your program
I did try adding a 0.01uF but it made no difference.
 
Last edited:

hippy

Technical Support
Staff member
And finally, reading C.1 tied to +V before the CALIBADC ...

Code:
#Picaxe 20M2
#Terminal 4800
Do
  SetFreq M32 : Pause 8000 : ReadAdc C.1, b0 : CalibAdc b4
  SetFreq M16 : Pause 4000 : ReadAdc C.1, b0 : CalibAdc b3
  SetFreq M8  : Pause 2000 : ReadAdc C.1, b0 : CalibAdc b2
  SetFreq M4  : Pause 1000 : ReadAdc C.1, b0 : CalibAdc b1
  SerTxd( #b1, TAB, #b2, TAB, #b3, TAB, #b4, CR, LF )
Loop
And the results are similar to what you are seeing, anomalous high readings at 32MHz ...

Code:
5V   53 52 53 94   2611/94 = 27.7   2.7
4V   66 65 66 96   2611/96 = 27.1   2.7
3V   89 88 87 98   2611/98 = 26.6   2.6
So at 32MHz it seems there's not enough time for the Vref to have been selected and stabilised before it's being read and converted. Doubling-up the CALIBADC resolves that.
 

hippy

Technical Support
Staff member
Hi Hippy,
I did try your code (20m2 V8.A @ 3.3v) I also needed a second 'CalibAdc b4' at M32 to correct that result.
my 20m2 probably been around abit
79 79 79 117
79 79 79 90
79 79 79 90
Thanks for testing.

It does seem there is some variation in exactly how CALIBADC does respond between chips at 32MHz but doubling CALIBADC should fix things.

Similar tricks can be used when switching between READADC inputs and the input source impedance is outside recommended specifications. The first READADC selects the inputs, starts charging the internal capacitor, but it doesn't reach the voltage the input actually is before converting and returning a result. Adding a second and subsequent READADC on the same input takes the cap from what it is to where it should be.

CALIBADC is a READADC on the Vref so can be affected in a similar way.

It's a bit like hoisting a bucket of rubble; easier to get it to the top in two or more goes. After the first tug it likely won't have got to the top.
 

PhilHornby

Senior Member
That may be because of the first switching of the ADC input selector to the Vref from something else. I vaguely recall something similar in the past and I believe the solution there was to perform consecutive CALIBADC commands and use the last reading. A double CALIBADC at the start of the Sample: routine fixed my anomalous reading.

and

So at 32MHz it seems there's not enough time for the Vref to have been selected and stabilised before it's being read and converted. Doubling-up the CALIBADC resolves that.
I tried this on a 14M2 - and executing two CALIBADC commands @32MHz does indeed work around the problem. (1st reading 1.9V, 2nd reading 4.8V)

Should be no reason why not to slow down for the calibadc and then speed up again, changing setfreq should not affect any LCD?
It's a lot quicker to execute two consecutive CALIBADC's, than to switch to 16MHz and back (240µS vs 1.49mS)

As a general point, given that issues like this don't seem to get fixed - could a list of them be maintained, along with the workarounds? . I can think of at least four more issues to go on such a list, that I've "discovered" - ​but which turned out to be 'known problems'.
 

Technical

Technical Support
Staff member
As a general point, given that issues like this don't seem to get fixed - could a list of them be maintained, along with the workarounds? . I can think of at least four more issues to go on such a list, that I've "discovered" - ​but which turned out to be 'known problems'.
This information is generally put on the revision history tab for that part e.g.
http://www.picaxe.com/Hardware/PICAXE-Chips/PICAXE-14M2-microcontroller

We've just updated it for calibadc at m32
 

AllyCat

Senior Member
Hi,

Here's another one, only for the 20M2. ;)

Also worth noting that CALIBADC{10} may give incorrect results if the ADC has been previously set to use a FVR reference voltage. :(

Cheers, Alan.
 

lbenson

Senior Member
... Here's another one, only for the 20M2.
Hmmm. Maybe here's another one with CALIBADC and B.1 on the 20M2.

Adding the second CALIBADC in my program didn't change anything--still reading 2.3 volts when my DVM said 3V. But I had a 50% voltage divider (2 10K Rs) on B.1 fed from a 5V wall plug to tell me when a UPS dropped out. On reading Alan's post I wondered if B.1 had anything to do with it, so I switched to B.2. Now, with the second CALIBADC, I get a correct-enough reading of 2.9V (2.967 if you use Excel to divide 2611 by 88).

Thanks to all for the investigations. I will test further, but I think I have a solution to my problem--and there looks to be something funky about B.1 and 32mHz on the 20M2.
 
Top