pico-micropython-examples
pico-micropython-examples copied to clipboard
Add PIO example for servo control
Controls one servo at GP16 and additionally the onboard LED This demonstrates use of two servos.
Could you add a README.adoc
file and accompanying wiring diagram, similar to that found in other examples, e.g. see the NeoPixel ring example.
Nice PIO example :slightly_smiling_face: Just a couple of queries: a) the comments talk about "IRQ4", but the code seems to be using relative IRQs? b) is there a reason for using relative IRQs, or would it make sense to use an absolute IRQ so that a single ServoTrigger could be used for multiple Servos?
I will add a readme.
Regarding IRQs: Sharing the IRQ did not work, so I used relative IRQs. That way, the Trigger needs to be the SM before the output program, so the IRQs match.
Regarding IRQs: Sharing the IRQ did not work, so I used relative IRQs. That way, the Trigger needs to be the SM before the output program, so the IRQs match.
Sounds like this should be in the README! :)
Regarding IRQs: Sharing the IRQ did not work, so I used relative IRQs.
I hope you don't mind, but I had a bit of a fiddle.... :wink: (I'm still getting to grips with PIO myself)
I was able to get it working with only a single Servo_Trigger
object by changing servo_trigger()
to do:
irq(clear, 4) # Clear IRQ4, allows servo code to run again
irq(4) # Set IRQ4 again, ready for the wait in servo code
(which I guess then means I need to change the trig_ctr calculation to trig_ctr = (trig_frq // 1000 * trig_target) - 4
), and changing servo_prog()
to do:
wait(0, "irq", 4) .side(0) # Wait here for IRQ to be released by trigger SM
:grinning:
Other comments:
- As this is purely an example, it might be more useful to change the
for _ in range(2):
towhile True:
? - IMHO the
Servo_Trigger
class ought to be renamedServoTrigger
(which is the typical Python convention) - Given the wide variability of servos, it's probably worth adding
min_pulse
andmax_pulse
arguments to yourServo
init-method, and then doing
self.base_pulse = min_pulse
self.free_pulse = max_pulse - min_pulse
But of course these are only suggestions, I'll leave the final decision up to you.
I don't mind - I'll check your suggestions later. During my testing, the 1-Trigger 2-Servo code compiled, but the output was garbage.
Thanks! The replacement with IRQ/Clear + Wait did work.
When testing the changes that I mentioned above, I had three separate servos all running from a single trigger :) But I had to insert some sleeps between moving each servo individually, because if I tried moving multiple servos at the same time, it tried to pull too much current from my computer's USB port and the Pico reset. (this is fixable by powering the servos from a separate PSU, but I couldn't be bothered to wire that up!)