PDA

View Full Version : Decimal to Degrees mathematics help



RFsolution
- 2nd October 2006, 08:28
Hi All,

I'm working on some code to read a AC or DC motors position
using a potmeter as indicator having max 5V at the whiper

I'm using the 16F819 with 10bit AD

I was wondering how I can convert the AD word value to 360 deg, as PBP has
limited math possibilitys

In the final code I want to implement a setup routine so that I can determine
which Digtal value (word) corresponds to 360deg or max azimuth to do the final divide

Can someone help me with the mathematics part as I dont see how to do that

Lets say that we have the following variables:

AZdeg position 0 to 360 deg
AZdig position from AD convertion
AZdigmax value which corresponds to 360deg (during setup) so here we have to determine the divide ratio

Thanks all for your time reading my request

sayzer
- 2nd October 2006, 08:45
If what I understood is correct, then a simple experiment could be as follows.

At 0 degree, record ADC value. Say it shows 150 (this would be your base value).

At 360 degree, record ADC value. Say it shows 900.

Then each degree would become as;
(900-150) / 360 = 2.

That means, when your ADC reading is 152, you will know that you are at 1st degree, 154 is 2nd, 156 is 3rd. etc...

With an additional math, which I am sure you can figure out, you can get the exact degree.


Was this what you needed, or I am in a different page?



----------------

Acetronics2
- 2nd October 2006, 09:40
At 0 degree, record ADC value. Say it shows 150 (this would be your base value).

At 360 degree, record ADC value. Say it shows 900.

Then each degree would become as;
(900-150) / 360 = 2.

That means, when your ADC reading is 152, you will know that you are at 1st degree, 154 is 2nd, 156 is 3rd. etc...

With an additional math, which I am sure you can figure out, you can get the exact degree.


Was this what you needed, or I am in a different page?



----------------

Hi, Sayzer

... life is easy with you !!!

RF:

at first, be sure to use the posssible max of the ADC range for your measure ...

As said by sayzer, read the min ( 0°) and Max ( 359.9 °)

then you get a result between 0 and 1023 ... no use to look at a better than .1% precision ( humour )

But, to keep decimals, just multiply the result by ... 64 , to use the max counting possibilities of the Pic.

so, let's make it clear:

Scale = MaxValue - MinValue

dummy = ( AdcResult - MinValue ) x 64

' disable interrupts ... if necessary

dummy = dummy x 360

Result_64 = DIV32 Scale

' re enable

Now, dividing Result_64 by ... 64 ( 6 right shifts ...) give the INT part.

... and , if needed, the 6 right digits will give 64 x the decimal part.... a little bits shifting ( or multiplying i.e. by 100 )and you can show it !!!


life is sooooooooo simple ....

Alain

sayzer
- 2nd October 2006, 10:10
Be My teacher Alain!


------------------------

Ingvar
- 2nd October 2006, 11:02
Keep in mind that "normal" potentiometers are NOT very linear. There are special types for positioning purposes.

sayzer
- 2nd October 2006, 12:07
Keep in mind that "normal" potentiometers are NOT very linear. There are special types for positioning purposes.


Multi turn pots could be a good choice for positioning.
In 360 degree, with the help of some gears, the pot can turn 10 times.

Thus, Alain's math can have a better accuracy.

ErnieM
- 2nd October 2006, 15:23
Some things to keep in mind here (and elsewhere too):

1) The max number from the analog conversion is 1023, which is the maximum number expressible with the 10 bits from the converter. SO, the maximum resolution you can get is 360/1023= .3519 degrees per bit

2) Converting from raw A2D number to degrees is simple, just (assuming max reading is 1023, and min is zero) A2Dreading x 360 / 1023. However, it is important to perform the calculation by doing the multiplication first, then the division. If you divide first you’ll loose a lot of precision (do you see why?) You’re working with integer numbers here, so the decimal parts get lost quickly. Alain has a good point when he scale up the reading, just be careful you do not overflow the variable; his use of 64 is the most you can scale this number up

Max scale factor = biggest word / biggest expected number = 65535 / 1023 = 64.0165… so use 64. PBP does have some facilities for handling double precision multiplicands (32 bit products), but that’s trouble to deal with.

sayzer
- 2nd October 2006, 15:29
Lets make it simple.

Try my way first.

You will be surprised with the result.

