how to increase accuracy of analogRead() ?

This forum is dedicated to software development related to MultiWii.
It is not the right place to submit a setup problem.
Software download
User avatar
Hamburger
Posts: 2578
Joined: Tue Mar 01, 2011 2:14 pm
Location: air
Contact:

how to increase accuracy of analogRead() ?

Post by Hamburger »

we use analogRead() for measuring analog values and sensors, here voltage and current.

Code: Select all

  #define V_BATPIN                   A3    // Analog PIN 3
  #define PSENSORPIN                 A2    // Analog PIN 2

Unfortunately, the result is only partially usable. According to arduino specs, for input range [ 0 ; 5.0 Volt] analogRead() returns 10 bit [0 ; 1023]; thus 4.9mV/unit. But when attaching a current sensor, with a constant load, I find the return value of analogRead() to be within a range of +-30 units, i.e. +-150mV. That is very inaccurate, about 5 bits of the 10 bits are garbage.
On the other hand, monitoring the output voltage of said sensor with a multimeter does not show such variance.

The maximum reading frequency is never reached with MWii http://arduino.cc/en/Reference/AnalogRead

Using averaging filter in MWii would only disguise the hardware inaccuracy, so it is not an option. Here I am wondering what could be done to increase the actual accuracy of analogRead() up to the nominal accuracy? Any ideas, please?

User avatar
Hamburger
Posts: 2578
Joined: Tue Mar 01, 2011 2:14 pm
Location: air
Contact:

Re: how to increase accuracy of analogRead() ?

Post by Hamburger »

from http://arduino.cc/en/Tutorial/AnalogInputPins
The Atmega datasheet also cautions against switching analog pins in close temporal proximity to making A/D readings (analogRead) on other analog pins. This can cause electrical noise and introduce jitter in the analog system. It may be desirable, after manipulating analog pins (in digital mode), to add a short delay before using analogRead() to read other analog pins

is this the explanation for the jitters of the analogRead() ? If so, any chance to avoid or lessen the effect?

copterrichie
Posts: 2261
Joined: Sat Feb 19, 2011 8:30 pm

Re: how to increase accuracy of analogRead() ?

Post by copterrichie »

If we are measuring voltage, the zener mod works fantastically for me. I also have 358 to amplify voltages less then 1 volt.

kataventos
Posts: 702
Joined: Sun Aug 28, 2011 8:14 pm
Contact:

Re: how to increase accuracy of analogRead() ?

Post by kataventos »

Hi Hamburger,

I would really like to understand what is your point here, please explain in "real description" what is inaccurate on the analogue readings (e.g) VBat, because I always use multimeter in real time to compare readings when calibrating, what I find is a 0.1v difference sometimes.

I too use LM358 for voltages <= 1v.

Cheers,
KV

User avatar
Hamburger
Posts: 2578
Joined: Tue Mar 01, 2011 2:14 pm
Location: air
Contact:

Re: how to increase accuracy of analogRead() ?

Post by Hamburger »

Hi KV,
I use current sensor; it converts measured current into voltage output signal, which goes into analogRead().
Now I run copter with constant speed => constant current => the sensor delivers a constant voltage to my multimeter, ok.
But in parallel, the analogRead() function jitters with +-30 units, like the measured value would go up/down +-30*4.9mV = +-150mV.
This contradicts the multimeter reading, which is steady with accuracy of +-0.01V.
The sensor is amploc.com 50A hall effect sensor (with 1% linearity, +-2% accuracy).

So I think the reason for inaccuracy is not in the sensor but in the analogRead() function (or in impedance mismatch?)

Also, sampling is done every 7th cycle, eq. about every 20ms, that should be abut 50Hz. Per arduino specs, this should be safe for analogRead().

User avatar
Hamburger
Posts: 2578
Joined: Tue Mar 01, 2011 2:14 pm
Location: air
Contact:

Re: how to increase accuracy of analogRead() ?

Post by Hamburger »

I have the same effect when measuring under load the battery voltage from lipo via voltage divider:
my multimeter shows steady 9,87V with +-0.02V,
but analogRead() jitters with a range of +-15 units. That would indicate +-15*4.9mV = +-75mV.
I do kinda trust my multimeter, so I blame the analogRead() function.
+-15 units inaccuracy means the lowest 4 bit of the value are useless; that sounds bad to me.
Since other projects do use analogRead() or the ADC with some access, I try to understand why the effect is so bad here with my MWii setup. (and I have heard from others about same experience).

