ラズベリーパイPico WでHTTPのPOSTで値を送信してみる


ラズベリーパイPico Wでやりたいことの一つにマイコンで得たデータをデータ収集用のサーバに送信することがあります。

今回はラズベリーパイPico WをHTTPクライアントにして、POSTでサーバに対して値を送信してみます。


先にパソコンの方でリクエスト受信用のサーバを構築します。

今回はラズベリーパイ4Bを使用しますが、Pythonを実行できるパソコンであれば何でも良いです。

※以後のコードはラズベリーパイ4Bを含めたDebian系のLinuxでの実行になります。

※今回の内容でサーバ側のマシンとしてクロームブックを使用したい場合はクロームブックでWebサーバを立ち上げるでIPアドレスについてを一読してから話を進めるようにしてください。


最初に端末(ターミナル)を開き、下記のコマンドでパソコンの方のローカルネットワークのIPアドレスを調べます。

$ hostname -I

192.168.1.27という値が表示されました。

この値はラズベリーパイPico Wの方で使用します。

※利用しているネットワークによって上記の値は異なります


続いてサーバの準備をします。

コードは説明用で~/workspace/pi-server/server.pyを作成します。

※~(チルダ)にはラズベリーパイ4Bであれば、/home/piが入ります。


~/workspace/pi-server/server.py

from http.server import HTTPServer
from http.server import BaseHTTPRequestHandler
import cgi

class RequestsHandler(BaseHTTPRequestHandler):
    def do_POST(self):
        self.send_response(200)
        self.send_header("User-Agent","sample")
        self.end_headers()
        html = "OK"
        self.wfile.write(html.encode())

        # POST されたフォームデータを解析する
        form = cgi.FieldStorage(
            fp=self.rfile, 
            headers=self.headers,
            environ={'REQUEST_METHOD':'POST',
                     'CONTENT_TYPE':self.headers['Content-Type'],
                     })
        # HTTP Clientから「value=%s」の値を送信している為、form["value"].valueで値を取得する
        print("value:"+form["value"].value)

        return

ip = '0.0.0.0'
port = 8000

server = HTTPServer((ip, port), RequestsHandler)
print("Serving HTTP on "+ip+" port "+str(port)+" (http://"+ip+":"+str(8000)+"/)")
server.serve_forever()

下記コマンドでサーバを立ち上げます。

$ pyyhon3 ~/workspace/pi-server/server.py
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...

今回のサーバはPOSTのリクエストのみ許可していて、ブラウザのアドレスバーに直接URLを打ち込んでも501エラーになり、ページが表示されません。




ラズベリーパイPico Wの方のコードの作成を行います。


main.py

import network
import utime
import machine
import urequests

# ssidは必ず2.4GHz帯(11n)の方を使用
ssid = "your ssid"
pw = "your password"

# POST先のURL
url = "http://192.168.1.27:8000"

def connect(ssid, pw):
    wlan = network.WLAN(network.STA_IF)
    wlan.active(True)
    wlan.connect(ssid, pw)
    wait = 0
    while wlan.isconnected() == False:
        print("Waiting for connection...")
        utime.sleep(1)
        wait += 1
        if wait > 20:
            raise RuntimeError("network connection failed")
    ip = wlan.ifconfig()[0]
    print(f'Connected on {ip}')
    return ip

def http_post(url, value):
    # https://docs.openmv.io/library/urequests.html
    body = "value=%s" % (value)
    headers = {'Content-Type': 'application/x-www-form-urlencoded'}
    response = urequests.post(url, data=body, headers=headers)
    print(response)

try:
    ip = connect(ssid, pw)
    http_post(url, "1")
except KeyboardInterrupt:
    machine.reset()

上記のコードの詳細は端折りますがThonny上で実行するとサーバに対してvalue=1の値を送信します。

urequests — Network Request Module — makeblock micropython docs 1.0.0 documentation


実行後にコンソールに出力された内容を確認してみると、

Connected on 192.168.1.35

のような値が出力されていました。




パソコンの方の端末(ターミナル)で出力された内容を見てみます。

192.168.1.35 - - [04/Apr/2023 09:29:23] "POST / HTTP/1.0" 200 -
value:1

ラズベリーパイPico Wから送信した値をサーバ側で受信出来ていることを確認しましょう。


4. ネットワークの基礎 — MicroPython latest ドキュメント