| Author |
Message |
|
|
Posted: Jun 20, 2012 - 04:49 PM |
|

Joined: Sep 21, 2010
Posts: 5
|
|
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 |
|
|
| |
|
|
|
|
|
Posted: Jun 20, 2012 - 05:01 PM |
|

Joined: Oct 07, 2010
Posts: 34
Location: San Dimas, CA
|
|
| 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. |
_________________ Mr. Informer
|
| |
|
|
|
|
|
Posted: Jun 20, 2012 - 05:58 PM |
|


Joined: Jan 08, 2009
Posts: 1160
Location: Lund, Sweden
|
|
| Or do the multiplication first
Code:
ADC_result = (ADC_result * 5000UL) / 1023;
(the parenthesis isn't really needed). |
|
|
| |
|
|
|
|
|
Posted: Jun 20, 2012 - 06:48 PM |
|

Joined: Sep 21, 2010
Posts: 5
|
|
| Thanks but think i use a double, its more precise. |
|
|
| |
|
|
|
|
|
Posted: Jun 20, 2012 - 06:53 PM |
|


Joined: Jul 18, 2005
Posts: 62354
Location: (using avr-gcc in) Finchingfield, Essex, England
|
|
|
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. |
_________________
|
| |
|
|
|
|
|
Posted: Jun 20, 2012 - 07:01 PM |
|

Joined: Sep 21, 2010
Posts: 5
|
|
|
snigelen wrote:
Or do the multiplication first
Code:
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? |
|
|
| |
|
|
|
|
|
Posted: Jun 20, 2012 - 07:08 PM |
|


Joined: Jan 08, 2009
Posts: 1160
Location: Lund, Sweden
|
|
| 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. |
|
|
| |
|
|
|
|
|
Posted: Jun 20, 2012 - 07:33 PM |
|

Joined: Nov 17, 2004
Posts: 13849
Location: Vancouver, BC
|
|
|
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 by Koshchi on Jun 20, 2012 - 08:33 PM; edited 1 time in total
|
| |
|
|
|
|
|
Posted: Jun 20, 2012 - 08:01 PM |
|

Joined: Sep 21, 2010
Posts: 5
|
|
| Thanks, every new day is a day to learn. |
|
|
| |
|
|
|
|
|
Posted: Jun 20, 2012 - 10:02 PM |
|


Joined: Feb 19, 2001
Posts: 25923
Location: Wisconsin USA
|
|
|
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. |
|
|
| |
|
|
|
|
|
Posted: Jun 21, 2012 - 04:19 AM |
|

Joined: Apr 28, 2012
Posts: 70
|
|
|
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. |
|
|
| |
|
|
|
|
|
Posted: Jun 29, 2012 - 07:41 PM |
|

Joined: Nov 28, 2004
Posts: 3552
Location: San Diego, Ca
|
|
| 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
|
| |
|
|
|
|
|
Posted: Jun 29, 2012 - 08:25 PM |
|


Joined: Jan 08, 2009
Posts: 1160
Location: Lund, Sweden
|
|
| Why? (ok it's cheaper). Isn't 1023 max?
Code:
octave:8> 5000*1023/1024
ans = 4995.1
octave:9> 5000*1023/1023
ans = 5000
|
|
|
| |
|
|
|
|
|
Posted: Jun 29, 2012 - 08:46 PM |
|

Joined: Nov 28, 2004
Posts: 3552
Location: San Diego, Ca
|
|
| 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
|
| |
|
|
|
|
|
Posted: Jun 29, 2012 - 08:51 PM |
|


Joined: Feb 19, 2001
Posts: 25923
Location: Wisconsin USA
|
|
|
|
|
|
|
Posted: Jun 29, 2012 - 09:38 PM |
|


Joined: Jan 08, 2009
Posts: 1160
Location: Lund, Sweden
|
|
|
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
|
|
|
| |
|
|
|
|
|
Posted: Jun 30, 2012 - 05:36 PM |
|

Joined: Nov 17, 2004
Posts: 13849
Location: Vancouver, BC
|
|
|
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.
|
| |
|
|
|
|
|
Posted: Jun 30, 2012 - 07:37 PM |
|

Joined: Nov 28, 2004
Posts: 3552
Location: San Diego, Ca
|
|
|
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 ! 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
|
| |
|
|
|
|
|