樹莓派 PICO基礎教程(基於MicroPython)

1 樹莓派 PICO 簡介

1.1 簡介

  Raspberry Pi Pico是具有靈活數字接口的低成本,高性能微控制器板。它集成了Raspberry Pi自己的RP2040微控制器芯片,運行速度高達133 MHz的雙核Arm Cortex M0 +處理器,嵌入式264KB SRAM和2MB板載閃存以及26個多功能GPIO引腳。對於軟件開發,可以使用Raspberry Pi的C / C ++ SDK或MicroPython。[1]

1.2 配置 [2]
樹莓派 PICO配置
雙核 Arm Cortex-M0 + @ 133MHz
2 個 UART、2 個 SPI 控制器和 2 個 I2C 控制器
芯片內置 264KB SRAM 和 2MB 的板載閃存
16 個 PWM 通道
通過專用 QSPI 總線支持最高 16MB 的片外閃存
USB 1.1 主機和設備支持
DMA 控制器
8 個樹莓派可編程 I/O(PIO)狀態機,用於自定義外圍設備支持
30 個 GPIO 引腳,其中 4 個可用作模擬輸入
支持 UF2 的 USB 大容量存儲啟動模式,用於拖放式編程
1.3 引腳圖

樹莓派 PICO 引腳圖

1.4 尺寸

2 安裝

2.1 燒錄固件
  1. 點擊 //micropython.org/download/rp2-pico/rp2-pico-latest.uf2 鏈接下載UF2文件;

如果連接失效,可以進入 //www.raspberrypi.org/documentation/rp2040/getting-started/#getting-started-with-micropython官網下載

  1. 按住BOOTSEL鍵不放,將Pico插入電腦的USB串口,電腦上會彈出一個新的U盤文件夾,把剛剛下載的UF2文件拖拽到文件夾中,樹莓派 PICO將會自動重啟,此時,固件燒錄完成。
2.2 安裝IDE(Thonny IDE)
  1. 進入軟件官網 //thonny.org/下載軟件,最好下載最新版的,否則可能不支持樹莓派 PICO;
  2. 安裝Thonny,安裝完成後打開Thonny軟件,打開工具->設置-> 解釋器,選擇MicroPython(Raspberry Pi Pico)解釋器,並在串口處選擇樹莓派PICO的串口號(如果板子已經連接在電腦上,軟件一般會自動檢測串口號)
  3. 重啟軟件,可以看到軟件左下方顯示了樹莓派PICO中的文件;

如果沒有顯示左側文件樹的話可以勾選 視圖->文件

2.3 離線運行程序

新建文件

  新建文件,編寫完代碼後,按住ctrl+s將該文件保存在樹莓派PICO上,並命名為main.py(一定要加後綴.py),下次樹莓派PICO通電時便會自動運行main.py中的程序。

3 基礎

3.01 點亮板載LED燈
from machine import Pin

if __name__ == '__main__':
    # 構建led對象
    # 板載LED燈連接與引腳25相連
    # LED = Pin(id, mode, pull)
    # id:PICO引腳編號
    # mode:輸入輸出方式,有Pin.IN(輸入)和Pin.OUT(輸出)兩種
    # pull:上下拉電阻配置,有None(無上下拉電阻)、Pin.PULL_UP(上拉電阻)和Pin.PULL_DOWN(下拉電阻)三種
    LED = Pin(25, Pin.OUT)
    # 高電平點亮
    LED.value(1)
3.02 板載LED閃爍
from machine import Pin
from utime import sleep
import utime

led = Pin(25, Pin.OUT)

if __name__ == '__main__':
    while True:
        # led點亮
        led.value(1)
        utime.sleep_ms(1000)
        # led熄滅
        led.value(0)
        utime.sleep_ms(1000)
3.03 LED流水燈
  1. LED發光二極管圖片

  1. LED發光二極管正負極區分
  • 一般引腳長的一端為正極,引腳短的為負極
  • 看發光二極管內部,支架大的為負極,支架小的為負極
  1. 電路連線圖

  1. 代碼