RFsolution
- 2nd October 2006, 16:38
Hey Guys

very suprised about the fast reply's , thanks to all !!!

I will give it a try this evening.

I agree that potmeters are not that linair, and I dont need the 0.3 deg
precision, but 8bit is not enough

Will try sayzers solution this evening, if it is not working i will post the code
for the specialists

Thanks agn

sayzer
- 2nd October 2006, 17:29
....
if it is not working i will post the code for the specialists



You broke my heart !


--------------------------

RFsolution
- 2nd October 2006, 21:02
Hi

This is what I have but dont see any light in "my" tunnel

OSCCON = $60
DEFINE OSC 4
DEFINE adc_bits 10
DEFINE adc_clock 3
DEFINE adc_sampleus 50

adcresult VAR WORD
dummy var word
adcon1=%100000010
maxvalue var word
minvalue var word
scale var word
result_64 var word

init:
maxvalue = 64000 'this is 359,8 degrees
minvalue = 2200 ' this is equal to 0 degrees

loop:
gosub readadc
Scale = MaxValue - MinValue
dummy = (AdcResult - MinValue) * 64
dummy = dummy * 360
Result_64 = DIV32 Scale
SerOut 6,6,["adc=",#adcresult," scale=",#scale," dummy=",#dummy," res64=",result_64,10,13]
goto loop


readADC:
ADCIN 0, adcresult
return

ErnieM
- 2nd October 2006, 22:00
OK, a lot of code, but no hint as to what is going wrong!

When getting up a new project, try to cut it into as many small slices as possible, get first to work, then move on to the next slice.



Slice 1: getting out debug info. Method: just post dummy data.

Slice 2: Read A2D. Method: read it, then output as debug info

Slice 3: Convert to degrees. Method: as discussed

sayzer
- 3rd October 2006, 03:29
Hi

This is what I have but dont see any light in "my" tunnel

OSCCON = $60
DEFINE OSC 4
DEFINE adc_bits 10
DEFINE adc_clock 3
DEFINE adc_sampleus 50

adcresult VAR WORD
dummy var word
adcon1=%100000010
maxvalue var word
minvalue var word
scale var word
result_64 var word

init:
maxvalue = 64000 'this is 359,8 degrees
minvalue = 2200 ' this is equal to 0 degrees

.....


You have 10bits of res. Thus you need the result as right justified. But you have adcon1=%100000010 one extra 0 is typed here. So the result becomes as left justified. Thus you get your results as 64000 and 2200.

Change it to adcon1=%10000010. So you now have correct right justified setting.

Then check the readings again.



-------------

HenrikOlsson
- 3rd October 2006, 06:24
Hi,
I think that your maxvalue and minvalue should be the raw value from the adc ie. between 0 and 1023 and not the raw value times 64.

Otherwise this will not work:


dummy = (AdcResult - MinValue) * 64

You get a value between 0 and 1023 from the ADC. Then you subtract 2200 from that which will make it negative and you don't want that.

Try setting the max and min value to the raw reading from the ADC.

/Henrik Olsson

RFsolution
- 3rd October 2006, 10:00
Hi sayzer and henrik thanks for your help

Well,

ADCON was wrong so I was getting more than a 10bits ADC result
so ofcouse my minvalue and maxvalue that i noticed was wrong
so all mathemacics also resulting in a non res_64 variable

I'm now getting a value of res_64 but and after dividing it by 64 I have
a nice 360 deg readout,

Can anyone help with the bitshifting and additional dividing ? to have a
.1 deg variable and readout ?

Thanks

ErnieM
- 3rd October 2006, 16:33
With a 10 bit A2D you have a max reading of 1023 counts, which represents 360 degrees. Therefor, each count is 1023/360=2.84... degrees.

You don't have .1 degree resolution here, you have 3 degree resolution. That .1 degree is not a true number.

sayzer
- 3rd October 2006, 17:20
Hi ErnieM,

I do not think your formula is ok. Your result is not in "degree" by the way. 2.84 is the step for per degree.

Lets leave 0.1 degree sensitivity issue to our teacher, Alain!

I love to learn.


----------------------

ErnieM
- 3rd October 2006, 19:35
Oops, I inverted it. I should have checked the units.

Resolution = 360 [degrees] / 1023 [count] = .3519... [degrees/count]



However, you still don't have .1 degree resolution.