Slide 1

Slide 1 text

1 Raspberry Pi Pico 好好玩 - 從 IoT 到 AIoT 台灣樹莓派 2022/11/25 @NUK

Slide 2

Slide 2 text

姓名標示 — 非商業性 — 相同方式分享 CC (Creative Commons) 姓名標示 — 你必須給予 適當表彰、提供指向本授權 條款的連結,以及 指出(本作品的原始版本)是否已 被變更。你可以任何合理方式為前述表彰,但不得以 任何方式暗示授權人為你或你的使用方式背書。 非商業性 — 你不得將本素材進行商業目的之使 用。 相同方式分享 — 若你重混、轉換本素材,或依本 素材建立新素材,你必須依本素材的授權條款來 散布你的貢獻物。

Slide 3

Slide 3 text

3 ● Raspberry Pi 官方經銷商 ● 專注 Raspberry Pi 應用與推廣 , 舉辦社群活動 關於我們

Slide 4

Slide 4 text

● 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 教學

Slide 5

Slide 5 text

No content

Slide 6

Slide 6 text

6 ● Raspberry Pi Pico 介紹 ● 環境設定 ● 輸入 / 輸出 ● 數位 / 類比 ● I2C 協定 本次主題

Slide 7

Slide 7 text

7 實驗 9: 呼吸燈 目的 : 瞭解訊號模擬

Slide 8

Slide 8 text

8 ● 數位 :0 與 1 的訊號 ● 類比 : 連續的訊號 數位與類比 http://www.bitscope.com/software/blog/DJ/?p=DJ19A

Slide 9

Slide 9 text

9 ● 數位 : 亮和不亮 ● 類比 : 亮 , 有點亮 , 有點不亮 ..., 不亮 ● 可是 GPIO 腳位輸出都是固定值 , 怎麼辦? 從 LED 的角度來看

Slide 10

Slide 10 text

10 ● 旋轉式 , 滑動式 ● 線性關係 (B 型 ), 對數關係 (A 型 ) ● 常見規格 :0 -10k Ohm( 線性 ) 可變電阻 Potentiometer(VR) https://en.wikipedia.org/wiki/Potentiometer 接高電位 接低電位 滑動接點 ( 可變輸出 )

Slide 11

Slide 11 text

11 利用可變電阻改變 LED 亮度

Slide 12

Slide 12 text

12 Pico 腳位定義 https://microdigisoft.com/led-blinking-with-raspberry-pi-pico-gpio-using-micropython/

Slide 13

Slide 13 text

13 有不使用額外硬體的方法嗎?

Slide 14

Slide 14 text

14 ● 是將數位信號轉為脈波的一種技術 ● 頻率不變 + 改變工作週期 , 使整體平均電壓值改變 ● 改變工作週期 (duty cycle)= 改變平均電壓 脈寬調變 (Pulse-Width Modulation) http://wiki.csie.ncku.edu.tw/embedded/PWM

Slide 15

Slide 15 text

15 ● 輸出總功率 = 脈衝寬度 ( 時間 )x 高電位值 公式計算 http://www.protostack.com/blog/2011/06/atmega168a-pulse-width-modulation-pwm/

Slide 16

Slide 16 text

16 ● 建立PWM 實體: ● p = machine.PWM(pin) # 預設freq=5kHz ● 設定duty cycle: ● p.duty_u16(dc) # set duty cycle, range 0-65535 ● 讀取duty cycle: ● p.duty_u16() # get current duty cycle ● 關閉該腳位的PWM: ● p.deinit() MicroPython PWM https://docs.micropython.org/en/latest/rp2/quickref.html

Slide 17

Slide 17 text

17 一樣的接線圖 330Ω 電阻 LED Pico 長腳 (RED) Pin20 (GPIO15) 短腳 (BLACK) Pin38 (Ground)

Slide 18

Slide 18 text

18 Pico 腳位定義 https://microdigisoft.com/led-blinking-with-raspberry-pi-pico-gpio-using-micropython/

