上一章我們學會:
Raspberry Pi
│
├── SDA
└── SCL
│
▼
I²C
│
▼
LCD1602
並且理解:
I²C
=
2 條主要訊號線
+
Device Address
這一章要進入另一個非常重要的 Serial Bus:
SPI
SPI 通常使用:
SCLK
MOSI
MISO
Chip Select
和 I²C 最大的差異之一,是 SPI 通常不是利用 Device Address 選擇裝置,而是使用:
Chip Select
選擇目前要通訊的 Peripheral。
Raspberry Pi 官方目前的標準 SPI0 Header 對應為 GPIO10=MOSI、GPIO9=MISO、GPIO11=SCLK、GPIO8=CE0、GPIO7=CE1。
本章更重要的目的,是解決 Raspberry Pi 與 Arduino 之間一個非常明顯的差異:
Arduino UNO
有 A0~A5 Analog Input
Raspberry Pi 5
40-pin Header
沒有 Arduino 式一般 Analog Input
Raspberry Pi 官方將一般 GPIO Input 描述為讀取 HIGH 3.3V 或 LOW 0V,也就是數位輸入。
因此如果要讀取:
Potentiometer
光敏電阻
Analog Sensor
Joystick Analog Axis
就需要:
ADC
Analog-to-Digital Converter。
本章使用:
MCP3008
將類比電壓轉換成 Raspberry Pi 可以處理的數位資料。
1. SPI 是什麼?
SPI:
Serial Peripheral Interface
是一種同步式 Serial Communication Bus。
典型架構:
Raspberry Pi
SPI Controller
│
├── SCLK
├── MOSI
├── MISO
└── CE / CS
│
▼
SPI Peripheral
Linux Kernel 的 SPI Framework 目前就是以 Linux 作為 Controller、和外部 SPI Peripheral 通訊的架構設計。
2. SPI 有哪些主要 Signal?
標準 SPI 最常見:
SCLK
MOSI
MISO
CS / CE
Raspberry Pi 官方也將 Standard SPI 描述為 SCLK、MOSI、MISO 三條 Serial Signal,再搭配 Chip Select 選擇裝置。
3. SCLK 是什麼?
SCLK:
Serial Clock
由 SPI Controller 產生 Clock。
例如:
Raspberry Pi
│
└── SCLK
│
▼
MCP3008
Clock 用來決定:
何時送資料
何時讀資料
因此 SPI 屬於:
Synchronous Serial Communication
4. MOSI 是什麼?
MOSI 傳統名稱:
Master Out, Slave In
現代也常理解為:
Controller Out, Peripheral In
資料方向:
Raspberry Pi
│
MOSI
│
▼
MCP3008
Raspberry Pi SPI0:
MOSI
=
GPIO10
=
Physical Pin 19
5. MISO 是什麼?
MISO:
Master In, Slave Out
也可以理解:
Controller In, Peripheral Out
方向:
Raspberry Pi
▲
MISO
│
MCP3008
Raspberry Pi SPI0:
MISO
=
GPIO9
=
Physical Pin 21
6. SCLK 使用哪一支 GPIO?
Raspberry Pi SPI0:
SCLK
=
GPIO11
=
Physical Pin 23
7. CE / CS 是什麼?
CE:
Chip Enable
CS:
Chip Select
概念幾乎是在說:
現在要和哪一顆 SPI Peripheral 通訊?
例如:
┌── ADC
CE0 ─────────┤
└── MCP3008
CE1 ─────────── Other SPI Device
Raspberry Pi 官方 SPI 文件也將 CE 定義為 Chip Enable,常稱 Chip Select。
8. Raspberry Pi SPI0 有兩個常見 Chip Select
標準 40-pin Header:
| SPI Function | BCM GPIO | Physical Pin |
|---|---|---|
| MOSI | GPIO10 | Pin 19 |
| MISO | GPIO9 | Pin 21 |
| SCLK | GPIO11 | Pin 23 |
| CE0 | GPIO8 | Pin 24 |
| CE1 | GPIO7 | Pin 26 |
這就是本章 MCP3008 使用的主要 SPI0 Pin。
9. 本章 MCP3008 使用 CE0
我們設定:
MCP3008 CS
│
▼
GPIO8
CE0
Physical Pin 24
如果未來第二顆 SPI Device 使用:
CE1
則可使用:
GPIO7
Physical Pin 26
10. SPI 不像 I²C 使用 Address
上一章 I²C:
Device A
0x27
Device B
0x68
靠 Address 選擇。
SPI:
Device A
← CE0
Device B
← CE1
主要由 Chip Select 決定目前 Peripheral。
因此 SPI 通常需要更多 Wire,但控制方式非常直接。
11. SPI 可以同時傳送與接收資料
標準 SPI 有:
MOSI
+
MISO
兩條獨立 Data Line。
所以在 Clock 進行時,可以:
Controller
→ Peripheral
同時
Peripheral
→ Controller
形成 Full-duplex Transfer。
Linux SPI Framework 支援這種同時 TX/RX 的 Transfer Model。
12. SPI 和 I²C 比較
| 項目 | I²C | SPI |
|---|---|---|
| Clock | SCL | SCLK |
| Controller → Device | SDA 共用 | MOSI |
| Device → Controller | SDA 共用 | MISO |
| Device Selection | Address | Chip Select |
| 主要 Signal 數 | 2 | 通常 4 |
| Full-duplex | 通常不是 | 標準 SPI 可 |
| 多 Device | Address 區分 | 多 CS |
| Pull-up | 需要 | 一般不依賴 I²C 式 Pull-up |
兩者不是誰全面比較好,而是適合不同 Peripheral 與資料傳輸需求。
13. SPI 要先在 Raspberry Pi OS 啟用
目前 Raspberry Pi OS 可以從:
Preferences
→ Control Centre
→ Interfaces
→ SPI
啟用。
也可以:
sudo raspi-config
目前官方選單:
3 Interface Options
→ I4 SPI
→ Yes
啟用後會開啟 SPI Interface,並在開機時載入相關 Kernel 支援。
14. 使用 raspi-config 啟用 SPI
執行:
sudo raspi-config
選:
3 Interface Options
再選:
I4 SPI
回答:
Yes
完成後:
OK
Finish
這是目前 Raspberry Pi 官方提供的標準方式。
15. SPI0 預設是關閉的
Raspberry Pi 官方硬體文件目前指出:
SPI0
=
disabled by default
可透過 raspi-config 開啟,或讓 /boot/firmware/config.txt 中:
dtparam=spi=on
生效。
初學者仍建議:
raspi-config
或:
Control Centre
不要一開始就手動修改 Boot Configuration。
16. 啟用後如何確認?
可以:
ls -l /dev/spidev*
正常的 SPI0 + CE0 / CE1 環境通常可以看到類似:
/dev/spidev0.0
/dev/spidev0.1
Raspberry Pi 官方將 spidev 定義為 Linux User-space 對單一 SPI Chip Select 的介面。
17. spidev0.0 是什麼?
可以拆成:
spidev 0 . 0
│ │
│ └── Device / Chip Select 0
│
└────── SPI Port 0
所以:
/dev/spidev0.0
通常就是:
SPI0
+
CE0
18. spidev0.1 是什麼?
同樣:
/dev/spidev0.1
代表:
SPI0
+
Device 1
+
CE1
GPIO Zero 對 Hardware SPI 也使用 port=0,而 device=0 對應 GPIO8、device=1 對應 GPIO7。
19. Raspberry Pi 為什麼需要 ADC?
Raspberry Pi 一般 GPIO Input 讀取:
LOW
=
0V
HIGH
=
約 3.3V
但如果電位器現在是:
1.37V
Digital GPIO 並不會告訴你:
1.37V
只會根據 Logic Threshold 判斷 HIGH / LOW。
因此需要:
Analog Voltage
│
▼
ADC
│
▼
Digital Number
20. ADC 是什麼?
ADC:
Analog-to-Digital Converter
中文:
類比數位轉換器
功能:
Analog Voltage
↓
Sample
↓
Quantization
↓
Digital Code
例如:
0V
→ 0
1.65V
→ 約中間值
3.3V
→ 接近 Full Scale
21. 本章使用 MCP3008
Microchip MCP3008 是:
10-bit、8-channel、SPI ADC
Microchip 目前仍將 MCP3008 列為量產產品,主要規格為 10-bit、最多 200kSPS、8-channel ADC,使用 SPI Serial Interface。
22. MCP3008 是 SAR ADC
MCP3008 使用:
Successive Approximation Register
也就是 SAR ADC 架構。
Microchip Datasheet 將 MCP3008 描述為具有 Sample-and-Hold 的 10-bit Successive Approximation ADC。
本章不需要深入 SAR Comparator 細節。
先理解:
Analog Voltage
↓
MCP3008
↓
10-bit Number
即可。
23. MCP3008 有幾個 Channel?
MCP3008 提供:
CH0
CH1
CH2
CH3
CH4
CH5
CH6
CH7
總共:
8 Channels
可設定成 8 個 Single-ended Input,或者形成 Pseudo-differential Pair。
本章全部使用:
Single-ended Mode
24. 什麼是 10-bit ADC?
10-bit 表示:
2^10
=
1024
個量化 Code。
Code 範圍:
0
~
1023
Microchip Datasheet 明確指定 MCP3008 Resolution 為 10-bit。
25. 為什麼最大是 1023,不是 1024?
因為從:
0
開始計數。
1024 個不同 Code:
0
1
2
...
1022
1023
總共就是:
1024
個狀態。
26. Arduino 使用者會很熟悉 0~1023
Arduino UNO 的 10-bit ADC 教學中也常看到:
0~1023
MCP3008 也是 10-bit。
因此概念非常接近:
Arduino
analogRead()
對應概念
Raspberry Pi
+
MCP3008
差異在於:
Arduino
ADC 在 MCU 裡
Raspberry Pi
ADC 在外部 MCP3008
27. MCP3008 VREF 是什麼?
MCP3008 有:
VREF
Reference Voltage。
它決定 ADC 的 Full-scale Analog Range。
Microchip Datasheet 指定 Single-ended Input Range 由 VSS 到 VREF。
如果本章:
VREF = 3.3V
那麼類比輸入範圍就設定為約:
0V
~
3.3V
28. 本章 VDD 與 VREF 都使用 3.3V
MCP3008 的正常 Supply Range 為:
2.7V ~ 5.5V
所以使用 Raspberry Pi 3.3V 可以正常落在 MCP3008 工作電壓範圍內。
本章統一:
VDD
=
3.3V
VREF
=
3.3V
這樣有一個非常重要的好處:
MCP3008 SPI Digital Logic 和 Raspberry Pi 同樣位於 3.3V Domain。
29. 為什麼不把 MCP3008 VDD 接 5V?
MCP3008 本身可以 5V 工作。
但是 Datasheet 的 Digital Input HIGH Threshold 與 VDD 有關,規格為:
VIH ≥ 0.7 × VDD
如果:
VDD = 5V
則最低 HIGH Threshold 約為:
3.5V
Raspberry Pi GPIO HIGH 約為:
3.3V
因此 5V VDD 不應被當成 Raspberry Pi SPI Logic 的理想教學接法。
本章直接使用:
3.3V VDD
最簡單。
30. 類比輸入也不能超過 VREF
本章:
VREF = 3.3V
所以 CH0~CH7 的 Single-ended Analog Input 應保持:
0V ~ 3.3V
Microchip Datasheet 將 Single-ended Analog Input Range 定義為 VSS 到 VREF。
因此:
不要把 5V Analog Signal 直接接到 CH0。
31. ADC 不會因為是 Analog 就自動耐 5V
這是一個重要觀念。
Raspberry Pi GPIO
3.3V
MCP3008 VREF
3.3V
並不代表:
MCP3008 CH0
可以隨便輸入 5V
ADC Input 必須遵守:
Input Voltage Range
32. MCP3008 有 16 支 Pin
以常見 16-pin PDIP MCP3008,從上方看 IC 缺口:
┌───────┐
CH0 1 │ │ 16 VDD
CH1 2 │ │ 15 VREF
CH2 3 │ │ 14 AGND
CH3 4 │ │ 13 CLK
CH4 5 │ │ 12 DOUT
CH5 6 │ │ 11 DIN
CH6 7 │ │ 10 CS/SHDN
CH7 8 │ │ 9 DGND
└───────┘
這個 Pinout 來自 Microchip 官方 MCP3008 Datasheet。
33. 一定要先找 IC 缺口
PDIP IC 通常有:
Notch
或:
Pin 1 Mark
用來判斷 Pin Number。
不要看到兩排 8 Pin 就直接猜:
左上
右上
方向。
如果 MCP3008 旋轉 180°,VDD、GND 和 SPI Signal 就會全部錯位。
34. MCP3008 Pin 功能表
| MCP3008 Pin | 名稱 | 用途 |
|---|---|---|
| 1 | CH0 | Analog Input 0 |
| 2 | CH1 | Analog Input 1 |
| 3 | CH2 | Analog Input 2 |
| 4 | CH3 | Analog Input 3 |
| 5 | CH4 | Analog Input 4 |
| 6 | CH5 | Analog Input 5 |
| 7 | CH6 | Analog Input 6 |
| 8 | CH7 | Analog Input 7 |
| 9 | DGND | Digital Ground |
| 10 | CS/SHDN | Chip Select |
| 11 | DIN | SPI Data In |
| 12 | DOUT | SPI Data Out |
| 13 | CLK | SPI Clock |
| 14 | AGND | Analog Ground |
| 15 | VREF | Reference Voltage |
| 16 | VDD | Supply Voltage |
35. DIN 對應 Raspberry Pi 哪一支?
MCP3008:
DIN
是:
Data Into MCP3008
因此要接 Raspberry Pi:
MOSI
也就是:
MCP3008 Pin 11 DIN
│
▼
GPIO10 MOSI
Physical Pin 19
36. DOUT 對應哪一支?
MCP3008:
DOUT
資料從 ADC 輸出。
所以接:
Raspberry Pi MISO
也就是:
MCP3008 Pin 12 DOUT
│
▼
GPIO9 MISO
Physical Pin 21
37. CLK 對應 SCLK
MCP3008 Pin 13 CLK
│
▼
GPIO11 SCLK
Physical Pin 23
38. CS/SHDN 對應 CE0
本章:
MCP3008 Pin 10
CS/SHDN
│
▼
GPIO8
CE0
Physical Pin 24
因此在 Linux:
SPI0
Device 0
對應這顆 MCP3008。
39. VDD
MCP3008 Pin 16
VDD
│
▼
Raspberry Pi 3.3V
Physical Pin 1
MCP3008 支援 2.7~5.5V Supply,本章採 3.3V。
40. VREF
MCP3008 Pin 15
VREF
│
▼
Raspberry Pi 3.3V
因此:
ADC Full Scale
≈ 3.3V
41. AGND 和 DGND 都要接 Ground
本章:
MCP3008 Pin 14
AGND
│
▼
GND
以及:
MCP3008 Pin 9
DGND
│
▼
GND
Microchip Datasheet 明確區分 Analog Ground 與 Digital Ground,並建議良好 PCB 設計中妥善連接兩者以降低數位 Noise 耦合。
Breadboard 教學中兩者都接 Raspberry Pi GND。
42. MCP3008 完整 SPI 接線表
| MCP3008 | Raspberry Pi | BCM | Physical |
|---|---|---|---|
| VDD Pin 16 | 3.3V | — | Pin 1 |
| VREF Pin 15 | 3.3V | — | Pin 1 |
| AGND Pin 14 | GND | — | Pin 6 |
| CLK Pin 13 | SCLK | GPIO11 | Pin 23 |
| DOUT Pin 12 | MISO | GPIO9 | Pin 21 |
| DIN Pin 11 | MOSI | GPIO10 | Pin 19 |
| CS Pin 10 | CE0 | GPIO8 | Pin 24 |
| DGND Pin 9 | GND | — | Pin 6 |
Raspberry Pi SPI0 Mapping 與 MCP3008 Pinout 分別由 Raspberry Pi 官方文件與 Microchip Datasheet 確認。
43. 建議增加 Bypass Capacitor
Microchip Datasheet 建議 MCP3008 應使用 Bypass Capacitor,並儘量靠近 Device Pin;Datasheet 建議值為:
1 µF
所以更完整的實驗電路,可以在:
VDD
│
1 µF
│
GND
附近加入去耦。
初學 Breadboard 雖然常省略,但正式設計最好養成:
Power Decoupling
習慣。
44. 本章 Analog Source 使用可變電阻
使用:
10kΩ Potentiometer
它有三支腳:
Left
Center
Right
其中中心腳通常是:
Wiper
旋轉時 Wiper Voltage 會在兩端電壓之間變化。
45. Potentiometer 接線
將一端:
3.3V
另一端:
GND
中間 Wiper:
MCP3008 CH0
完整:
3.3V
│
│
┌────────────┐
│ 10kΩ POT │
└────────────┘
│
└── Wiper
│
▼
MCP3008 CH0
另一端
│
▼
GND
旋轉後:
CH0
≈
0~3.3V
46. 為什麼 Pot 不可以接 5V?
因為本章:
VREF = 3.3V
CH0 Single-ended Input Range 為 VSS~VREF。
如果電位器兩端使用:
5V
Wiper 就可能輸出:
0~5V
超過本章 ADC Full-scale Range。
所以一定:
Potentiometer 使用 3.3V。
47. 完整硬體架構
Raspberry Pi 5 MCP3008
3.3V Pin 1 ─────────────── VDD Pin 16
│
└──────────────────── VREF Pin 15
GND Pin 6 ──────────────── AGND Pin 14
│
└──────────────────── DGND Pin 9
GPIO11 / Pin 23 ────────── CLK Pin 13
GPIO9 / Pin 21 ◀───────── DOUT Pin 12
GPIO10 / Pin 19 ─────────▶ DIN Pin 11
GPIO8 / Pin 24 ────────── CS Pin 10
3.3V
│
10k Pot
│── Wiper ─────────────── CH0 Pin 1
│
GND
48. 接線前先關機
和前面所有 GPIO 實驗相同:
sudo poweroff
接著:
關機
↓
拔除 USB-C
↓
確認 MCP3008 缺口
↓
接 VDD / VREF
↓
接 AGND / DGND
↓
接 SPI
↓
接 Pot
↓
檢查
↓
再開機
不要在 Raspberry Pi 通電時拿 MCP3008 在 Breadboard 上移位。
49. 最危險的 MCP3008 錯接
要特別避免:
5V
→ CH0
以及:
5V
→ MCP3008 Digital Interface
或:
VDD / GND 接反
所以在第一次 Power On 之前,至少重新確認:
Pin 16 = VDD
Pin 15 = VREF
Pin 14 = AGND
Pin 9 = DGND
50. 先確認 SPI Device Node
開機後:
ls -l /dev/spidev*
如果 SPI0 正常,通常會看到:
/dev/spidev0.0
/dev/spidev0.1
如果:
No such file or directory
先檢查 SPI 是否真的啟用,不要先改 Python。
51. 本章優先使用 GPIO Zero MCP3008
GPIO Zero 目前內建:
MCP3008
支援 MCP3008 的:
8 Channels
10-bit ADC
SPI
官方範例就是:
from gpiozero import MCP3008
pot = MCP3008(0)
print(pot.value)
這是本章最適合初學者的方式。
52. GPIO Zero SPI Mapping
GPIO Zero 對預設 Hardware SPI:
port=0
使用:
SCLK GPIO11
MOSI GPIO10
MISO GPIO9
而:
device=0
→ GPIO8
device=1
→ GPIO7
所以:
MCP3008(channel=0)
預設正好對應本章:
SPI0
+
CE0
53. 建立 Chapter 13 目錄
cd ~
建立:
mkdir -p raspberrypi-course/chapter13
進入:
cd raspberrypi-course/chapter13
54. GPIO Zero 通常已存在 Raspberry Pi OS
前面 GPIO 章節已經使用:
gpiozero
所以先確認:
python3 -c \
"from gpiozero import MCP3008; print('MCP3008 OK')"
如果顯示:
MCP3008 OK
就可以開始。
55. 第一支 MCP3008 Python 程式
建立:
nano mcp3008_value.py
內容:
from gpiozero import MCP3008
from time import sleep
adc = MCP3008(
channel=0
)
try:
while True:
print(
f"Value: "
f"{adc.value:.3f}"
)
sleep(0.2)
except KeyboardInterrupt:
print(
"\nProgram stopped."
)
finally:
adc.close()
56. 執行
python3 mcp3008_value.py
旋轉 Potentiometer。
可能看到:
Value: 0.001
Value: 0.172
Value: 0.406
Value: 0.701
Value: 0.998
GPIO Zero 將 MCP3008 value Normalized 到:
0.0 ~ 1.0
57. value=0 是什麼?
大約代表:
Analog Input
接近 GND
也就是:
CH0 ≈ 0V
58. value=0.5 是什麼?
若:
max_voltage = 3.3V
則:
value ≈ 0.5
大約代表:
1.65V
59. value=1.0 是什麼?
大約代表:
CH0
接近 Full Scale
本章:
Full Scale ≈ 3.3V
GPIO Zero MCP3008 的 voltage 會依 max_voltage 輸出 0~max_voltage,而預設 max_voltage 為 3.3V。
60. 直接讀 Voltage
建立:
nano mcp3008_voltage.py
內容:
from gpiozero import MCP3008
from time import sleep
adc = MCP3008(
channel=0,
max_voltage=3.3
)
try:
while True:
print(
f"Voltage: "
f"{adc.voltage:.3f} V"
)
sleep(0.2)
except KeyboardInterrupt:
print(
"\nProgram stopped."
)
finally:
adc.close()
GPIO Zero 官方 API 的 voltage Property 會將目前 Reading 轉成 0~max_voltage。
61. 讀取 Raw ADC Value
GPIO Zero 還提供:
adc.raw_value
代表 ADC 直接讀出的 Raw Code。
MCP3008 是 10-bit ADC,因此 Single-ended Raw Code 為:
0~1023
62. Raw Value 程式
from gpiozero import MCP3008
from time import sleep
adc = MCP3008(
channel=0
)
try:
while True:
print(
f"Raw: "
f"{adc.raw_value}"
)
sleep(0.2)
except KeyboardInterrupt:
print(
"\nProgram stopped."
)
finally:
adc.close()
旋轉可變電阻:
Raw: 12
Raw: 268
Raw: 507
Raw: 812
Raw: 1020
63. 一次顯示 Raw、Value、Voltage
最適合 Debug:
from gpiozero import MCP3008
from time import sleep
adc = MCP3008(
channel=0,
max_voltage=3.3
)
try:
while True:
print(
f"Raw={adc.raw_value:4d} "
f"Value={adc.value:.3f} "
f"Voltage={adc.voltage:.3f} V"
)
sleep(0.2)
except KeyboardInterrupt:
print(
"\nProgram stopped."
)
finally:
adc.close()
可能:
Raw= 510 Value=0.499 Voltage=1.646 V
64. 10-bit 每一個 LSB 大約是多少?
如果:
VREF = 3.3V
理想 10-bit ADC 有:
1024
個量化 Step。
因此每個 LSB 約:
3.3V / 1024
≈
0.00322V
也就是:
約 3.22mV / LSB
這只是理想量化解析度,不代表實際整個系統一定具有 3.22mV 的絕對量測精度;Reference、Noise、ADC Error、Source Impedance 與 Wiring 都會影響實際結果。Microchip 對 MCP3008 規格另外定義 INL、DNL 與 Gain/Offset Error。
65. Resolution 不等於 Accuracy
這是 ADC 非常重要的觀念。
10-bit
代表:
Quantization Resolution
不代表:
實際電壓一定準到 1/1024。
實際 Accuracy 會受到:
VREF
Noise
INL
DNL
Offset
Gain Error
Wiring
Power Supply
影響。
MCP3008 Datasheet 對 INL / DNL 提供 ±1 LSB 等級的規格。
66. 為什麼 Value 可能不會剛好到 0 或 1?
實際 Potentiometer、Reference、Contact Resistance、Noise 與 ADC 誤差都可能讓結果是:
0.002
到:
0.997
而不是理想:
0.000
1.000
這很正常。
67. 類比值為什麼一直跳?
例如:
512
513
510
514
511
這種小幅變化通常與:
Analog Noise
ADC Quantization
Power Noise
Breadboard
Pot Contact
有關。
不要把每 1 LSB 的變化都當成故障。
68. 可以使用 Moving Average
假設最近五次:
510
513
511
515
512
取平均:
512.2
可以讓顯示值更平滑。
69. 第一個 Moving Average 程式
from collections import deque
from statistics import mean
from time import sleep
from gpiozero import MCP3008
adc = MCP3008(
channel=0
)
samples = deque(
maxlen=10
)
try:
while True:
samples.append(
adc.raw_value
)
average = mean(
samples
)
print(
f"Raw={adc.raw_value:4d} "
f"Average={average:7.2f}"
)
sleep(0.05)
except KeyboardInterrupt:
print(
"\nProgram stopped."
)
finally:
adc.close()
70. Average Window 越大越好嗎?
不是。
例如:
10 Samples
比:
2 Samples
平滑。
但如果使用:
1000 Samples
系統反應就可能變慢。
因此:
Smoothness
和
Response Time
需要取得平衡。
71. GPIO Zero 本身也有 Filtering Tool
GPIO Zero 提供:
gpiozero.tools.smoothed
可對 ADC Value 做移動平均,官方文件也直接用 MCP3008 作為平滑 Analog Data 的 Example。
所以較大型 GPIO Zero Project 可以使用 Library 現成的 Data Pipeline。
72. 讀取第二個 Channel
假設另一顆 Sensor 接:
CH1
建立:
adc0 = MCP3008(
channel=0
)
adc1 = MCP3008(
channel=1
)
MCP3008 GPIO Zero API 支援 Channel:
0~7
73. 一次讀 8 Channels
例如:
from gpiozero import MCP3008
from time import sleep
channels = [
MCP3008(channel=i)
for i in range(8)
]
try:
while True:
values = [
adc.raw_value
for adc in channels
]
print(
values
)
sleep(0.5)
except KeyboardInterrupt:
print(
"\nProgram stopped."
)
finally:
for adc in channels:
adc.close()
輸出可能:
[512, 0, 1023, 217, 681, 0, 0, 0]
74. 8 Channel 可以拿來做什麼?
例如:
CH0
→ Potentiometer
CH1
→ Light Sensor
CH2
→ Joystick X
CH3
→ Joystick Y
CH4
→ Analog Temperature Sensor
MCP3008 的 8 個 Single-ended Channel 很適合 Raspberry Pi 小型 Data Acquisition Project。Microchip 將其應用包含 Sensor Interface 與 Data Acquisition。
75. MCP3008 的 Reference 可以不是 3.3V 嗎?
技術上 VREF 可以依 Datasheet 條件設計;Reference Input 最大不能超過 VDD,而 Datasheet 列出的正常 Reference Range與性能需依實際條件評估。
但是本系列初學統一:
VDD = 3.3V
VREF = 3.3V
避免增加:
- External Reference
- Level Compatibility
- Full-scale Calculation
等額外變數。
76. 不要把 VREF 當 Power Output
VREF 是:
Reference Input
不是:
給 Sensor 大電流供電的 Power Supply。
如果 Sensor 需要供電,應從合適的:
3.3V Rail
取得。
77. GPIO Zero 直接控制 PWMLED
第 10 章學過:
PWMLED
現在可以把:
Potentiometer
↓
MCP3008
↓
Normalized Value
直接控制:
LED Brightness
這是一個非常漂亮的:
Analog Input → PWM Output
範例。
78. LED 接線
LED 使用:
GPIO17
=
Physical Pin 11
接:
GPIO17
│
330Ω
│
LED
│
GND
MCP3008 則仍使用 SPI0。
79. 手動控制 LED Brightness
from gpiozero import MCP3008
from gpiozero import PWMLED
from time import sleep
adc = MCP3008(
channel=0
)
led = PWMLED(
17
)
try:
while True:
led.value = adc.value
print(
f"ADC={adc.value:.3f} "
f"LED={led.value:.3f}"
)
sleep(0.02)
except KeyboardInterrupt:
print(
"\nProgram stopped."
)
finally:
led.off()
adc.close()
led.close()
旋轉 Pot:
低電壓
↓
LED 暗
高電壓
↓
LED 亮
80. GPIO Zero 還可以更簡單
GPIO Zero 官方 MCP3008 文件直接示範:
from gpiozero import MCP3008
from gpiozero import PWMLED
pot = MCP3008(
channel=0
)
led = PWMLED(
17
)
led.source = pot
這會把:
MCP3008 Value
直接 Feed 給:
PWMLED
81. 這叫 Declarative Device Connection
傳統寫法:
Read ADC
↓
Save Variable
↓
Write PWMLED
GPIO Zero source:
ADC
────────▶ LED
直接描述:
LED 的輸出來源就是 Potentiometer。
這種資料流設計在 GPIO Zero 中非常方便。
82. Analog Input + PWM Output 架構
現在我們已經做到:
Human
│
▼
Potentiometer
│
▼
Analog Voltage
│
▼
MCP3008
│
▼
SPI
│
▼
Raspberry Pi
│
▼
Python
│
▼
PWMLED
│
▼
Brightness
這就是完整的:
Analog Control Interface
83. 也可以直接使用 Python spidev
GPIO Zero 很方便,但學習 SPI 時,也值得知道較底層的:
spidev
Linux Kernel 提供 spidev User-space SPI Interface,而 Raspberry Pi 官方文件也列出 Python spidev 作為 SPI User-space 使用方式。
84. 安裝 Python spidev
Debian Trixie 提供:
python3-spidev
Package,作為 Linux spidev 的 Python Binding。
可以:
sudo apt update
sudo apt install -y \
python3-spidev
85. 如果在 venv 使用 apt spidev
可以建立:
python3 -m venv \
.venv \
--system-site-packages
再:
source .venv/bin/activate
即可讓 venv 使用部分系統安裝 Package。
86. spidev 第一個 MCP3008 Reader
建立:
nano mcp3008_spidev.py
內容:
import time
import spidev
SPI_BUS = 0
SPI_DEVICE = 0
spi = spidev.SpiDev()
spi.open(
SPI_BUS,
SPI_DEVICE
)
spi.max_speed_hz = 1_000_000
spi.mode = 0
def read_adc(channel):
if not 0 <= channel <= 7:
raise ValueError(
"channel must be 0-7"
)
command = [
1,
(8 + channel) << 4,
0
]
response = spi.xfer2(
command
)
raw = (
((response[1] & 0x03) << 8)
| response[2]
)
return raw
try:
while True:
raw = read_adc(0)
voltage = (
raw
* 3.3
/ 1023
)
print(
f"Raw={raw:4d} "
f"Voltage≈{voltage:.3f} V"
)
time.sleep(0.2)
except KeyboardInterrupt:
print(
"\nProgram stopped."
)
finally:
spi.close()
Microchip MCP3008 的 SPI Protocol 會傳送 Start Bit、Single/Differential 選擇與 Channel Bits,再讀回 10-bit Conversion Result;GPIO Zero 現行 Source 也依這個 3-byte MCP3008 Transaction 結構實作。
87. spi.open(0, 0)
spi.open(
0,
0
)
代表:
SPI Bus 0
+
Device 0
也就是本章:
CE0
GPIO8
對應:
/dev/spidev0.0
88. 如果 MCP3008 接 CE1
硬體 CS 改接:
GPIO7
Physical Pin 26
程式:
spi.open(
0,
1
)
GPIO Zero 則可以:
adc = MCP3008(
channel=0,
device=1
)
GPIO Zero 官方 SPI API 明確對應 device 0→GPIO8、device 1→GPIO7。
89. SPI Mode
MCP3008 Datasheet 支援:
SPI Mode 0,0
和
Mode 1,1
本章使用:
spi.mode = 0
也就是常見:
CPOL = 0
CPHA = 0
模式。
90. 為什麼設定 1 MHz?
本章使用:
spi.max_speed_hz = 1_000_000
目的不是追求最大速度,而是為 Breadboard 教學提供保守、容易工作的 Clock。
MCP3008 最大可用 Clock / Sample Rate 會隨 VDD 與條件變化,Datasheet 在不同 Supply 下提供不同 Throughput 與 SCLK 規格。
所以不要看到:
SPI 很快
就直接:
50 MHz
硬跑 MCP3008。
91. GPIO Zero 和 spidev 哪個比較好?
對本系列:
GPIO Zero
適合:
快速實作
初學
MCP3008
PWMLED Integration
spidev
適合:
理解 SPI Transaction
自己處理 Protocol
特殊 SPI Device
Register-level Driver
因此:
先會 GPIO Zero,再理解 spidev。
92. GPIO Zero 不是把 SPI 原理藏掉就沒有 SPI
例如:
MCP3008(0)
背後仍然需要:
CS
SCLK
MOSI
MISO
GPIO Zero 只是替我們封裝:
Start Bit
Channel Selection
SPI Transfer
10-bit Result Extraction
而已。
GPIO Zero Source 目前就可以看到 MCP3008 3-byte Transfer 的實作。
93. ADC Raw Value 如何估算 Voltage?
若:
VREF ≈ 3.3V
並希望用 Raw Endpoint 做簡單顯示,可以寫:
voltage = (
raw
* 3.3
/ 1023
)
這會把:
0
→ 0V
1023
→ 3.3V
做端點式估算。
如果使用 GPIO Zero,更簡單:
adc.voltage
因為 GPIO Zero 已提供 0~max_voltage 的 Voltage Property。
94. 量測電壓還是應該用 Multimeter 驗證
例如 Pot Wiper:
1.65V
先用 Multimeter 量:
Wiper ↔ GND
再比較:
MCP3008
結果。
如果:
Multimeter = 1.65V
ADC = 0.1V
就明顯有:
Wiring
VREF
Ground
SPI
Channel
問題。
95. ADC 永遠顯示 0
優先檢查:
Pot Wiper
→ CH0?
Pot 兩端
→ 3.3V / GND?
VREF
→ 3.3V?
VDD
→ 3.3V?
AGND / DGND
→ GND?
如果 SPI 完全沒有工作,也可能讀到不合理或固定結果。
96. ADC 永遠顯示 1023
可能:
CH0 一直接近 VREF
或:
Pot 接錯
也可能 Analog Input Floating 且被其他路徑拉高。
先使用 Multimeter 量 CH0。
97. ADC 值只有一半範圍
例如 Pot 完整旋轉卻只能:
0~500
先檢查:
Pot Supply Voltage
VREF
Wiper Voltage
假設:
VREF = 3.3V
但 Pot 最大只到:
1.65V
那 10-bit ADC 讀到約 Full Scale 一半是合理的。
98. ADC 值劇烈亂跳
檢查:
AGND
DGND
VREF
VDD
Pot Wiper
Breadboard Connection
Power Noise
Wire Length
Microchip 也建議使用靠近 Device 的 Bypass Capacitor,並減少 Digital Clock 等高頻 Signal 對 Analog Circuit 的 Noise Coupling。
99. Analog Ground 和 Digital Ground 為什麼分開?
ADC 一邊處理:
Analog Signal
另一邊處理:
Fast Digital Clock
Digital Signal 容易帶來 Noise。
因此 MCP3008 提供:
AGND
DGND
協助 PCB Layout 分離 Analog 與 Digital Return Current。
在本章 Breadboard 中:
兩個都接共同 GND。
正式 PCB 則依 Datasheet 的 Ground Layout Guidance 設計。
100. SPI Device Not Found 怎麼辦?
SPI 不像 I²C:
i2cdetect
那樣有常用 Address Scanner。
SPI Device 通常不會自動回答:
我是誰。
所以 Debug 更依賴:
Device Node
Wiring
CS
Protocol
Known Register / Known Response
101. Raspberry Pi 官方提供 SPI Loopback 測試
官方 SPI Troubleshooting 建議可將:
MOSI
和:
MISO
暫時相接做 Loopback Test,確認送出的資料是否能讀回。這個方法不測試 CE0 / CE1,但可以協助確認 SPI Data/Clock Path。
這屬於進階 Debug,測試時不要同時接 MCP3008。
102. 不要同時讓兩個程式搶 spidev0.0
例如:
Program A
使用 MCP3008
Program B
也直接操作 /dev/spidev0.0
就可能造成:
Resource Conflict
所以一個實際 SPI Peripheral 應由明確的 Application / Driver 管理。
103. 不要用 sudo 當第一個解法
如果 Python:
Permission denied
不要立刻:
sudo python3 program.py
當永久方案。
先檢查:
ls -l /dev/spidev0.0
以及:
groups
找出真正 Device Permission 問題。
104. SPI 可以接很多 Device 嗎?
可以共用:
SCLK
MOSI
MISO
然後每顆 Device 使用不同:
CS
例如:
┌─ MCP3008
CE0 ──────────┘
┌─ Display
CE1 ──────────┘
如果需要更多 Device,可以透過額外 GPIO 作 Software Chip Select;Raspberry Pi 官方 Linux SPI 文件也支援使用 GPIO 作為 CS。
105. 多 Device 的 MISO 要注意
未被選中的 Peripheral 應該正確 Release MISO。
如果某個設計在未選中時仍強制驅動 MISO,就可能與其他 Device 發生 Bus Contention。
所以多 Device SPI Project 必須:
查 Datasheet
不能只把所有 MISO 任意並在一起。
106. SPI Wire 可以拉很長嗎?
和 I²C 一樣,不應把 Breadboard SPI 當成:
長距離 Field Bus。
高 Clock Speed 對:
Signal Integrity
Rise/Fall Time
Crosstalk
Ground
Wire Length
更敏感。
SPI 越高速,Breadboard 與長 Dupont Wire 越容易出問題。
107. 高速 SPI Debug 第一招是降速
如果:
低速正常
高速錯誤
通常應優先懷疑:
Signal Integrity
Wiring
Device Timing
而不是 Python Random Bug。
所以 spidev 測試時可以先從:
500kHz
1MHz
這種保守值開始。
108. MCP3008 最高 200kSPS 不等於 Python 一定可以穩定讀 200kSPS
Microchip 說的是 ADC Device 在指定電氣與 Clock 條件下的最大 Conversion Rate,例如 5V 條件最高可到 200kSPS。
但完整 Raspberry Pi Python Application 還包含:
Linux
Python
SPI Driver
Function Call
Scheduling
Printing
Data Processing
所以:
Datasheet 200kSPS
不等於:
print() while loop
可以得到 200000 lines/s。
109. 如果需要高速 Data Acquisition
應該重新評估:
Sampling Rate
Timing Determinism
Buffering
DMA
C / C++
Kernel Driver
Dedicated ADC Hardware
Microcontroller
而不是只把 Python sleep() 刪掉。
110. 本章的目標不是高速示波器
MCP3008 本章的定位是:
理解 ADC
理解 SPI
讀 Potentiometer
讀慢速 Analog Sensor
建立 Data Acquisition 基礎
不是製作:
高速 Oscilloscope。
這樣學習路徑比較正確。
111. MCP3008 Differential Mode
MCP3008 除了:
8 個 Single-ended
也可使用:
4 組 Pseudo-differential Pair
Microchip Datasheet 有完整 Channel Selection Table。
GPIO Zero 也提供:
MCP3008(
channel=0,
differential=True
)
相關能力。
不過本章基礎全部維持:
differential=False
112. 為什麼初學先用 Single-ended?
因為比較直觀:
CH0 Voltage
相對
GND
也就是:
0~3.3V
而 Pseudo-differential 要理解:
IN+
IN-
Common Mode
Differential Range
屬於更進階 Analog Measurement。
113. MCP3008 Data Logging
現在每次已經可以取得:
Timestamp
Raw
Value
Voltage
例如:
2026-08-17 23:20:01
Raw=512
Voltage=1.652V
後面第 19 章就可以直接:
ADC
↓
SQLite
↓
Historical Data
114. Analog Sensor 也能加入 MQTT
後面:
MCP3008
↓
Python
↓
MQTT
↓
Network
↓
Remote Dashboard
因此本章其實已經為 IoT Analog Sensor 做好基礎。
115. 本章 SPI Pin 快速對照
| SPI0 | BCM | Physical | MCP3008 |
|---|---|---|---|
| MOSI | GPIO10 | Pin 19 | DIN Pin 11 |
| MISO | GPIO9 | Pin 21 | DOUT Pin 12 |
| SCLK | GPIO11 | Pin 23 | CLK Pin 13 |
| CE0 | GPIO8 | Pin 24 | CS Pin 10 |
| CE1 | GPIO7 | Pin 26 | 第二裝置可用 |
116. MCP3008 Power 快速對照
| MCP3008 | Raspberry Pi |
|---|---|
| VDD Pin 16 | 3.3V |
| VREF Pin 15 | 3.3V |
| AGND Pin 14 | GND |
| DGND Pin 9 | GND |
本章把 VDD 與 VREF 都設為 3.3V,既符合 MCP3008 2.7~5.5V 工作範圍,也讓 SPI Digital Interface 和 Pi 3.3V Logic 保持一致。
117. GPIO Zero MCP3008 API 速查
| API | 功能 |
|---|---|
| MCP3008(channel=0) | 建立 CH0 ADC |
| channel | 目前 Channel |
| value | Normalized 0~1 |
| raw_value | Raw ADC Code |
| voltage | 估算 Voltage |
| max_voltage | Full-scale Voltage 設定 |
| bits | ADC Resolution |
| close() | 釋放 SPI Resource |
目前 GPIO Zero MCP3008 為 10-bit、8-channel Device,並提供 value、raw_value 與 voltage Property。
118. SPI Linux 指令速查
sudo raspi-config
用途:
啟用 SPI
目前選單:
3 Interface Options
→ I4 SPI
查看 Device:
ls -l /dev/spidev*
安裝 Python spidev:
sudo apt install \
python3-spidev
Debian Trixie 目前提供 python3-spidev。
119. GPIO Zero 和 spidev 快速比較
| 項目 | GPIO Zero MCP3008 | spidev |
|---|---|---|
| 難度 | 低 | 中 |
| Channel | 自動處理 | 自己組 Command |
| Raw ADC | raw_value | 自己解析 |
| Voltage | voltage | 自己計算 |
| SPI Protocol | Library 封裝 | 自己處理 |
| 適合 | 初學、應用 | Driver、Protocol 學習 |
120. 本章故障排除總流程
遇到 MCP3008 無法正常讀值時,建議依序檢查:
SPI Enabled?
↓
/dev/spidev0.0 ?
↓
MCP3008 Direction?
↓
VDD = 3.3V?
↓
VREF = 3.3V?
↓
AGND / DGND?
↓
CLK = GPIO11?
↓
DIN = GPIO10?
↓
DOUT = GPIO9?
↓
CS = GPIO8?
↓
Pot Wiper = CH0?
↓
CH0 Voltage 0~3.3V?
↓
Python Library?
這個順序比直接一直修改 Python 有效得多。
121. 本章重點整理
完成本章後,應掌握以下核心觀念:
- SPI 是同步式 Serial Communication Bus。
- Raspberry Pi 標準 SPI0 使用 MOSI、MISO、SCLK 與 CE。
- SPI0 MOSI 是 GPIO10 / Pin 19。
- SPI0 MISO 是 GPIO9 / Pin 21。
- SPI0 SCLK 是 GPIO11 / Pin 23。
- SPI0 CE0 是 GPIO8 / Pin 24。
- SPI0 CE1 是 GPIO7 / Pin 26。
- SPI 通常透過 Chip Select 選擇 Peripheral。
- MOSI 代表 Controller → Peripheral Data。
- MISO 代表 Peripheral → Controller Data。
- 標準 SPI 可以同時 TX / RX。
- Raspberry Pi OS 目前由 3 Interface Options > I4 SPI 啟用 SPI。
- SPI0 預設關閉。
- dtparam=spi=on 可以啟用 SPI0。
- /dev/spidev0.0 對應 SPI0 Device 0。
- /dev/spidev0.1 對應 SPI0 Device 1。
- Raspberry Pi 一般 GPIO 沒有 Arduino 式類比讀值功能,GPIO Input 基本上讀 HIGH / LOW。
- ADC 用來將 Analog Voltage 轉成 Digital Code。
- MCP3008 是 10-bit ADC。
- MCP3008 有 8 個 Analog Channel。
- MCP3008 使用 SPI Interface。
- MCP3008 Supply Range 為 2.7~5.5V。
- 本章 MCP3008 VDD 使用 3.3V。
- 本章 VREF 使用 3.3V。
- CH0~CH7 Single-ended Input 應維持 VSS~VREF。
- 本章 Analog Input 因此限制為約 0~3.3V。
- 不可把 5V Analog Signal 直接接 CH0。
- MCP3008 10-bit 有 1024 個 Code。
- Raw Range 為 0~1023。
- VREF=3.3V 時理想 LSB 約 3.22mV。
- Resolution 不等於實際 Accuracy。
- MCP3008 有 INL、DNL、Offset 與 Gain Error 等實際誤差。
- MCP3008 Pin 1~8 是 CH0~CH7。
- Pin 9 是 DGND。
- Pin 10 是 CS/SHDN。
- Pin 11 是 DIN。
- Pin 12 是 DOUT。
- Pin 13 是 CLK。
- Pin 14 是 AGND。
- Pin 15 是 VREF。
- Pin 16 是 VDD。
- DIN 接 Raspberry Pi MOSI。
- DOUT 接 Raspberry Pi MISO。
- CLK 接 SCLK。
- CS 接 CE0。
- AGND / DGND 都需正確 Ground。
- Microchip 建議 MCP3008 加入靠近 IC 的 Bypass Capacitor。
- 本章使用 10kΩ Potentiometer。
- Pot 兩端接 3.3V / GND。
- Wiper 接 MCP3008 CH0。
- GPIO Zero 目前直接支援 MCP3008。
- MCP3008(channel=0) 讀 CH0。
- value 約為 0~1。
- raw_value 可讀取 Raw ADC Result。
- voltage 可回傳 0~max_voltage 的電壓估算。
- GPIO Zero 預設 MCP3008 max_voltage=3.3。
- Channel 可選 0~7。
- GPIO Zero device=0 對應 CE0。
- GPIO Zero device=1 對應 CE1。
- Moving Average 可以降低顯示抖動。
- Filter Window 越大不代表越好。
- GPIO Zero 也提供 Analog Value Smoothing Tool。
- MCP3008 可以同時建立多個 Channel Object。
- Potentiometer 可以控制 PWMLED Brightness。
- GPIO Zero 可直接 led.source = pot。
- Linux spidev 提供 SPI User-space Interface。
- Raspberry Pi 官方支援從 Python 使用 spidev。
- Debian Trixie 提供 python3-spidev。
- MCP3008 支援 SPI Mode 0,0 與 1,1。
- 本章 spidev 使用 Mode 0。
- SPI Clock 不應盲目追求最大值。
- 高速 SPI 對 Wire、Ground 與 Signal Integrity 更敏感。
- MCP3008 Datasheet 最高 Conversion Rate 可達 200kSPS,但依 VDD 等條件而定。
- Python Application Rate 不等於 ADC Datasheet Maximum Rate。
- SPI 不像 I²C 一樣有普遍可用的 Address Scanner。
- SPI Debug 依靠 Wiring、Chip Select 與已知 Protocol Response。
- Raspberry Pi 官方提供 MOSI/MISO Loopback 的 SPI Troubleshooting 方法。
- Analog Noise 不代表一定硬體故障。
- Multimeter 是 ADC Debug 非常重要的工具。
- 本章已讓 Raspberry Pi 第一次具備真正一般用途的 Analog Input 能力。
FAQ:Raspberry Pi SPI / MCP3008 常見問題
Q1:Raspberry Pi 5 有 Analog Input 嗎?
標準 Raspberry Pi 40-pin Header 沒有 Arduino UNO A0~A5 這種一般類比讀取介面;官方 GPIO Input 的基本模式是讀 HIGH 3.3V 或 LOW 0V。
因此讀 Analog Sensor 通常需要外部:
ADC
例如 MCP3008。
Q2:MCP3008 是什麼?
MCP3008 是 Microchip 生產的:
10-bit
8-channel
SPI ADC
目前仍為量產產品。
Q3:MCP3008 的 ADC 範圍是多少?
本章設定:
VREF = 3.3V
因此 Single-ended Input 使用約:
0~3.3V
MCP3008 Datasheet 規定 Single-ended Input Range 為 VSS 到 VREF。
Q4:MCP3008 可以輸入 5V 嗎?
如果本章 VREF 為 3.3V:
不可以直接輸入 5V。
Analog Input 不應超出 VREF 定義的範圍。
Q5:MCP3008 為什麼讀值是 0~1023?
因為 MCP3008 是:
10-bit ADC
10-bit 有:
2^10 = 1024
種 Code,因此從:
0~1023。
Q6:SPI MOSI 是哪一支 Raspberry Pi Pin?
GPIO10
=
Physical Pin 19
Q7:SPI MISO 是哪一支?
GPIO9
=
Physical Pin 21
Q8:SPI SCLK 是哪一支?
GPIO11
=
Physical Pin 23
Q9:CE0 是哪一支?
GPIO8
=
Physical Pin 24
Q10:如何開啟 Raspberry Pi SPI?
sudo raspi-config
目前選:
3 Interface Options
→ I4 SPI
→ Yes
Q11:如何確認 SPI 已啟用?
執行:
ls -l /dev/spidev*
通常 SPI0 會有:
/dev/spidev0.0
/dev/spidev0.1
spidev 是 Linux 提供給 User-space SPI Application 的介面。
Q12:GPIO Zero 如何讀 MCP3008?
最簡單:
from gpiozero import MCP3008
adc = MCP3008(
channel=0
)
print(
adc.value
)
這就是 GPIO Zero 官方 MCP3008 基本用法。
Q13:如何取得 0~1023?
使用:
adc.raw_value
raw_value 會回傳 ADC 的原始讀值。
Q14:如何直接取得 Voltage?
adc.voltage
GPIO Zero 會依 max_voltage 提供電壓值,本章使用:
max_voltage=3.3
Q15:MCP3008 可以讀幾個 Sensor?
MCP3008 有:
8 Channels
也就是 CH0~CH7。
Q16:為什麼 MCP3008 數值一直跳?
小幅跳動可能來自:
Analog Noise
Power Noise
ADC Quantization
Pot Contact
Breadboard
可以採用:
Moving Average
改善顯示穩定度。
Q17:可以用 MCP3008 控制 LED 亮度嗎?
可以。
例如:
from gpiozero import MCP3008
from gpiozero import PWMLED
pot = MCP3008(0)
led = PWMLED(17)
led.source = pot
這是 GPIO Zero 官方直接示範的 Analog Input → PWMLED 用法。
Q18:GPIO Zero 還是 spidev 比較適合?
初學 MCP3008:
GPIO Zero
比較簡單。
如果要理解:
SPI Command
Register
Bit Protocol
則應學:
spidev
兩者都值得掌握。
Q19:SPI 和 I²C 哪個比較快?
SPI 一般能提供較高的資料吞吐能力,但實際速度取決於 Controller、Peripheral、Clock、Wiring 與 Driver。
選擇不應只看:
誰比較快。
還要看:
Device 數量
Pin 數
Address
Chip Select
Power
Protocol
Q20:下一步 MCP3008 可以接什麼?
可以逐步接:
Potentiometer
Photoresistor Circuit
Joystick
Analog Temperature Sensor
Force Sensor
Gas Sensor Analog Output
但每一種 Sensor 都必須先確認:
輸出電壓不超過 MCP3008 VREF。
結語
完成第 13 章後,我們的 Raspberry Pi 硬體能力已經從:
Digital Input
+
Digital Output
+
PWM
+
Digital Sensor
+
I²C
進一步增加:
Analog Input
雖然 Raspberry Pi 本身沒有 Arduino UNO 式的 A0~A5,
但透過:
Analog Signal
↓
MCP3008
↓
SPI
↓
Raspberry Pi
↓
Python
現在已經可以讀取:
0~3.3V
的類比訊號,轉成:
0~1023
的 10-bit Digital Code。
而且我們不是只讀數字。
最後還完成:
Potentiometer
↓
Analog Voltage
↓
MCP3008
↓
SPI
↓
Python
↓
PWMLED
↓
LED Brightness
這代表 Raspberry Pi 已經第一次具備真正的:
類比人機控制能力。
現在我們已學會兩種非常重要的 Peripheral Bus:
I²C
+
SPI
下一章則要進入第三種極重要通訊介面:
UART Serial
不同於 I²C 與 SPI,
UART 不需要:
Clock Line
而是透過:
TX
RX
Baud Rate
進行非同步 Serial Communication。
更重要的是,下一章我們會真正讓兩個不同平台互相合作:
Raspberry Pi 5 ↔ Arduino UNO R3
Raspberry Pi 負責:
Linux
Network
Python
Database
Web
MQTT
Arduino 負責:
Real-time GPIO
Sensor Timing
Motor
Low-level Control
正式建立多處理器控制架構。
下一章
第 14 章 Raspberry Pi UART Serial 通訊:與 Arduino 進行序列資料交換
下一章將完整介紹:
UART
TX
RX
Baud Rate
Start Bit
Data Bit
Stop Bit
Parity
Asynchronous Serial
GPIO14
GPIO15
Physical Pin 8
Physical Pin 10
Raspberry Pi 5 UART 架構
Dedicated Debug UART
Primary UART
/dev/serial0
/dev/ttyAMA*
raspi-config
Serial Port
Serial Console
3.3V Logic
Arduino UNO 5V Logic
Level Shifter
TX → RX
RX ← TX
Common Ground
Python pyserial
serial.Serial()
Arduino Serial.begin()
Raspberry Pi → Arduino
Arduino → Raspberry Pi
文字命令
LED ON / OFF
Sensor Data
CSV Protocol
JSON Protocol
Timeout
Buffer
Newline
Serial Debug
完成第 14 章後,就可以建立:
Raspberry Pi
Linux / Python
│
│ UART
▼
Arduino UNO
Real-time Control
│
▼
Sensor / Motor / Relay
也就是把 Raspberry Pi 與 Arduino 從兩個獨立平台,真正整合成一套完整控制系統。