#タイマ割込み使ってストップウォッチを作ってみよう
m5stackを使ってストップウォッチを作ってみました。
-
Button A
でSTART/STOP -
Button B
でSTOP状態の時だけRESET -
Button C
は機能無し
m5stackについて調べた自分の記事のテスト編になります。
m5stackで遊ぼう
https://qiita.com/zasshyu6/items/35a1048a9781bdcfebb7
##開発環境
- windows 10 Home 64bit
- Visual Studio Code 1.36.1
- PlatformIO
- 使用言語はarduino
##m5stackのタイマ割込について
以下の説明を参考にしました
ESP32 Arduino: Timer interrupts
https://techtutorialsx.com/2017/10/07/esp32-arduino-timer-interrupts/
英語なので読むのしんどい・・・グーグル翻訳が大活躍です
しかし、読んではみたものマクロが何をやっているかわからない・・・
portENTER_CRITICAL
portEXIT_CRITICAL
portENTER_CRITICAL_ISR
portEXIT_CRITICAL_ISR
以上のマクロを調べてみたら以下の記事が見つかった
ESP32でマルチタスクを行う為の、とりあえずここまで判った事 by freeRTOS 20タスク目 [ESP32]
https://hamayan.blog.so-net.ne.jp/2018-03-06
なんと!RTOSのAPIじゃないか!!!
そしてクリティカルセクションってなんだ!って調べたら以下の記事に乗っていました
マイコン徹底入門:RTOS編:フリーのリアルタイムOS活用法: 6. クリティカルセクション
http://miqn.net/rtos/54.html
なんでRTOSのAPI?
そもそもarduinoってRTOSじゃないよね?
気になったので調べてみたら以下の記事にだいぶ詳しく載っていました
Arduino – ESP32 のマルチタスク ( Dual Core ) を試す
https://www.mgo-tec.com/blog-entry-arduino-esp32-multi-task-dual-core-01.html
-
aruduino core for the esp32
でFreeRTOS API
をたたくことでマルチコア対応ができる
gpio関連はarduino API
、割り込みとかマルチスレッドとか周期実行はFreeRTOS API
というと、結構ガチな周期制御できるのでは・・・奥が深すぎる・・・
#ストップウォッチを作ってみた
上記を踏まえ、ストップウォッチということで以下の2パターンで作ってみてどう変わるかを試します
-
loop()
関数の中だけでLCD表示を行う。 - マルチスレッドで処理を行う。
- 組みながら調べてみたこと
-
portMUX
は同期をとるためって書かれてましたが、ミューテックスの機能かな・・・ -
IRAM_ATTR
はArm-coreのセクション直叩きしてるみたいな感じ
-
##1. loop()
関数の中だけでLCD表示を行う。
ソースはgithubに上げました。
https://github.com/zasshyu66/m5stack_Study/tree/master/StopWatch1
中身は以下の様になってます。
-
loop()
内の処理- LCD表示
- 表示用数値の演算
- Start/Stop/Resetの処理(主にチャタリング防止)
-
タイマ割込は
5usec
ごとにカウンタをカウント-
1usec
周期の割込でカウントしようとしたがloop()
関数の監視に引っかかってリセットがかかる模様
-
portENTER_CRITICAL
portEXIT_CRITICAL
を使ってLCD表示の時に割り込み禁止をかけてみるとmsec
周期のカウントになってしまったので使う必要がないと判断しました。
やっぱりLCDの処理は時間がかかりますね。
##2. マルチスレッドで処理を行う。
ソースはgithubに上げました。
https://github.com/zasshyu66/m5stack_Study/tree/master/StopWatch2
-
loop()
内の処理- 無し
-
thread1()
内の処理- Start/Stop/Resetの処理(主にチャタリング防止)
-
thread2()
内の処理- LCD表示
- 表示用数値の演算
threadでの監視周期をもたせない場合は4秒くらいでリセットがかかってしまう
vTaskDelay()
を持たせるとリセットがかからずに動いてくれる
vTaskDelay()
はどうやらusec
周期で動いている様子
なので、結局1usec
周期の動作を行うことは無理そうです
残念
また、マルチスレッドにしたことでボタン動作が不安定になってしまった。
この辺もいろいろいじらないといけなさそう・・・難しい・・・
##次にやること
次にパルスカウンターを作ろうと思ったが、タイマ割込やマルチスレッドの動作のやり方など勉強することが色々あるのでどうしようか迷い中です。
タイマ割込を調べましたがESP32の奥の深さにはまってしまいました。
(2019/08/19更新)
ストップウォッチを使って気になったところを調べて直しました。
続・m5stackでストップウォッチを作る
https://qiita.com/zasshyu6/items/a68d98edb08ef5439434