User avatar
shikra
Posts: 783
Joined: Wed Mar 30, 2011 7:58 pm

Re: how to increase accuracy of analogRead() ?

Post by shikra »

Try testing with pwm generation disabled. See if the switching is causing the variance.
Actually start with a simple read sketch to see if the readings are more stable.

User avatar
KasparsL
Posts: 75
Joined: Wed May 16, 2012 3:31 pm

Re: how to increase accuracy of analogRead() ?

Post by KasparsL »

What abaut capacitor at Vref pin of Atmega? Is it there? Maybe try to increase the capacitance of it. and in software it should be set o internal Ref with external cap.

Paulmann
Posts: 13
Joined: Thu Mar 21, 2013 11:54 pm

Re: how to increase accuracy of analogRead() ?

Post by Paulmann »

Hi,

maybe your measured signal itself has high frequency noise (current spikes). To get meanigful reading from the adc the signal should be lowpass filtered before it is feed to the analog pin. You could use a series resistor and a cap from your AIN-Pin to AGND eg. 10KOHm + 330nF.

User avatar
Hamburger
Posts: 2578
Joined: Tue Mar 01, 2011 2:14 pm
Location: air
Contact:

Re: how to increase accuracy of analogRead() ?

Post by Hamburger »

thank you everybody for your thoughts.
I will follow these suggestions over time
- build another test case without motors&servos defined; that should remove the pwm as possible source. Could also test with mega board with hardware pwm.
- try to find the cap for the Vref and check if it is even soldered correctly. I have tested wth both a mini crius and a crius lite, same effect (but same manufacturer, so possibly same error in board design and/or production)
- will wire up some RC lowpath filter.

I have rewritten parts of the voltage and current sensors' handling in MWii to make it easier to config. At least, doing both analogRead() every cycle does not seem to worsen the jitter.

nhadrian
Posts: 421
Joined: Tue Oct 25, 2011 9:25 am

Re: how to increase accuracy of analogRead() ?

Post by nhadrian »

I have also interresting problems.

When only vbat is used and connected to A0, it have rock solid voltage reading (through resistor divired of course).
BUT! If I connect current sensor to A1 and (/or) an RSSI, the voltage reading also gets jittered, AND the value is less by 8-10%!!! (for example at 12,4V reading it becomes around 11,5 but jitters by 0,3-4 V + and -)
I tried with a modified code, I wrote a task switcher for analog readings but didn't helped. (I read somewhere in arduino site that reading at the same time can cause some internal overflow in cap).
I also tried the internal pull-up resistors ( digitalWrite(A0, HIGH); ), the result is as noisy as without it (of corse values changed because of pull-up)
I have Crius AIO pro boart and flytron ultralight 25A current sensor, FRSky Fasst compatible receiver with RSSI.

The same current sensor and RSSI reading works just great with my Mobidrone OSD (328p based).
There aren't any resistor or cap in the Mobidrone in front of analog inputs!!!

