Arduino程式除錯
Revised on September 17, 2019
 認識bug
 解讀語法錯誤訊息
 利用Serial Monitor除錯
 TinkerCAD程式除錯功能
 1946年第⼀代電腦是由18800個真空管所組成,有⼀回電腦發⽣故障,
檢查發現其中⼀⽀真空管跑進了⼩蟲⼦(bug),將其除去之後電腦就
恢復正常了。⼀直到現在,要找出程式的錯誤並加以修護時,習慣上
會說"Debug"
為什麼程式有錯叫Bug?
2
 語法錯誤(syntax error)
指令敘述不符合程式語言之語法規範,例如:遺漏標點符號、變數命
名不正確(與保留字相衝突)、未宣告函式庫標頭檔...
float x //敘述必須加分號
X = 3/2; //x變數名稱為小寫
 執行時期錯誤(run time error)
程式執行時發⽣的異常,例如:陣列index值超出範圍、除數為0、記
憶體空間不足…
 邏輯錯誤(semantic error)
程式的作業邏輯不正確而造成的錯誤,例如除法運算時,忽略了餘數
的處理,使作業結果暗藏錯誤
float x;
x = 3/2; //x值為1.0,而不是你認知的1.5
程式bug
3
 開啟顯示行號功能可方便對照錯誤訊習中的行號資訊
 選單命令File> Preferences
 Settings頁面勾選Display line numbers
顯示行號
4
 點擊Verify,驗證程式語法
語法錯誤處理 1/3
5
複製錯誤訊息
錯誤訊息
自動跳到第一個錯誤行
 解讀錯誤訊息
語法錯誤處理 2/3
6
Blink程式檔第9行第29字元
錯誤說明,low識別字未宣告
發現錯誤處
Blink程式檔第11行第1字元
錯誤說明,在'}'之前應該要有';'
發現錯誤處
 修正錯誤後重新編譯
語法錯誤處理 3/3
程式正確編譯
7
 程式順利編譯並上傳Arduino,並不表示程式功能就正確,必須執行
驗證執行結果
 檢視執行結果,發現LED能夠每秒閃爍,但亮度非常微弱
邏輯錯誤處理 1/3
8
亮度微弱
 詳細檢查程式,發現LED_BUILTIN腳位設定錯誤,修正後重新上傳測
試,程式功能正確
邏輯錯誤處理 2/3
修正LED_BUILTIN腳位為輸出
9
 邏輯錯誤只能依據執行結果分析推斷程式可能錯誤處
 Arduino IDE並沒有專用的除錯工具,通常我們會在程式中安插
Serial.print()指令輸出訊息到Serial Monitor,藉以查核程式執
行過程中是否與預期結果⼀致
 TinkerCAD程式模擬工具⽀援中斷點及單步執行,就可以在疑似有錯
誤之程式碼處設置中斷點,再以單步執行方式,逐行驗證程式流程及
結果
邏輯錯誤處理 3/3
10
 序列埠監控視窗是⼀個UART資料監看及資料傳送工具程式
 選單命令Tools> Serial Monitor
使用Serial Monitor 1/2
11
訊息區
傳輸速率(必須與Arduino程式所設定的速率一致)
 Arduino程式必須設定序列埠傳輸速率
 Serial.begin(傳輸速率);
Serial.begin(9600);
 Arduino程式中可使用下列指令輸出訊息到序列埠監控視窗
 Serial.print(輸出訊息字串);
 Serial.println(輸出訊息字串);
 二者用法相同,差別在於println()輸出訊息後會自動換行
Serial.print("debug message");
使用Serial Monitor 2/2
12
 設定輸出數字格式
 Serial.println(整數值, 格式碼);
 格式碼:DEC(10進位)、HEX(16進位)、OCT(8進位)、BIN(2進位)
Serial.println(23, BIN); //輸出10111
 設定⼩數點位數 (四捨五入)
Serial.println(3.14159); //預設小數點2位,輸出3.14
Serial.println(3.14159, 0); //不輸出小數點,輸出3
Serial.println(3.14159, 3); //指定小數點3位,輸出3.142
Serial.println()
13
 序列繪圖家會自動描繪UART接收到的數值資料
 選單命令Tools> Serial Plotter
 只能搭配Serial.println()指令
使用Serial Plotter
14
TinkerCAD除錯功能 1/2
15
開啟Serial Monitor
開啟Debugger
TinkerCAD除錯功能 2/2
16
開啟Serial Plotter
Click行號設定中斷點
Serial PlotterSerial Monitor
單步執行
滑鼠游標移到變數上方可檢視變數值
 實驗目的
 依錯誤訊息修正程式語法
 依程式執行結果,修正程式
Lab 使用Serial Monitor除錯 1/5
17
 載入除錯練習程式debug_exercise.ino
 參照錯誤訊息修正程式,可能需反覆編譯修正
#define SW 2
#define LED 3
char msg1[] = {'A', 'r', 'd', 'u', 'i', 'n', 'o'};
char msg2[] = "Hello, ;
byte click = 0;
bool lastState = high;
void setup() {
pinMode(sw, INPUT_PULLUP);
pinMode(LED, INPUT);
Serial.begin(9600);
}
Lab 使用Serial Monitor除錯 2/5
18
void loop() {
bool b1 = digitalRead(SW); //讀取開關目前狀態
if (b1 != lastState) { //開關狀態改變
delay(20); //防彈跳
if (b1 == digitalRead(SW)) { //再次確認開關狀態
laststate = b1;
click++;
}
}
if (click = 2){ //檢查是否已Click開關
click = 0;
Serial.print(msg2);
Serial.println(msg1);
for (char i = 0; i < 255; i += 5) {
analogWrite(LED, i);
delay(100);
}
analogWrite(LED, 0);
}
}
Lab 使用Serial Monitor除錯 3/5
19
debug_exercise:4:1: error: missing terminating " character
char msg2[] = "Hello, ;
^
debug_exercise:5:6: error: expected primary-expression before 'click'
byte click = 0;
^
debug_exercise:6:18: error: 'high' was not declared in this scope
bool lastState = high;
^
D:clouding storageMeganotesarduinocodedebug_exercisedebug_exercise.ino: In function
'void setup()':
debug_exercise:9:11: error: 'sw' was not declared in this scope
pinMode(sw, INPUT_PULLUP);
^
D:clouding storageMeganotesarduinocodedebug_exercisedebug_exercise.ino: In function
'void loop()':
debug_exercise:18:7: error: 'laststate' was not declared in this scope
laststate = b1;
^
debug_exercise:19:7: error: 'click' was not declared in this scope
click++;
^
debug_exercise:22:7: error: 'click' was not declared in this scope
if (click = 2){ //已Click開關
^
Lab 使用Serial Monitor除錯 4/5
20
 執行程式,開啟Serial Monitor
 每按⼀次按鈕,Serial Monitor應該會顯示⼀行"Hello, Arduino",同
時LED漸亮後熄燈,如果不是,修正程式錯誤
Lab 使用Serial Monitor除錯 5/5
21

Arduino程式除錯