Raspberry Pi Picoで無線LAN(最終章)と今後の展開
はじめに
Raspberry Pi Pico × MicroPython の組み合わせで「ESP-WROOM-02」を動かします。そのものズバリのサンプルが無いか、非常に少ないみたいなので、とりあえず動いた配線やソースコードを上げておきます。
(今後進展があったら追記があると思います)
「Raspberry Pi Picoで無線LAN(1)~(3)」で、一通りの通信を試したので、サーバー側含めて、本番で動かすような形に仕上げました。
併せて、今あるIoT構想を図にしてまとめておきたいと思います。
誰の参考になるかわからないですが、どこかの誰かのヒントになれば幸いです。
配線・コードサンプル
Raspberry Pi Pico側
前章(3)のほぼそのままですが、ブザーやOLEDディスプレイもあったのでつけました。
とりあえず動く感が満載のコードとなっております。

import machine, utime
from ssd1306 import SSD1306_I2C
#”映え”が必要だったので...
def show( s ):
global oled
oled.fill(0)
r=0
max = 0
if type(s) is str:
oled.text(s, 0, 2)
else:
for r in range( len(s) ):
oled.text(s[r], 0, 10*r)
oled.show()
utime.sleep_ms(1000)
def getTemp( i2c ):
print('----getTemp')
address = 0x38
send = bytearray([0xAC, 0x33, 0x00])
dat = bytearray([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00])
i2c.writeto(address, send)
utime.sleep_ms(100)
dat =i2c.readfrom(address, 7)
hum = dat[1] << 12 | dat[2] << 4 | ((dat[3] & 0xF0) >> 4)
tmp = ((dat[3] & 0x0F) << 16) | dat[4] << 8 | dat[5]
hum = hum / 2**20 * 100
tmp = tmp / 2**20 * 200 - 50
return tmp,hum
def blink(led):
for i in range(2):
utime.sleep_ms(100)
LED.value(1)
utime.sleep_ms(100)
LED.value(0)
def execCommand( serial, cmd ):
execCommand_withWait( serial, cmd, 2000 )
def execCommand_withWait( serial, cmd, mswait ):
serial.write(cmd)
utime.sleep_ms(mswait)
res = serial.read()
stat = ''
try:
stat = res.decode('utf-8').replace('\r\n\r\n','\r\n').split('\r\n')
except Exception as ex:
stat = ['Decode Error','Unknown Responce']
show(stat)
for w in stat:
print('-> '+w)
print('------')
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+CIPSTA_CUR="192.168.100.64","192.168.100.1","255.255.255.0"\r\n')
#アクセスポイントに接続
execCommand(u,'AT+CWJAP_CUR="whome-v6-24","365fb068847e7"\r\n')
utime.sleep(4)
#IP確認
execCommand(u,'AT+CIFSR\r\n')
def createServer(u):
#マルチプルコネクション
execCommand(u,'AT+CIPMUX=1\r\n')
#サーバーモード実行
execCommand(u,'AT+CIPSERVER=1,1235\r\n')
i2c = machine.I2C(1, scl=machine.Pin(27), sda=machine.Pin(26))
print("I2C START")
oled = SSD1306_I2C(128, 64, i2c)
print('I2C OK')
show("I2C OK")
print('OLED START')
show('OLED START')
#u = machine.UART(0, 115200, tx=machine.Pin(0), rx=machine.Pin(1))
u = machine.UART(0, 115200, tx=machine.Pin(12), rx=machine.Pin(13))
print("UART START")
show("UART START")
LED = machine.Pin(25, machine.Pin.OUT)
LED.value(0)
print("LED START")
show("LED START")
#Bz = machine.Pin(16, machine.Pin.OUT)
Bz = machine.PWM( machine.Pin(16, machine.Pin.OUT) )
Bz.freq(400)
Bz.duty_u16(0)
#バージョン表示
execCommand(u,'AT+GMR\r\n')
#無線ネットワーク検出
execCommand(u,'AT+CWLAP\r\n')
networkConnect(u)
createServer(u)
#接続状況の表示
execCommand(u,'AT+CIPSTATUS\r\n')
#IP,MAC
execCommand(u,'AT+CIFSR\r\n')
for i in range(2):
utime.sleep_ms(80)
Bz.duty_u16(1023)
utime.sleep_ms(80)
Bz.duty_u16(0)
show('Waiting...')
while True:
if u.any() > 0: #クライアントからデータの受信
blink(LED)
print('----START')
res = u.read(1024) #読み取り
print(res) #生データ
stat = res.decode('utf-8').split('\r\n')
for w in stat:
if w.find('+IPD') >= 0 :
blink(LED)
blink(LED)
print('--DataRecive')
show('--DataRecive')
rcvary = w.split(',')
ID = rcvary[1]
DATA = (rcvary[2].split(':'))[1]
print('=>'+ID)
print('=>'+DATA)
show( (ID+":"+DATA) )
tmp,hum = getTemp(i2c)
returnword ='recved='+DATA+ '&'
returnword = returnword + 'tmp=' + str(tmp) + '&'
returnword = returnword + 'hum=' + str(hum)
returnword = returnword + '\r\n'
command ='AT+CIPSEND='+ID+','+str(len(returnword))+'\r\n'
print('>>'+command)
print('>>'+returnword)
execCommand_withWait(u,command, 250)
execCommand_withWait(u,returnword, 250)
execCommand_withWait(u,'AT+CIPCLOSE='+ID+'\r\n',250)
show('waiting......')
print('----END')
#接続終了コマンド=サーバー側で切断する
#execCommand(u,'AT+CIPCLOSE\r\n')
一応、モバイルバッテリで動くのでそれで動かしてます。
サーバー側
crontab
*/3 * * * * sh /home/user/work.sh
シェル
# /home/user/work.sh
python3 /home/user/py/cl.py 192.168.100.64
Python
# /home/user/py/cl.py
import sys,datetime
import socket
arg_IP =sys.argv[1]
arg_File =sys.argv[1]+".dat"
dataGetTime = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
IP = arg_IP
PORT = 1235
sock = socket.socket(socket.AF_INET)
sock.connect((IP,PORT))
sock.send("getdata".encode("utf-8"))
rs = sock.recv(128)
#print(rs.decode("utf-8"))
fp=open(arg_File,'a')
fp.write(dataGetTime + ',' + rs.decode("utf-8"))
fp.close()
#ラズパイ側でCloseする
#sock.close()
一応、Raspberry Pi Pico=サーバー間で(つたない)連携ができるようになりました。
世間一般のIoT(?)だと、サーバーからマイコン(センサー)ではなく、各センサー(マイコン)からのサーバーへデータを送るような仕組みが一般的です。
今回は、LINEからのメッセージを受けて、マイコンを動作させるという構想なので、こういった動作になってます。
今後の展開予定
マイコン ー サーバー間・・・○一応OK
サーバー ー クラウド間・・・×まだ
クラウド内の連携 ・・・×まだ
クラウド ー LINE間 ・・・△サンプルだけ
参考
((1)、(2)と同じですが載せておきます)
http://nonnoise.github.io/ESP-WROOM-02/ATcommand.html
https://trac.switch-science.com/wiki/ESP-WROOM-02_AT
<追加分>
https://analogicintelligence.blogspot.com/2019/09/wroom-02atweb-server.html
http://www.microtechnica.tv/support/manual/espwroom02jp_man.pdf
Espressifのマニュアル
https://www.espressif.com/en/support/documents/technical-documents?keys=Command
https://docs.espressif.com/projects/esp-at/en/latest/esp32/index.html