Could you please check if the crius aio pro have any cap/resistors attached to the analog inputs? (Unfortunatelly I can't see the circuit because I have an extend board built in).

BR
Adrian

User avatar
Hamburger
Posts: 2578
Joined: Tue Mar 01, 2011 2:14 pm
Location: air
Contact:

Re: how to increase accuracy of analogRead() ?

Post by Hamburger »

so if I understand you,
it is not a timing issue, we are not doing consecutive analogRead() - on same or other input - too fast. The two inputs used for analogRead() do influence each others results.

I too seem to have noticed the voltage drop on first input (used for lipo voltage with divider), when I activate second input for current sensor. Since you mention to have this effect with crius pro board, that has hardware pwm. I will look for the Vref cap over the weekend.

What voltage divider do you use? Someone noted our usual 33k&56k was too high, better switch to 3k3&5k6. The internal impedance of input was quoted as around 1M.

To add to the confusion, does swapping the order of sensors make any difference for you? At one point it felt like that to me. A0 for psensor, A1 for voltage. But it may have been dillusion on my part.

Seems like wiring up a test with barebone promini/nano board and two variable inputs should be my next step.

nhadrian
Posts: 421
Joined: Tue Oct 25, 2011 9:25 am

Re: how to increase accuracy of analogRead() ?

Post by nhadrian »

Hi,

I tried to move from A0 to A1, from A1 to A2, etc. Doens't helped.
It looks like there is some "connection" between the inputs (can it be???)
When I disconnect the other sensors and let only VBat in, the other inputs are not exactly 0, jitters around.

I'm using the 33k56k as usual.
The interresting is that when ony VBat is connected, the value is rock solid.

What can be the difference between 328p (mobidrone) and crius aio panel (mega2560)? I didn't find any important difference in the mobidrone code.

BR
Adrian

kataventos
Posts: 702
Joined: Sun Aug 28, 2011 8:14 pm
Contact:

Re: how to increase accuracy of analogRead() ?

Post by kataventos »

Well, part of this is "explained" already by nhadrian because I too have a rock solid VBAT.

I do not notice the issue because I use it (33k56k) on A0 and have no current sensor! AIOPro as well.
This weekend I will flash my D8R-II Plus for PPMSum (27msec) because of the RSSI, and after I can start to debug readings.

I am also thinking that if this problem is going to make big difference on RSSI analogue reading even with the buffer, modifying the code to read PWM (pulsein) on a free digital pin is the best way to go because almost all RX´s output PWM for this propose.

KV

copterrichie
Posts: 2261
Joined: Sat Feb 19, 2011 8:30 pm

Re: how to increase accuracy of analogRead() ?

Post by copterrichie »

Maybe this has some relevance: viewtopic.php?f=8&t=3007

kataventos
Posts: 702
Joined: Sun Aug 28, 2011 8:14 pm
Contact:

Re: how to increase accuracy of analogRead() ?

Post by kataventos »

Hamburger wrote:Seems like wiring up a test with barebone promini/nano board and two variable inputs should be my next step.


Don´t forget to report this test because this will for sure tell what is going on... :ugeek:

KV

User avatar
Hamburger
Posts: 2578
Joined: Tue Mar 01, 2011 2:14 pm
Location: air
Contact:

Re: how to increase accuracy of analogRead() ?

Post by Hamburger »

Of course.

User avatar
Hamburger
Posts: 2578
Joined: Tue Mar 01, 2011 2:14 pm
Location: air
Contact:

Re: how to increase accuracy of analogRead() ?

Post by Hamburger »

here is what I found so far:
test rig is a crius lite with two batteries+voltage divider as analog input sources; one is 1k+1k, the other 33k+56k.

- pin order for analogRead() does not matter
- two sources do influence each other, the averaged input values do change
- lowering sample speed with delay(10) or delay(100) has no impact
- when averaging single input over 50 samples, the values have a delta of about 8 (3bits)
- when averaging two input over 50 samples, the values of one input have a delta of about 8 (3bits), the other of 4bits

to bore you with some test code

Code: Select all

#define V_BATPIN                   A1 // instead of A3    // Analog PIN 3
#define PSENSORPIN           A0
#define X 50 // samples for min/max

void setup()
{
//analogReference(DEFAULT);

//I2C_PULLUPS_DISABLE       
PORTC &= ~(1<<4); PORTC &= ~(1<<5);

Serial.begin(115200); // setup serial

       ADCSRA |= _BV(ADPS2) ; ADCSRA &= ~_BV(ADPS1); ADCSRA &= ~_BV(ADPS0); //this speeds up analogRead without loosing too much resolution: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1208715493/11
// pullups disable fuer a0 a1
//PORTC &= ~(1<<0); PORTC &= ~(1<<1);

}
static uint16_t pmin =1023;
static uint16_t pmax = 0;
static uint16_t vv[X], pp[X];
static uint8_t vi = 0;
static uint8_t pi = 0;
void loop()
{
uint16_t p = 7;
//p= analogRead(PSENSORPIN);
Serial.print("P: ") ;
Serial.print(p) ;
pp[(pi++)%X] = p;
 uint16_t pmin =1023;
 uint16_t pmax = 0;
for (uint8_t i=0; i<X; i++) {
   p = pp[i];
   if (p < pmin) pmin = p;
   if (p > pmax) pmax = p;
}
Serial.print(" - ") ;
Serial.print(pmax - pmin);

Serial.print(" ---- ") ;
delay(1);

uint16_t v = 7;
v = analogRead(V_BATPIN);
Serial.print("V: ") ;
Serial.print(v) ;
vv[(vi++)%X] = v;
 uint16_t vmin =1023;
 uint16_t vmax = 0;
for (uint8_t i=0; i<X; i++) {
   v = vv[i];
   if (v < vmin) vmin = v;
   if (v > vmax) vmax = v;
}
Serial.print(" - ") ;
Serial.print(vmax - vmin);

Serial.println(".");
delay(1);
}


Next step will be to repeat with a pure nano board.

User avatar
Hamburger
Posts: 2578
Joined: Tue Mar 01, 2011 2:14 pm
Location: air
Contact:

Re: how to increase accuracy of analogRead() ?

Post by Hamburger »

still on crius board,
- two input resistances seem to influence each other,
- better result with lower resistance 1k+1k is better than 33k+33k - giving less min/max delta
- so far best with both inputs at 1k+1k, both delta 8 (3bit) most of the time, when averaged over 50 samples

time to move testing to other arduino board - but now is sunshine flying weather.

copterrichie
Posts: 2261
Joined: Sat Feb 19, 2011 8:30 pm

Re: how to increase accuracy of analogRead() ?

Post by copterrichie »

Impedance?

User avatar
Hamburger
Posts: 2578
Joined: Tue Mar 01, 2011 2:14 pm
Location: air
Contact:

Re: how to increase accuracy of analogRead() ?

Post by Hamburger »

Impedance of analog inputs?
I found a note saying 1M, which should be considered for computing because that goes in series with the external.

What confuses me is that other projects like t9x use adc for reading several pots. So it must be possible?

bicycle
Posts: 27
Joined: Sun May 06, 2012 4:58 am

Re: how to increase accuracy of analogRead() ?

Post by bicycle »

according to atmel you are supposed to have an inductor before Avcc, and decouple Aref. But i have never actually seen this done.

timecop
Posts: 1880
Joined: Fri Sep 02, 2011 4:48 pm

Re: how to increase accuracy of analogRead() ?

Post by timecop »

lol, of course. if you want to take clean analog readings, you need proper filtered power supply to avcc.

copterrichie
Posts: 2261
Joined: Sat Feb 19, 2011 8:30 pm

Re: how to increase accuracy of analogRead() ?

Post by copterrichie »

Back in the days when I was playing around with analog gyros and Accelerators, PinMode was a primary factor. Maybe the pinmode is being set someplace unknowingly.

nhadrian
Posts: 421
Joined: Tue Oct 25, 2011 9:25 am

Re: how to increase accuracy of analogRead() ?

Post by nhadrian »

Hi,

maybe we should use ARef with filtered input for reference voltage.
I tried analogReference(EXTERNAL), the values become static 1023 so I think the ARef pin is not connected to Vin at least in crius AIO Pro board.
What do you think?

BR
Adrian

copterrichie
Posts: 2261
Joined: Sat Feb 19, 2011 8:30 pm

Re: how to increase accuracy of analogRead() ?

Post by copterrichie »

I have use analogReference(EXTERNAL) when I was experimenting with analog gyros, it works very well but you have to have a very precision voltage for reference. I think what is happening in this situation is, pinmode is being activated somewhere because I have used all six analog ports (gyro and ACC) on the ATMega328 at one time without issues.

1.6 Code segment:

Code: Select all

void adc_Gyro_init(){
  //analogReference(EXTERNAL);
  pinMode(GyrX,INPUT);
  pinMode(GyrY,INPUT);
  pinMode(GyrZ,INPUT);
  gyroPresent = 1;
}

void adc_Get_AnalogGyros(){
 
    gyroADC[ROLL]   =  -(analogRead(GyrX));
    gyroADC[PITCH]  =   (analogRead(GyrY));
    gyroADC[YAW]    =  -(analogRead(GyrZ));
   
}
#endif


Note: I turned on the Interal Pullup Resistors: http://arduino.cc/en/Tutorial/AnalogInputPins

User avatar
Hamburger
Posts: 2578
Joined: Tue Mar 01, 2011 2:14 pm
Location: air
Contact:

Re: how to increase accuracy of analogRead() ?

Post by Hamburger »

the arduino nano has 100nF between Aref and Gnd. All my crius boards have that _not_.
At least, after I solder 100nF, and leave default setting of analogRef() and powering the board via a BEC and _not_ the USB port, then I get analogRead() delta down to 1 bit. :)