Slide 19

Slide 19 text

19 led = PWM(Pin(15)) ● led.freq(100) led.duty_u16(0) while True: for dc in range(0, 65536, 4096): led.duty_u16(dc) utime.sleep(0.1) utime.sleep(2) for dc in range(65535, -2, -4096): led.duty_u16(dc) utime.sleep(0.1) utime.sleep(2) 呼吸燈就是漸明漸亮

Slide 20

Slide 20 text

20 DEMO 09_1-pwm_led.py

Slide 21

Slide 21 text

21 實驗 10: 伺服馬達 目的 : 使用 PWM 控制伺服馬達

Slide 22

Slide 22 text

22 ● servo 是可控制旋轉角度的動力輸出裝置 伺服馬達 (Servo) https://www.youtube.com/watch?v=LXURLvga8bQ&ab_channel=HowToMechatronics

Slide 23

Slide 23 text

23 ● 工作電壓 :4.8V~6V ● 工作電流 :100mA(4.8V)/120mA(6V) ● 堵轉電流 :700mA(4.8V)/800mA(6V) ● 扭矩 :1.3kg·cm(4.8V)/1.5kg·cm(6V) ● 速度 :0.12s/60º(4.8V)/0.12s/60º(6V) ● 轉動角度 :0(0.5ms)~180 度 (2.5ms) ● 尺寸 :23x12.2x29mm ● 重量 :9g SG90 塑膠齒輪伺服馬達 https://electronics.stackexchange.com/questions/246642/ power-supply-circuit-for-powering-sg90-servo-how-to-handle-high-current-require

Slide 24

Slide 24 text

SG90 脈衝寬度和旋轉角度變化 https://howtomechatronics.com/how-it-works/how-servo-motors-work-how-to-control-servos-using-arduino/

Slide 25

Slide 25 text

25 接線圖 SERVO Pico 橘線 (ORANGE) Pin1 (GP0) 棕線 (BROWN) Pin3 (Ground) 紅線 (RED) 訊號線接 Pin1

Slide 26

Slide 26 text

26 Pico 腳位定義 https://microdigisoft.com/led-blinking-with-raspberry-pi-pico-gpio-using-micropython/

Slide 27

Slide 27 text

27 ● 頻率 =1/ 週期 ● 週期 =On 時間 +Off 時間 Duty Cycle 和週期 / 頻率的關係 https://circuitdigest.com/microcontroller-projects/ control-a-servo-motor-with-raspberry-pi-pico-using-pwm-in-micropython

Slide 28

Slide 28 text

28 ● SG90 轉動角度 :0(0.5ms)~180 度 (2.5ms) ● MicroPython 用 0-65535 對應 0-100% DC ● Duty Cycle = 2.5+( 角度 /180)*10 ● 轉動角度 0 度 =65535*2.5%=1638( 取 1000) ● 轉動角度 90 度 =65535*12.5%=8191( 取 9000) 從 Duty Cycle 轉換成時間和角度 脈寬 轉動角度 Duty Cycle 0.5ms 0 度 2.5% (0.5ms 高電位 + 19.5ms 低電位 ) 1ms 45 度 5% (1ms 高電位 + 19.0ms 低電位 ) 1.5ms 90 度 7.5% (1.5ms 高電位 + 18.5ms 低電位 ) 2.0ms 135 度 10% (2ms 高電位 + 18.0ms 低電位 ) 2.5ms 180 度 12.5% (2.5ms 高電位 + 17.5ms 低電位 )

Slide 29

Slide 29 text

29 servo = PWM(Pin(0)) servo.freq(50) servo.duty_u16(1000) ● utime.sleep(5) ● while True: for dc in range(1000, 9000, 50): servo.duty_u16(dc) utime.sleep(0.01) utime.sleep(1) for dc in range(9000, 1000, -50): servo.duty_u16(dc) utime.sleep(0.01) utime.sleep(1) 使用 PWM 控制伺服馬達 一開始先定位到 0 度

