使用 Raspberry Pi Pico W 和 MicroPython 開發物聯網應用

前言

當我們提及物聯網(IoT, Internet of Things)開發,可能首先想到的是Arduino或是ESP8266這樣的微控制器開發板。然而,Raspberry Pi的微控制器開發板——Raspberry Pi Pico W,也是一個很好的選擇。

本文將介紹如何使用Raspberry Pi Pico W和MicroPython,並用Thonny IDE的平台來撰寫程式。

撰寫/攝影 許鈺莨 (ChatGPT協作編輯)
時間 2小時 材料表
難度 2(滿分5)

本文

Raspberry Pi Pico W簡介

Raspberry Pi Pico W是由Raspberry Pi基金會出品的微控制器開發板。它配備了一個RP2040微控制器,有264KB的內部RAM,並且支援MicroPython程式語言,這讓我們可以更方便地開發物聯網應用。

使用上和Raspberry Pi Pico沒有多大差別,只是Raspberry Pi Pico W 還 支援Wi-Fi 802.11n無線網路和藍牙,更多Raspberry Pi Pico相關介紹連結如下:

Raspberry Pi Pico family
Raspberry Pi Pico介紹(含使用Arduino IDE和擴充板教學)

MicroPython簡介

MicroPython是一種針對微控制器和受限環境設計的 Python 3 程式語言編譯器和執行環境。這種程式語言實現了Python 3的大部分語法和特性,並對於開發板所需的低功耗和即時回應有進一步最佳化。MicroPython提供了豐富的API,可以直接控制微控制器的GPIO、I2C、SPI等各種硬體資源。

Thonny IDE簡介

Thonny是一個專為Python初學者設計的整合式開發環境(IDE)。它的介界面簡單,功能強大,對於學習Python語言非常有幫助。而且,Thonny IDE 也支援 MicroPython,我們可以直接在Thonny IDE中編寫MicroPython 程式,並上傳到Raspberry Pi Pico W上執行。

請由 Thonny 官方網站下載 Thonny IDE,本文將使用 portable 免安裝版。

電路接線圖

本次專案分享如何透過Thonny IDE來撰寫MicroPython程式,並使用PMS5003粉塵感測器取得數值和經由Raspberry Pi Pico W的Wi-Fi功能取得目前台灣時間,並顯示在OLED中。
以下介紹Raspberry Pi Pico W、Raspberry Pi Pico W擴充板、OLED、PMS5003接線圖。

Raspberry Pi Pico與擴充板接法(擴充板可相容於Raspberry Pi Pico W):
https://cavedu.gitbook.io/cavedu/raspberry_pi_pico_info/pico_breakout

 

Raspberry Pi Pico W擴充板與OLED接線圖
Raspberry Pi Pico W擴充板與PMS5003接線圖

接下來是使用Thonny IDE來撰寫,由於筆者使用的是Micropython 來撰寫物聯網相關應用,需要用到 pico 的Wi-Fi 功能,所以需要下載 Raspberry Pi Pico W 的最新韌體檔,請到樹莓派基金會網站下載。除非有更新版本的韌體,否則更新只要一次即可。

如何上傳Raspberry Pi Pico W的 uf2 韌體檔

按住 Raspberry Pi Pico W 的 BOOTSET 按鈕時,插上USB 傳輸線連接到電腦。

Raspberry Pi Pico W 會被電腦辨識為一個磁碟,將 uf2 韌體檔拖放到其中就會自動更新韌體。

Raspberry Pi Pico W連接Thonny IDE

● 將Thonny IDE下載至電腦,並解壓縮後開啟,請選擇 執行>設定直譯器

● 選Micro Python (RP2040)

● 連接埠選擇USB序列裝置(COM X)

[註] COM號要記住,後續上傳程式需要正確指定 COM 號,概念如同 Aduino IDE

● 確認是否抓到 Raspberry Pi Pico W

檢查 Thonny IDE 下方的 互動環境(Shell),如果沒有紅字錯誤訊息即可上傳程式,這時候還沒寫,繼續看下去吧。

匯入OLED函式庫至 Raspberry Pi Pico W

本專案需要透過 OLED 顯示模組來顯示數值,故需要先匯入OLED 函式庫
1. 下載 OLED 函式庫,檔名ssd1306.py 到您的電腦

2. 在 Thonny IDE 中安裝套件

我們可由 Thonny IDE 呼叫系統命令列來安裝 python 套件,請由工具 –> 開啟系統命令列

