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 引腳圖
1.4 尺寸
2 安裝
2.1 燒錄韌體
如果連線失效,可以進入 https://www.raspberrypi.org/documentation/rp2040/getting-started/#getting-started-with-micropython官網下載
- 按住BOOTSEL鍵不放,將Pico插入電腦的USB串列埠,電腦上會彈出一個新的U盤資料夾,把剛剛下載的UF2檔案拖拽到資料夾中,樹莓派 PICO將會自動重啟,此時,韌體燒錄完成。
2.2 安裝IDE(Thonny IDE)
- 進入軟體官網 https://thonny.org/下載軟體,最好下載最新版的,否則可能不支援樹莓派 PICO;
- 安裝Thonny,安裝完成後開啟Thonny軟體,開啟工具->設定-> 直譯器,選擇
MicroPython(Raspberry Pi Pico)
直譯器,並在串列埠處選擇樹莓派PICO的串列埠號(如果板子已經連線在電腦上,軟體一般會自動檢測串列埠號) - 重啟軟體,可以看到軟體左下方顯示了樹莓派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流水燈
- LED發光二極體圖片
- LED發光二極體正負極區分
- 一般引腳長的一端為正極,引腳短的為負極
- 看發光二極體內部,支架大的為負極,支架小的為負極
- 電路連線圖
- 程式碼
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 按鍵實驗
- 四角按鍵圖片
- 四角按鍵怎麼連線
預設按鍵未按下的情況下,12相連線,34相連線;當按下按鍵時,1234才相連線。
- 電路接線圖
- 程式碼
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')
按鍵消抖可以參考https://baike.baidu.com/item/%E6%8C%89%E9%94%AE%E6%B6%88%E6%8A%96
3.05 外部中斷(改進3.04 按鍵實驗)
- 什麼是外部中斷
外部中斷是微控制器實時地處理外部事件的一種內部機制。當某種外部事件發生時,微控制器的中斷系統將迫使CPU暫停正在執行的程式,轉而去進行中斷事件的處理;中斷處理完畢後.又返回被中斷的程式處,繼續執行下去。[3]
- 外部中斷的作用
- 節省CPU資源
- 程式碼實現
在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閃爍)
- 什麼是定時器中斷
- 定時器中斷是由微控制器中的定時器溢位而申請的中斷,即設定一個時間,到達這個時間後就會產生中斷
- 程式碼
通過設定定時器中斷使樹莓派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呼吸燈)
- 什麼是PWM
脈衝寬度調製是一種模擬控制方式,根據相應載荷的變化來調製電晶體基極或MOS管柵極的偏置,來實現電晶體或MOS管導通時間的改變,從而實現開關穩壓電源輸出的改變。這種方式能使電源的輸出電壓在工作條件變化時保持恆定,是利用微處理器的數字訊號對類比電路進行控制的一種非常有效的技術。脈衝寬度調製是利用微處理器的數字輸出來對類比電路進行控制的一種非常有效的技術,廣泛應用在從測量、通訊到功率控制與變換的許多領域中。[4]
- 程式碼
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螢幕)
- I2C匯流排簡介
I2C匯流排是由Philips公司開發的一種簡單、雙向二線制同步序列匯流排。它只需要兩根線即可在連線於總線上的器件之間傳送資訊。I2C由 2 條線組成:SDA(序列資料線)和SCL(序列時鐘線),都是雙向I/O線。[5]
- SSD1306 OLED簡介
SSD1306是一款帶控制器的用於OLED點陣圖形顯示系統的單片CMOS OLED/PLED驅動器。它由128個SEG(列輸出)和64個COM(行輸出)組成。該晶片專為共陰極OLED面板設計。
SSD1306內建對比度控制器、顯示RAM(GDDRAM)和振盪器,以此減少了外部元件的數量和功耗。該晶片有256級亮度控制。資料或命令由通用微控制器通過硬體選擇的6800/8000系通用並行介面、I2C介面或序列外圍介面傳送。該晶片適用於許多小型行動式應用,如手機副顯示屏、MP3播放器和計算器等。[6][7]
- 電路連線圖
- 程式碼
ssd1306.py下載地址: https://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檔案下載地址: https://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()
https://baike.baidu.com/item/脈衝寬度調製/10813756?fromtitle=PWM&fromid=3034961&fr=aladdin ︎
https://baike.baidu.com/item/I2C匯流排/918424?fromtitle=I2C&fromid=1727975&fr=aladdin ︎
https://blog.csdn.net/qq_39829913/article/details/104716829 ︎
https://wenku.baidu.com/view/10b60c264a73f242336c1eb91a37f111f1850d88.html ︎