Slide 30

Slide 30 text

30 DEMO 10_1-servo.py

Slide 31

Slide 31 text

● 寫一個可以根據輸入角度而轉動伺服馬達的函式 練習

Slide 32

Slide 32 text

32 ● 工作電壓 :4.8V~6V ( ) ✓ ● 工作電流 :100mA(4.8V)/120mA(6V) (×) ● 堵轉電流 :700mA(4.8V)/800mA(6V) (×) ● Pico 的 GPIO 腳位無法提供足夠的電流 , 直接接 上 GPIO 有可能會燒毀 RP2040 SG90 這樣有什麼問題?

Slide 33

Slide 33 text

33 建議使用獨立電源接線圖 SERVO Pico 橘線 (ORANGE) Pin1 (GP0) 棕線 (BROWN) Pin3 (Ground) 紅線 (RED) 訊號線接 Pin1

Slide 34

Slide 34 text

34 實驗 11: 光敏電阻 目的 : 類比訊號的讀取

Slide 35

Slide 35 text

35 ● 硫化鎘 (CdS) 或光敏電阻器 (LDR), 阻抗隨光落 在表面的總量而轉變 ● 光越強阻值越小 , 反之光越弱阻值則越大 ● 應用 : 光控開關 , 電子玩具 , 工業控制 光敏電阻 http://www2.nkfust.edu.tw/~jlkuo2/31/a6.htm

Slide 36

Slide 36 text

36 ● Pico 內建 3 個可用的 12bits ADC, 第四個用於內 建的溫度感測器 (ADC4), 但在 MicroPython 會用 read_u16() 轉成 0~65535 之間的數字 類比訊號轉換為數位訊號 http://www.planetoftunes.com/digital-audio/how-do-analogue-to-digital-converters-work.html IN ADC OUT 此 ADC 的解析度為 4bits 從 0000 到 1111( 看 Y 軸 )

Slide 37

Slide 37 text

37 ● ADC 轉換時間為 2μs 等於 500k/s( 頻率 ) ● 計算方式是由於 RP2040 預設時脈為 48MHZ, 而 ADC 需 96 CPU 週期 (clock cycle) 轉換 , 因此 每次轉換時間為 96 x 1 / 48MHz = 2μs ● Pico 可用的 ADC 腳位有四個 , 但只有 3 個對外 RP2040 ADC 特色

Slide 38

Slide 38 text

38 讀取光敏電阻的接線圖 Pin31(GPIO26)

Slide 39

Slide 39 text

39 Pico 腳位定義 https://microdigisoft.com/led-blinking-with-raspberry-pi-pico-gpio-using-micropython/

Slide 40

Slide 40 text

40 ● 由於 MCU 無法直接讀取電阻值 , 需透過分壓電路回推阻值 ● 分壓電路是根據已知的 Vin, Vout, R2 計算未知的 R1 ● Vin = 3.3V ● Vout = ADC ● R2 = 330Ω 分壓電路計算 https://www.elprocus.com/voltage-divider-rule-with-examples/

Slide 41

Slide 41 text

41 photoresistor = ADC(Pin(26)) ● ● def readADC(pin): ● vout = photoresistor.read_u16() ● vout = round((vout/65535)*3.3, 2) ● r1 = 330*(3.3-vout)/vout ● ● return (vout, r1) ● ● while True: ● vout = readADC(photoresistor)[0] ● r1 = readADC(photoresistor)[1] ● ● print("Vout: " + str(vout) +" V") ● print("R1: " + str(r1) +" ohm") ● ● utime.sleep(1) 用分壓電路計算光敏電阻阻值 用已知的 Vin, Vout, R2 計算未知的 R1

Slide 42

Slide 42 text

42 DEMO 11_1-photoresistor.py

Slide 43

Slide 43 text

