uasyncio with time-critical bit-banging

General discussions and questions abound development of code with MicroPython that is not hardware specific.
Target audience: MicroPython Users.
Post Reply
User avatar
devnull
Posts: 146
Joined: Sat Jan 07, 2017 1:52 am
Location: Singapore / Cornwall
Contact:

uasyncio with time-critical bit-banging

Post by devnull » Thu Apr 20, 2017 2:54 am

I've never used the asyncio library and are wondering if this would be a good solution to reducing the awake time of a mqtt client device that reads several sensors and values.

Presently, my device wakes up hourly, and takes readings synchronously from 4 sensors as well as system info.

Of course each read takes time, and I was thinking that if these could be fired off asynchronously, then the awake time could be dramatically shortened and probably determined by the longest read time.

Is my reasoning / assumptions here correct ?

And what if the sensors are using bit-banging with critical timings, and one of the drivers increases the clock speed for a short period during reading of bit data, will this affect the other sensors which are also being read in parallel ?
Last edited by devnull on Thu Apr 20, 2017 9:25 am, edited 1 time in total.

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

Re: uasyncio with multiple sensors

Post by pythoncoder » Thu Apr 20, 2017 5:13 am

It's not clear from your post how familiar you are with cooperative multi-tasking. If you're new to it you might like to read the beginner's section of the tutorial referenced here https://github.com/peterhinch/micropython-async.

In essence cooperative multi-tasking provides an illusion of concurrency without the hazards and overheads of true pre-emptive scheduling (the _thread module). So a task (coroutine) in uasyncio can change the clock rate and perform some bit banging. So long as it restores the clock to its original rate before yielding to the scheduler, other tasks will be unaffected. This is because only one task is actually running at any one time.

The principal merit of cooperative systems is that they enable a task to wait on an event without causing other tasks to be blocked: while the task is in a waiting loop it yields to the scheduler allowing other tasks to run.

If each task requires time-critical bit banging which cannot be interrupted until the sequence is complete, then uasyncio may not be much help. If a task can only yield when its work is complete then the tasks will effectively run sequentially, negating the uasyncio advantage.

The other option is pre-emptive scheduling. However this may not be appropriate if the bit banging is time critical because a sequence could be interrupted by the pre-emption mechanism; cooperative scheduling guarantees that this cannot occur.

I should add a caveat here: I have no experience of the _thread module on MicroPython. In my experience cooperative scheduling is used in firmware design unless the need for a pre-emptive model is inescapable. This is because the latter brings significant problems in design and debugging because any thread can interrupt any other thread at any point in its execution. Special techniques have to be employed to control access to shared resources and data structures.

Good luck.
Peter Hinch

Post Reply