For a test I provided external Aref from a separate lipo cell. Then the measured values were accurate to the last bit as far as I can tell with my multimeter & lipo cell meters. When doing the math the voltages on 2 inputs were accurate to 1/100 Volt. Good enough.

So for crius boards best advice seems to be: add 100nF cap between pin20 Aref and pin21 Gnd (or wherever you find accessable gnd). This should allow us to remove the software averaging completely!

Ok, so new question is: which boards have the 100nF cap already onboard?
+ arduino nano (according to schematics, not verified yet - I do not currently fly separate nano+freeimu)
- crius lite
? crius mini
? crius aiop 2560
+ nanoWii prototype 1uF
? nanoWii
+ ???

User avatar
Hamburger
Posts: 2578
Joined: Tue Mar 01, 2011 2:14 pm
Location: air
Contact:

Re: how to increase accuracy of analogRead() ?

Post by Hamburger »

bad - with two analogRead() adding the cap seems to not be good enough, especially when varying loads like servos are added to the power train.
Best result so far was with adding an external Vref (separate lipo cell). Are there not special ICs which provide very accurate Vref - better than your standard linear voltage regulator?

User avatar
EOSBandi
Posts: 802
Joined: Sun Jun 19, 2011 11:32 am
Location: Budapest, Hungary
Contact:

Re: how to increase accuracy of analogRead() ?

Post by EOSBandi »

Hamburger wrote:bad - with two analogRead() adding the cap seems to not be good enough, especially when varying loads like servos are added to the power train.
Best result so far was with adding an external Vref (separate lipo cell). Are there not special ICs which provide very accurate Vref - better than your standard linear voltage regulator?

Look for voltage reference IC's there are many of them.... for example : http://hu.farnell.com/jsp/search/browse ... allpartial

User avatar
KasparsL
Posts: 75
Joined: Wed May 16, 2012 3:31 pm

Re: how to increase accuracy of analogRead() ?

Post by KasparsL »

Are you sure using Internal voltage refference (1.1V)? Or is it set to VCC? The cap at the Vref should be atleast 10uf and good (ceramic or tantalum).

User avatar
Hamburger
Posts: 2578
Joined: Tue Mar 01, 2011 2:14 pm
Location: air
Contact:

Re: how to increase accuracy of analogRead() ?

Post by Hamburger »

I am currently using default internal - I think that is 5V.
The cap with 10uF is new to me. Is that from atmel specs?. Arduino uses 100nF on nano.
An external vref was my hope to get this issue solved for good. At least once I buy such ICs and find someone to do the soldering on the mega2560 boards for me.

User avatar
Hamburger
Posts: 2578
Joined: Tue Mar 01, 2011 2:14 pm
Location: air
Contact:

Re: how to increase accuracy of analogRead() ?

Post by Hamburger »

nhadrian wrote:Could you please check if the crius aio pro have any cap/resistors attached to the analog inputs? (Unfortunatelly I can't see the circuit because I have an extend board built in).

Adrian,
I did not find any cap attached to Vref pin on crius aio pro (mega2560); seems the board's designer was consistent throughout the entire product line.

User avatar
Hamburger
Posts: 2578
Joined: Tue Mar 01, 2011 2:14 pm
Location: air
Contact:

Re: how to increase accuracy of analogRead() ?

Post by Hamburger »

KasparsL wrote:Are you sure using Internal voltage refference (1.1V)? Or is it set to VCC? The cap at the Vref should be atleast 10uf and good (ceramic or tantalum).

Only reference to the value of cap I found here. Maybe the 10uF is for smoothing the VCC?
AVR042 wrote:To be able to obtain good accuracy with the ADC the analog supply voltage must be
decoupled separately, in the same manner as the digital supply voltage. AREF must
also be decoupled, a typical value for the capacitor is 100nF.

User avatar
shikra
Posts: 783
Joined: Wed Mar 30, 2011 7:58 pm

Re: how to increase accuracy of analogRead() ?

Post by shikra »

Sounds like your using Default not internal. Definitely need a smooth filtered supply if you want really accurate voltage measure

That is your max pin voltage from the resistor ladder? on the mega there is an accurate internal reference of 2.5v You can use that if the pin voltage is not higher.

I thought its analogReference(3);
But looking at the arduino ref page it says INTERNAL2V56 so maybe thats is correct - or the same!

User avatar
Hamburger
Posts: 2578
Joined: Tue Mar 01, 2011 2:14 pm
Location: air
Contact:

Re: how to increase accuracy of analogRead() ?

Post by Hamburger »

yes, so far I have used the MWii default which is DEFAULT. What options are available depends on the mcu.
http://arduino.cc/en/Reference/AnalogReference wrote: DEFAULT: the default analog reference of 5 volts (on 5V Arduino boards) or 3.3 volts (on 3.3V Arduino boards)
INTERNAL: an built-in reference, equal to 1.1 volts on the ATmega168 or ATmega328 and 2.56 volts on the ATmega8 (not available on the Arduino Mega)
INTERNAL1V1: a built-in 1.1V reference (Arduino Mega only)
INTERNAL2V56: a built-in 2.56V reference (Arduino Mega only)
EXTERNAL: the voltage applied to the AREF pin (0 to 5V only) is used as the reference.

Using INTERNAL is on my list.
Using EXTERNAL will require a special RefVoltage IC.

User avatar
KasparsL
Posts: 75
Joined: Wed May 16, 2012 3:31 pm

Re: how to increase accuracy of analogRead() ?

Post by KasparsL »

Hamburger wrote:I am currently using default internal - I think that is 5V.
The cap with 10uF is new to me. Is that from atmel specs?. Arduino uses 100nF on nano.

It is from personal experience. For me 10uf was good value ;) .

