AOA Forums AOA Forums AOA Forums Folding For Team 45 AOA Files Home Front Page Become an AOA Subscriber! UserCP Calendar Memberlist FAQ Search Forum Home


Go Back   AOA Forums > Software > Programming and Assembly Language

Programming and Assembly Language Please read this Topic's rules!!


Reply
 
LinkBack Thread Tools Rate Thread
  #1 (permalink)  
Old 2nd February, 2010, 07:24 PM
Chief Systems Administrator
 
Join Date: September 2001
Location: Europe
Posts: 13,075

Question Analog to digital with a varying reference!

Ok, I've been working on a small circuit that measures various different voltages (basically a gyro and the speed of some motors), but I've got a small problem that I'm not 100% sure of a good way of solving.

The ADC is using the battery voltage as it's reference (It's ratiometric). However, the gyro isn't - the output voltage doesn't change as the battery voltage changes.

The good news is that I have a 1.6V reference that I can sample, so at least I have a known reference. Now, if I understand this correctly, I can measure the battery voltage by seeing what output I get from 1.6V reference. It would seem that the Bv = 410/ADC_result.

Now, I'm doing all this in assembler, and I don't have a good grip on integer maths for multiplying and dividing.

How do I convert these variable measurement back into a fixed value - effectively compensating for the changing battery voltage?
__________________
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #2 (permalink)  
Old 2nd February, 2010, 09:07 PM
Gizmo's Avatar
Chief BBS Administrator
BassTeroids Champion, Global Player Champion, Aim & Fire Champion, Puzzle Maniax Champion, Othello Champion, Canyon Glider Champion, Unicycle Challenge Champion, YetiSports 9: Final Spit Champion, Zed Champion
 
Join Date: May 2003
Location: Webb City, Mo
Posts: 16,178
Send a message via ICQ to Gizmo Send a message via AIM to Gizmo Send a message via MSN to Gizmo Send a message via Yahoo to Gizmo Send a message via Skype™ to Gizmo

What chip are you using? I assume it's a PIC of some flavor?

There's no external vref pin for the ADC; its only reference is the battery supply?

Where does the 1.6v come from? Also, is the 410 the sample value you get when reading the 1.6v reference?

How many bits is the ADC? I'm assuming it's linear? What's the input range?
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #3 (permalink)  
Old 3rd February, 2010, 11:43 AM
Chief Systems Administrator
 
Join Date: September 2001
Location: Europe
Posts: 13,075

It is indeed a PIC of some flavour (12F615 - an 8 pin device). Whilst there can be an external VREF, it is multiplexed with another pin, and I need the other pin functionality, otherwise I need to change the PIC I'm using.

The PIC generates two internal references, 0.6V and 1.6V, and I can set the ADC multiplexer to select one of these references, or one of the external pins. Technically, the ADC is 10bit linear, but I was only planning on using 8 bits of resolution. The input range between VDD and VSS.

The output from measuring the 1.6V reference is going to depend on the battery voltage, as it is the reference. From this, the battery voltage (Bv) is related to the reference via:
256/Bv * 1.6 = Res

Rearranging this gives me:

Bv = 410/Res

Where Bv is battery voltage, and Res is the result from the ADC when measuring the 1.6V reference voltage.
__________________
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #4 (permalink)  
Old 3rd February, 2010, 06:15 PM
Gizmo's Avatar
Chief BBS Administrator
BassTeroids Champion, Global Player Champion, Aim & Fire Champion, Puzzle Maniax Champion, Othello Champion, Canyon Glider Champion, Unicycle Challenge Champion, YetiSports 9: Final Spit Champion, Zed Champion
 
Join Date: May 2003
Location: Webb City, Mo
Posts: 16,178
Send a message via ICQ to Gizmo Send a message via AIM to Gizmo Send a message via MSN to Gizmo Send a message via Yahoo to Gizmo Send a message via Skype™ to Gizmo

Err.....unless you are reading a different reference manual than I am, the PIC generates an internal 1.2v reference, not 1.6v.

You're going to have to do something interesting, because the PIC doesn't support multiply and divide operations directly. Fortunately, it DOES support subtraction, so you don't have to do a bunch of two's complement crap to implement subtraction as a series of additions.

Basically, you're dealing with a fixed point precision problem. You're going to have to scale the numbers up (probably multiply by 16 or something) then do your math and shift your decimal point as appropriate.

I wrote some code a long time ago to do exactly this sort of thing on the 6502. It's not particularly difficult, just tedious. Scaling by an even binary value (like 16) is what I would suggest, simply because that's an easy rotate-left 4 times, which is very simple and fast. However, that still means you've got to do the multiplication and division using successive addition and subtraction operations.

Last edited by Gizmo; 3rd February, 2010 at 06:16 PM.
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #5 (permalink)  
Old 3rd February, 2010, 07:07 PM
Chief Systems Administrator
 
Join Date: September 2001
Location: Europe
Posts: 13,075

