LoginSignup
8
7

More than 5 years have passed since last update.

LOLIN ESP32 OLED ボードの MicroPython で マルチスレッド とタイマー割り込み

Last updated at Posted at 2017-12-21

清水@ロボット部 (日本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を獲得して時刻を出力します。

main.py
# 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つのタイマーが割り込みを発生します。
中間にタイマー割り込み停止期間を設けています。

main.py
# 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

8
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
7