ADC conversion problem

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

Hi i am new in c programming, and now i have a problem/question.

My ADC will only show 4092mV althoug i measure on the 5V VCC point, and i came down to that it has something to do with this line of code:

ADC_result = (ADC_result * (5000 / 1023));

Can it realy be right that i need to use a float/double as sub calculations to get the right result?

I am curretly running the code on a atmega16 and i would like to keep it simple and low on ressources

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

5000/1023 = 4 using integer math. Using 50000/1023 and then dividing by the final result by 10 will get you closer. There is probably another ratio approach that will get you even closer without using float.

 

In consideration of others, please RTFM!

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

Or do the multiplication first

ADC_result = (ADC_result * 5000UL) / 1023; 

(the parenthesis isn't really needed).

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

Thanks but think i use a double, its more precise.

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

Quote:

Thanks but think i use a double, its more precise.

As you posted in GCC forum note that you are kidding yourself if you think avr-gcc has "double". It does not float==double=32bit IEEE754 which means you never get 64bit (16 decimal digits) floats but just 32 bit (6.5 decimal digit) numbers. This may or may not be an issue for you.

To be honest I don't know why you'd use float/double for this anyway. Surely ints are far tighter/faster and if you want to hold more accuracy scale them.

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

snigelen wrote:
Or do the multiplication first
ADC_result = (ADC_result * 5000UL) / 1023; 

(the parenthesis isn't really needed).

This metod work even better than with a double:)

But how can it work, if i do the math 1023 * 5000 is 5115000, way more than ADC_result can represent as it is a unsigned int?

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

Notice the UL in 5000UL, it means that it's an unsigned long (32 bits in avr-gcc), so the calculation is done in 32 bit math, and when ADC_result * 5000UL is divided by 1023 the result fits in 16 bits.

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

Quote:
Surely ints are far tighter/faster and if you want to hold more accuracy scale them.
And floating point will be particularly useless if the result is cast to an int anyways.

Regards,
Steve A.

The Board helps those that help themselves.

Last Edited: Wed. Jun 20, 2012 - 07:33 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks, every new day is a day to learn.

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

Quote:

Thanks, every new day is a day to learn.

Also think about what "accuracy" and "precision" mean.

In this case, let me put it this way: You said "Thanks but think i use a double, its more precise." But that ignores the fact that you are starting with a 10-bit A/D value. In all likelihood you are losing a few bits of accuracy unless you have a squeaky-clean analog subsystem in your app. At most, no matter how many decimal places you print out from your "double" you still only have about three useful significant digits. You can print out 1.23456789 but that really represents about 1.23 +/-0.01.

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.

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

Rolfiboy wrote:
Thanks but think i use a double, its more precise.

I hope you are aware that the ADC only has 10 bits of resolution, and unless you pay close attention to your AREF and your AVCC and your timing and de-coupling, you may actually get less than that.

So, an unsigned long has all the precision you will ever need for this application, and spending time with the floating point emulation does nothing but waste perfectly good CPU cycles.

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

Also, you should be dividing by 1024, NOT 1023.

1) Studio 4.18 build 716 (SP3)
2) WinAvr 20100110
3) PN, all on Doze XP... For Now
A) Avr Dragon ver. 1
B) Avr MKII ISP, 2009 model
C) MKII JTAGICE ver. 1

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

Why? (ok it's cheaper). Isn't 1023 max?

octave:8> 5000*1023/1024
ans =  4995.1
octave:9> 5000*1023/1023
ans =  5000
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Because it's the correct equation. An ADC can't read full-scale Vcc value, which the wrong eq'n implies ( A 3 bit system would read to 7/8*Vcc, NOT 7/7*Vcc = Vcc for example ). 1023 is max COUNT, but there are 1024 STATES. It's always ( 2^N ) -1 / 2^N.

1) Studio 4.18 build 716 (SP3)
2) WinAvr 20100110
3) PN, all on Doze XP... For Now
A) Avr Dragon ver. 1
B) Avr MKII ISP, 2009 model
C) MKII JTAGICE ver. 1

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

Quote:

Also, you should be dividing by 1024, NOT 1023.

Quote:

Why? (ok it's cheaper). Isn't 1023 max?

LOL--this has been tossed about before:
2004: https://www.avrfreaks.net/index.p...
2007: https://www.avrfreaks.net/index.p...
2008: https://www.avrfreaks.net/index.p...
2010: https://www.avrfreaks.net/index.p...

... and others. In practice it >>usually<< doesn't matter much even when trying to get "good" ADC results: except in squeaky-clean analog subsystems there is almost always a few LSB of uncertainty in the ADC result--ripple anywhere for example. So in some apps I've even done 5000/1025 for fast and small units conversion in a tight Mega48 app. That's 5000mV/1025 "approximate" counts. Why? 5000*ADC/1025 => 200*ADC/41 and everything fits nicely into 16-bit operations.

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.

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

theusch wrote:
In practice it >>usually<< doesn't matter much even when trying to get "good" ADC results:
I know. I just get a little pissed of when people that don't know that shout
Quote:
NOT

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

indianajones11 wrote:
Because it's the correct equation. An ADC can't read full-scale Vcc value, which the wrong eq'n implies ( A 3 bit system would read to 7/8*Vcc, NOT 7/7*Vcc = Vcc for example ). 1023 is max COUNT, but there are 1024 STATES. It's always ( 2^N ) -1 / 2^N.
No, you are wrong. Think of it as a pie. If the pie is cut into 8 pieces, and you have all 8 pieces, then you have 8/8's of a pie. But the pie has 9 "states" (0-8). With your logic, if you had all 8 pieces you would have only 8/9's of a pie.

Regards,
Steve A.

The Board helps those that help themselves.

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

Koshchi wrote:
indianajones11 wrote:
Because it's the correct equation. An ADC can't read full-scale Vcc value, which the wrong eq'n implies ( A 3 bit system would read to 7/8*Vcc, NOT 7/7*Vcc = Vcc for example ). 1023 is max COUNT, but there are 1024 STATES. It's always ( 2^N ) -1 / 2^N.
No, you are wrong. Think of it as a pie. If the pie is cut into 8 pieces, and you have all 8 pieces, then you have 8/8's of a pie. But the pie has 9 "states" ( 0-8 ). With your logic, if you had all 8 pieces you would have only 8/9's of a pie.
I don't know about your pie analogy ( made me hungry though ), but you don't have a '0' slice like you have a count of 0 for 0 volts ( Your 1st slice would have a cnt of 1, not 0. ). But if you built a 5V, 3 bit ADC you will not read, the count of 7 happens at ~4.3V, NOT ( my caps is for emphasis, NOT shouting ) 5V. Which is when it would hit 7 if you were right.

Edit: Steve, your pie only has 8 states, 0-7 with a max. cnt of 7 ! :wink: Now I need to go to Marie Callender's !

1) Studio 4.18 build 716 (SP3)
2) WinAvr 20100110
3) PN, all on Doze XP... For Now
A) Avr Dragon ver. 1
B) Avr MKII ISP, 2009 model
C) MKII JTAGICE ver. 1