清水@ロボット部 (日本Androidの会 秋葉原支部)です。
ロボット部の勉強会で、説明とデモを予定しています。 日程は 2018/1/8 月、成人の日 で調整中です。
ロボット部 Googleグループ
https://groups.google.com/forum/?hl=ja#!forum/robot-android-group-japan-akb
WEMOS社 LOLIN32 ESP32 OLED ボード上で MicroPython のマルチスレッドとタイマー割り込みを動かして見ました。
-
import _thread でマルチスレッドが使えます。
_thread は、Python 3.6.3 標準ライブラリの低水準のスレッド API です。 -
import machine、machine.Timer でタイマー割り込みも動いているようです。
センサーで計測しながら、Webサーバで情報提供ができそうです。
マルチスレッド プログラム
3つのスレッドが並列に走ります。順番にLockを獲得して時刻を出力します。
# Multiple threads & lock program
# MicroPython on Lolin ESP32 OLED 128x64 16x6(0..50)
import _thread, time
Lock = _thread.allocate_lock()
global Start
def now(): return 'time {:0>4}'.format(time.time() - Start)
def heavyPrint(msg):
with Lock:
print('%s, %s' % (now(), msg))
time.sleep(1)
def th_func(id, limit, delay):
for i in range(limit):
heavyPrint('%s Running thread %d, Count %d' % (now(), id, i))
time.sleep(delay)
def go(multi, limit, delay):
global Start; Start = time.time()
for id in range(multi):
_thread.start_new_thread(th_func, (id, limit, delay))
go(3,2,0)
マルチスレッド 実行結果
3つのスレッドが排他的にLockを獲得しています。
Lock待ちが観察できます。
time 0000, time 0000 Running thread 0, Count 0
time 0001, time 0000 Running thread 1, Count 0
time 0002, time 0000 Running thread 2, Count 0
time 0003, time 0001 Running thread 0, Count 1
time 0004, time 0002 Running thread 1, Count 1
time 0005, time 0003 Running thread 2, Count 1
タイマー割り込み プログラム
2つのタイマーが割り込みを発生します。
中間にタイマー割り込み停止期間を設けています。
# 2 timers test program
# MicroPython on Lolin ESP32 OLED
import machine, time
timers = (machine.Timer(0), machine.Timer(1))
counts = [0,0]
global Start
def now():return 'time {:0>4}'.format(time.time() - Start)
def timePrint(msg): print('%s, %s' % (now(), msg))
def handl(timer):
global counts
i = timers.index(timer)
timePrint("Timer %s, Count %s" % (i, counts[i]))
counts[i] += 1
def go(delay):
global Start; Start = time.time()
timers[0].init(period=1000, mode=machine.Timer.PERIODIC, callback=handl)
timers[1].init(period=2000, mode=machine.Timer.PERIODIC, callback=handl)
time.sleep(delay)
state = machine.disable_irq()
timePrint(" main IRQ disable ---")
time.sleep(delay)
machine.enable_irq(state)
timePrint(" main IRQ enable ---")
time.sleep(delay)
timers[0].deinit()
timers[1].deinit()
time.sleep(1)
timePrint(" main stop ---")
go(3)
タイマー割り込み 実行結果
2つのタイマー割り込みが動いています。
途中に割り込み停止期間があります。
time 0001, Timer 0, Count 0
time 0002, Timer 1, Count 0
time 0002, Timer 0, Count 1
time 0003, main IRQ disable ---
time 0003, Timer 0, Count 2
time 0006, main IRQ enable ---
time 0006, Timer 0, Count 3
time 0006, Timer 0, Count 4
time 0006, Timer 1, Count 1
time 0006, Timer 1, Count 2
time 0007, Timer 0, Count 5
time 0008, Timer 1, Count 3
time 0008, Timer 0, Count 6
time 0009, Timer 0, Count 7
time 0010, main stop ---
参考情報
Threading
https://docs.pycom.io/chapter/tutorials/all/threading.html
17.9. _thread — 低水準の スレッド API
https://docs.python.jp/3/library/_thread.html
ESP32 MicroPython: Timer interrupts
https://techtutorialsx.com/2017/10/07/esp32-micropython-timer-interrupts/
MicroPython on an ESP32 Board With Integrated SSD1306 OLED Display (WEMOS/Lolin)
https://www.instructables.com/id/MicroPython-on-an-ESP32-Board-With-Integrated-SSD1/
Micropython + ESP32のためのIDE「uPyCraft」を使ってみた
http://blog.boochow.com/article/453812032.html