That's what you get for mixing 1.2 and 0.6 together. Are there any good references on fixed point to get my head around how some of these things work?
__________________
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #6 (permalink)  
Old 3rd February, 2010, 11:22 PM
Gizmo's Avatar
Chief BBS Administrator
BassTeroids Champion, Global Player Champion, Aim & Fire Champion, Puzzle Maniax Champion, Othello Champion, Canyon Glider Champion, Unicycle Challenge Champion, YetiSports 9: Final Spit Champion, Zed Champion
 
Join Date: May 2003
Location: Webb City, Mo
Posts: 16,178
Send a message via ICQ to Gizmo Send a message via AIM to Gizmo Send a message via MSN to Gizmo Send a message via Yahoo to Gizmo Send a message via Skype™ to Gizmo

Well basically, when you are dealing with fixed point math on an architecture that only supports integer operations, you simply shift the decimal point so that you can do everything in the integer domain.

First, the equation needs to change to reflect 1.2v rather than 1.6:

256/Bv * 1.2 = Res

Solving for Bv:

Bv = 307.2/Res

Multiply by 10 to make things easier later, and let us retain some accuracy:

Bv * 10 = 3072/Res

Do the math, and remember that the result is 10 times bigger.

As for doing the math itself, I'm sure you remember from primary-school math that multiplication is just a short-hand for successive additions, e.g.

6 * 6 = 36

is the same as

0 + 6 + 6 + 6 + 6 + 6 + 6 = 36

Division is the inverse:

36 / 6 = 6

Is the same as

36 - 6 - 6 - 6 - 6 - 6 - 6 = 0

For a machine that only knows how to do addition and subtraction, you have to manually implement the operations necessary to do multiplication and division.

(Side note: anyone know how to do subtraction on a machine that only supports addition? Hint: It requires a fixed register, i.e. number size, and an operation that I mentioned in a previous post)

Turns out, though, that you don't have to be quite that pedantic about it. ROR and ROL instructions (Rotate register right, rotate register left) have the effect of multiplying or dividing a number by 2. It's the binary equivalent of shifting the decimal point and thus allows you to implement the algorithmic equivalent of long multiplication and division.

So, multiplication is your basic add-and-shift algorithm and looks like this:

Given two numbers:
Let A be the Multiplicand
Let B be the Multiplier
Let C be the Product of A and B
(Note: the product of two 8-bit numbers can be up to 16 bits in size, so A and B are constrained to 8 bits, and C must be implemented as 16 bits. For 8-bit oriented architectures, this means you have to do a lot of shifting)

Set C to 0.
Begin
Test the LSB of B. If it is 1, add the contents of A to the high order byte of C (remember, C is a 16-bit register). Finally, ROR C.

If the LSB is 0, simply ROR C (To implement this with an 8-bit architecture, you first clear the Carry flag, ROR through Carry on the high byte, then ROR through Carry on the low byte. Finally, test the Carry flag and if it's set you've had an overlow, so bail with an error.)

ROR B, rinse and repeat until you've run the loop 8 times (for an 8-bit multiply). When you're done, C will contain the 16-bit product.

(Note: this architecture supports the bit test operation allowing you to test any bit in the byte, but does not support directly testing the carry flag. Some architectures do not support testing a bit in the byte, but do support directly testing the carry flag. As a result, you'll have to adjust the code accordingly.)

Division follows a similar operation, but as your basic shift-and-subtract algorithm, and looks like this:

Given two numbers:
Let C be the 16-bit Dividend
Let B be the Divisor
Let A be the quotient

Set A to 0
If B is 0 the result is undefined, so bail with an error.
Begin
Clear Carry
ROR through Carry A.
Test Carry: if set, you've had an underflow. Signal error and bail.
ROL through carry the 16 bits of C.
Test high-order byte of C, if equal or greater than B, subtract B from C (C - B), and set High order bit of A.

Rinse and repeat 8 times (for an 8-bit subtraction). When you're done, whatever's left in C is your remainder and A is your quotient.

Note: on the PIC, there is no specific comparison operation, but the subtraction operation has the same effect: subtract the two numbers you want to compare (C - B): if the carry flag is set B is larger; it the zero flag is set, they are equal; otherwise C is larger.

I would bet if you look around, there is probably a math library for the PIC you can use that already does this stuff, and more besides.

Edit: Here's one example: http://www.piclist.com/techref/microchip/math/index.htm

Last edited by Gizmo; 4th February, 2010 at 04:26 AM.
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
Reply



Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On


Similar Threads
Thread Thread Starter Forum Replies Last Post
Set top digital to analog boxes--with cabling? cloasters General Hardware Discussion 3 11th January, 2009 11:00 PM
Digital speakers to analog booman Graphics and Sound cards; Speakers and other Peripherals 8 4th April, 2007 04:59 PM
Vdimm/Vdd reference points. MONKEYMAN Hardware Hacking 18 16th December, 2005 03:03 AM
ISO/OSI Reference Model lplate80 Random Nonsense! 3 10th July, 2003 12:19 PM
digital vs analog audio output from 8rda+ bigmouse EPoX MotherBoards 7 15th February, 2003 09:51 PM


All times are GMT +1. The time now is 02:10 PM.


Copyright ©2001 - 2010, AOA Forums
Don't Click Here Don't Click Here Either

Search Engine Friendly URLs by vBSEO 3.3.0