開啟系統命令列,如下圖

3. 安裝 adafruit-ampy 套件
為了順利執行程式,我們需要安裝 adafruit-ampy 套件,用於透過序列埠與 CircuitPython 或 MicroPython 開發板互動,安裝方式就是一般的 pip 指令,相當簡單:

[pastacode lang=”bash” manual=”pip%20install%20adafruit-ampy” message=”” highlight=”” provider=”manual”/]

4. 匯入OLED函式庫到Raspberry Pi Pico W

[pastacode lang=”bash” manual=”cd%20module_library%0Aampy%20–port%20COMX%20put%20ssd1306.py” message=”” highlight=”” provider=”manual”/]

[註]請注意,並不是開啟下方的視窗,若出現下方視窗,則要再按一次開啟系統命令列。

5. 如何查看已匯入的函式庫

在 Thonny IDE 中,點選檢視 -> 檔案,可以查看Raspberry Pi Pico W中匯入的檔案

確認已匯入先前所操作的檔案

執行程式

本專題有兩個程式 (點我下載原始碼,或由以下複製也可以):

  • 在 OLED 顯示時間(OLED_wifitime.py)
  • 在 OLED 顯示 PMS5003 粉塵感測器數值(PMS5003_OLED.py)
[pastacode lang=”python” manual=”import%20machine%0Aimport%20utime%0Aimport%20ssd1306%0Afrom%20time%20import%20sleep%0Aimport%20network%0Aimport%20ntptime%0Aimport%20urequests%0A%0Ai2c%20%3D%20machine.SoftI2C(scl%3Dmachine.Pin(15)%2C%20sda%3Dmachine.Pin(4))%0A%0Aoled_width%20%3D%20128%0Aoled_height%20%3D%2064%0Aoled%20%3D%20ssd1306.SSD1306_I2C(oled_width%2C%20oled_height%2C%20i2c)%0A%0A%23%20%E5%88%9D%E5%A7%8B%E5%8C%96%20UART%0Auart%20%3D%20machine.UART(0%2C%20baudrate%3D9600%2C%20tx%3Dmachine.Pin(0)%2C%20rx%3Dmachine.Pin(1)%2C%20timeout%3D1000)%0Auart.init(9600%2C%20bits%3D8%2C%20parity%3DNone%2C%20stop%3D1)%0A%0A%0A%0A%23%20%E5%88%9D%E5%A7%8B%E5%8C%96WiFi%0Asta_if%20%3D%20network.WLAN(network.STA_IF)%0Asta_if.active(True)%0A%0A%0Awifi_ssid%20%3D%20%22XXXXX%22%0Awifi_password%20%3D%20%22XXXXXXX%22%0A%0A%0Asta_if.connect(wifi_ssid%2C%20wifi_password)%0A%0A%0A%23%20%E9%A1%AF%E7%A4%BAWiFi%E9%80%A3%E6%8E%A5%E7%8B%80%E6%85%8B%0Aoled.fill(0)%0Aoled.text(‘WiFi%3A’%2C%200%2C%200)%0Aif%20sta_if.isconnected()%3A%0A%20%20%20%20oled.text(‘connected’%2C%2040%2C%200)%0Aelse%3A%0A%20%20%20%20oled.text(‘connceting’%2C%2040%2C%200)%0Aoled.show()%0A%0A%23%E8%A8%AD%E5%AE%9A%E6%99%82%E5%8D%80%0ATIME_ZONE%20%3D%208%0A%0A%23%20%E5%8F%96%E5%BE%97NTP%E6%99%82%E9%96%93%0A%23ntptime.settime()%0Afor%20i%20in%20range(5)%3A%20%0A%20%20%20%20try%3A%0A%20%20%20%20%20%20%20%20ntptime.settime()%0A%20%20%20%20%20%20%20%20break%0A%20%20%20%20except%20OSError%3A%0A%20%20%20%20%20%20%20%20print(‘Error%20connecting%20to%20NTP%20server%2C%20retrying…’)%0A%20%20%20%20%20%20%20%20utime.sleep(5)%0Aelse%3A%0A%20%20%20%20print(‘Could%20not%20connect%20to%20NTP%20server%20after%205%20retries.’)%0A%20%20%20%20%0A%0A%23%20%E7%AD%89%E5%BE%85%E4%B8%80%E6%AE%B5%E6%99%82%E9%96%93%0Autime.sleep(3)%0A%0Awhile%20True%3A%0A%20%20%20%20t%20%3D%20utime.localtime(utime.time()%20%2B%20TIME_ZONE%20*%203600)%0A%20%20%20%20oled.fill(0)%0A%20%20%20%20oled.text(str(%22%25d%2F%2502d%2F%2502d%22%20%25%20(t%5B0%5D%2C%20t%5B1%5D%2C%20t%5B2%5D))%2C%200%2C%200)%0A%20%20%20%20oled.text(str(%22%2502d%3A%2502d%3A%2502d%22%20%25%20(t%5B3%5D%2C%20t%5B4%5D%2C%20t%5B5%5D))%2C%200%2C%2016)%0A%20%20%20%20oled.show()%0A%20%20%20%20utime.sleep(1)%20%20%20%20%20%20%20%0A” message=”OLED_wifitime.py” highlight=”” provider=”manual”/] [pastacode lang=”python” manual=”import%20machine%0Aimport%20utime%0Aimport%20ssd1306%0Afrom%20time%20import%20sleep%0A%0A%0Ai2c%20%3D%20machine.SoftI2C(scl%3Dmachine.Pin(15)%2C%20sda%3Dmachine.Pin(4))%0A%0Aoled_width%20%3D%20128%0Aoled_height%20%3D%2064%0Aoled%20%3D%20ssd1306.SSD1306_I2C(oled_width%2C%20oled_height%2C%20i2c)%0A%0A%0A%23%20%E5%88%9D%E5%A7%8B%E5%8C%96%20UART%0Auart%20%3D%20machine.UART(0%2C%20baudrate%3D9600%2C%20tx%3Dmachine.Pin(0)%2C%20rx%3Dmachine.Pin(1)%2C%20timeout%3D1000)%0Auart.init(9600%2C%20bits%3D8%2C%20parity%3DNone%2C%20stop%3D1)%0A%0Awhile%20True%3A%0A%20%20%20%20%23%20%E8%AE%80%E5%8F%96%20PMS5003%20%E8%B3%87%E6%96%99%0A%20%20%20%20data%20%3D%20bytearray(uart.read(32))%0A%20%20%20%20%0A%20%20%20%20%23%20%E5%88%A4%E6%96%B7%E6%98%AF%E5%90%A6%E7%82%BA%E6%AD%A3%E7%A2%BA%E7%9A%84%20PMS5003%20%E8%B3%87%E6%96%99%0A%20%20%20%20if%20data%20is%20not%20None%20and%20len(data)%20%3E%3D%2010%20and%20data%5B0%5D%20%3D%3D%200×42%20and%20data%5B1%5D%20%3D%3D%200x4d%3A%0A%20%20%20%20%20%20%20%20pm1_cf%20%3D%20int.from_bytes(data%5B4%3A6%5D%2C%20’big’)%0A%20%20%20%20%20%20%20%20pm25_cf%20%3D%20int.from_bytes(data%5B6%3A8%5D%2C%20’big’)%0A%20%20%20%20%20%20%20%20pm10_cf%20%3D%20int.from_bytes(data%5B8%3A10%5D%2C%20’big’)%0A%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%23%20%E6%B8%85%E9%99%A4%20OLED%0A%20%20%20%20%20%20%20%20oled.fill(0)%0A%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%23%20%E9%A1%AF%E7%A4%BA%20PMS5003%20%E8%B3%87%E6%96%99%0A%20%20%20%20%20%20%20%20oled.text(%22PM1.0%3A%20%25d%20ug%2Fm3%22%20%25%20pm1_cf%2C%200%2C%2022)%0A%20%20%20%20%20%20%20%20oled.text(%22PM2.5%3A%20%25d%20ug%2Fm3%22%20%25%20pm25_cf%2C%200%2C%2038)%0A%20%20%20%20%20%20%20%20oled.text(%22PM10%20%3A%20%25d%20ug%2Fm3%22%20%25%20pm10_cf%2C%200%2C%2054)%0A%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%23%20%E6%9B%B4%E6%96%B0%20OLED%0A%20%20%20%20%20%20%20%20oled.show()%0A%20%20%20%20%20%20%20%20%0A%20%20%20%20utime.sleep(1)%0A” message=”PMS5003_OLED.py” highlight=”” provider=”manual”/]

實際展示

執行程式之後,可在 OLED 顯示模組上看到相關資訊,恭喜成功囉!

發佈留言

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