Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Pico 從 IoT 到 AIoT (Day 1)

Pico 從 IoT 到 AIoT (Day 1)

這是 Raspberry Pi Pico 入門套件的說明(Day 1)。

購買 Raspberry Pi Pico 入門套件(含 Pico)。
https://piepie.com.tw/39346/raspberry-pi-pico-starter-kit

範例程式。
https://github.com/piepie-tw/pico-aiot

台灣樹莓派

February 10, 2023
Tweet

More Decks by 台灣樹莓派

Other Decks in Technology

Transcript

  1. 姓名標示 — 非商業性 — 相同方式分享 CC (Creative Commons) 姓名標示 —

    你必須給予 適當表彰、提供指向本授權 條款的連結,以及 指出(本作品的原始版本)是否已 被變更。你可以任何合理方式為前述表彰,但不得以 任何方式暗示授權人為你或你的使用方式背書。 非商業性 — 你不得將本素材進行商業目的之使 用。 相同方式分享 — 若你重混、轉換本素材,或依本 素材建立新素材,你必須依本素材的授權條款來 散布你的貢獻物。
  2. • COSCUP, MakerConf, PyCon, HKOSCon 講者 • 投影片 • https://speakerdeck.com/piepie_tw

    • 程式碼 • https://github.com/piepie-tw • 台灣樹莓派網站 : • https://piepie.com.tw/ • Facebook: • https://www.facebook.com/RaspberryPi.Taiwan 分享 x 教學
  3. 6 • Raspberry Pi Pico 介紹 • 環境設定 • 輸入

    / 輸出 • 數位 / 類比 • I2C 協定 本次主題
  4. 9 • MCU 從 2015-2021 的出貨數量 ( 單位 : 十億

    ) MCU 的出貨數量 https://www.statista.com/statistics/935382/worldwide-microcontroller-unit-shipments/
  5. 10 • MPU 是 Micro Processing Unit( 微處理單元 ) •

    MCU 是 MicroController Unit( 微控制單元 ) MPU vs. MCU https://www.microcontrollertips.com/microcontrollers-vs-microprocessors-whats-difference/
  6. 11 • SoC 是 System on Chip( 系統單晶片 ) •

    SoC 適複雜的應用 , 常整合更多硬體例如 DSP 或 是 Audio 等 , 通常可安裝作業系統 SoC vs. MCU https://www.microcontrollertips.com/what-is-an-soc-faq/
  7. 13 • 第一顆 Raspberry Pi 自行研發的 MCU Raspberry Pi RP2040

    MCU 特色 https://www.cytron.io/p-raspberry-pi-rp2040-dual-core-microcontroller
  8. 20 • 高性能 , 靈活的 I/O, 低成本 (RP2040 僅 USD$1)

    • RP2040 是英國製晶片 (vs. 中國製的 ESP32) • 支援多種 IDE 開發環境 , 例如 Thonny, Visual Studio Code, Arduino IDE 開發等。可一鍵 上傳 • 可使用 MicroPython/CircuitPython,C/C++ • 完整的硬體設計文件 , 軟體開發文件 • RP2040 生態系 , 未來可輕鬆移植 / 量產 使用 RP2040/Pico 的好處
  9. 23 • 可用 MicroPython/CircuitPython 開發 • 可用 C/C++ 開發 ,

    但每次需編譯成 uf2 格式燒錄 可使用 MicroPython/C/C++ 開發
  10. Pico H vs. Arduino UNO http://functy.sourceforge.net/?p=328 Pico H Arduino UNO

    Processor ARM Cortex-M0+ dual-core ATmega328P Clock Speed 48MHz/133MHz 16MHz RAM 264KB 2KB Flash 2MB 32KB Wi-Fi No No Bluetooth No No Ethernet No No I/Os 2 × UART, 2 × I2C, 2 × SPI, 16 × PWM channels 1 × UART, 2 × I2C, 2 × SPI, 6 × PWM channels GPIO 26, plus 3 analogue pins 14, plus 6 analogue pins PIO 8 No Native USB Support USB 1.1 (Device or Host) USB 1.1 Device Language MicroPython, C/C++ Wiring-based(~C++) Price $4 $26 https://history-computer.com/raspberry-pi-pico-vs-arduino/
  11. Pico W vs. ESP32 http://functy.sourceforge.net/?p=328 Pico W ESP32 Processor ARM

    Cortex-M0+ dual-core Xtensa 32-bit dual-core Clock Speed 48MHz/133MHz 80/160/240MHz RAM 264KB 520KB Flash 2MB 4MB Wi-Fi 802.11n 802.11b/g/n Bluetooth N/A Bluetooth 4.2, BLE Other Interfaces 2 × UART, 2 × I2C, 2 × SPI, 16 × PWM channels 2 × I2S, 2 × I2C, 3 × UART, 4 × SPI, 16 × PWM channels Sensors Temperature Touch, Temperature, Hall Effect GPIO 26, plus 3 analogue pins 34 programmable pins PIO 8 No Native USB Support USB 1.1 (Device or Host) No https://www.makeuseof.com/raspberry-pi-pico-vs-esp32-microcontroller/
  12. 30 • 下載 MicroPython 的韌體 • 更新 Pico 的韌體 •

    下載安裝 Thonny • 在 Thonny 撰寫 MicroPython 程式 , 一鍵上傳 將 Pico 換成 MicroPython 的韌體
  13. 32 • MicroPython 是在微控制器上運作的 Python3 直譯器 • 最初用在 ARM Cortex-M,

    由劍橋大學 Damien George 開發 • 2013 年 Prof. Damien 設計 pyboard 上架到 Kickstarter • 2016 年移植 MicroPython 到 ESP8266 模組 MicroPython 歷史 https://www.kickstarter.com/projects/214379695/micro-python-python-for-microcontrollers https://www.kickstarter.com/projects/214379695/micropython-on-the-esp8266-beautifully-easy-iot pyboard ESP8266
  14. 33 • MicroPython ≠ Python, 只是長的像而已 • 但 MicroPython 支援多數的

    Python3 語法 • MicroPython 在不同的硬體支援的語法略有不同 • MicroPython 不適合有嚴格時序或性能要求的程式 • MicroPython 可以視為一個迷你的 Python OS MicroPython: Python for Microcontrollers https://techexplorations.com/guides/esp32/micropython-with-the-esp32/1-what-is-micropython/
  15. • 執行 putty 1. 選擇 Session 2. 選擇 Serial 3.Serial

    line 填 COM5 4.Speed 填入 115200 5.Open! • 沒畫面 , 先按 ENTER • 再不行 , 重插拔電源 使用 putty 連線到 Pico
  16. • 專為初學者設計的 Python 整合式開發環境 (IDE) • 由愛沙尼亞程式設計師 Aivar Annamaa 開發

    • Raspberry Pi OS 內建的 Python 程式開發工具 • 特色 : • 由 Python 所開發出的編輯器 • 支援 Windows, Linux 和 macOS • 支援 Python 直譯器的 REPL 介面 • 可安裝多版本直譯器環境 • 可單步執行 , 可在除錯階段即時變數賦值 • 支援 MicroPython 與多種硬體 , 例如 Pico 和 ESP32 等 Thonny
  17. 56 • General Purpose Input Output • GPIO 是一種可用軟體控制的數位訊號 什麼是

    GPIO ? http://www.tek.com/datasheet/tps2000b-series-digital-storage-oscilloscopes-datasheet
  18. 59 • GPIO 高電位輸出為 3.3V • GPIO 容忍輸入電位為 3.3V •

    單一 Pin 輸出電流為 2mA-12mA • 全部 Pin 輸出總和小於 50mA • GPIO 輸入低電位為小於 0.8V, 高電位為大於 2V 幾個 GPIO 的數字 https://datasheets.raspberrypi.com/rp2040/rp2040-datasheet.pdf
  19. 62 • 變數 , 物件 , 型別 , 註解 •

    模組 • 縮排 • 迴圈 • 條件判斷 • 函式 MicroPython 五分鐘速成
  20. 63 • 動態型別 (dynamic typing) # 這是註解 i = 3

    # 變數 i 指到數字物件 3 i = [1, 2, 3, 4, 5] # 變數 i 指到串列物件 print(i[2]) # 印出串列中第三個元素 i = "abcde" # 變數 i 指到字串物件 print(i[2]) # 印出字串中第三個元素 變數 , 物件 , 型別 , 註解
  21. 64 # 匯入 Module 內所有 Function • # import MODULE

    import machine • # 只匯入 Module 內指定 Function • # from MODULE import FUNCTION from machine import Pin 模組
  22. 66 • 自動迭代 (iterator) for i in range(start, stop[, step]):

    process for i in range(0, 11, 5): print(i) 迴圈
  23. 73 • 電路組成元件 : 電源、導線、負載 • 閉路 : 當三者形成一完整路徑 ,

    有電流經過電路 • 歐姆定律 : 導體兩端的電壓與通過的電流成正比 • V = I x R 電路一分鐘速成 I I V R V R I https://zh.wikipedia.org/wiki/ 电路
  24. 75 • V F : 順向電壓 • I F :

    在順向電壓下的安全電流 LED 的特性 https://learn.adafruit.com/all-about-leds/forward-voltage-and-kvl
  25. 76 • 在順向電壓下一般的 LED 能承受的安全電流是 20mA • 由於順向電壓 (Typical) 為

    1.85V • Pico 的 GPIO 腳位能提供 3.3V • 計算公式:電阻 = 電壓 / 電流 R =V/I R =(3.3-1.85)/0.02=72.5 歐姆 • 表示最小要接 72.5 歐姆的電阻 , 才能避免 LED 燒毀 如何解讀?
  26. 81 接線圖 LED Pico 長腳 (RED) Pin12 (GPIO18) 短腳 (BLACK)

    Pin6 (Ground) 330Ω 電阻 : 橙橙黑黑 ( 棕 )
  27. 87 • VBUS:microUSB 輸入電壓 • VSYS: 外部電源 / 電池輸入 (1.8V~5.5V)

    • 3V3_EN: 重啟電源 (hardware power off/on) • 3V3(OUT): 輸出 3.3V • ADC_VREF:ADC 參考電壓 • RUN/RESET: 重啟 RP2040(software reset) 特殊腳位意義 https://peppe8o.com/raspberry-pi-pico-pinout/ https://raspberrypi.stackexchange.com/questions/139210/
  28. 89 • 載入模組 (Import module) • 定義腳位 (Setup up a

    channel) • 讀取輸入 / 寫入輸出 (Input/Output) MicroPython Code 基本流程
  29. 90 • from machine import Pin # Import module import

    utime • led = Pin(15, Pin.OUT) # Setup up a channel print("LED is on") • led.value(1) # Input/Output status utime.sleep(5) print("LED is off") • led.value(0) # Input/Output status 一個實際的範例
  30. 94 • 在 Python 中的 utime 模組是設計給微控制器 , 例如 Pico

    這類型的硬體使用 • 在 MicroPython 中 , 使用 utime 模組等於 time (time is an alias to utime and uses the same code) UTIME vs. TIME https://forum.micropython.org/viewtopic.php?t=8222
  31. 97 from machine import Pin led = Pin(15, Pin.OUT) while

    True: print("LED is on") led.value(1) utime.sleep(1) • print("LED is off") led.value(0) utime.sleep(1) 永不停止的 while 迴圈
  32. 101 • 紅 , 黃 , 綠燈依序亮燈 • 紅燈亮 4

    秒 , 黃燈亮 2 秒 , 綠燈亮 4 秒 設計一個紅綠燈 http://www.clipartbest.com/traffic-light-photo
  33. 102 接線圖 紅 LED Pico 長腳 (RED) Pin20 (GPIO15) 短腳

    (BLACK) Pin38 (Ground) 綠 LED Pico 長腳 (GREEN) Pin17 (GPIO13) 短腳 (BLACK) Pin38 (Ground) 黃 LED Pico 長腳 (YELLOW) Pin19 (GPIO14) 短腳 (BLACK) Pin38 (Ground)
  34. 104 def RLED_OnOff(duration): red_led.value(1) utime.sleep(duration) • red_led.value(0) def YLED_OnOff(duration): •

    .... def GLED_OnOff(duration): • ... while True: • RLED_OnOff(4); • YLED_OnOff(2); • GLED_OnOff(4); 把亮燈拿到外面寫成 Function
  35. 109 • 常開 (normally open, N.O.) • 常閉 (normally close,

    N.C.) 按鍵 Button / 開關 Switch http://www.engineersgarage.com/sites/default/files/imagecache/Original/wysiwyg_imageupload/4214/Switch-2_0.jpg
  36. 117 button = Pin(14, Pin.IN) previousStatus = None while True:

    input = button.value() if input == 0 and previousStatus == 1: print("Button pressed") previousStatus = input 判斷條件 : 這次低 && 上次高
  37. 121 • 硬體方法 : 以 RC 電路或正回授的比較器電路解決 • 軟體方法 :

    調整觸發的延遲時間 • 不同的按鍵會有不同的延遲時間 解決彈跳問題 (de-bounce) 10ms - 20ms
  38. 122 previousStatus = None currentTime = None previousTime = utime.mktime(utime.localtime())

    while True: input = button.value() currentTime = utime.mktime(utime.localtime()) if input == 1 and \ previousStatus == 0 and \ (currentTime - previousTime) > 0.2: previousTime = currentTime print("Button pressed”) previousStatus = input 不反應在延遲時間內的觸發 現在的 timestamp
  39. 125 button = Pin(14, Pin.IN, Pin.PULL_UP) previousStatus = None currentTime

    = None previousTime = utime.mktime(utime.localtime()) while True: input = button.value() currentTime = utime.mktime(utime.localtime()) if input == 1 and \ previousStatus == 0 and \ (currentTime - previousTime) > 0.2: previousTime = currentTime print("Button pressed”) previousStatus = input 要搭配內建的上拉電阻 (50k)
  40. 127 • 輪詢 (polling) • MCU 每隔一段時間檢查週邊硬體的資料 • 中斷 (interrupt)

    • 當週邊硬體的狀態改變時 , 對 MCU 發出 IRQ 輪詢與中斷
  41. 128 • 定義腳位 • button = Pin() • 建立回呼函數 •

    def button_handler() • 綁定事件和回呼函數 • button.irq(trigger # 觸發條件 handler # 回呼函數 ) 中斷的程式寫法
  42. 129 From machine import Pin button = Pin(14, Pin.IN, Pin.PULL_UP)

    def button_handler(pin): print("Button pressed") button.irq(trigger=Pin.IRQ_FALLING, \ handler=button_handler) while True: utime.sleep(10) 即使在 sleep 狀態下也可立即回應
  43. 132 • 發聲原理 : 聲音是由振動產生 , 其頻率稱為音頻 • 蜂鳴器發聲原理 :

    電流 (6) 通過電磁線圈 (3) 產生 磁場來驅動振動膜 (11) • 人耳可聽到 20Hz - 20KHz 原理 http://www.itianer.com/diancishifengmingqigouzaoyuyuanlijieshao.html
  44. 133 • 自激 ( 有源 ): 只能發出同頻率的聲音 • 黑膠封裝 ,

    高低腳 • 他激 ( 無源 ): 需從外部輸入震盪方波發聲 • 綠色電路板 , 兩腳同長 • 腳位有正負之分 ( 看底板 ) 蜂鳴器 Buzzer http://www.buzzer-speaker.com/manufacturer/piezo%20buzzer.htm 自激式 他激式 自激式
  45. 135 from machine import Pin buzzer = Pin(15, Pin.OUT) while

    True: print("Buzzer is on") • buzzer.value(1) utime.sleep(1) • print("Buzzer is off") • buzzer.value(0) utime.sleep(1) 一秒發聲一秒安靜
  46. 142 • 輸入電壓 :DC 3.3V - 24V • 輸出電壓 :3.3V(

    可直接接上 Raspberry Pi) • 延遲時間 (Tx):2.45 秒 – 248 秒 • 感應之後輸出維持的時間 • 封鎖時間 (Ti):2.4 秒 • 感應輸出結束之後 , 再次觸發必須等待的時間 • 感應角度 :110 度 x 70 度 • 感應距離 :3 米 - 7 米 瞭解規格
  47. 143 • 感測距離設定 • 順時針 : 最高為 7 米 •

    逆時針 : 最小為 3 米 • 延遲時間設定 (Tx) • 順時針 : 最長為 248 秒 • 逆時針 : 最短為 2.45 秒 • 實際可調整時間要看 R10,C6,R9,C7 而定 感測距離 / 延遲時間設定 感測距離設定 延遲時間設定
  48. 144 • 可重複觸發模式 (H) • 不可重複觸發模式 (L) 觸發模式 H: 可重複觸發

    L: 不可重複觸發 ( 預設 ) 感應 & 輸出 感應 & 等待 & 輸出
  49. 146 sensor_pir = Pin(28, Pin.IN, Pin.PULL_DOWN) def pir_handler(pin): if pin.value():

    print("ALARM! Motion detected") sensor_pir.irq(trigger=Pin.IRQ_RISING, handler=pir_handler) while True: utime.sleep(10) 再一次使用 interrupt 模式
  50. 151 sensor_pir = Pin(28, Pin.IN, Pin.PULL_DOWN) led = Pin(15, Pin.OUT)

    def pir_handler(pin): if pin.value(): print("ALARM! Motion detected") for i in range(10): led.toggle() utime.sleep_ms(200) sensor_pir.irq(trigger=Pin.IRQ_RISING, handler=pir_handler) while True: utime.sleep(10) 偵測到人 , 燈閃 5 次 燈閃 5 次