はじめに
ESP32のコーディングをMicroPythonで行うことができます。
自身の備忘録として、コードメモを残します。
環境の構築は、下記の記事を参考にしてください。
[備忘録]ESP32-VSCode-microPythonでの開発環境の構築
注意事項
動く程度のものなので、書き方として間違っている場合があります。
確認環境
- ホストPC
- windows10 64bit Home
- VSCode - 1.41.1
- Pymakr 1.1.5
- NodeJS - 12.14.1 LTS
- ターゲット
- MicroPython v1.12 on 2019-12-20; ESP32 module with ESP32
GPIO関連
Lチカ(GPIO-OUTPUT)
27番PINにLEDを接続するのを前提に記載しています。
from machine import Pin
led = Pin(27, Pin.OUT)
# LED ON
led.value(1)
# LED OFF
led.value(0)
# 別の書き方
# LED ON
led.on()
# LED OFF
led.off()
GPIO-INPUT
27番PINにタクトスイッチを接続するのを前提に記載しています。
from machine import Pin
# GPIO INPUT
btn = Pin(27, Pin.IN)
# GPIO INPUT - プルアップ
btn = Pin(27, Pin.IN, Pin.PULL_UP)
# GPIO INPUT - プルダウン
btn = Pin(27, Pin.IN, Pin.PULL_DOWN)
# 状態の取得
btn.value()
# -> 0 or 1
GPIO-IRQ割り込み
27番PINの変化を検出ことを前提に記載しています。
from machine import Pin
irq_count = 0
# 割り込み発生時にコールされる
# 引数のpinにて、設定したピンの状態取得可能
def irq_callback(p):
global irq_count
irq_count += 1
# pin27をinput設定
btn = Pin(27, Pin.IN, Pin.PULL_UP)
# pin27に対し、立ち上がりに検出時irq_callback()がコールされる
btn.irq(trigger=Pin.IRQ_RISING, handler=irq_callback)
立下りや両方を取得したい場合は、
# pin27に対し、立ち下がり検出時
btn.irq(trigger=Pin.IRQ_FALLING, handler=irq_callback)
# pin27に対し、立ち上がり or 立ち下がり検出時
btn.irq(trigger=Pin.IRQ_RISING | Pin.IRQ_FALLING, handler=irq_callback)
タイマー関連
タイマー ONESHOT, 定期処理
import machine
import time
TIMER_ID = 0
def tmr_callbak(t):
print("call tmr_callbak")
tmr = machine.Timer(TIMER_ID)
# 3秒後(3000msec)、1回だけtmr_callbak()がコールされる
tmr.init(period=3000, mode=machine.Timer.ONE_SHOT, callback=tmr_callbak)
# このスリープの間にコールされる
time.sleep(5)
# ->"call tmr_callbak"
# 3秒毎(3000msec)に、tmr_callbak()がコールされる
tmr.init(period=3000, mode=machine.Timer.PERIODIC, callback=tmr_callbak)
# このスリープの間にコールされる
time.sleep(10)
# ->"call tmr_callbak"
# ->"call tmr_callbak"
# ->"call tmr_callbak"
タイマーを停止する
tmr.deinit()
ストリーム関連(テキストIO)
テキストファイルの書き込み
import uio as io
SETTINGS_TXT = "settings.txt"
mojiretu = "0123456789abcdef"
f = io.open(SETTINGS_TXT, "w")
f.write(mojiretu)
# ->16
f.close()
テキストファイルの読み込み
import uio as io
SETTINGS_TXT = "settings.txt"
f = io.open(SETTINGS_TXT, "r")
yomidasi = f.read()
f.close()
print(yomidasi)
# ->"0123456789abcdef"
テキストファイルのjsonと組み合わせ
import uio as io
import ujson as json
SETTINGS_TXT = "settings.txt"
wt_dict = {
"key1": "value1",
"key2": "value2",
"key3": "value3",
}
f = io.open(SETTINGS_TXT, "w")
f.write(json.dumps(wt_dict))
f.close()
f = io.open(SETTINGS_TXT, "r")
rd_dict = json.loads( f.read() )
f.close()
print(rd_dict)
# ->{'key2': 'value2', 'key3': 'value3', 'key1': 'value1'}
テキストファイルのseek
import uio as io
SETTINGS_TXT = "settings.txt"
f = io.open(SETTINGS_TXT, "r")
yomidasi = f.read()
print(yomidasi)
# ->"0123456789abcdef"
yomidasi = f.read()
# ->""
f.seek(0)
yomidasi = f.read()
print(yomidasi)
# ->"0123456789abcdef"
f.close()
1行単位でリストにする
f.readlines()
['line1', 'line2', 'line3']
並行処理(スレッド)
MicroPythonには、threadingはありません。
低水準APIの_threadを使用します。
簡単な例
import _thread
import time
def dummy_func():
count = 0
while True:
print("call dummy_func", count)
count += 1
time.sleep(1)
_thread.start_new_thread(dummy_func, ())
# ->call dummy_func 0
# ->call dummy_func 1
# ->call dummy_func 2
# ->call dummy_func 3
スレッド間通信(socket通信)
Queueが存在しないので、socket通信を使用しています。
ファイル名:thread_socket.py
import _thread
from usocket import socket, AF_INET, SOCK_DGRAM
import time
HOST = ""
ADDR = '127.0.0.1'
PORT = 50001
RCV_BUF_SIZE = 1024
def rcv_func():
s = socket(AF_INET, SOCK_DGRAM)
s.bind((HOST, PORT))
while True:
msg, address = s.recvfrom(RCV_BUF_SIZE)
print("rcv_func : ", msg, address)
s.close()
def snd_func():
s = socket(AF_INET, SOCK_DGRAM)
for i in range(3):
send_data = "send " + str(i)
s.sendto(send_data.encode(), (ADDR, PORT))
time.sleep(1)
s.close()
_thread.start_new_thread(rcv_func, ())
time.sleep(1)
_thread.start_new_thread(snd_func, ())
実行結果
>>> import thread_socket
I (7310) modsocket: Initializing
>>> rcv_func : b'send 0' ('127.0.0.1', 61289)
rcv_func : b'send 1' ('127.0.0.1', 61289)
rcv_func : b'send 2' ('127.0.0.1', 61289)
Wifi関連
アクセスポイントへの接続
ファイル名:sample_wifi000.py
※SSID, PASSは各自の環境に合わせ変更が必要です
import network
import time
# 接続するアクセスポイント情報
SSID = "XXXXXXXXXXXXX"
PASS = "XXXXXXXXXXXXX"
def do_connect():
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
if not wlan.isconnected():
print('connecting to network...')
wlan.connect(SSID, PASS)
while not wlan.isconnected():
time.sleep(1)
print('network config:', wlan.ifconfig())
return
do_connect()
実行結果:
>>> import sample_wifi000
I (18060) wifi: wifi driver task: 3ffd2bcc, prio:23, stack:3584, core=0
略
I (36952) wifi: STA_START
connecting to network...
I (37072) wifi: new:<1,0>, old:<1,0>, ap:<255,255>, sta:<1,0>, prof:1
略
I (37962) network: CONNECTED
I (38742) tcpip_adapter: sta ip: 192.168.11.26, mask: 255.255.255.0, gw: 192.168.11.1
I (38742) network: GOT_IP
network config: ('192.168.11.26', '255.255.255.0', '192.168.11.1', '192.168.11.1')
>>>
HTTP通信(urequests)
urequestモジュールを使用します。
※WiFiに接続している前提で記載します。
HTTP GETメソッド
ファイル名:sample_urequests.py
import urequests as requests
url = "https://www.example.com/"
response = requests.get(url)
print(response.text)
response.close()
実行結果:
>>> import sample_wifi000
略
>>> import sample_urequests000
<!doctype html>
<html>
略
</html>
さいごに
定期的に更新する予定です。