07-21-2009, 02:49 AM
In response to another posting I have prepared two simple demo programs.
Both programs do the same thing. They utilize an R-C circuit with a potentiometer to control the position of a servo motor in response to the position of the Potentiometer.
Both demos use my own version of an RCTime equivalent to the BS2’s RCTime command.
One demo uses the excellent Servo32v5.Spin object by Beau Schwabe which has many advantages, but is quite complex for the beginner Spin programmer to study.
In this light I created my own SAM_Simple_Servo.Spin object which controls one Servo but is very simple and therefore can be studied by a beginner programmer as a stepping stone to Beau’s object.
The second demo uses the simplified servo-control object to do the very same as the previous demo.
All files are well documented with circuit diagrams and connections schematics.
I hope you find these demos useful.
07-27-2009, 11:12 AM
I noticed that some may not understand the formula in the top-level program which converts an RC-Time reading into a Servo position (pulse width).
The formula is:
············ PulseWidth:= 500+RCTime*21000/5425/10
The formula is to convert a current RCTime value into a corresponding PulseWidth value.
To do this we need to know 4 limits
······· Maximum RCTime value.
······· Minimum· RCTime value.
······ Maximum PulseWidth value.
····· Minimum PulseWidth value.
The max-min pulse width values are defined by the Servomotor you are using. These values are to be expressed in microseconds. So if the pulse width that represents the leftmost position of the motor is 0.5 milliseconds then the minimum is 500 microseconds. Likewise, if the right most position is attained with 2.6 milliseconds pulse then the maximum is 2600 microseconds.
You can establish your servos values if you do not have its specification using the demo program given within the documentations at the top of the SAM_Simple_Servo.Spin object. Using this demo program you can change the Maximum and minimum values and see the travel of the servo. The servo should attain these limit positions with the values you put without chatter.
For the RCTime max-min you will need to write a program that uses the SAM_RCTime.Spin object and also reports the values of the RCTime as you move the Potentiometer from maximum to minimum.
The program that does just that is given as an example in the documentation at the top of the object file. This program uses the FullDuplex.Spin object to write the RCTime values to the ParallaxTerminal program to display the value.
Use the example and determine the maximum and minimum readings. With my setup and circuit I obtained the limits of 0 and 5425. These values are actually Clock cycles and the actual time depends on the frequency of the propeller. The frequency I had was 80 MHz. However, it does not really matter whether these numbers are in actual time or in clock-ticks. So there is no real advantage in converting them to seconds. Nevertheless, if you actually want to do that, just device clock ticks by 80 x 106.
If you want to scale a value X that varies over a range Xmin to Xmax to a value Y that varies over a range Ymin to Ymax then you want to have:
·········· (Y-Ymin)/(Ymax-Ymin) = (X-Xmin)/(Xmax-Xmin)
With a bit of manipulation:
········· Y = Ymin + (X-Xmin)*(Ymax-Ymin)/(Xmax-Xmin)
Using the math above we establish the formula:
··········· PulseWidth := Min PulseWidth+ (RCTime-Min RCTime)*(Max PulseWidth-Min PulseWidth) /(Max RCTime· - Min RCTime)
This formula will convert an RCTime value over the established range to a Pulsewidth over the allowed range. For my case, min pulse width is 500, max pulse width is 2600. Also I established that the max RCTime was 5425 (it varied a little· from reading to reading but I took the maximum of all the readings). The min RCTime was 0. Thus :
··················· PulseWidth := 500+ (RCTime-0)*(2600-500)/5425-0)
··········· è ···PulseWidth := 500+ RCTime*2100/5425
I then multiplied 2100 by 10 which makes 21000 and therefore had to divide by 10 in the end. I did this to get a little better resolution with the integer division, just in case it is needed (in fact, I did an experiment and it is not really needed and you can leave it out).
The final formula is then:
················· PulseWidth := 500+ RCTime*21000/5425/10
Remember the pulse width is expressed in microseconds. The SAM_Simple_Servo.Spin object will expect the value to be in microseconds and will calculate the pulse width accordingly. Also the Servo32v5.Spin will expect the values in microseconds too.
You can replace the hard-coded numbers in the formula with Constants. This will make it easier to change the limits and the formula will then
calculate the values. You will have to use formula at the top. However, this will require·more calculations which will make the routine a little slower.
Post Edited (SamMishal) : 7/27/2009 4:17:44 AM GMT