Go Down

Topic: ADC Noise Reduction code please (Read 21621 times) previous topic - next topic

Todd Houstein

Can someone please provide code for using ADC Noise Reduction when reading an analog input? Thanks!

Coding Badly


http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1294478456/14#14

Todd Houstein

Thanks Coding Badly.  The thread you've linked to is too long and complex for a noob like me.  Where is the analog pin to be read defined? Where is the call made to read it with the ADC?

Todd Houstein

Would this work?

Code: [Select]
#include <avr/sleep.h>

void setup()
{
 Serial.begin(9600);
}

void loop()
{
 int reading;
 
 reading = analogNoiseReducedRead(0);
 Serial.println();
 delay(500);
}

int analogNoiseReducedRead(int pinNumber)
{
 int reading;
 
 ADCSRA |= _BV( ADIE );             //Set ADC interrupt
 set_sleep_mode(SLEEP_MODE_ADC);    //Set sleep mode
 reading = analogRead(pinNumber);   //Start reading
 sleep_enable();                    //Enable sleep
 do
 {                                  //Loop until reading is completed
   sei();                           //Enable interrupts
   sleep_mode();                    //Go to sleep
   cli();                           //Disable interrupts
 } while(((ADCSRA&(1<<ADSC))!= 0)); //Loop if the interrupt that woke the cpu was something other than the ADC finishing the reading
 sleep_disable();                   //Disable sleep
 ADCSRA &= ~ _BV( ADIE );           //Clear ADC interupt
 sei();                             //Enable interrupts
 
 return(reading);
}

Coding Badly

Quote
Where is the analog pin to be read defined?


The answer is in the link I gave you...

Quote
You must set ADMUX before calling this function.


There's at least one example in that thread...
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1294478456/8#8

For more details, refer to the datasheet.

Quote
Where is the call made to read it with the ADC?


Another quote from that link...

Quote
This performs an A/D conversion using the current ADMUX settings.


Coding Badly

Quote
Would this work?

No.  The Arduino core does not support Noise Reduction Mode.  You will have to manipulate the registers directly.

Todd Houstein

Well, I'm sure a lot of people would find it useful to have a function that reads an analog input using ADC noise reduction, defined as such:

int analogNoiseReducedRead(int pinNumber)

But coding this is beyond my knowledge and skills. Anyone feel like taking it on and posting it here?

Coding Badly

Quote
Well, I'm sure a lot of people would find it useful to have a function that reads an analog input using ADC noise reduction

Why?  Have you noticed a problem with analogRead?

Todd Houstein

Quote
Have you noticed a problem with analogRead?


My analogRead values have been jumping around a bit. Admittedly, this could be due to any number of reasons.  However, I figured Atmel must have put the noise reduction mode in for a reason and thought I'd give it a try first.  But this didn't turn out to be so straightforward with Arduino, so I'm on to looking at my hardware now.

Coding Badly


In my experimenting, jumping analog readings are caused by...

1. General digital noise.  Cured by adding a 0.1 uF capacitor across VCC and GND as close to the processor as possible.  Already present on Arduino.

2. General digital noise.  Cured by adding a capacitor from AREF to GND and using the appropriate analog reference setting

3. General digital noise.  Cured by adding filtering to the analog input.

4.  CPU digital noise.  Cured by using Noise Reduction Mode.


I've only had problems with #4 on ATtiny processors or when reading the internal temperature sensor.  For the rest, the Atmel documentation is a good source of information and Grumpy_Mike has graciously written about filtering.  If you still have problems after adding filtering then it's time to add Noise Reduction Mode.

However, Noise Reduction Mode certainly won't hurt anything.

retrolefty

Quote
2. General digital noise.  Cured by adding a capacitor from AREF to GND and using the appropriate analog reference setting


Interestingly I found a difference in behaviour between my clone serial rs-232 mega328 board and my Seeeduino mega board.

The 328 board using standard arduino AVcc reference and using simple analogRead() statements, did show a few counts of noise on typical reads, that was improved pretty well by wiring a .1 mfd cap from Aref pin to ground. The Seeeduino mega on the other hand showed no noise even without a cap.

Not sure the difference is because of different processor chips or just differences in board layout.

Lefty

Coding Badly

Quote
just differences in board layout

That's my guess.  In their datasheets, Atmel makes a big deal about having "a digital ground plane" and "an analog ground plane" and separating digital pins from analog pins and other such stuff that's all Greek to me.  The point is, they imply and state that less digital noise = better analog readings.  They also imply and state that good board layout = less digital noise.

I've noticed that a pin generating a PWM signal near (a few rows away on a breadboard) an analog pin can cause problems.

Go Up