from machine import Pin
import utime

# 定義LED引腳數組
leds = [Pin(i,Pin.OUT) for i in range(0,5)]

if __name__ == '__main__':
    while True:
        # 依次點亮
        for n in range(0,5):
            leds[n].value(1)
            utime.sleep_ms(200)
        # 依次熄滅
        for n in range(0,5):
            leds[n].value(0)
            utime.sleep_ms(100)

3.04 按鍵實驗
  1. 四角按鍵圖片

  1. 四角按鍵怎麼連接

默認按鍵未按下的情況下,12相連接,34相連接;當按下按鍵時,1234才相連接。

  1. 電路接線圖

  1. 代碼
from machine import Pin
import utime

# 配置按鍵
# key = machine.Pin(id, mode, pull)
# id:樹莓派Pico引腳編號
# mode:輸入輸出方式,有Pin.IN(輸入)和Pin.OUT(輸出)兩種
# pull:上下拉電阻配置,有None(無上下拉電阻)、Pin.PULL_UP(上拉電阻)和Pin.PULL_DOWN(下拉電阻)三種
key = Pin(0, Pin.IN, Pin.PULL_UP)

if __name__ == '__main__':
    while True:
        # print(key.value())
        if key.value() == 0:
            # 等待一段時間,防止抖動
            utime.sleep_ms(100)
            if key.value() == 0:
                print('The button is pressed')

按鍵消抖可以參考//baike.baidu.com/item/%E6%8C%89%E9%94%AE%E6%B6%88%E6%8A%96

3.05 外部中斷(改進3.04 按鍵實驗)
  1. 什麼是外部中斷

  外部中斷是單片機實時地處理外部事件的一種內部機制。當某種外部事件發生時,單片機的中斷系統將迫使CPU暫停正在執行的程序,轉而去進行中斷事件的處理;中斷處理完畢後.又返回被中斷的程序處,繼續執行下去。[3]

  1. 外部中斷的作用
  • 節省CPU資源
  1. 代碼實現

  在3.04 按鍵實驗中,檢測按鍵是否被按下採用的是在主程序中寫死循環的辦法,假如這個按鍵被按下的頻率十分低(一天只有幾次被按下),採用死循環的方法將會浪費大量的CPU資源,而採用外部中斷的方式檢測按鍵是否被按下將大大節省CPU資源。

from machine import Pin
import utime

#配置按鍵
key = Pin(0, Pin.IN, Pin.PULL_UP)

def external_interrupt(key):
    # 消除抖動
    utime.sleep_ms(100)
    # 再次判斷按鍵是否被按下
    if key.value() == 0:
        print('The button is pressed')

if __name__ == '__main__':
    # KEY.irq(handler,trigger)
    # handler:中斷執行的回調函數
    # trigger:觸發中斷的方式,分別為Pin.IRQ_FALLING(下降沿觸發)、
    # Pin.IRQ_RISING(上升沿觸發)、Pin.IRQ_LOW_LEVEL(低電平觸發)和
    # Pin.IRQ_HIGH_LEVEL(高電平觸發)四種
    # 定義中斷,下降沿觸發
    key.irq(external_interrupt, Pin.IRQ_FALLING)
3.06 定時器中斷(改進3.02 板載LED閃爍)
  1. 什麼是定時器中斷
  • 定時器中斷是由單片機中的定時器溢出而申請的中斷,即設定一個時間,到達這個時間後就會產生中斷
  1. 代碼

通過設置定時器中斷使樹莓派PICO板載LED每隔兩秒閃爍一次

from machine import Pin, Timer

# 創建LED對象
led=Pin(25, Pin.OUT)

# 閃爍回調函數
def twinkle(tim):
    # toggle方法:LED狀態翻轉
    led.toggle()

if __name__ == '__main__':
    # 構建定時器
    tim = Timer()
    # tim.init(period, mode, callback)
    # period:周期時間(單位為ms)
    # mode:工作模式,有Timer.ONE_SHOT(執行一次)和Timer.PERIODIC(周期性執行)兩種
    # callback:定時器中斷的回調函數
    tim.init(period=2000, mode=Timer.PERIODIC, callback=twinkle)
