What is wrong with my ADC setup ?

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

I am looking at this for a few hours now and I simply can't see why this setup does not result in free running ADC. I'm on attiny85.

 

void setup_adc()
{
	// Init ADCSRA and B
	ADCSRA = 0;
	ADCSRB = 0;

	// Set ADC to do 8 bit resolution (left align and we will only use ADCH)
	sbi(ADMUX, ADLAR);

	// Set PB2 (ADC1) as input
	sbi(ADMUX, MUX0);

	// Disable digital input on PB2, we will only need it for ADC
	sbi(DIDR0, ADC1D);

	// Perform clk/128 conversions per second (which is more than enough)
	sbi3(ADCSRA, ADPS0, ADPS1, ADPS2);

	// Choose pin change interrupt as ADC trigger
	//sbi2(ADCSRB, ADTS1, ADTS2); Free running for now

	// Finally enable auto-trigger, conversion complete interrupt and ADC as a whole
	sbi3(ADCSRA, ADATE, ADIE, ADEN);
}

I'm not getting any calls to the ADC complete interrupt handler:

ISR(ADC_vect)
{
	adcData = ADCH;
	adcDataAvailable = 1;
}

I am already using PWM on timer 0 and 1 (for some reason PWM on timer 1 does not seem to run without start PWM on timer 0).

 

Anyway, my question is whether anyone can see what I am missing in my setup ? I'm clueless. Tried different examples. Setting ADCSRA and B to 0 is the result of being desperate, that shouldn't be necessary, right ?

 

Many thanks,

 

Henk

 

PS: I do start a first conversion:

 

	setup_pwm();
	setup_adc();
	
	// Turn on Pin Change interrupt
	//sbi(GIMSK, PCIE);
	
	// Enable external interrupt on PB2
	//sbi(PCMSK, PCINT2);

	//clearNote();

	// Start conversion
	sbi(ADCSRA, ADSC);

	sei();

 

Last Edited: Tue. Nov 24, 2020 - 04:40 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Why are you using this strange notation?    Why not just say  ADCSRA =what you want   ???  

 

in any case, you can see from the table ADCSRB,  ADTS2/1/0 must be zero for free running---but THAT IS NOT what your are setting them to

 

You have two (actually 3) different lines changing ADCSRA --why?   why not use one  ADCSRA=  kgkjgkf;fg

set it in ONE place , then there can be no doubt, confusion, overlooking anything.   At least the makes it simpler to see what is going on.

 

Are you sure the ISR is not  tripping?  How do you know?

 

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

Last Edited: Tue. Nov 24, 2020 - 06:45 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I just like to take one step at a time. I just dislike the Blah = _BV(bit1) | _BV(bit2) etc stuff.

 

Anyway, I did set ADCSRB to 0, the line you're referring to is commented out to enable free running for now. My hardware design suffers from my lack of really understanding analog electronics. The moment I come up with something better I will change to pin change interrupt for triggering ADC. That's the commented-out line ...

 

The ISR isn't tripping because I've set it up to high a digital pin. Which stays low ...

 

Many thanks,

 

Henk

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

The ISR isn't tripping because I've set it up to high a digital pin. Which stays low ...

You ISR isn't setting any pin at all---so how do you check the ISR is not working?  What do you use to see it being called?

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

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

That's how I found out ... I changed the ISR back to what I want it to do (which is basically take the last reading of a potmeter strip). When I wanted to make sure it was called I used it to set PB1 to high.

 

Manual ADC does work, BTW (just setting ADEN and skipping ADIE and ADATE).

 

What are my options, not having the ability to do live on-chip debugging, to find out otherwise ?

 

Many thanks,

 

Henk

 

PS: I meant 'I've set it up', past perfect. Like in, I did that yesterday. English is not my native tongue, so I may cripple the actual meaning of what I wanted to say in strange and unexpected ways ...

Last Edited: Tue. Nov 24, 2020 - 08:24 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You can toggle a pin in the ISR & watch on the scope to see when you get the IRQ.

 

most AVR let you toggle an output pin easy by writing 1 to the corresponding PIN register bit

 

In your isr you can compare the result to, say 100, & if above 100 turn on an led & below, turn off the led....then hook up a pot & try it out.  So you can verify the ADC is giving something useful.

You can do a similar in main, assuming the result makes it that far.

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

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

That's *exactly* what I did. First compare to some magic number (11 in my case, but that's due to my hardware). And when I didn't trust the reading, just blindly toggle a pin in the ISR regardless.

 

The pin doesn't toggle. So the ISR is never fired.

 

I'm doing a FAST pwm on timer 0 and 1 on a attiny85. Can it be that I'm just asking too much of it ?

 

Many thanks,

 

Henk

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

I'm doing a FAST pwm on timer 0 and 1 on a attiny85. Can it be that I'm just asking too much of it ?

No, you are asking for nothing, really. 

 

If you accidentally turned on a timer IRQ, but don't have a coded IRQ routine for it...that will result in disaster!!!  Or you could have a timer IRQ (or any IRQ) that never finishes for some reason (like waiting for aaa == aaa+3 )...so the system gets stuck. 

 

I am already using PWM on timer 0 and 1 (for some reason PWM on timer 1 does not seem to run without start PWM on timer 0).

Never ignore such mysteries...they are often "warnings" of some underlying trouble.   Trouble in one code spot bleeds into another until it finds you. 

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

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

I'm sorry, I didn't show all code. There are handlers for all interrupts ...

 

BUT, I'm eternally grateful for your remark on timer 0!! I read somewhere there's been a bug in the tiny85 where PWM wouldn't start unless timer 0 was also configured to do PWM. I just blindly assumed this to be the truth (the attiny85 is new for me, I'm usually on the mega 328). Your remark caused me to re-inspect my complete setup and ... my fuses were off! I had internal 8 MHz clock on CKSEL which had to be PLL ...

 

I now have a working PWM setup with just timer 1 and I will try free running ADC again ...

 

Many thanks,

 

Henk