ADC pot to servo position mapping

hippy

Technical Support
Staff member
#1
It's commonly desired to control the position of a servo so it moves from a minimum position to a maximum position when the pot is moved from one extreme to the other and the ADC goes from 0-255.

The maths for using READADC is as follows -

Code:
ReadAdc POT, b0
b1 = MAX_SERVO - MIN_SERVO * b0 / 255 + MIN_SERVO
Servo SERVO_PIN, b1
The MIN_SERVO and MAX_SERVO can be numeric constants ( directly in the code or defined by SYMBOL commands ) or values held in byte or word variables.

When the full pot range is between MIN_POT and MAX_POT rather than 0 and 255 the maths becomes -

Code:
ReadAdc POT, b0
b1 = MAX_POT - MIN_POT
b1 = b0 Min MIN_POT - MIN_POT Max b1 * 255 / b1
b1 = MAX_SERVO - MIN_SERVO * b1 / 255 + MIN_SERVO
Servo SERVO_PIN, b1
Again, MIN_POT and MAX_POT can be numeric constants ( directly in the code or defined by SYMBOL commands ) or values held in byte or word variables.
 
#2
Hi to the Forum,

Having fallen on this post by researching the use of servos used in radio control and piloted with the ReadADC command, I wanted to tell you my solution to use all the potentiometer stroke.

The control potentiometer (read on the transmitter) ranges from 0 to 5 Volts.
ReadADC gives values from 0 to 255 but the servo can only use values from 75 to 225 (0.75msec to 2.25 msec).
The aim was therefore to find a mathematical equation linking ranges of values 0-255 to a new complete range of 75-225.

In this way, all the potentiometer stroke is used.

Excel being, sometimes, our friend the solution was quickly found to solve this system of equation.

Code:

Code:
#picaxe 14M2
#no_data

symbol Servo1 = B.5  	'Define Servo 1
servo  Servo1,150		'init servo1

'=============================
Do
	ReadADC C.4, W0
	  W1=W0*6/10
	  W1=W1+75
	Servopos Servo1,W1
Loop
Looking forward to reading your comments ...

Regards
 

Attachments

hippy

Technical Support
Staff member
#3
The mapping for full pot motion (0-255) to full servo movement (75-225) is -

servo = pot * 150 / 255 + 75

As 'pot' never exceeds 255, and 255*150 is less than 65536 so no overflow, you could just use that 150/255 instead of the less accurate 6/10.
 
#4
Hello Hippy,

My equation gave me the factor 0.5882..., which corresponds exactly to 150/255 (Neutral / Max). There, I had not made this mathematical connection :rolleyes:!
I then rounded this value to 0.6 in my process without obtaining a great abduction calculation, knowing that the picaxe treats only the integers.
Your term 150/255 will certainly also be rounded to the value 0.6.
Thank you for your reply. ADC Servo Control 02.jpg
 

hippy

Technical Support
Staff member
#5
Your term 150/255 will certainly also be rounded to the value 0.6.
No; that is not correct. The 150/255 will not be rounded; it is a multiply by 150 then a divide by 255, nothing more, nothing less, though decimal fraction parts of the result will sometimes be lost in the division.

Take the maximum pot value of 255 which should give maximum servo position of 225 ...

( ( 255 * 150 ) / 255 ) + 75 => 225

( ( 255 * 6 ) / 10 ) + 75 => 228
 

hippy

Technical Support
Staff member
#6
My equation gave me the factor 0.5882..., which corresponds exactly to 150/255 (Neutral / Max).
Technically the 150/255 is the ratio of ...

( max_servo - min_servo ) / ( max_pot - min_pot )

If the neutral position were offset ( as it is for some servos ) one would not adjust the 150 at the top but would adjust the +75.
 
#7
OK. When I spoke of rounding, I was actually thinking of the loss of the decimal fraction parts because we agree that the picaxe only deals with integers.
Your formula has the merit of not exceeding the max value of 225.
Thanks for the explanation of this formula.
 

hippy

Technical Support
Staff member
#8
One other trick is that 150/255 can also be represented as 30/51 or even 10/17 without any loss of accuracy.

That is not important here as there is no chance of overflow but can be useful where that does play a part.

That would apply when using a READADC10 to read the pot which would deliver a 0 to 1023 result -

servo = pot10 * 150 / 1023 + 75 would overflow

servo = pot10 * 50 / 341 + 75 will not
 
#9
I do not understand the math in the third line in above code: "b1 = b0 Min MIN_POT - MIN_POT Max b1 * 255 / b1".
Should I read it as " b1 = b0 times minimum of MIN_ POT minus MIN_POT times the maximum of b1 times 225/b1"? I can't visualize the PICAXE code.

2012 is a half a memory ago, but I bet you still remember.

John
 
#11
Hippy, I must be dense because I don't know if Min is meant as a selection from a set of values by the program or by the programmer prior to coding. I don't find Min in the list of PICAXE BASIC commands, so ( b0 Min MIN_POT) means little to me, and 'Max b1' suggests the 'MAX value of B1' except that b1 has a particular value at execution of 'MAX b1'. Maybe you will have a similar problem interpreting by punctuation.
Thank you for your reply.
John
 
#12
Thank you. I should have done more study: in other words, more use of my time than use of your time. You are very kind. I have long been pleased how willing you and others on this forum are to give their up time. It makes this experience so much more enjoyable. Thank you.
John
 

hippy

Technical Support
Staff member
#13
MIN and MAX confused me when I first encountered them on the PICAXE because I imagined they selected the minimum or maximum value of two values respectively.

They are in fact limiting or constraining operators; 'don't let a value be below a minimum', 'don't let the value be above a maximum'.

In "a Min b - b", the MIN limits 'a' to have a value equal to or greater than the minimum value 'b', so that when 'b' is then subtracted the result will never go below zero - which would actually give a wrapround result on the PICAXE which only deals with positive integers.
 
Top