🌟
M5StackCore2(MicroPython)でポモドーロタイマーを作った
以前、下のようなM5Stackでポモドーロタイマーを作ったのですが、そのときはCPPだったので次はMicroPythonでやってみようということで移植しました。
できたこと、できなかったこと
できた
とりあえずMicroPythonでも同様のものができた。
できなかった
beep音が出せない。
ファームウェアの問題かもしれない。リセットしたときの音は出るのでいまいち理由が不明
準備
前提: M5StackがPCと接続できていること、Wifiがあること
ファームウェア
焼くためにM5Burnerダウンロードする
とりあえず、micropython用の、M5Stack公式のファームウェアを使う(Ulflow)
UIFlow_Core2 v1.13.1
M5Stack側の接続をWifiにする。API KEYが出る。
これにアクセスしてAPI KEYを入力して接続、コードを書く。
参考:
(VSCodeの拡張は使えない、ずっと不具合がでているらしい)
MicroPython感想など
- 慣れていないのもあり使いにくい。Thonnyというものが人気があるらしい。
- 書き込みするときに毎回リセットするのが面倒なのだけど、エラーしたときはやり直しで書き込みができる
- MicroPythonは3.4がベースだそうで、例えば
f"{}"
が使えなかったりする - MicroPythonとCppの位置づけは、PoCとプロダクション、みたいなものらしい。スピード、メモリ、電力消費の観点。参考reddit
コード
import time
from imu import IMU
from m5stack import btnA, btnB, btnC, lcd
# Constants and initial setup
WORK_TIMER_SEC = 25 * 60
BREAK_TIMER_SEC = 5 * 60
STOPPED, RUNNING = 0, 1
UP, SIDE = 0, 1
timer_state = STOPPED
remaining_time = WORK_TIMER_SEC
is_work_timer = True
is_reset_prompt = False
imu = IMU()
def setup_lcd():
lcd.clear()
lcd.font(lcd.FONT_DejaVu40)
lcd.setTextColor(lcd.WHITE)
def beep():
# NOTE: Cannot use sound via UiFlow
pass
def get_orientation():
_, _, az = imu.acceleration
return UP if abs(az) > 0.8 else SIDE
def update_display():
bg_color = lcd.RED if is_work_timer else lcd.GREEN
lcd.clear(bg_color)
lcd.print(
"{:02d}:{:02d}".format(*divmod(remaining_time, 60)), lcd.CENTER, lcd.CENTER
)
def display_reset_prompt():
lcd.clear(lcd.BLACK)
lcd.font(lcd.FONT_Default)
lcd.print("Reset?", lcd.CENTER, 150)
lcd.print("Yes", 40, 200)
lcd.print("No", 150, 200)
def handle_reset_prompt():
global is_reset_prompt, is_work_timer, remaining_time, timer_state
display_reset_prompt()
while True:
time.sleep(0.1) # Debounce delay
if btnA.wasPressed():
is_reset_prompt, is_work_timer, remaining_time, timer_state = (
False,
True,
WORK_TIMER_SEC,
STOPPED,
)
lcd.font(lcd.FONT_DejaVu40)
break
elif btnB.wasPressed():
is_reset_prompt = False
lcd.font(lcd.FONT_DejaVu40)
break
def check_buttons():
global is_reset_prompt
if btnC.wasPressed():
is_reset_prompt = True
def update_timer():
global remaining_time, is_work_timer, timer_state
if timer_state == RUNNING:
remaining_time -= 1
if remaining_time <= 0:
beep()
is_work_timer = not is_work_timer
remaining_time = WORK_TIMER_SEC if is_work_timer else BREAK_TIMER_SEC
def loop():
global timer_state
check_buttons()
if is_reset_prompt:
handle_reset_prompt()
else:
orientation = get_orientation()
timer_state = STOPPED if orientation == UP else RUNNING
update_timer()
update_display()
# Main execution starts here
setup_lcd()
while True:
loop()
time.sleep(1) # Main loop delay
次にやりたいこと
- 時間を変更できるようにする
- 音を鳴らす
- ファイル分割
- いろいろ適当なので直す(0秒の表示がないとか)
Discussion