A task to take values from the ADC on the arduino nano ATmega168PA

Hi everybody! I had a task to take values from the ADC on the arduino nano ATmega168PA. I noticed that the ADC value changes in the range of 40 values while the voltage on the multimeter is stable. What could be? How to overcome the noise problem?

Please show your test code and connection diagram

Smooth the raw data as your multimeter did.

1 Like
// Подключаем библиотеки
#define F_CPU 16000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <math.h>
#include <avr/interrupt.h>






// Define pins
#define HEATER_PIN PB0 // Heater pin (relay on/off)
#define CHECK_PIN PB1 // LED RED
#define TEMP_PIN PC2 // Temperature sensor pin PC2

// Define variables
//volatile float temp; // Current temperature in Celsius
volatile float u; // Control signal
volatile float I=0; // Integral component

void initADC()
{
	ADMUX = (1 << REFS1) | (1 << REFS0) | (1 << MUX1) ; // Select internal 1.1V reference and ADC5 channel
	ADCSRA = (1 << ADEN) | (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0); // Enable ADC, set prescaler to 128
}

// Initialize timer
void initTimer()
{
  TCCR1A = (1 << WGM01); // Set CTC mode
  TCCR1B = (1 << CS01) | (1 << CS00); // Set prescaler to 64
  OCR1B = 0x61A8; // Set compare match value to 25000, 100ms
  TIMSK1 = (1 << OCIE1B); // Enable compare match interrupt
}




// Interrupt service routine for timer compare match
ISR(TIMER1_COMPB_vect)
{
  uint16_t adcValue; // ADC value variable
  
  ADCSRA |= (1 << ADSC); // Start ADC conversion
  
  while(ADCSRA & (1 << ADSC)); // Wait for conversion to complete
  
  adcValue = ADCW; // Read ADC value
  Serial.println(ADCW);
  
}

// Main function
int main(void)
{
  DDRB |= (1 << HEATER_PIN); // initialization of the pin (heater) to the output
  DDRB |= (1 << CHECK_PIN); // initialization of the red test LED
   // Set the PC2 pin to read
  DDRC &= ~(1 << TEMP_PIN);
 // Turn on the internal pull-up resistor on pin PC2
  PORTC &= ~(1 << TEMP_PIN);
  
  
  Serial.begin(9600);
  initTimer();    // Initialize timer
  initADC();
  sei();      // Enable global interrupts
  
  while(1)
  {
    
    // Do other tasks if needed
    
  }
  
  return 0;
  
}

How to do it? I posted my code.

Hello roman_arduino

Take a view to gain the knowledge:

Your code is way overcomplicated. Why all this dances with registers, if finally your code is almost equivalent to this:

void setup() {
Serial.begin(9600);
analogReference(INTERNAL);
}
void loop() {
Serial.println(analogRead(A0));
delay(100);
}

You use 1.1v reference, so the 40 units of ADC is only +/-0.02v. Your multimeter may not notice this changes.

And how then to configure the program? I wanted to take values in the range from 0 (0 ADC value) to 1.1 volts (1023 ADC value).

Blocking code and serial I/O in interrupt context - going for all the no-nos, huh?

2 Likes

What do you need to configure?

I need that at approximately constant voltage, the ADC value shows more or less the same value.

I think this has nothing to do with your program and its configuration.
The voltage variations has a completely external cause.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.