CircuitPythonのWi-Fi接続
マイコンボードはAdafruit Metro M4 Express AirLift (WiFi)を使います。主な特徴です。
*CPU 120MHz Cortex M4 ATSAMD51(浮動小数点、DSP、フラッシュ・メモリ512Kバイト、RAM 192Kバイト)
*外付けEEPROM 2Mバイト
*動作電圧 3.3V(DCジャック7~9V入力、MicroUSBの5V入力)
*無線 ESP32-WROOM-32 SPI接続
*アナログ(D-Aコンバータ)出力 A0とA1ピン
*インターフェース・バス I2C SPI
CircuitPythonは5.0.0 Beta 0( https://github.com/adafruit/circuitpython/tags
)
を使います。インストールは省略します。Wi-Fiを使うとき、ESP32-WROOM-32のファームウェアは1.3.0以上が必要です。Adafruitの解説に従って1.4.0もしくは1.5.0に上げます。
こちらの記事を参照してください。
https://www.denshi.club/pc/python/circuitpython/circuitpython-10-step3-1.html
Muエディタに、examplesにあるesp32spi_simpletest.pyを読み込み、40行にあるWi-Fiルータの接続個所の2か所(ルータ名とパスワード)を修正します。
main.pyで保存します。メニューにあるシリアルを開きます。画面下部に実行の様子が表示されます。
CircuitPython のソケット(BSD)はMicroPythonベース
Docs » ESP8266 用クイックリファレンス » ESP8266用 MicroPythonチュートリアル » 5. ネットワーク - TCPソケット
https://micropython-docs-ja.readthedocs.io/ja/latest/esp8266/tutorial/network_tcp.html
の解説記事を見ると、通常のPythonのsocketプログラムとは異なります。
import socket
は、同じですが、
addr_info = socket.getaddrinfo("towel.blinkenlights.nl", 23)
getaddrinfo()関数で接続をします。そして、不要な部分を破棄し、
addr = addr_info[0][-1]
そのaddrでconnectします。
s.connect(addr)```
サンプルのなかで、必要な部分を抜き出しました。
```python
import board
import busio
from digitalio import DigitalInOut
import adafruit_esp32spi.adafruit_esp32spi_socket as sockets
from adafruit_esp32spi import adafruit_esp32spi
import adafruit_requests as requests
import time
esp32_cs = DigitalInOut(board.ESP_CS)
esp32_ready = DigitalInOut(board.ESP_BUSY)
esp32_reset = DigitalInOut(board.ESP_RESET)
spi = busio.SPI(board.SCK, board.MOSI, board.MISO)
esp = adafruit_esp32spi.ESP_SPIcontrol(spi, esp32_cs, esp32_ready, esp32_reset)
requests.set_socket(sockets, esp)
if esp.status == adafruit_esp32spi.WL_IDLE_STATUS:
print("ESP32 found and in idle mode")
print("Connecting to AP...")
while not esp.is_connected:
try:
esp.connect_AP(b'Buffalo-G-20EA', b'xxxxxx')
except RuntimeError as e:
print("could not connect to AP, retrying: ",e)
continue
print("Connected to", str(esp.ssid, 'utf-8'), "\tRSSI:", esp.rssi)
print("My IP address is", esp.pretty_ip(esp.ip_address))
つづいてソケットの接続方法を記述します。Windowsやラズパイでは、.localが使えます(mDNSやavahi)が、CircuitPythonではサポートされていないので、IPアドレスを直接記述します。
host = "K-34461A-16054.local"
ipAddr = "192.168.111.111"
ports = 5025
addr_info = sockets.getaddrinfo(ipAddr, ports)
print(addr_info)
addr = addr_info[0][-1]
print(addr)
skt = sockets.socket()
print("connect to")
skt.connect(addr)
print("connect'd")
print("send to")
skt.send("*IDN?\n")
print("received")
data = skt.recv(64).decode()
print(data)
skt.close()
print("Done")
受信するrecv()関数は、処理系によっては、送られてくる文字数がバッファより少ないと終了しません。CircuitPythonでもそういう仕様のようです。機器名の問い合わせの*IDN?に対して、このDMMは約70文字を返してきます。recv(256)では、受け取りが終了しませんでした。
電圧を測る
import board
import busio
from digitalio import DigitalInOut
import adafruit_esp32spi.adafruit_esp32spi_socket as sockets
from adafruit_esp32spi import adafruit_esp32spi
import adafruit_requests as requests
import time
# If you are using a board with pre-defined ESP32 Pins:
esp32_cs = DigitalInOut(board.ESP_CS)
esp32_ready = DigitalInOut(board.ESP_BUSY)
esp32_reset = DigitalInOut(board.ESP_RESET)
spi = busio.SPI(board.SCK, board.MOSI, board.MISO)
esp = adafruit_esp32spi.ESP_SPIcontrol(spi, esp32_cs, esp32_ready, esp32_reset)
requests.set_socket(sockets, esp)
if esp.status == adafruit_esp32spi.WL_IDLE_STATUS:
print("ESP32 found and in idle mode")
print("Connecting to AP...")
while not esp.is_connected:
try:
esp.connect_AP(b'Buffalo-G-20EA', b'xxxxxxx')
except RuntimeError as e:
print("could not connect to AP, retrying: ",e)
continue
print("Connected to", str(esp.ssid, 'utf-8'), "\tRSSI:", esp.rssi)
print("My IP address is", esp.pretty_ip(esp.ip_address))
ipAddr = "192.168.111.111"
ports = 5025
addr = sockets.getaddrinfo(ipAddr, ports)[0][-1]
skt = sockets.socket()
skt.connect(addr)
skt.send("*IDN?\n")
print(skt.recv(71).decode())
skt.send('CONF:VOLT:DC 10,0.001\n')
skt.send('READ?\n')
print('DC: ' + skt.recv(17).decode())
skt.close()
print("Done")
実行結果です。DMMの測定端子には、実験用電圧源TL431の出力をつないでいます。