ATMEGA 2560/ Arduino ADC does not work

Go To Last Post
5 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi guys.

 

Need your help.

 

I wanted to control a PWM with an ADC value from a Poti.

If I only run the PWM the LED gets brighter and darker as expected.

 

When I try to use a ADC it seems that the ADC does not start. The ADCH is always "0x00". Did I make a mistake?

As analog input I use a poti with pull down resistor.

 

I read a couple of webpages on the internet but nothing worked... :-(

 

Thanks in advance!!!

#include <avr/io.h>
#include <avr/interrupt.h>

#define F_CPU 16000000UL
#include <util/delay.h>

void init_TMR1_PWM(int ocr_wert)//CTC init
{
	TCCR1A = (1<<COM1A1)|(0<<COM1A0)|(0<<WGM11)|(1<<WGM10);
	TCCR1B = (0<<WGM13)|(1<<WGM12)|(1<<CS12)|(0<<CS11)|(1<<CS10);
	OCR1A = 0;
}

void set_OCR1A(char ocr_wert) //setpoint for LED
{
	OCR1A = ocr_wert;
}

void LED_rise_fall(void) //CTC PWM
{
	char i;
	for (i = 0; i < 255; i++ )
	{
		set_OCR1A(i);
		_delay_ms(1);
	}
	for (i = 0; i < 255; i++ )
	{
		set_OCR1A(255-i);
		_delay_ms(1);
	}
}

void init_ADC()
{
	//AD0 connected = Pin22 = PA0
	//AVcc is ref
	//Left justified
	//Prescaler 128
	ADCH = 0;
	ADCL = 0;
	ADMUX = (0<<REFS1)|(1<<REFS0)|(1<<ADLAR)|(0<<MUX4)|(0<<MUX3) |(0<<MUX2)|(0<<MUX1)|(0<<MUX0);
	ADCSRB = (0<<MUX5)|(0<<ADTS2)|(0<<ADTS1)|(0<<ADTS0);
	ADCSRA = (1<<ADEN)|(0<<ADSC)|(0<<ADATE)|(0<<ADIF)|(0<<ADIE)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS1);
	DIDR0 = (1<<ADC0D);
}

char ADC_measure()
{
	ADCSRA = (1<<ADSC);

	loop_until_bit_is_clear(ADCSRA, ADSC); //should run until conversion is finished
	char temp = ADCH; //read ADCH because it is left justified

	return temp;
}

int main(void)
{
	DDRB |= (1<<PB5);//LED
	DDRA = (0<<PA0);//AD0 is used
	init_TMR1_PWM(0x000F);//for the PWM; see LED_rise_fall()
	init_ADC();
	while(1)
	{
		set_OCR1A(ADC_measure()); //doesn't work
		//LED_rise_fall(); //works perfectly fine if active
	}

}

 

Last Edited: Mon. Jan 29, 2018 - 02:30 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

andi_avr_2560 wrote:
As analog input I use a poti with pull down resistor.

 

Can you elaborate on this along with a schematic of the circuit?

 

Jim

 

EDIT: And where do you call the READ ADC routine?  Otherwise your reading could be anything...in this case 0x00.

 

EDIT AGAIN:  I looked some more and there is no way this code will work the way you want it to.  Use the ADC reading to set the OCR1A register and let the PWM do its job.  The FOR loops are not needed if you set the PWM up properly.

If you want a career with a known path - become an undertaker. Dead people don't sue! - Kartman

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB user

Last Edited: Mon. Jan 29, 2018 - 02:20 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

jgmdesign wrote:

andi_avr_2560 wrote:
As analog input I use a poti with pull down resistor.

 

Can you elaborate on this along with a schematic of the circuit?

 

Jim

 

EDIT: And where do you call the READ ADC routine?  Otherwise your reading could be anything...in this case 0x00.

 

EDIT AGAIN:  I looked some more and there is no way this code will work the way you want it to.  Use the ADC reading to set the OCR1A register and let the PWM do its job.  The FOR loops are not needed if you set the PWM up properly.

Schematic:

EDIT 1: Sorry I tried something else and did forget to change it back to

set_OCR1A(ADC_measure());

EDIT 2:The LED_rise_fall() in the main() is not active. That was just to test if the PWM works.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

A good, clear, in-focus photograph (or photographs) showing how you've actually wired it up would also be good ...

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
Last Edited: Mon. Jan 29, 2018 - 02:39 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

andi_avr_2560 wrote:
and did forget to change it back to
Never do that - folks reading fora like this put in their precious time to try and help others, it's a waste of their time if you don't post the same code that actually has the problem you are trying to solve.

 

BTW not that it matters but this:

	char temp = ADCH; //read ADCH because it is left justified

	return temp;

could simply be:

	return ADCH;

No need for 'temp'

 

BTW the ADC reading can only ever return 0..255 (it is uint8_t) but OCR1A is uint16_t and can hold 0..65535. Is this intentional that OCR1A is only ever set to the bottom 1/256th of its range? Did you perhaps mean:

set_OCR1A(ADC_measure() * 256);

or similar?