p.s.
i have done one project which required oversampling on Atmega - there was better to have smaller cap to get more noise from which to average the signal.

User avatar
Hamburger
Posts: 2578
Joined: Tue Mar 01, 2011 2:14 pm
Location: air
Contact:

Re: how to increase accuracy of analogRead() ?

Post by Hamburger »

KasparsL wrote:It is from personal experience. For me 10uf was good value ;) .

ok :) I would have tried that too but I just burnt my cirus lite test board with wrong polarity on vbat pin.

Anyway I used a crius aiop mega board (unmodified) and have found the following combo to be an improvement
- read at most one analog channel per MWii main loop cycle
- disable the ADCSRA speedup of analog reads
- make len of averaging vector a config item for psensor and vbat readings.

This is available in r1375 now. It would be good if this got tested for rssi reading as well.

I found another note @atmel saying that after switching to another (multiplexed) analog channel the first (few?) values of analogRead() could not be trusted and should be ignored. This I have not followed further but it would be easy to implement if neccessary.

User avatar
Hamburger
Posts: 2578
Joined: Tue Mar 01, 2011 2:14 pm
Location: air
Contact:

Re: how to increase accuracy of analogRead() ?

Post by Hamburger »

Alex asked for some more hard facts, so here's some
My test rig was
- crius lite board with oled,
- two large lipo cells with different voltages attached to two analog inputs,
- board powered from external 5V regulator from 3rd battery, no usb attached (usb voltage cannot be trusted as being clean here)

Reading each of the two analog channels P (powersensor) and V (battery voltage) gave (observing over a minute)
P 524-528
V 800-806

Repeat with removing the speedup via ADCSRA asignments. Now
P 522-523
V 799-802

The span of the assembled data dropped from 3bit to 1bit or 2bit.
The overall lower voltages between first and second run may be the result of the declining batteries - I use old lipos for bench testing mostly.

Repeated this test several times. Varying values but the trend of reducing the span was consistently observable.

I did run that same test with one fixed battery voltage and one current sensor with motor+prop combo which provided varying voltage. The varying value from current sensor seemed to introduce even more jitter into the other value. Again, removing the speedup seemed to lessen this influence and thus the jitter. No hard data for this test though.

To me that justifies (optionally) removing the speedup and taking the time penalty in order to get better accuracy.
My guess is that for future use, better boards would have to come with a proper cap or even better a special Vref source IC at the Vref pin.

kataventos
Posts: 702
Joined: Sun Aug 28, 2011 8:14 pm
Contact:

Re: how to increase accuracy of analogRead() ?

Post by kataventos »

I can confirm that RSSI is totally unusable at this time on the FC.

It influences a little on VBAT but the worse is the inaccuracy of the RSSI. Dramida asked me to double check the RSSI code because when he turns off the TX the value goes to 100% for 1 second then it starts to go down.

When TX is ON (e.g) ADC is 151 and 37 with TX OFF, but somehow when the RSSI is in some kind of 50% the ADC is 255 so, it seems OK until certain value !??! Now, this is a rare thing...
I noticed too that when I turn off my TX the ADC jumps to 255 one or two times before go to 37. (confirm what Dramida experienced before)

When measuring from the OSD it works exactly as it should with 100% accuracy.

I inspired myself on the MW lines using a moving average for VBAT and used it on the OSD code since KV Team 2.1, the difference´s between, are easy to catch and made all the difference on accuracy and softness ;)

