The need to convert the result of the ADC pins proportionally to servo positions arose recently in my Pic-Aim project, which in turn was inspired by this comment. In it, user chench shared the following formula to convert one into the other:
Readadc C.1,b1 ; read value into b1
b2 = (b1 / 2) + 75; convert from 0-255 to 75 - 203
Which works beautifully well.
However if you are looking for more accuracy -specially when refining and debugging code-, there is some room to improve on the given formula. I gave it to my younger sister who is a lot better at math than I am, and in 8 seconds flat she came up with the following:
y=ax+b
...where:
Y= is the servo position
A (constant)=(225-75)/255 or 0.588235
X= the ADC value
B (also constant)= 75
A little implementation: Let´s say you want to calculate the servo position that would result from an ADC value of 111. All you have to do is replace the explained components with their values:
y=(((225-75)/255)*111)+75
y=(0.588235*111)+75
y=65.294085+75
y=140
As you can see, the difference with Chench´s formula is minimal, but it is there.
Hope this helps any of you who finds themselves in the same situation I was in last week!
Cheers,
Andrés
NOTE (July 28th, 2011): This formula will only work correctly with exponential potentiometers. If you are using linear ones, the servo response will not be full range.
Good beginner tip. For those using Arduino the map(value, fromLow, fromHIgh, toLow, toHigh) function will do a linear mapping of values in much the same way.
The special sauce formula as I came up with and explained in this post(source included). This was specific to the picaxe and used on a 08M for my testing purposes or several servos. I set the limit of 80 and 220 due to the fact that not all servos like 75-225 so cutting it down slightly worked for test purposes.
My approach was merely theoretical, Ignoblegnome. This is, by no means, a law. In theory, everything is nice, tidy and simmetrical. Reality is a nasty can of worms.
However this is intended to be merely an approach, a stepping stone, but at least a nice and accurate one… in theory!
Just pointing out that results may vary based on your servo, and a linear change from the analog input may not be a perfect linear change in your servo position. The error may not be significant, and for many purposes this tip should work just fine!
The reason for chench’s b1/2 and your b1*.588235 are different is that chench might know the PICAXE has no floating point ability. To get more precise results you would need to do what voodoobot did and use word variables and multiply by a fraction.
To work with voodoobot’s concern of varying servo ranges, just use a pair of min/max variables and don’t send anything outside of the range or use the MIN/MAX keywords that are available in PICAXE BASIC. My preference would be variables as they could be quickly found and changed, if need be.
Integers are whole numbers or numbers without decimal places. Floating point numbers are numbers with decimal points and numbers that follow to the right. I guess it is possible on your side of the pond that rather than decimal points they would be commas. For example, 12 is an integer and so is 24/2, they infact are the same number. OTH 1/2 and 0.5(or 0,5) have decimal places and therefore are floating point numbers. Many lower end microcontrollers do not understand decimal points and require a user to do integer math. Multiplying 3.14 by 100 and using that as PI then remembering that you will need to divide your final answer by 100 to get your answer truncated to a whole number(integer).
I hope my response helped your understanding. Maybe I should have started this with “I am not a teacher”
Ok, birdmun. I get it. Thanks. I just didn´t know that decimals were called “floating points”. I am fully aware of what kind of numbers the Picaxe “likes” and what kind of math they´ll accept. I guess I should have been more specific as to the theoretical nature of the tip. I thought that not giving any code samples was proof enough. I will rewrite it.
BTW, very cool that you know that not all of use use a decimal POINT, and that some of us, use a COMMA!!