Inconsistent adc_volts() function ???
Rsadeika
Posts: 3,837
I am getting inconsistent readings with my avolts function. I am reading two voltage sources, Parallax Li-ion Power Pack and a 12V SLA battery. While the readings for the power pack are the expected values, the readings for the 12V battery are all over the place, 8.xxx, 15.xxx, 11.xxx, 23.xxx, and so on. Both have the appropriate voltage divider setup [+V 10K . 10K -V] for the Power Pack, and [+V 10K-10K-10K . 10K -V] for the 12V battery. I am not sure what the cure for this would be, hopefully somebody will try it out to replicate this.
I brought this up in another thread, but decided maybe this specific problem? should be highlighted here.
Ray
I brought this up in another thread, but decided maybe this specific problem? should be highlighted here.
Ray
/* SAabsun.c */ #include "simpletools.h" #include "simpletext.h" #include "fdserial.h" #include "adcDCpropab.h" serial *xbee; float v3,v2; void menu(); void mvolts(); void avolts(); int main() { // Add startup code here. char inBuff[40]; adc_init(21, 20, 19, 18); xbee = fdserial_open(11, 10, 0, 9600); pause(50); while(1) { // Add main loop code here. if(fdserial_rxReady(xbee)) { readStr(xbee, inBuff, 40); if(!strcmp(inBuff, "help")) menu(); else if(!strcmp(inBuff, "mbat")) mvolts(); else if(!strcmp(inBuff, "abat")) avolts(); else { writeLine(xbee,"Unknown Command."); } } } return 0; } void menu() { writeStr(xbee,"Menu - help, mbat, abat \n"); } void mvolts() { v3 = adc_volts(3); v3 = (v3*2); writeStr(xbee,"mBattery "); writeFloat(xbee,v3); writeStr(xbee," Volts\n"); } void avolts() { // adc_init(21, 20, 19, 18); v2 = adc_volts(2); v2 =(v2*8.50); writeStr(xbee,"aBattery "); writeFloat(xbee,v2); writeStr(xbee," Volts\n"); }
Comments
Ray
You list four 10K resistor in your voltage divider.
If you used four 1K resistors instead of four 10K resistors the voltage at the divider should remain the same but the ADC would have an easier time measuring it.
The adjustment factor is pretty easy stuff. It will probably be something like:
The above should give you the volts times one thousand (or you can think of the number in units of millivolts). The code assume 20V will produce a reading of 4095.
Now I am at a loss, not sure if it is the ADC chip on my Activity Board, the actual ADC_volts function or what, is the problem? Even if I took a sample of a thousand readings and averaged that, I am not sure that it would reveal the actual battery state. The next thing that I will try is testing with the other two ADC ports that are available, I cannot imagine that I already smoked this ADC port.
Ray
sampling:
Lead acid batteries vary greatly in their makeup based on what they are for. You get different behaviors between starter and deep cycle batteries, for example. Most SLA batteries you purchase are for power backup, and have higher internal resistances.
Wouldn't the following code:
Output the voltage in millivolts rather than volts?
The "20_000 / 4_095" conversion was given assuming the calculations were being done with integers. I scaled the "20" by one thousand in order to preserve the precision. If floating point numbers are used, then the conversion to volts would be "20 / 4095". Right?
Aren't the volts displayed actually off by several orders of magnitude?
I'm not sure how the C compiler treats the equation:
Are the values "20000" and "4095" treated as floating point numbers right from the beginning or do they get converted to floats when they're multiplied by "v2"?
If the calculation "20000/4095" is done in integer math, then there will be a large rounding error in the calculation. This rounding error, if it exists, doesn't explain the numbers displayed.
The '(20000/4095)' method was not yielding the expected values, so I am using a different scheme, now I am wondering if I am supplying an adjustment scheme to show the numbers that I want see for that time slice.
Ray
I am wondering if anybody else is having a problem like mine, using the ADC with more than one circuit. Today, for awhile I was thinking that maybe you can only use one active working circuit on an ADC port, and nothing on the other 3 ADC ports, at the same time. Today after verifying both circuits, adding another circuit on line, the voltage results changed for the same batteries that I used to verify the circuit to begin with.
I was able to verify that the ADC chip is not smoked, but when I try to use it with more then one circuit, it starts to flake out. Not sure what to make of this situation. Anybody have any ideas?
Ray
That may be your experience with this particular application, but it's not really fair to say that about the Activity Board and its ADC until you have tried the same circuit on other boards/ADCs without observing the same issue.
Please post your current schematic and a zip of your test code. Close-up shots of your circuit might also help.
In the meantime, I will wire up three voltage dividers on an Activity Board and test to rule out the possibility that a programming error made it into the library.
Andy
"Because the reference for the ADC124S021 is the supply voltage, any noise on the supply will degrade device
noise performance. To keep noise off the supply, use a dedicated linear regulator for this device, or provide
sufficient decoupling from other circuitry to keep noise off the ADC124S021 supply pin. Because of the
ADC124S021's low power requirements, it is also possible to use a precision reference as a power supply to
maximize performance."
"Resistor R1 is the on resistance of the multiplexer and track / hold switch, and is typically 500 ohms. Capacitor C2 is the
ADC124S021 sampling capacitor, and is typically 30 pF. The ADC124S021 will deliver best performance when
driven by a low-impedance source to eliminate distortion caused by the charging of the sampling capacitance.
This is especially important when using the ADC124S021 to sample AC signals. Also important when sampling
dynamic signals is a band-pass or low-pass filter to reduce harmonics and noise, improving dynamic
performance."
ADCs can have sampling perturbations on the input at the time of sampling that cause readings to be off (a small amount). If your VA moves around then so is your VRef and your readings will be off. To get 12 bit accuracy you must have a steady VRef and the exact VA voltage used in calculations (ie 4.983V/4096). Each LSB bit will then be 1.22mv.
Test Code
Results
Steady measurements, not at all like post number 5.
I've been using the Activity Boards ADC in the OPP#8 without issue. I have a couple of Sharp IR sensors being read by the Activity Board's ADC and it appears to work fine. Of course this is in Spin but I don't think there's anything wrong with the Activity Boards ADC chip.
Ray
Circuit
Results
I am hoping that this is the last problem that I have to deal with, I am getting to old for this kind of adventure, or should I call it learning process.
Ray
I do need an explanation as to how the float variables work, in terms of calling them as global verses local define. In the avolts() function, when I have 'float y3,y1;' as a local call out, then the function does not work. When I change 'y3,y1' to global, then the function works as expected. I do not understand what is going on, if somebody could explain it, would be greatly appreciated.
Ray
John Abshier
Ray
Ray
This is some really good news, I don't care about the global variable issue and increasing the compiled program size, now I have a lot more program size to work with. Now I can add the softRTC, data log to the uSD card, horns a tooting, lights a flashen, ...
Ray