43 實驗 12: 煙霧感測器 目的 : 瞭解感測器的讀取

Slide 44

Slide 44 text

44 ● 每個型號感測器都可讀取到多種氣體 , 但單一型 號會對特定的氣體有比較高的響應值 MQ 系列感測器

Slide 45

Slide 45 text

45 ● MQ-2 感測器適用於檢測液化石油氣 (LPG), 例 如異丁烷 (C4H10), 丙烷 (C3H8), 甲烷 (CH₄), 酒精 (C₂H₆O), 氫氣 (H2) 和煙霧 MQ-2 煙霧感測器 https://peppe8o.com/mq-2-with-raspberry-pi-pico-gas-sensor-wiring-and-micropython-code/

Slide 46

Slide 46 text

46 MQ-2 內部結構 https://peppe8o.com/mq-2-with-raspberry-pi-pico-gas-sensor-wiring-and-micropython-code/ (1) SnO2 二氧化錫 (2) 測量電極 (4) 加熱器 (5) AL2O3 陶瓷管 (6) 不銹鋼網 (7) 夾環 (9) 接腳

Slide 47

Slide 47 text

47 MQ-2 作動原理 https://www.figaro.co.jp/en/technicalinfo/principle/mos-type.html

Slide 48

Slide 48 text

48 MQ-2 腳位定義 https://circuitdigest.com/microcontroller-projects/interfacing-mq2-gas-sensor-with-arduino 數位訊號 靈敏度調整

Slide 49

Slide 49 text

49 接線圖 MQ-2 Pico 橘線 (AO) Pin31 (GPIO26) 黑線 (GND) Pin33 (AGND) 紅線 (Vcc) Pin36 (3.3V)

Slide 50

Slide 50 text

50 Pico 腳位定義 https://microdigisoft.com/led-blinking-with-raspberry-pi-pico-gpio-using-micropython/

Slide 51

Slide 51 text

51 from machine import ADC, Pin ● import utime ● ● mq2 = ADC(Pin(26)) ● conversion_factor = 3.3 / (65535) ● ● while True: ● value = mq2.read_u16() * conversion_factor ● print("MQ-2:", value) ● utime.sleep(1) 規格書建議預熱 24Hrs 讀出 0-65535(16-bits) 的數值 將讀出的數值正規化成電壓

Slide 52

Slide 52 text

52 ● MQ-2 感測器偵測到不同氣體會有不同響應特性 根據靈敏度特性將電壓轉換成 ppm https://peppe8o.com/mq-2-with-raspberry-pi-pico-gas-sensor-wiring-and-micropython-code/ 空氣 一氧化碳 煙霧等

Slide 53

Slide 53 text

53 DEMO 12_1-mq2.py

Slide 54

Slide 54 text

54 讀取內建的溫度感測器

Slide 55

Slide 55 text

55 ● Pico 內建的溫度感測器連接到 AINSEL=4 的 ADC ● 內建溫度感測器在 27 攝氏度時 Vbe=0.706V, 斜 率為每度 -1.721mV Pico 內建溫度感測器 https://datasheets.raspberrypi.com/rp2040/rp2040-datasheet.pdf

Slide 56

Slide 56 text

56 讀取溫度方程式 https://datasheets.raspberrypi.com/rp2040/rp2040-datasheet.pdf

Slide 57

Slide 57 text

57 from machine import ADC ● ● sensor_temp = machine.ADC(ADC.CORE_TEMP) ● normalization = 3.3 / (65535) ● ● while True: ● reading = sensor_temp.read_u16() * normalization ● temperature = 27 - (reading - 0.706)/0.001721 ● ● print(temperature) ● utime.sleep(1) 根據 ADC 數值計算溫度方程式 將讀出的數值正規化成電壓 溫度方程式

Slide 58

Slide 58 text

58 DEMO 12_2-temperature.py

Slide 59

Slide 59 text

59 ● 是因為計算溫度數值會根據 VREF, 但 VREF 通常 會低於 3.3V, 因此計算出的溫度會略低於室溫 如果內建溫度感測器略低於室溫

Slide 60

Slide 60 text

60 檔案讀取

Slide 61

Slide 61 text

61 ● Pico 的檔案系統大小為 1.375MB=4096*352 ● LittleFS 目標是使用在 32KB RAM 和 512KB ROM 和 4MB 存儲空間的 32 位元微控制器上 ● 設計特點在於 ● 能從任何寫操作期間從斷電中恢復 ● 避免重複寫入同一個 block 降低 flash 耗損 ● 和因應有限的 RAM 與 ROM 需簡化設計 Pico 的檔案管理系統 LittleFS https://hackmd.io/@RinHizakura/SJ8Sv7kBY https://github.com/littlefs-project/littlefs

Slide 62

Slide 62 text

使用 Thonny 的 REPL 界面互動執行 https://www.youtube.com/watch?v=G06tPDjZ3zM

Slide 63

Slide 63 text

os.listdir() 列出目前的檔案和目錄 點選可展開

Slide 64

Slide 64 text

Object Inspector 顯示完整資訊

Slide 65

Slide 65 text

os.stat("FILE") 顯示檔案統計資訊 0. Type(Directory) 4000HEX = 16384Decimal (File) 8000HEX = 32768Decimal 1. inode 2. Device 3. Number of Hard Links 4. User ID of Owner 5. Group ID of Owner 6. File Size 7. Time of most recent access 8. Time of most recent content modification 9. Time of most recent metadata change

Slide 66

Slide 66 text

os.statvfs("/") 顯示檔案系統資訊 0. File system block size 1. Fragment size 2. Size of the total file system in blocks 3. Number of free blocks 4. Number of free blocks for unprivileged users 5. Number of nodes 6. Number of free inodes 7. Number of free inodes for unprivileged users 8. Mount flags 9. Maximum filename length

Slide 67

Slide 67 text

os.uname() 顯示系統韌體版本

Slide 68

Slide 68 text

68 ● os.listdir() # 列出檔案和目錄 ● os.mkdir() # 建立目錄 ● os.chdir() # 切換目錄 ● os.getcwd() # 列出所在目錄 ● os.rmdir() # 刪除目錄 ● os.remove() # 刪除檔案 ● os.rename() # 更換檔案或目錄名稱 更多 os 函式 https://docs.micropython.org/en/latest/library/os.html

Slide 69

Slide 69 text

69 file = open("test.txt", "w") ● file.write("Hello, File!\n") ● file.close() ● ● file = open("test.txt") ● line=file.readline() ● print(line) ● file.close() ● ● file = open("test.txt", "a") ● file.write("Append, Hello!\n") ● file.close() ● ● file = open("test.txt") ● line=file.readline() ● line=file.readline() ● print(line) ● file.close() 開檔 / 寫檔 / 讀檔 / 關檔 開檔 寫檔 關檔 讀檔

Slide 70

Slide 70 text

70 DEMO 12_3-read-write-file.py

Slide 71

Slide 71 text

● 讀出內建的溫度感測器數值 , 並每秒紀錄一筆 在 /temperature.txt 檔案裡 練習

Slide 72

Slide 72 text

72 實驗 13: 用 1602 LCD 顯示資訊 目的 : 瞭解 I2C 通訊協定

Slide 73

Slide 73 text

73 ● 1602 LCD 表示有 16 欄 2 列 , 共可顯示 32 字元 ● 每個字元由 5x8 像素組成 1602 LCD https://how2electronics.com/interfacing-16x2-lcd-display-with-raspberry-pi-pico/ 16 欄 2 列 每個字元由 5x8 像素組成

Slide 74

Slide 74 text

74 ● 要處理 1602 LCD 顯示 , 每次需要處理 5x8x32 像 素的位置 , 因此通常會透過 HD44780 IC, 幫忙從 MCU 獲取命令和資訊並在 LCD 顯示有意義的資訊 ● HD44780 靠 RS 腳位初始化 ,E 腳位做命令控制 1602 LCD 顯示

Slide 75

Slide 75 text

75 Pico 和 1602 LCD 接線 https://how2electronics.com/interfacing-16x2-lcd-display-with-raspberry-pi-pico/

Slide 76

Slide 76 text

76 透過 I2C 通訊簡化接線 (PCF8574T) I2C LCD Pico 黑線 (GND) Pin3 (GND) 紅線 (Vcc) Pin40 (5V) 藍線 (SDA) Pin1 (GP0) 紫線 (SCL) Pin2 (GP1)

Slide 77

Slide 77 text

77 Pico 腳位定義 https://microdigisoft.com/led-blinking-with-raspberry-pi-pico-gpio-using-micropython/

Slide 78

Slide 78 text

78 ● 全名為 Inter-Integrated Circuit Bus, 是 1982 年由荷蘭飛利浦半導體公司所開發 , 設計目 的是讓 MCU 連接眾多的低速週邊裝置 ● I2C 是同步傳輸界面 , 僅需兩條接線 , 是半雙工 ● I2C 是主從式架構 , 以匯流排型式介接 , 可以有 多個 master 和多個 slave, 個別有位址通訊用 I2C 通訊介紹 https://magicjackting.pixnet.net/blog/post/173061691

Slide 79

Slide 79 text

79 ● I2C 位址空間為 7 bits, 可定址 128 個地址 , 但保留 16 個地址作為系統擴充使用 , 因此理論可 同時使用 112=128-16 個節點 ● I2C Bus 的傳輸都是由 master 端發起 ,slave 只能就 master 送出的命令作出回應 ● 訊號傳輸為 8 bits, 外加 1 bit 的 ACK/NACK I2C 通訊介紹 https://magicjackting.pixnet.net/blog/post/173061691

Slide 80

Slide 80 text

80 ● 優點 : ● 電路簡單 , 僅需兩條線就可以進行同步傳輸 ● 可連接多個週邊裝置 , 方便當 IC 間溝通的橋樑 ● 缺點: ● 速度慢 , ● 不適合長距離的傳輸 ● 不支援不同工作電壓的晶片連接 I2C 優缺點

Slide 81

Slide 81 text

81 常見的 I2C 設備和串接 https://howtomechatronics.com/tutorials/arduino/how-i2c-communication-works-and-how-to-use-it-with-arduino/ MPU6050 ADXL345 Arduino Raspberry Pi

Slide 82

Slide 82 text

82 from machine import Pin, I2C sda = Pin(0) scl = Pin(1) i2c = I2C(0, sda=sda, scl=scl, freq=200000) print(i2c.scan()) 先掃描 I2C Address PCF8574T I2C 頻率使用 200K

Slide 83

Slide 83 text

如果正確連接會回傳 I2C Address 十進位的 39 是十六進位的 27

Slide 84

Slide 84 text

84 DEMO 13_1-i2c_scan.py

Slide 85

Slide 85 text

85 使用 pico_i2c_lcd 控制 PCF8574 I2C LCD https://github.com/T-622/RPI-PICO-I2C-LCD

Slide 86

Slide 86 text

86 from lcd_api import LcdApi ● from pico_i2c_lcd import I2cLcd ● I2C_ADDR = 0x27 I2C_NUM_ROWS = 2 I2C_NUM_COLS = 16 sda = Pin(0) scl = Pin(1) i2c = I2C(0, sda=sda, scl=scl, freq=200000) lcd = I2cLcd(i2c, I2C_ADDR, I2C_NUM_ROWS, I2C_NUM_COLS) ● lcd.move_to(5, 0) lcd.putstr("It Works!") utime.sleep(5) lcd.clear() 使用 pico_i2c_lcd 移動游標 I2C Address (x, y)

Slide 87

Slide 87 text

87 DEMO 13_2-i2c_lcd_move.py

Slide 88

Slide 88 text

88 ● 每個字元由 5x8 像素組成 自定義圖形 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00

Slide 89

Slide 89 text

89 ● https://maxpromer.github.io/LCD-Character-Creator/ 自定義圖形

Slide 90

Slide 90 text

90 自定義圖形 自己畫出喜歡的樣子

Slide 91

Slide 91 text

91 自定義圖形 Blue I2C HEX 記錄下來

Slide 92

Slide 92 text

92 lcd.custom_char(0, bytearray([ 0x0E, ● 0x11, ● 0x11, ● 0x02, ● 0x04, ● 0x04, ● 0x00, ● 0x04])) ● lcd.move_to(0, 0) ● lcd.putstr(chr(0)) ● utime.sleep(10) ● lcd.clear() 將剛剛記錄下來的值貼上去 自定義圖形

Slide 93

Slide 93 text

93 DEMO 13_3-i2c_lcd_custom_char.py

Slide 94

Slide 94 text

94 i2c = I2C(0, sda=sda, scl=scl, freq=200000) ● lcd = I2cLcd(i2c, I2C_ADDR, I2C_NUM_ROWS, I2C_NUM_COLS) ● ● lcd.clear() ● lcd.show_cursor() # Turning cursor on ● lcd.hide_cursor() # Turning cursor off ● lcd.blink_cursor_on() # Turning blink cursor on ● lcd.blink_cursor_off() # Turning blink cursor off ● lcd.backlight_off() # Turning backlight off ● lcd.backlight_on() # Turning backlight on ● lcd.display_off() # Turning display off ● lcd.display_on() # Turning display on 更多控制 LCD 的範例

Slide 95

Slide 95 text

95 DEMO pico_i2c_lcd_test.py

Slide 96

Slide 96 text

96 ● Qwiic 是由美國的 SparkFun 所設計的界面 , 可讓多 種 I2C 設備快速連接 , 特點為 ● 使用 4-pin JST 接頭最為唯一接頭 ● Qwiic 接頭的腳位是固定的 , 避免 SDA 和 SCL 反接 ● 可在開發板上建立多個接頭 , 方便設備串接 ● 可串接多個設備 , 並達到 1 米長度的通訊 ● 但目前 Qwiic 只支援 3.3V 逐漸流行的 Qwiic 界面

Slide 97

Slide 97 text

97 多執行緒

Slide 98

Slide 98 text

98 ● 如何控制紅色黃色共兩個 LED, 紅色 LED 每 1 秒 閃一次 , 黃色 LED 每 0.5 秒閃一次? 問題

Slide 99

Slide 99 text

99 ● 如何控制紅色黃色共兩個 LED, 紅色 LED 每 1 秒 閃一次 , 黃色 LED 每 0.5 秒閃一次? ● 由於 MicroPython 程式是循序執行 , 可以用 ● 1. 計時器 (Timer) 定時執行 ● 2. 多執行緒 (multi-thread) 分別執行 問題

Slide 100

Slide 100 text

100 接線圖 紅 LED Pico 長腳 (RED) Pin20 (GPIO15) 短腳 (BLACK) Pin38 (Ground) 黃 LED Pico 長腳 (YELLOW) Pin19 (GPIO14) 短腳 (BLACK) Pin38 (Ground)

Slide 101

Slide 101 text

101 Pico 腳位定義 https://microdigisoft.com/led-blinking-with-raspberry-pi-pico-gpio-using-micropython/

Slide 102

Slide 102 text

102 Dual Processor vs. Dual Core https://superuser.com/questions/214331/what-is-the-difference-between-multicore-and-multiprocessor

Slide 103

Slide 103 text

103 ● 並行 (Concurrency) 通常指 multitasking ● 如果有很多 CPU 時 , 就可以”同時”執行多個工作 Multitasking vs. Parallel Processing http://www.dabeaz.com/usenix2009/concurrent/

Slide 104

Slide 104 text

104 ● 一個工作 (task) 可以拆成多個 process 執行 ● 但有多個 process 就需要透過 IPC 溝通 ● 常用的 IPC 有 Pipes, FIFOs, shared memory Multi-Processes http://www.dabeaz.com/usenix2009/concurrent/

Slide 105

Slide 105 text

105 ● Thread( 執行緒 ) 是最小的執行單位 , 也稱為 light-weight process ● 一個 process( 行程 ) 最少有一個 thread Process vs. Thread https://sites.google.com/site/sureshdevang/thread-vs-process process

Slide 106

Slide 106 text

106 ● 如果講 "concurrent programming", 大部 分的 programmer 想的是 multi-threading ● 一個行程裡可獨立運行的工作 ● 在行程中共享記憶體 , 檔案 , 或是網路連線等 ● 每個執行緒有獨立的執行流程與資源 (stack, current instruction 等等 ) Threads http://www.dabeaz.com/usenix2009/concurrent/

Slide 107

Slide 107 text

107 ● $ python program.py 慢動作拆解 Threads statement statement 當程式 (program) 被載入以後 , 會順序執行 statement “main thread” http://www.dabeaz.com/usenix2009/concurrent/

Slide 108

Slide 108 text

108 ● $ python program.py create thread(foo) def foo(): 慢動作拆解 Threads statement statement 建立一個執行緒 (thread), 並執行 foo() http://www.dabeaz.com/usenix2009/concurrent/

Slide 109

Slide 109 text

109 ● $ python program.py create thread(foo) def foo(): 慢動作拆解 Threads statement statement statement statement ...... statement statement ...... 同時執行 statement http://www.dabeaz.com/usenix2009/concurrent/

Slide 110

Slide 110 text

110 ● $ python program.py create thread(foo) def foo(): 慢動作拆解 Threads statement statement statement statement statement statement ...... statement statement ...... return or exit 執行緒結束後 , 返回 (return) 或是離開 (exit) http://www.dabeaz.com/usenix2009/concurrent/

Slide 111

Slide 111 text

111 ● $ python program.py create thread(foo) def foo(): 慢動作拆解 Threads statement statement statement statement statement statement ...... statement statement ...... return or exit 執行緒像是一個小工作 (task) 獨立在行程中 http://www.dabeaz.com/usenix2009/concurrent/

Slide 112

Slide 112 text

112 ● 雙核心可同時執行兩個執行緒 , 預設 Core0 執行 所有任務 ,Core1 保持空閒或待機模式 RP2040 雙核心 ,Core0 和 Core1 https://microcontrollerslab.com/dual-core-raspberry-pi-pico-programming-micropython/

Slide 113

Slide 113 text

113 ● 每個核心分別執行自己的程式 , 並各自有獨立的程 式碼和記憶體空間 , 雙核心通訊採 FIFO( 先進先 出 ) 雙核心通訊 https://www.theengineeringprojects.com/2022/05/raspberry-pi-pico-dual-core-programming-with-micropython.html

Slide 114

Slide 114 text

114 ● 1. 主執行緒使用 core0 ● 2. 當執行 start_new_thread(), 由 core1 產 生新的執行緒 , 並將 function 當參數傳入執行 用 _thread 模組產生新的執行緒

Slide 115

Slide 115 text

115 import _thread ● red = Pin(16, Pin.OUT) green = Pin(15, Pin.OUT) def core0_thread(t): for i in range(t): red.toggle() utime.sleep(0.5) def core1_thread(t): for i in range(t): green.toggle() utime.sleep(1) _thread.start_new_thread(core1_thread, (20,)) core0_thread(10) ● 將 function 當作參數傳入 core1 建立執行緒 , 並傳入函式執行

Slide 116

Slide 116 text

116 DEMO 14_1-thread.py

Slide 117

Slide 117 text

117 如何上電就執行 ?