Author Message
 Rolfiboy
 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

 jpmargis
 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

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

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

 clawson
 Posted: Jun 20, 2012 - 06:53 PM
 Joined: Jul 18, 2005 Posts: 62321 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. _________________

 Rolfiboy
 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?

 snigelen
 Posted: Jun 20, 2012 - 07:08 PM
 Joined: Jan 08, 2009 Posts: 1155 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.

 Koshchi
 Posted: Jun 20, 2012 - 07:33 PM
 Joined: Nov 17, 2004 Posts: 13842 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

 Rolfiboy
 Posted: Jun 20, 2012 - 08:01 PM
 Joined: Sep 21, 2010 Posts: 5
 Thanks, every new day is a day to learn.

 theusch
 Posted: Jun 20, 2012 - 10:02 PM
 Joined: Feb 19, 2001 Posts: 25918 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.

 jwatte
 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.

 indianajones11
 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

 snigelen
 Posted: Jun 29, 2012 - 08:25 PM
 Joined: Jan 08, 2009 Posts: 1155 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

 indianajones11
 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

 theusch
 Posted: Jun 29, 2012 - 08:51 PM
 Joined: Feb 19, 2001 Posts: 25918 Location: Wisconsin USA
 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: http://www.avrfreaks.net/index.php?name ... 309#112309 2007: http://www.avrfreaks.net/index.php?name ... torder=asc 2008: http://www.avrfreaks.net/index.php?name ... torder=asc 2010: http://www.avrfreaks.net/index.php?name ... 024+divide ... 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.

 snigelen
 Posted: Jun 29, 2012 - 09:38 PM
 Joined: Jan 08, 2009 Posts: 1155 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

 Koshchi
 Posted: Jun 30, 2012 - 05:36 PM
 Joined: Nov 17, 2004 Posts: 13842 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.

 indianajones11
 Posted: Jun 30, 2012 - 07:37 PM
 Joined: Nov 28, 2004 Posts: 3552 Location: San Diego, Ca