Code: Select all

if (!Settings[S_MAINVOLTAGE_VBAT]){
      static uint8_t ind = 0;
      static uint16_t voltageRawArray[8];
      voltageRawArray[(ind++)%8] = analogRead(voltagePin);                 
      uint16_t voltageRaw = 0;
      for (uint8_t i=0;i<8;i++)
        voltageRaw += voltageRawArray[i];
      voltage = float(voltageRaw) * Settings[S_DIVIDERRATIO] * (1.1/102.3/4/8); 
    }


Cheers,
KV

kataventos
Posts: 702
Joined: Sun Aug 28, 2011 8:14 pm
Contact:

Re: how to increase accuracy of analogRead() ?

Post by kataventos »

Hamburger wrote:ok :) I would have tried that too but I just burnt my cirus lite test board with wrong polarity on vbat pin.

Anyway I used a crius aiop mega board (unmodified) and have found the following combo to be an improvement
- read at most one analog channel per MWii main loop cycle
- disable the ADCSRA speedup of analog reads
- make len of averaging vector a config item for psensor and vbat readings.

This is available in r1375 now. It would be good if this got tested for rssi reading as well.

I found another note @atmel saying that after switching to another (multiplexed) analog channel the first (few?) values of analogRead() could not be trusted and should be ignored. This I have not followed further but it would be easy to implement if neccessary.


Upppsss sorry about your lost and for missed this post...

Sure I can try it with RSSI asap...

KV

Alexinparis
Posts: 1630
Joined: Wed Jan 19, 2011 9:07 pm

Re: how to increase accuracy of analogRead() ?

Post by Alexinparis »

Hamburger wrote:Alex asked for some more hard facts, so here's some
My test rig was
- crius lite board with oled,
- two large lipo cells with different voltages attached to two analog inputs,
- board powered from external 5V regulator from 3rd battery, no usb attached (usb voltage cannot be trusted as being clean here)

Reading each of the two analog channels P (powersensor) and V (battery voltage) gave (observing over a minute)
P 524-528
V 800-806

Repeat with removing the speedup via ADCSRA asignments. Now
P 522-523
V 799-802

The span of the assembled data dropped from 3bit to 1bit or 2bit.
The overall lower voltages between first and second run may be the result of the declining batteries - I use old lipos for bench testing mostly.

Repeated this test several times. Varying values but the trend of reducing the span was consistently observable.

I did run that same test with one fixed battery voltage and one current sensor with motor+prop combo which provided varying voltage. The varying value from current sensor seemed to introduce even more jitter into the other value. Again, removing the speedup seemed to lessen this influence and thus the jitter. No hard data for this test though.

To me that justifies (optionally) removing the speedup and taking the time penalty in order to get better accuracy.
My guess is that for future use, better boards would have to come with a proper cap or even better a special Vref source IC at the Vref pin.

Ok, thanks. It's clearer.

I just want to warn that without the ADCSRA line, the conversion ADC time also increases and lasts some time a lot (100 or 200 microseconds and not steady). It's just something to know

User avatar
Hamburger
Posts: 2578
Joined: Tue Mar 01, 2011 2:14 pm
Location: air
Contact:

Re: how to increase accuracy of analogRead() ?

Post by Hamburger »

kataventos wrote:Upppsss sorry about your lost and for missed this post...
Sure I can try it with RSSI asap...

funny thing is I was amused at the smell for quite some time. When it hit me, it was too late already. The good side: one step closer to another hardware upgrade for another copter.

Yes, please try the RSSI with the switching between different channels for readings.

nhadrian
Posts: 421
Joined: Tue Oct 25, 2011 9:25 am

Re: how to increase accuracy of analogRead() ?

Post by nhadrian »

Hi Hamburger,

With your latest r1376 VBAT, PMETER and RSSI works together on Crius AIO Pro!
Thanks, great job!

Here is my setup for Flytron 25A ultralight current sensor:

