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


この記事が気に入ったらサポートをしてみませんか?