3.07 PWM 脈衝寬度調製(實現板載LED呼吸燈)
  1. 什麼是PWM

  脈衝寬度調製是一種模擬控制方式,根據相應載荷的變化來調製晶體管基極或MOS管柵極的偏置,來實現晶體管或MOS管導通時間的改變,從而實現開關穩壓電源輸出的改變。這種方式能使電源的輸出電壓在工作條件變化時保持恆定,是利用微處理器的數字信號對模擬電路進行控制的一種非常有效的技術。脈衝寬度調製是利用微處理器的數字輸出來對模擬電路進行控制的一種非常有效的技術,廣泛應用在從測量、通信到功率控制與變換的許多領域中。[4]

  1. 代碼
from machine import Pin, Timer, PWM
import utime

led = PWM(Pin(25))
# 設置頻率值
led.freq(1000)

led_value = 0
# led以5%增長/減少的速度變化亮度
led_space = 5

if __name__ == '__main__':
    while True:
        led_value += led_space
        if led_value >= 100:
            led_value = 100
            led_space = -5
        elif led_value <= 0:
            led_value = 0
            led_space = 5
        # 設置占空比,需在0-65535之間
        led.duty_u16(int(led_value * 500))
        utime.sleep_ms(100)

3.08 I2C總線(使用SSD1306 OLED屏幕)
  1. I2C總線簡介

  I2C總線是由Philips公司開發的一種簡單、雙向二線制同步串行總線。它只需要兩根線即可在連接於總線上的器件之間傳送信息。I2C由 2 條線組成:SDA(串行數據線)和SCL(串行時鐘線),都是雙向I/O線。[5]

  1. SSD1306 OLED簡介

  SSD1306是一款帶控制器的用於OLED點陣圖形顯示系統的單片CMOS OLED/PLED驅動器。它由128個SEG(列輸出)和64個COM(行輸出)組成。該芯片專為共陰極OLED面板設計。
  SSD1306內置對比度控制器、顯示RAM(GDDRAM)和振蕩器,以此減少了外部元件的數量和功耗。該芯片有256級亮度控制。數據或命令由通用微控制器通過硬件選擇的6800/8000系通用並行接口、I2C接口或串行外圍接口發送。該芯片適用於許多小型便攜式應用,如手機副顯示屏、MP3播放器和計算器等。[6][7]

  1. 電路連線圖

  1. 代碼

ssd1306.py下載地址: //elijah.lanzoui.com/iJ13fpnq6je

下載完成後,在Thonny軟件左側的文件窗口內找到這個文件,右鍵點擊文件,選擇上載到選項,文件即可傳輸到樹莓派PICO上

from machine import SoftI2C, Pin
# 導入SSD1306驅動模塊
from ssd1306 import SSD1306_I2C

if __name__ == '__main__':
    # 初始化SoftI2C
    # OLED屏幕的scl連接到樹莓派PICO的GPIO0, sda連接到GPIO1
    i2c = SoftI2C(scl=Pin(0), sda=Pin(1))
    # oled = SSD1306_I2C(width, height, i2c, addr)
    # width:屏幕寬
    # height: 屏幕高
    # i2c:已定義的I2C對象
    oled = SSD1306_I2C(128, 64, i2c) #OLED顯示屏初始化:128*64分辨率,OLED的I2C地址是0x3c
    # OLED顯示的字符串,橫坐標和縱坐標
    oled.text("Hello World!", 0, 0)
    # OLED顯示
    oled.show()

4 傳感器程序

4.1 溫度傳感器(DS18B20)

DS18B20是常用的數字溫度傳感器,其輸出的是數字信號,具有體積小,硬件開銷低,抗干擾能力強,精度高的特點。

  • 測溫範圍: -55℃~+125℃,固有測溫誤差1℃

  • 工作電源: 3.0~5.5V/DC

  • 單總線驅動,只佔用一個IO口

