搭載Wi-Fi與藍牙通訊晶片的Raspberry Pi Pico W微控制板(二)

Raspberry Pi Pico W開發板(以下簡稱Pico W)相較於Pico板,重點當然是Wi-Fi無線通訊功能。使用MicroPython編寫Wi-Fi通訊相關應用,程式跟ESP8266及ESP32的寫法完全相同。本文介紹的三個程式分別改自《超圖解Python物聯網實作入門》第6, 16和17章的範例。

無線網路連線

這段程式碼將把Pico W板的Wi-Fi設成STA模式,連上指定的W-Fi路由器並顯示它的IP位址:

import network

ssid = '你的無線網路名稱'
password = '網路密碼'

wlan = network.WLAN(network.STA_IF)  # 設為STA模式
wlan.active(True)  # 啟用網路
wlan.connect(ssid, password)  # 連線到網路AP

while not wlan.isconnected():  # 重複直到連上網路為止
    pass

print('IP: ', wlan.ifconfig()[0])  # 顯示IP位址

ifconfig()用於設定或傳回網路介面參數。連線成功之後呼叫此方法,它將傳回包含4個參數的元組,依序代表IP位址、子網路遮罩、閘道器位址和DNS伺服器位址,例如:(‘192.168.0.100’, ‘255.255.255.0’, ‘192.168.0.1’, ‘192.168.0.1’)。所以wlan.ifconfig()[0]將傳回IP位址。

把程式碼輸入Thonny IDE,再按下F5功能鍵或「執行目前程式」鈕,過一會兒就能看到它分配到的IP位址:

無線網路連線

建立Web伺服器

這個範例透過socket偵聽用戶端連線,只要收到連線請求,就發送一個顯示“Hello World”!的HTML網頁文件給用戶端。

Pico Pi Web伺服器

程式碼如下,請自行修改其中的網路名稱和密碼:

import socket
import network

ssid = '你的無線網路名稱'
password = '網路密碼'

# 網頁HTML碼
html = """<!DOCTYPE html>
<html>
  <head>
    <title>Pico W</title>
  </head>
  <body>
    <p>Hello World!</p>
  </body>
</html>
"""

wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect(ssid, password)

while not wlan.isconnected():
    pass

print('IP: ', wlan.ifconfig()[0]) # 顯示IP位址

# 建立socket連線物件,繫結到埠口80。
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('', 80))
s.listen(5)

# 偵聽用戶端連線請求
while True:
    try:
        client, addr = s.accept()
        print('client connected, IP: ', addr)
        client.send('HTTP/1.0 200 OK\r\nContent-type: text/html\r\n\r\n')
        client.send(html)
        client.close()

    except OSError as e:  # 若出現錯誤,則中斷連線。
        client.close()
        print('connection closed')

REST風格的無線開關燈網站伺服器程式

超圖解Python物聯網實作入門》第17章的網路調光控制器,採用「查詢字串」傳遞燈光控制參數給充當伺服器的MicroPython微控制板:

採用「查詢字串」傳遞燈光控制參數

底下範例採用REST風格控制Pico W開發板內建的LED,也就是把控制對象和數值寫成URL路徑形式:

REST風格控制Pico W開發板內建的LED

當使用者在瀏覽器中輸入Pico W開發板的IP位址,請求首頁時,瀏覽器將向Pico W傳遞如右下的HTTP GET訊息。

HTTP GET訊息

若是輸入/led/on路徑,瀏覽器將傳出如右下的HTTP GET訊息給開發板:

HTTP GET訊息

Pico W開發板接收到HTTP請求之後,要先把位元組格式的訊息轉換成字串,然後透過find()方法,在其中找尋“/led/on”或“/led/off”,若有找到,代表用戶端發出開燈或關燈的請求,而find()也將傳回找到的字串的起始位置,此例為4:

HTTP GET訊息

用上述方式簡單判斷用戶端傳入值的完整程式碼:

from machine import Pin
import socket
import network

ssid = '你的無線網路名稱'
password = '網路密碼'

led = Pin('LED', Pin.OUT)  # 指定控制內建的LED

# 首頁的HTML碼
html = """<!DOCTYPE html>
<html>
  <head>
    <title>Pico W</title>
  </head>
  <body>
    <p>Hello World!</p>
  </body>
</html>
"""

wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect(ssid, password)

while not wlan.isconnected() :
    pass

print('IP: ', wlan.ifconfig()[0])  # 顯示開發板的IP位址

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('', 80))
s.listen(5)

# 偵聽用戶端連線
while True:
    try:
        client, addr = s.accept()
        req = client.recv(1024).decode('UTF-8')
        client.send('HTTP/1.0 200 OK\r\nContent-type: text/html\r\n\r\n')

        if req.find('/led/on') == 4:  # 若連線請求字串包含'/led/on'
            client.send('<h1>LED ON!</h1>') 
            led.value(1)  # LED接腳設為高電位
        elif req.find('/led/off') == 4:
            client.send('<h1>LED OFF!</h1>')
            led.value(0)
        else:
            client.send(html)

        client.close()

    except OSError as e:
        client.close()
        print('connection closed')

Posts created 483

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

Related Posts

Begin typing your search term above and press enter to search. Press ESC to cancel.

Back To Top