Subject
- Posted on
Need help with PIC and servo
- 02-23-2006
February 23, 2006, 11:39 pm
I found the post from "Eriswerks" in this group on February 12th that
described my problem exactly: my Futaba 3004 servo turns clockwise 90-180
degrees when pulsed by my PIC 16F84A (code attached below). I've selected
pulse widths from 0-1000 counts, which is supposedly 0-10ms with my 4MHz
crystal. I've also varied the low part of each pulse from 10 to 1800, which
is supposed to be in milliseconds in the PICBasic Pro PULSOUT command.
Regardless of these values the result is about the same: the servo rotates
90-180 degrees clockwise (viewed from the top) per set of cycles. I'd
really appreciate any help. --Buddy
Here's the latest version of my servo calibration routine with the shortest
pulse widths I've tested (it's supposed to work with 100-200 counts per
pulse but did not):
***************************************************************************
Include "modedefs.bas" ' Include serial modes
trisa = %00000000 ' set porta to outputs
trisb = %00000000 ' set portb to outputs
lcd var PORTA.3 'lcd signal on 16F84A pin 2
piezo var PORTB.4
left_led var PORTB.0
right_led var PORTB.1
servo var PORTB.7 'servo signal on 16F84A
pin 13
baud con N2400
timer var Byte
width var byte
width_init var byte
high left_led ' turn on left LED
low right_led ' turn off right LED
Serout lcd,baud,[254,1] ' clear lcd screen
pause 1000 ' give time to initialize lcd
Serout lcd,baud,[254,128,"- Servo cal -"] ' display program title on the
LCD
Serout lcd,baud,[254,192,"Pulse: "] ' set up the LCD display
pause 5000 ' wait for 5 seconds
low left_led ' turn off left LED
high right_led ' turn on right LED
sound piezo,[125,50]
low piezo
width_init = 0 ' set initial pulse width
width = width_init ' initial pulse width
variable
low servo ' initialize servo pin
main:
Serout lcd,baud,[254,200,#width," "] ' display the pulse width in
counts
for timer = 1 to 20 ' send pulses to servo
pulsout servo,width
pause 15
next timer
pause 4000
toggle left_led ' toggle left LED
toggle right_led ' toggle right LED
if width < 100 then ' increase width through
max then repeat
width = width + 10
else
width = width_init
sound piezo,[125,50]
low piezo
endif
Goto main
end
**************************************************************************
described my problem exactly: my Futaba 3004 servo turns clockwise 90-180
degrees when pulsed by my PIC 16F84A (code attached below). I've selected
pulse widths from 0-1000 counts, which is supposedly 0-10ms with my 4MHz
crystal. I've also varied the low part of each pulse from 10 to 1800, which
is supposed to be in milliseconds in the PICBasic Pro PULSOUT command.
Regardless of these values the result is about the same: the servo rotates
90-180 degrees clockwise (viewed from the top) per set of cycles. I'd
really appreciate any help. --Buddy
Here's the latest version of my servo calibration routine with the shortest
pulse widths I've tested (it's supposed to work with 100-200 counts per
pulse but did not):
***************************************************************************
Include "modedefs.bas" ' Include serial modes
trisa = %00000000 ' set porta to outputs
trisb = %00000000 ' set portb to outputs
lcd var PORTA.3 'lcd signal on 16F84A pin 2
piezo var PORTB.4
left_led var PORTB.0
right_led var PORTB.1
servo var PORTB.7 'servo signal on 16F84A
pin 13
baud con N2400
timer var Byte
width var byte
width_init var byte
high left_led ' turn on left LED
low right_led ' turn off right LED
Serout lcd,baud,[254,1] ' clear lcd screen
pause 1000 ' give time to initialize lcd
Serout lcd,baud,[254,128,"- Servo cal -"] ' display program title on the
LCD
Serout lcd,baud,[254,192,"Pulse: "] ' set up the LCD display
pause 5000 ' wait for 5 seconds
low left_led ' turn off left LED
high right_led ' turn on right LED
sound piezo,[125,50]
low piezo
width_init = 0 ' set initial pulse width
width = width_init ' initial pulse width
variable
low servo ' initialize servo pin
main:
Serout lcd,baud,[254,200,#width," "] ' display the pulse width in
counts
for timer = 1 to 20 ' send pulses to servo
pulsout servo,width
pause 15
next timer
pause 4000
toggle left_led ' toggle left LED
toggle right_led ' toggle right LED
if width < 100 then ' increase width through
max then repeat
width = width + 10
else
width = width_init
sound piezo,[125,50]
low piezo
endif
Goto main
end
**************************************************************************
Re: Need help with PIC and servo
milliseconds, it's the minimum timing amount for the particular chip, in
MICROseconds. So, with the BS2, which has a minimum 2 microsecond
granularity, a value of 750 is 1500 microseconds.
Try something simpler. All you need is a pulsout command, a pin number,
and a value. Keep setting values in your code, and re-download your code
to try different values. After you get this code to work you can create
a more fancy program that sweeps the servo, updates an LCD, etc.
Provide ONLY pulses in the range of 1000 to 2000 microseconds (1 to 2
milliseconds). The servo should center at 1500 microseconds (1.5
milliseconds). If the servo is unmodified, using longer or shorter
pulses may *permanently damage* the servo, because it will case the
servo to hit its stops. Even if the servo is modified for contiunuous
rotation, values much shorter or longer than 1000-2000 microseconds may
put the servo electronics into an unknown state.
You may, after determining your programming timing is correct,
experiment with SLIGHTLY longer or shorter values. This will allow you
to achieve close to 180 degree rotation of the servo. However, start
with the safe 1000-2000 microsecond range.
-- Gordon
Buddy wrote:
Re: Need help with PIC and servo
milliseconds when I should have said PAUSE. As I mentioned elsewhere in the
post, PULSOUT counts supposedly equal 10us for this PIC when using a 4MHz
crystal.
I agree also that a shorter routine would have been quicker to write, but
now that this one's done it seems it should actually help solve this problem
by telling me what pulse width is being sent to the servo while I watch it
respond. The LCD commands work OK and don't require any attention when I
change the code to try new pulse widths.
Finally, I tried to say in the original post that I had varied the pulse
widths from 0 to 1000 counts, which should be about 0-10ms. This includes
1000-2000 microseconds, as you suggest, which is where I started. As I
mentioned, all non-zero pulse widths produce essentially the same results,
including 1us, 100us, 1000us, 1500us, 2000us, 5000us and 10000us, plus many
others between the extremes.
Thanks again for your thoughts. What do you think I should try next?
Buddy
Re: Need help with PIC and servo
significantly shorter than the designed 1000-2000 microseconds can put
them into an unstable/unknown state. Your code shouldn't be going below
1000 microseconds, or above 2000 microseconds. Some servo models are
known to deadlock in this condition, and the only way to get them
working again is to unplug them (remove power).
You CAN go slightly higher or lower, depending on the servo, but again,
emphasis on *slightly*.
-- Gordon
Buddy wrote:
Re: Need help with PIC and servo
between 100 and 200 counts, which is what every source I've found
recommends. Every group of ten (in that version) pulses drove the servo
90-180 degrees clockwise. I then moved the boundaries a little at a time
after removing power from everything each time, but the performance never
changed. It took a lot of tries before I sent the 1us and 10000us pulses
but the servo never acted differently. Incidentally, I tried another servo
with the "nominal" code values, hoping that I had a bad one, but it behaved
the same way.
As soon as I hit "Send" I'm going to build a little servo control circuit
with a pot and a 555 timer. Depending on the results I may also download a
sound-card oscilloscope and see if I can find out what these pulses look
like.
Thanks again, and please share any other thoughts or comments. --Buddy
Re: Need help with PIC and servo
grounds from my servo power supply and my logic circuit power supply tied
together. Gordon's book mentions this but I didn't appreciate its
importance until afterwards. One 1/2" (12mm) wire on my breadboard took
care of everything! --BR
Site Timeline
- » More Visual Recognition and the SIFT algorithm
- — Next thread in » General Robotics Forum
-

- » stepper driving problem!
- — Previous thread in » General Robotics Forum
-

- » evoMUSART 2013: First CFP (with correct dates)
- — Newest thread in » General Robotics Forum
-

- » DCC sound question
- — The site's Newest Thread. Posted in » Model Railroad Forum
-