import machine, onewire, ds18x20, time, utime

# 使用GPIO0口傳輸數據
# 將DS18B20的VCC端連接到樹莓派PICO的3V3(OUT)端
# 將DS18B20的數據端連接到樹莓派PICO的GPIO0口
# 將DS18B20的GND端連接到樹莓派PICO的GND端
pin = machine.Pin(0)
sensor = ds18x20.DS18X20(onewire.OneWire(pin))

# 掃描是否存在DS18B20設備
roms = sensor.scan()
print('Found a ds18x20 device')

# 獲取溫度數據
def detect_tem():
    while True:
      sensor.convert_temp()
      for rom in roms:
        # 打印出溫度值
        # 第一個打印出來的數值可能不太準確,從第二條數據開始才會顯示出正常數據
        print("{:.3f}".format(sensor.read_temp(rom)))  
      utime.sleep_ms(2000)
      
# 程序入口
if __name__ == '__main__':
    detect_tem()
4.2 溫濕度傳感器

DHT22.py文件下載地址: //elijah.lanzoui.com/iFueapnq6id

文件上傳方法參考3.08 I2C總線

4.2.1 DHT11

DHT11是一款有已校準數字信號輸出的溫濕度傳感器。 其精度濕度±5%RH, 溫度±2℃,量程濕度5-95%RH, 溫度0-+50℃。[8]

from machine import Pin
from DHT22 import DHT22
import utime

pin = Pin(0,Pin.IN,Pin.PULL_UP)
# 創建dht11對象
# 將DHT11的VCC端連接到樹莓派PICO的3V3(OUT)端
# 將DHT11的數據端連接到樹莓派PICO的GPIO0口
# 將DHT11的GND端連接到樹莓派PICO的GND端
dht_sensor=DHT22(pin, dht11=True)

# 循環函數
def detection():
    while True:
        T, H = dht_sensor.read()
        if T is None:
            print("sensor error")
        else:
            print("{}'C  {}%".format(T, H))
        utime.sleep_ms(2000)

# 程序入口
if __name__ == '__main__':    
    detection()
4.2.1 DHT22

  DHT22也稱AM2302,是一款含有已校準數字信號輸出的溫濕度複合傳感器,濕度量程範圍0-99.9%RH,精度±2%RH,而溫度量程範圍是-40℃-80℃,精度±0.5℃。[9]

from machine import Pin
from DHT22 import DHT22
import utime

pin = Pin(0,Pin.IN,Pin.PULL_UP)
# 創建dht11對象
# 將DHT11的VCC端連接到樹莓派PICO的3V3(OUT)端
# 將DHT11的數據端連接到樹莓派PICO的GPIO0口
# 將DHT11的GND端連接到樹莓派PICO的GND端
dht_sensor=DHT22(pin, dht11=False)

# 循環函數
def detection():
    while True:
        T, H = dht_sensor.read()
        if T is None:
            print("sensor error")
        else:
            print("{:.2f}'C  {:.2f}%".format(T, H))
        utime.sleep_ms(2000)

# 程序入口
if __name__ == '__main__':    
    detection()

  1. //www.waveshare.com/wiki/Raspberry_Pi_Pico ↩︎

  2. //pico.org.cn/ ↩︎

  3. //baike.baidu.com/item/外部中斷 ↩︎

  4. //baike.baidu.com/item/脈衝寬度調製/10813756?fromtitle=PWM&fromid=3034961&fr=aladdin ↩︎

  5. //baike.baidu.com/item/I2C總線/918424?fromtitle=I2C&fromid=1727975&fr=aladdin ↩︎

  6. //blog.csdn.net/qq_39829913/article/details/104716829 ↩︎

  7. //wenku.baidu.com/view/10b60c264a73f242336c1eb91a37f111f1850d88.html ↩︎

  8. //baike.baidu.com/item/DHT11/1206271?fr=aladdin ↩︎

  9. //blog.csdn.net/k1ang/article/details/98789397 ↩︎