Raspberry Pi Picoで無線LAN(2)
2022.5.26:ソースコードを修正(例外処理をの範囲を狭めました)
はじめに
Raspberry Pi Pico × MicroPython の組み合わせで「ESP-WROOM-02」を動かします。そのものズバリのサンプルが無いか、非常に少ないみたいなので、とりあえず動いた配線やソースコードを上げておきます。
(今後進展があったら追記があると思います)
「Raspberry Pi Picoで無線LAN(1)」では、ESP-WROOM-02のバージョン情報を取得するとこまででしたが、ここでは、いわゆる”無線LANクライアント”として動作させて、何かしらデータを送る辺りをを残しておきたいと思います。
配線・コードサンプル
配線は変更なしです。
import machine, utime
def execCommand( serial, cmd ):
serial.write(cmd)
utime.sleep(2)
res = serial.read()
print('------')
print(res)
print('------')
try:
print(res.decode('utf-8'))
except Exception as ex:
print('Decode Err')
print('Unknown Responce')
def networkConnect(u):
#フラッシュメモリに保存しない設定
execCommand(u,'AT+CWMODE_CUR=1\r\n')
#クライアントモードでDHCPでIP自動割り当て有効
execCommand(u,'AT+CWDHCP_CUR=1,1\r\n')
#アクセスポイントに接続
execCommand(u,'AT+CWJAP_CUR="SSID","Password"\r\n')
u = machine.UART(1, 115200, tx=machine.Pin(4), rx=machine.Pin(5))
print("UART START")
#バージョン表示
execCommand(u,'AT+GMR\r\n')
#無線ネットワーク検出
execCommand(u,'AT+CWLAP\r\n')
networkConnect(u)
#接続状況の表示
execCommand(u,'AT+CIPSTATUS\r\n')
#接続開始
execCommand(u,'AT+CIPSTART="TCP","192.168.100.5",1235\r\n')
#データ送信 CIPSEND=N で送信データ長を送ってからデータを送信
execCommand(u,'AT+CIPSEND=24\r\n')
u.write('Data from ESP-WROOM-02\r\n')
utime.sleep(1)
while u.any() > 0: #ESP-WROOM-02からのバイト数
res = u.read(3000) #読み取り
print('------')
print(res) #生データ
print('------')
try:
print(res.decode('utf-8')) #デコード
except Exception as ex:
print('Decode Err')
print('Unknown Responce')
#接続終了コマンド=サーバー側で切断する
#execCommand(u,'AT+CIPCLOSE\r\n')
関数networkConnectは、無線LANネットワークに接続する関連のコマンドをまとめてあります。ネットワークに接続する部分なので、エラーや何かがなければ、一回実行すればよく、通信のたびに実行する必要はない部分です。
テストやデバックで何回も送受信テストするようなときなどでは、この行ををコメントアウトすればよいので作業が楽になってます。
「AT+CIPSTART」から下の部分は、実際にデータを送るたびに必要な部分。他サイトでは、HTTPリクエスト書いてWEBサーバーと通信させてる例が多いようですが、PythonのSocketで簡単なサーバー書いて通信させてます。
ローカルで、単純なデータ送信だけであればHTTPのお作法関係なしに出来た方が簡単に思いましたので。
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((socket.gethostname(), 1235)) # IPとポート番号を指定します
s.listen(5)
while True:
clientsocket, address = s.accept()
print(f"Connection from {address} has been established!")
clientsocket.send(bytes("Welcome to the server!", 'utf-8'))
rcvmsg = clientsocket.recv(1024)
print('Receved -> %s' % (rcvmsg) )
s_msg = 'Thanks&Bye!'.encode('utf-8')
clientsocket.sendall(s_msg)
print(f'{address} is Close!')
clientsocket.close()
参考までに、Pythonで書いた単純なサーバーになります。
<追記>
bindでIPとポートを設定している部分
「socket.gethostname()」が、Ubuntsだと「127.0.x.x」のローカルホストのアドレスが、Windowsだと「192.168.x.x」のプライベートIPアドレスが返るようです。Ubuntsでサンプルそのままだと接続に行ったとき失敗します。IP固定なりして、ちゃんと入力すべし。
参考
(「Raspberry Pi Picoで無線LAN(1)」と同じですが載せておきます)
http://nonnoise.github.io/ESP-WROOM-02/ATcommand.html
https://trac.switch-science.com/wiki/ESP-WROOM-02_AT
おまけの一言
応用例としては、やはり、人感センサーや距離センサー、ホールセンサーとの組み合わせでしょうか。人の反応・扉の開閉などでデータを投げるというような、何かイベントが起きたとき系で使えそう。
さらにおまけ
「人感センサー」を組み込んで、人が来たらサーバーにデータを投げるようなものを作っていろいろ実験してました。
その中であったのは、モバイルバッテリ(5V)では動かなかったということ。正確には、ラズパイPicoは動くが、ESP-WROOM-02モジュールが動かないようです。(詳細なとこまでデバッグしたわけではありませんが、無線ネットワークにつながらなかったです。)
電池4本(6V)をレギュレータで3.3Vに落として、ESP-WROOM-02とラズパイPicoのVSYSに突っ込んだら動きました。
電源周りは多少気を使うようです。