## how to set lower adc precision value on Atmega16?

6 posts / 0 new
Author
Message

Hi, i'm new to programming and micro-controllers and i would like to get a 6 bit adc precision in my Atmega16 project, to get values from 0 to 64 instead of 0 to 255.

here's my code for now :

{
ADMUX = channel & 0x07;            // single ended channel 0..7
ADMUX |= (0 << REFS1) | (0 << REFS0);            // AVCC as reference

return ADCH;                // 8 bit precision and i need 6 bit

This topic has a solution.

Hi, i'm new to programming and micro-controllers and i would like to get a 6 bit adc precision in my Atmega16 project, to get values from 0 to 64 instead of 0 to 255.

??? Do you mean 0-63?

Did you mean 0-1023 from a 10 bit result?

The obvious answer to your question is "divide by 4" (or equivalently shift two places), isn't it?

Tell why you "need 6 bit"?  Now, your derived control signal may be desired in a different range.  So you gather a full ADC result, filtering/averaging as needed.  Then you apply a transfer function to relate the ADC reading (e.g. speed) into the units you desire (e.g. furlongs per fortnight, 0-63).  And that transfer function is /4.

In the real world it usually isn't quite that cut-and-dried.  The "/4" is often a multiply and divide with calibration factors, perhaps with an offset.  (Can you say "y = (rise/run)*x + b" ?)

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

yes 0-63

why? i making a midi controller for a program that cant recive CC values higher than 64 (or 63).

/4 does it mean return ADCH/4 ;? can you give me an exemple? (i know that 255/4 is 63.75 but i thought that making something like ADMUX |= (ADLAR>>2) would be better;

according to http://maxembedded.com/2011/06/t... if you have 10 bit adc precision it gives you max value of 2^10 = 1024 so i think if i will use 6 bit precision i will get max value of 64 2^6 = 64.

Last Edited: Tue. May 19, 2015 - 03:31 PM
This reply has been marked as the solution.

uint16_t control value;

...

// I guess 8-bit (ADLAR) or 10-bit is up to you.

//  Many of us would take multiple readings and average or otherwise filter to minimize noise.

// (average, filter as needed)

// Convert to control signal by applying transfer function

// Now use the control_value in the desired units

...

With the above approach, you keep read_adc() "pure" to be able to use with other signal ranges.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

ADMUX |= (0 << REFS1) | (0 << REFS0);            // AVCC as reference

???  Where in the world did you get this routine?  ORing anything with zero does nothing.  There are many discussions here on re-building ADMUX each time, rather than doing any bit fussing.

AVcc as reference is >>not<< 0-0 for the bits, is it?

Mega48 app code fragment below; similar to Mega16 but the internal reference is a different value:

```// VREF
// ====
//	Note that in ADMUX, bit 7 is REFS1; bit 6 is REFS0

//	------- 	----------		-----------
//	0 			0x00			External AREF
//	1			0x40			Use Vcc as Aref
//	3			0xc0			Internal 1.1V bandgap

...
```

```uint16_t read_adc(uchar channel)
{

return ADCH;                // 8 bit precision
}
```

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

Last Edited: Tue. May 19, 2015 - 03:43 PM