Scheduler for Micropython

General discussions and questions abound development of code with MicroPython that is not hardware specific.
Target audience: MicroPython Users.
Post Reply
User avatar
pythoncoder
Posts: 3720
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Scheduler for Micropython

Post by pythoncoder » Fri Aug 22, 2014 8:30 am

I've posted some code for a simple library which implements lightweight threads using generators. This is designed for the Micropython board and allows programs to be written in a threaded style using cooperative multitasking. There are two additional libraries, both of which employ the scheduler. One provides debounced input for switches, and the other provides support for LCD displays using the popular Hitachi HD44780 controller chip.

There is also a selction of simple demonstration programs illustrating the use of the libraries. Code is on
https://github.com/peterhinch/Micropython-scheduler.git

Regards, Pete
Peter Hinch

Turbinenreiter
Posts: 288
Joined: Sun May 04, 2014 8:54 am

Re: Scheduler for Micropython

Post by Turbinenreiter » Sun Aug 24, 2014 2:26 pm

Nice!

Based on your examples I wrote the code attached on the bottom.

There is thread for each:
* get the accelerations
* print it
* write the data to a buffer
* clear and write the buffer to a file once it reaches a certain length

It works, but some parts I don't fully understand yet.

Code: Select all

import pyb
from usched import Sched, Roundrobin, Poller, Timeout

accel = pyb.Accel()

pyb.delay(200)

def stop(fTim, objSch):
    yield Timeout(fTim)
    objSch.stop()

def buff_len(data_buff):
    print(len(data_buff))
    if len(data_buff) == 3:
        return 1
    return None

def write_to_file(data_buf):
    wf = Poller(buff_len, (data_buf,), 2)
    while True:
        reason = (yield wf())
        if reason[1]:
            with open('newlog.csv', 'a') as outfile:
                outfile.write(str(data_buf)+'x\n')
            del data_buf[1:]
            del data_buf[0]
        if reason[2]:
            pass

def write_buf(data, buff):
    wf = Roundrobin()
    while True:
        buff.append(data)
        yield wf()

def output(out):
    wf = Roundrobin()
    while True:
        print(out)
        yield wf()

def acc(result):
    wf = Roundrobin()
    while True:
        result[0] = accel.filtered_xyz()
        yield wf()

# USER TEST PROGRAM

def robin_test(duration):
    result = [(0)]
    buff = []
    objSched = Sched()

    objSched.add_thread(acc(result))
    objSched.add_thread(output(result))
    objSched.add_thread(write_buf(result, buff))
    objSched.add_thread(write_to_file(buff))

    objSched.add_thread(stop(duration, objSched))

    objSched.run()

robin_test(2)

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

Re: Scheduler for Micropython

Post by pythoncoder » Mon Aug 25, 2014 10:31 am

I'm glad you're finding it useful. If you're new to multi-threaded programming it can take a little getting used to. But it makes embedded code much easier to write (and read!) when it has to respond to events such as user input.

I'm not a Micropython dev but it may be more efficient to allocate a fixed length buffer and to maintain a separate index into the buffer rather than dynamically appending and deleting list elements - potentially for long periods. The latter technique may cause the garbage collector to take longer than it otherwise might. Perhaps a Micropython implementor will advise...

Regards, Pete
Peter Hinch


Post Reply