ラズベリーパイPico WでHTTPリクエストを送信してみる

ラズベリーパイPico WでHTTPリクエストを送信してみます。



ラズベリーパイPico Wがクライアントになって、WiFiを介してサーバにリクエストを送信します。


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

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

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

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


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

$ hostname -I

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

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

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


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

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

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


~/workspace/pi-server/index.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>python simple server</title>
<head>
<body>
hello python simple server.
</body>
</html>

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

$ cd ~/workspace/pi-server
$ python3 -m http.server 8000

Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...

パソコンの方でブラウザを開き、アドレスバーにhttp://localhost:8000を打ち込んでアクセスしてみます。



ブラウザで上のキャプチャのようなページが表示されることを確認しましょう。




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


main.py

import network
import utime
import socket
import machine

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

# Pythonでサーバを構築する時にhostname -Iのコマンドで取得したIPアドレス
host = "192.168.1.27"
# Pythonでサーバを構築する時に指定したポート番号
port = 8000

# ssidとpwでWLANに接続する
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

		# 20秒が経過しても接続出来なかった場合はエラー
		if wait > 20:
			raise RuntimeError("network connection failed")
	ip = wlan.ifconfig()[0]
	print(f'Connected on {ip}')
	return ip

# GETのリクエストを行う
def http_get(host, port):
	ai = socket.getaddrinfo(host, port)
	addr = ai[0][-1]

	# HTTPリクエストを生成して送信する
	s = socket.socket()
	s.connect(addr)
	s.send(b"GET / HTTP/1.0\r\n\r\n")

	# レスポンスの内容を確認する
	while True:
		data = s.recv(100)
		if data:
			print(str(data, 'utf8'), end='')
		else:
			break

try:
	ip = connect(ssid, pw)
	http_get(host, port)
except KeyboardInterrupt:
	machine.reset()

※各々の関数の内容は端折ります。


上記コードをThonny上で実行してみると、コンソール上に下記の内容が出力されました。

Connected on 192.168.1.35
HTTP/1.0 200 OK
Server: SimpleHTTP/0.6 Python/3.9.2
Date: Sun, 02 Apr 2023 21:03:30 GMT
Content-type: text/html
Content-Length: 147
Last-Modified: Sat, 01 Apr 2023 23:48:46 GMT

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>python simple server</title>
<head>
<body>
hello python simple server.
</body>
</html>

HTTPのヘッダとパソコンの方で作成しましたindex.htmlの内容が返ってきました。




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

192.168.1.35 - - [01/Apr/2023 23:48:46] "GET / HTTP/1.0" 200 -

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




ラズベリーパイPico Wの方のコードをurequestsライブラリで行えるように書き直してみます。

urequests — Network Request Module — makeblock micropython docs 1.0.0 documentation


main.py

import network
import utime
import machine
import urequests

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

# Pythonでサーバを構築する時にhostname -Iのコマンドで取得したIPアドレス
host = "192.168.1.27"

# Pythonでサーバを構築する時に指定したポート番号
port = "8000"

url = "http://" + host + ":" + port


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_get(url):
	# https://docs.openmv.io/library/urequests.html
	response = urequests.get(url)
	print(response.text)

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