Code: Select all

    //#define POWERMETER_SOFT
    #define POWERMETER_HARD
    /* PLEVELSCALE is the step size you can use to set alarm */
    #define PLEVELSCALE 50 // if you change this value for other granularity, you must search for comments in code to change accordingly
    /* larger PLEVELDIV will get you smaller value for power (mAh equivalent) */
    //#define PLEVELDIV 5000 // (*) default for soft - if you lower PLEVELDIV, beware of overrun in uint32 pMeter
    #define PLEVELDIV 36000 // fixed value for hard - do not tune
    //#define PLEVELDIVSOFT PLEVELDIV // for soft always equal to PLEVELDIV
    #define PLEVELDIVSOFT 5000 // for hard fixed to 5000
    #define PSENSORNULL 0 // (*) set to analogRead() value for zero current; for I=0A my sensor gives 1/2 Vss; that is approx 2.49Volt;
    #define PINT2mA 50 // (*) one integer step on arduino analog translates to mA (example 4.9 / 37 * 1000


BR
Adrian

User avatar
Hamburger
Posts: 2578
Joined: Tue Mar 01, 2011 2:14 pm
Location: air
Contact:

Re: how to increase accuracy of analogRead() ?

Post by Hamburger »

Hi Adrian.
That is fantastic news!
So I understand accuracy for all 3 sensors is ok now for your setup? Which averaging lengths for voltage and current do you use?
I did my latest tests with aiop too.
Have fun flying.

nhadrian
Posts: 421
Joined: Tue Oct 25, 2011 9:25 am

Re: how to increase accuracy of analogRead() ?

Post by nhadrian »

Hamburger wrote:Hi Adrian.
That is fantastic news!
So I understand accuracy for all 3 sensors is ok now for your setup? Which averaging lengths for voltage and current do you use?
I did my latest tests with aiop too.
Have fun flying.


I use the default length for both.
It looks like now pmeter and rssi doesn't have influence on vbat value! That's great.
But, since my RSSI output is quite noisy (measured by multimeter also...), so I had to add more length.
Now I defined RSSI_SMOOTH 32 with this code modification:

Code: Select all

  #if defined(RX_RSSI)
  case 2:
  {
    static uint8_t ind = 0;
    static uint16_t rvec[RSSI_SMOOTH], rsum;
    uint16_t r = analogRead(RX_RSSI_PIN);
    #if RSSI_SMOOTH == 1
      analog.rssi = rssiRaw;
    #else
      rsum += r;
      rsum -= rvec[ind];
      rvec[ind++] = r;
      ind %= RSSI_SMOOTH;
      r = rsum / RSSI_SMOOTH;
      analog.rssi = r;
    #endif
    break;
    }
  #endif


BR
Adrian

User avatar
Hamburger
Posts: 2578
Joined: Tue Mar 01, 2011 2:14 pm
Location: air
Contact:

Re: how to increase accuracy of analogRead() ?

Post by Hamburger »

Ok looking good.
I think your mod should go into the official code. Add the define to the other two in config.h

nhadrian
Posts: 421
Joined: Tue Oct 25, 2011 9:25 am

Re: how to increase accuracy of analogRead() ?

Post by nhadrian »

Hamburger wrote:Ok looking good.
I think your mod should go into the official code. Add the define to the other two in config.h


Hi,

in the shared r1379, I think this line should be modified:

Code: Select all

    #if RSSI_SMOOTH == 1
       analog.rssi = rssiRaw;
    #else


to this:

Code: Select all

    #if RSSI_SMOOTH == 1
       analog.rssi = r;
    #else


because we don't use the rssiRaw anymore for reading:

Code: Select all

    uint16_t r = analogRead(RX_RSSI_PIN);


BR
Adrian

User avatar
Hamburger
Posts: 2578
Joined: Tue Mar 01, 2011 2:14 pm
Location: air
Contact:

Re: how to increase accuracy of analogRead() ?

Post by Hamburger »

I had inserted that correction for r1379 already :)

kataventos
Posts: 702
Joined: Sun Aug 28, 2011 8:14 pm
Contact:

Re: how to increase accuracy of analogRead() ?

Post by kataventos »

Hi,

thanks nhadrian, that was supposed to be my work and I have already made some (I am slow)... but I must say that no more work should be done on that :oops: you have already done it!

Looks precisely what we need, I will test it during next week.

Cheers,
KV

kataventos
Posts: 702
Joined: Sun Aug 28, 2011 8:14 pm
Contact:

Re: how to increase accuracy of analogRead() ?

Post by kataventos »

@ Hamburger,

Hi hope you are fine ;)

Using r1391
Please change to this or no compilation using POWERSOFT:

Code: Select all

if (analog.vbat > conf.vbatlevel_crit) { // by all means - must avoid division by zero


Cheers,
KV

Post Reply