Pages: [1]   Go Down
Author Topic: ADC Noise Reduction code please  (Read 16007 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Newbie
*
Karma: 0
Posts: 15
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Global Moderator
Dallas
Offline Offline
Shannon Member
*****
Karma: 200
Posts: 12779
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset


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

0
Offline Offline
Newbie
*
Karma: 0
Posts: 15
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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?
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 15
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Would this work?

Code:
#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);
}
Logged

Global Moderator
Dallas
Offline Offline
Shannon Member
*****
Karma: 200
Posts: 12779
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Global Moderator
Dallas
Offline Offline
Shannon Member
*****
Karma: 200
Posts: 12779
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Would this work?
No.  The Arduino core does not support Noise Reduction Mode.  You will have to manipulate the registers directly.
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 15
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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?
Logged

Global Moderator
Dallas
Offline Offline
Shannon Member
*****
Karma: 200
Posts: 12779
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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?
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 15
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Global Moderator
Dallas
Offline Offline
Shannon Member
*****
Karma: 200
Posts: 12779
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset


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.
Logged

Left Coast, CA (USA)
Online Online
Brattain Member
*****
Karma: 361
Posts: 17263
Measurement changes behavior
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Global Moderator
Dallas
Offline Offline
Shannon Member
*****
Karma: 200
Posts: 12779
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Pages: [1]   Go Up
Jump to: