The Great Bottle Opener Giveaway

Home Brew Forums > Home Brewing Beer > Brew Science > to the electrical engineers and c programmers

Reply
 
LinkBack Thread Tools
Old 02-16-2013, 07:33 AM   #1
KuntzBrewing
Feedback Score: 0 reviews
Recipes 
 
Join Date: Aug 2011
Location: Kokomo, Indiana
Posts: 629
Liked 12 Times on 11 Posts

Default to the electrical engineers and c programmers

I'm using Atmega Studio 6 and an ATmega328P on an arduino board. I've coded an Analog to Digital converter and can successfully read analog inputs on a scale of 0-1023 (10bit memory space is fixed)

I made a voltage splitter (voltage divider circuit) that halves my input of 5Vcc, but for some reason I cannot convert my adc value to a voltage. Which sounds simple (adcvalue*5000mV/1023) to get a value saved in an unsigned 16bit value. My result is 0 or some invalid answer. I tried saving this as a float in a regular voltage (*5V not *5000Mv) but using print(%f, voltagevalue) returns a "?", using %d yields "0"

I thought it was an overflow issue (adc of 512 * 5000 gives 2.5Million+ return) I went as far as saving it as a unit64_t. Didn't work. I want to make sure my values are correct so I use printf and read them on a hyper terminal using serial communication between board and computer. I even printed a hex number (showed 0xFC78) which wouldn't be correct.
Has anyone ran into this problem or can anyone come up with a solution.

The whole reason behind this is to read a thermistor, but I'm using a voltage divider to test the values for now. Grounding gives me a reading of 0 full on gives 1023. Circuit reads 512 (which is about half) so I know its right

__________________
KuntzBrewing is offline
 
Reply With Quote Quick reply to this message
Old 02-16-2013, 12:29 PM   #2
WoodlandBrew
HBT_SUPPORTER.png
Feedback Score: 0 reviews
 
WoodlandBrew's Avatar
Recipes 
 
Join Date: Oct 2012
Location: Malden, MA
Posts: 1,739
Liked 123 Times on 120 Posts
Likes Given: 57

Default

Sounds like a type casting issue. Can you post the line of code that is not working, and the type defs for the variables uses?

It might be as simple as changing 5000 to 5000.0

__________________

The 2nd edition is now available: Brewing Engineering
BLOG: Brewing Boiled Down Brewing science for those of us without a Ph.D

WoodlandBrew is offline
 
Reply With Quote Quick reply to this message
Old 02-16-2013, 03:23 PM   #3
ajf
Senior Member
HBT_LIFETIMESUPPORTER.png
Feedback Score: 0 reviews
 
ajf's Avatar
Recipes 
 
Join Date: Oct 2005
Location: Long Island
Posts: 4,643
Liked 97 Times on 91 Posts
Likes Given: 39

Default

Firstly, I think your "/1023" should be /1024
Next, I agree with the overflow as 512 * 5000 is > 16 bits. (I'm not sure what a unit64_t is. I'm guessing uint64_t but does your compiler and hardware support 64 bit ints?)
The easy fix is to change 500mV/1024 to 625mV/128 (divide both components by 8). This ensures that the multiplication of the adc value does not overflow.
As WoodlandBrew said, if you try saving it as a float but you multiply by 5 instead of 5.0, you will get wrong answers (and you should get compiler warnings).

-a.

__________________

There are only 10 types of people in this world. Those that understand binary, and those that don't.

ajf is offline
 
Reply With Quote Quick reply to this message
Old 02-16-2013, 07:46 PM   #4
TheLastDamnBatch
Registered User
Feedback Score: 0 reviews
Recipes 
 
Join Date: Feb 2013
Posts: 44
Liked 7 Times on 6 Posts

Default

You'll have to typecast (for promotion) such that the intermediate result does not overflow:

unsigned short adcvalue = ReadADC();
unsigned short result = (unsigned short)((int)adcvalue * (int)5000 / (int)1023);

Just make sure your int's are 32 bit, otherwise you'll have to more work.

Also make sure you're reading the 10bit adc into at least a 16 bit variable.

The " / 1023 " is correct as your min and max values are 0 and 1023 which give you 1024 unique values for the range. Using 1024 would produce a scaling error at the top of range limiting it to 4995.

__________________
TheLastDamnBatch is offline
 
Reply With Quote Quick reply to this message
Old 02-17-2013, 12:18 AM   #5
ajf
Senior Member
HBT_LIFETIMESUPPORTER.png
Feedback Score: 0 reviews
 
ajf's Avatar
Recipes 
 
Join Date: Oct 2005
Location: Long Island
Posts: 4,643
Liked 97 Times on 91 Posts
Likes Given: 39

Default

If you want the best accuracy, try:

unit16 reply;

reply = (adcvalue * (5000 / 8) + 1024 / 16) / (1024 / 8) ;

This will work with 16 bit unsigned integers, handles all 1024 adcvalues, and includes rounding.

-a.

__________________

There are only 10 types of people in this world. Those that understand binary, and those that don't.

ajf is offline
 
Reply With Quote Quick reply to this message
Old 02-17-2013, 12:24 AM   #6
weirdboy
HBT_LIFETIMESUPPORTER.png
Feedback Score: 3 reviews
Recipes 
 
Join Date: May 2009
Location: Los Angeles
Posts: 7,908
Liked 424 Times on 345 Posts
Likes Given: 58

Default

I would mask the 10 bit value you are reading when you do the assignment as well, to make sure it's exactly 10 bits of data. It could be you are getting junk in the other 6 bits (or however many bits are in the data type you're assigning to).

__________________
weirdboy is online now
 
Reply With Quote Quick reply to this message
Old 02-17-2013, 04:11 AM   #7
GotPushrods
Bearded Lagerjack
HBT_SUPPORTER.png
Feedback Score: 0 reviews
 
GotPushrods's Avatar
Recipes 
 
Join Date: Jul 2012
Location: Phoenix, AZ
Posts: 339
Liked 56 Times on 41 Posts
Likes Given: 6

Default

Quote:
Originally Posted by weirdboy
I would mask the 10 bit value you are reading when you do the assignment as well, to make sure it's exactly 10 bits of data. It could be you are getting junk in the other 6 bits (or however many bits are in the data type you're assigning to).
Which would explain the 0xFC78, which is 6 1s followed by 0x0078 (120).
__________________
GotPushrods is offline
 
Reply With Quote Quick reply to this message
Old 02-17-2013, 04:33 AM   #8
KuntzBrewing
Feedback Score: 0 reviews
Recipes 
 
Join Date: Aug 2011
Location: Kokomo, Indiana
Posts: 629
Liked 12 Times on 11 Posts

Default

Im gonna try type casting. Im kinda jumping the gun on this project i basically know the basics of c and am in an intro to digital systems class. But now that im able to flash leds i think i can write huge complex codes to do all kinds of cool stuff. Thats partially my problem lol but its fun to learn anyways.

__________________
KuntzBrewing is offline
 
Reply With Quote Quick reply to this message
Old 02-17-2013, 03:39 PM   #9
WoodlandBrew
HBT_SUPPORTER.png
Feedback Score: 0 reviews
 
WoodlandBrew's Avatar
Recipes 
 
Join Date: Oct 2012
Location: Malden, MA
Posts: 1,739
Liked 123 Times on 120 Posts
Likes Given: 57

Default

Quote:
Originally Posted by GotPushrods View Post
Which would explain the 0xFC78, which is 6 1s followed by 0x0078 (120).
That's more than likely the two's compliment representation of a negative number.

Invert:
0x0387
add one
0x0388
convert to decimal and add the sign:
-905
__________________

The 2nd edition is now available: Brewing Engineering
BLOG: Brewing Boiled Down Brewing science for those of us without a Ph.D

WoodlandBrew is offline
 
Reply With Quote Quick reply to this message
Old 02-17-2013, 03:57 PM   #10
GotPushrods
Bearded Lagerjack
HBT_SUPPORTER.png
Feedback Score: 0 reviews
 
GotPushrods's Avatar
Recipes 
 
Join Date: Jul 2012
Location: Phoenix, AZ
Posts: 339
Liked 56 Times on 41 Posts
Likes Given: 6

Default

Quote:
Originally Posted by WoodlandBrew View Post
That's more than likely the two's compliment representation of a negative number.

Invert:
0x0387
add one
0x0388
convert to decimal and add the sign:
-905

Ya know that crossed my mind, although the negative value seemed less relevant.

I once tried to pull undocumented data from Canon digital pictures' EXIF field. There were some values in 2's compliment, and some straight signed binary. It was a mess. Hopefully if nothing else this board is consistent. For the sake of doing math efficiently it would almost have to be.
__________________
GotPushrods is offline
 
Reply With Quote Quick reply to this message
Reply


Quick Reply
Message:
Options
Thread Tools


Similar Threads
Thread Thread Starter Forum Replies Last Post
Programmers elbow ESB MooMooBrew All Grain & Partial Mash Brewing 26 08-24-2011 02:13 AM
Any Siemens PLC programmers out there? dtfeld Electric Brewing 6 03-24-2011 03:34 PM
Need electrical advice from electrical engineers Photopilot Equipment/Sanitation 1 01-23-2011 10:58 AM
Electrical Engineers oldschool DIY Projects 10 01-27-2010 01:43 AM
Calling all electricians and other saavy electrical engineers HELP!!!! flananuts DIY Projects 55 09-26-2009 02:39 AM