Operations with different servos

The official pyboard running MicroPython.
This is the reference design and main target board for MicroPython.
You can buy one at the store.
Target audience: Users with a pyboard.
Post Reply
crystalattice
Posts: 2
Joined: Mon Oct 01, 2018 6:07 pm

Operations with different servos

Post by crystalattice » Mon Oct 01, 2018 6:24 pm

I have a project that requires three different servos: two continuous rotation (CR) and one linear. The two CR servos are represent radars, while the linear one controls a security gate.

The gate is currently has a time.sleep() command to cause the arm to move 90 degrees open/close every 10 seconds. I have all servos monitoring pin X5 for a control signal: if a voltage is seen on X5, then the servos run. If that voltage goes away, then the servos should stop.

Eventually, I would like to have a separate control signal for each servo, as well as having the gate respond to user input. But, for the current simulation, having the gate cycle open and closed simply demonstrates the capability of the model, as well as justifying the purchase of more pyboards.

The main problem is the sleep command. Because it sleeps the entire program, the servos continue in their current state until the sleep command finishes. Thus, if X5 loses voltage, it can be up to 10 seconds before the servos start/stop.

I looked at threading the gate function but have had no luck, probably because I don't know how to properly implement the _thread module. In lieu of rewiring the model, is there a way to make the gate cycling not affect the other servos?

Current code is below:
[code]
# main.py -- put your code here!

from pyb import Pin, Servo, Timer
import _thread
import time

control_pin = Pin("X5", Pin.IN)

weather = Servo(1)
atc = Servo(2)
gate = Servo(3)


def radar():
if control_pin.value() == 1:
weather.speed(5)
atc.speed(5)
else:
weather.speed(-1)
atc.speed(-1)

def gate_cycle():
if gate.angle() <= 5:
gate.angle(90, 1000)
time.sleep(10)
else:
gate.angle(5, 1000)
time.sleep(10)

while True:
radar()
gate_cycle()
[/code]

User avatar
mattyt
Posts: 410
Joined: Mon Jan 23, 2017 6:39 am

Re: Operations with different servos

Post by mattyt » Mon Oct 01, 2018 11:12 pm

I suggest you start by looking at (Micro)Python's asyncio functionality. It allows you to create an event loop and execute functions that appear to operate asynchronously; specifically for your application an async sleep doesn't prevent other operations from happening, it just relinquishes control so that other tasks can run while the sleep is in effect.

A great place to start would be Peter Hinch's tutorial, which has a good introduction for newcomers to asyncio.

I'd definitely steer clear of threading for this application. :)

rhubarbdog
Posts: 168
Joined: Tue Nov 07, 2017 11:45 pm

Re: Operations with different servos

Post by rhubarbdog » Tue Oct 02, 2018 4:59 am

Code: Select all

import _thread

def main():
    _thread.start_new_thread(gate, ())
    _thread.start_new_thread(radar, ())
    
    while True:
        pass

main()   
Remember you need to download and install thread capable firmware from http://micropython.org/download. Following instructions at https://github.com/micropython/micropyt ... are-Update. Upload it onto your pyboard with a dfu programmer.

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: Operations with different servos

Post by pythoncoder » Tue Oct 02, 2018 10:53 am

I would second @mattyt's observation: use uasyncio. For reasons why, see the docs he cited.
Peter Hinch
Index to my micropython libraries.

crystalattice
Posts: 2
Joined: Mon Oct 01, 2018 6:07 pm

Re: Operations with different servos

Post by crystalattice » Tue Oct 02, 2018 1:48 pm

I'll take a look at asyncio. Thanks for the help.

Post Reply