Hello.
I am investigating using a servo, and I have breadboarded a simple circuit on the AX091 development board. I have programmed a 08M2 so that depending on a couple of switches the servo drives to one position and stays there, or drives to another and stays there.
Unfortunately, the servo twitches at either position - once every roughly 4 seconds.
I have tried two different types of servo and both do the same.
Is this because the AX091 board is not really set for using servos - will the problem go away if I make up a "proper" circuit board with a separate power supply for the servo?
Many thanks in advance for any advice
hnorwood, it looks like you got your problem solved, but thought I'd post some code and thoughts here, too. I have an existing printed circuit board with a Picaxe20M2 that I wanted to use to drive a micro-servo to open and close a pair of tweezers VERY accurately.
Because of the board design, it was easiest for me to use port A.0 as the servo signal. A.0 is normally the serout pin for the picaxe during programming, so you would expect it to occassionally glitch when the Picaxe checked for new downloads. Not so. Notice in the code that the "disconnect" command is commented out.
I tried servo and servopos commands. Very glitchy. I tried pulsout. Better, but not perfect (I couldn't tolerate even one servo position step when the tweezers were closed).
So I decided to "brute force" the entire thing. I cranked up the 20M2 clock rate to the max (32 MHz), disabled brown out detection (the servo runs from the regulated Picaxe +5 volt supply), and explicitly told the A.0 pin to go high and low to give the correct pulse width for the servo.
On the two, very different, servos I controlled with this code it worked perfectly. The servo goes exactly and repeatably to the position commanded, and stays there with absolutely no twitching, glitching, or even humming. The use of pulseus at 32 MHz lets you set positions within 1.25 microseconds, although I am sure the internal servo mechanism is no way capable of tracking that kind of timing resolution (potentiometer noise, gear backlash, servo clock, etc.).
At least for the two very different servos I have tested, the 20 msec pulse repetition rate is not at all critical, and I don't even try to compensate for the pulse width.. The rep rate only determines how long the servo can go before a force applied to the output shaft can over-ride its position holding capability. In my case, the gear ratio itself is more than enough to keep the tweezers either opened or closed even if the servo has lost all power.
In addition, I have a green LED which illuminates to show that the tweezers have achieved their completely open position, and a red LED to show that the tweezers have achieved their completely closed position.
In operation, you press a button, and the tweezers go to the position they are not currently in, and the appropriate LED lights up. Under the microscope (where I use the tweezers), they are repeatable within +/- 0.00025 inch. Even better, they don't twitch, or even make noise.
I'm sure a better programmer than me (which is everyone), could clean this code up, but I found it interesting that servos are pretty forgiving, and a brutal "high-low" approach worked best for me.
Code:
[COLOR=Navy]#Picaxe [/COLOR][COLOR=Black]20M2 [/COLOR][COLOR=Green];Picaxe type[/COLOR]
[COLOR=Navy]#no_data [/COLOR][COLOR=Green];do not load data[/COLOR]
[COLOR=Navy]#no_end [/COLOR][COLOR=Green];do not auto-end
;disconnect ;do not allow new downloads[/COLOR]
[COLOR=Blue]disablebod [/COLOR][COLOR=Green];disable brownout detection to prevent servo glitch[/COLOR]
[COLOR=Blue]setfreq M32 [/COLOR][COLOR=Green];clock frequency 32 MHz[/COLOR]
[COLOR=Blue]pullup [/COLOR][COLOR=Navy]%0000010000000000 [/COLOR][COLOR=Green];apply weak pull-up to C.2 for switch[/COLOR]
[COLOR=Blue]symbol [/COLOR][COLOR=Black]open[/COLOR][COLOR=DarkCyan]=[/COLOR][COLOR=Navy]1430 [/COLOR][COLOR=Green];open servo pulsewidth: 1.78750 msec[/COLOR]
[COLOR=Blue]symbol [/COLOR][COLOR=Black]close[/COLOR][COLOR=DarkCyan]=[/COLOR][COLOR=Navy]925 [/COLOR][COLOR=Green];close servo pulsewidth: 1.15625 msec[/COLOR]
[COLOR=Black]init:[/COLOR]
[COLOR=Blue]high B.0 [/COLOR][COLOR=Green];turn on open LED anode[/COLOR]
[COLOR=Blue]pwmout B.1[/COLOR][COLOR=Black],[/COLOR][COLOR=Navy]24[/COLOR][COLOR=Black],[/COLOR][COLOR=Navy]96 [/COLOR][COLOR=Green];dim at 4% duty cycle at LED cathode[/COLOR]
[COLOR=Blue]do
high A.0 [/COLOR][COLOR=Green];initialize servo (open)
[/COLOR][COLOR=Blue]pauseus [/COLOR][COLOR=Black]open
[/COLOR][COLOR=Blue]low A.0
pause [/COLOR][COLOR=Navy]160 [/COLOR][COLOR=Green];20 msec delay[/COLOR]
[COLOR=Blue]loop until [/COLOR][COLOR=Purple]pinC.2[/COLOR][COLOR=DarkCyan]=[/COLOR][COLOR=Navy]0
[/COLOR]
[COLOR=Black]main:[/COLOR]
[COLOR=Blue]do
if [/COLOR][COLOR=Purple]pinC.2[/COLOR][COLOR=DarkCyan]=[/COLOR][COLOR=Navy]0 [/COLOR][COLOR=DarkCyan]and [/COLOR][COLOR=Purple]b0[/COLOR][COLOR=DarkCyan]=[/COLOR][COLOR=Navy]0 [/COLOR][COLOR=Blue]then [/COLOR][COLOR=Green];if button is pressed and tweezers are open
[/COLOR][COLOR=Blue]pause [/COLOR][COLOR=Navy]160 [/COLOR][COLOR=Green];20 msec switch debounce
[/COLOR][COLOR=Blue]for [/COLOR][COLOR=Purple]w1[/COLOR][COLOR=DarkCyan]=[/COLOR][COLOR=Black]open [/COLOR][COLOR=Blue]to [/COLOR][COLOR=Black]close [/COLOR][COLOR=Blue]step [/COLOR][COLOR=DarkCyan]-[/COLOR][COLOR=Navy]1 [/COLOR][COLOR=Green];servo signal from open to close
[/COLOR][COLOR=Blue]high A.0 [/COLOR][COLOR=Green];slowly rotate servo clockwise (close)
[/COLOR][COLOR=Blue]pauseus [/COLOR][COLOR=Purple]w1
[/COLOR][COLOR=Blue]low A.0
pause [/COLOR][COLOR=Navy]50 [/COLOR][COLOR=Green];set closing speed
[/COLOR][COLOR=Blue]next [/COLOR][COLOR=Purple]w1
b0[/COLOR][COLOR=DarkCyan]=[/COLOR][COLOR=Navy]1 [/COLOR][COLOR=Green];set position flag
[/COLOR][COLOR=Blue]low B.0 [/COLOR][COLOR=Green];turn off open LED
[/COLOR][COLOR=Blue]high B.2 [/COLOR][COLOR=Green];turn on closed LED
[/COLOR][COLOR=Blue]endif
if [/COLOR][COLOR=Purple]pinC.2[/COLOR][COLOR=DarkCyan]=[/COLOR][COLOR=Navy]0 [/COLOR][COLOR=DarkCyan]and [/COLOR][COLOR=Purple]b0[/COLOR][COLOR=DarkCyan]=[/COLOR][COLOR=Navy]1 [/COLOR][COLOR=Blue]then [/COLOR][COLOR=Green];if button is pressed and tweezers are closed
[/COLOR][COLOR=Blue]pause [/COLOR][COLOR=Navy]160 [/COLOR][COLOR=Green];20 msec switch debounce
[/COLOR][COLOR=Blue]for [/COLOR][COLOR=Purple]w1[/COLOR][COLOR=DarkCyan]=[/COLOR][COLOR=Black]close [/COLOR][COLOR=Blue]to [/COLOR][COLOR=Black]open [/COLOR][COLOR=Blue]step [/COLOR][COLOR=Navy]10 [/COLOR][COLOR=Green];servo signal from close to open
[/COLOR][COLOR=Blue]high A.0 [/COLOR][COLOR=Green];rotate servo counterclockwise (open)
[/COLOR][COLOR=Blue]pauseus [/COLOR][COLOR=Purple]w1
[/COLOR][COLOR=Blue]low A.0
pause [/COLOR][COLOR=Navy]16 [/COLOR][COLOR=Green];delay 2 msec for servo stability
[/COLOR][COLOR=Blue]next [/COLOR][COLOR=Purple]w1
b0[/COLOR][COLOR=DarkCyan]=[/COLOR][COLOR=Navy]0 [/COLOR][COLOR=Green];set position flag
[/COLOR][COLOR=Blue]high B.0 [/COLOR][COLOR=Green];turn on open LED
[/COLOR][COLOR=Blue]low B.2 [/COLOR][COLOR=Green];turn off closed LED
[/COLOR][COLOR=Blue]endif
loop[/COLOR]