第14/31-2課:Arduino編程 millis() 示例2 帶事件
喺呢個教學入面,你會學到點樣用 Arduino millis() 函數嚟喺指定時間過去之後先觸發一個動作,而且唔會阻住你程式嘅其餘部分。呢個係一個基本技巧,用嚟整啲反應靈敏嘅 Arduino 項目,等佢可以同時處理多個任務,例如閃LED燈嘅同時讀取感應器或者監察按鈕撳壓。呢個具體例子係集中喺五秒之後觸發一個事件,但係呢個邏輯可以應用喺好多真實世界嘅場景度。
以下係一啲實際例子,話你知點樣喺自己嘅項目入面用呢個模式:
- 延遲啟動:喺系統運行咗一段設定時間之後先開風扇或者水泵。
- 安全聯鎖:要求按鈕要撳住一段時間先可以做危險動作,例如啟動摩打。
- 基於時間嘅警報:如果感應器讀數喺某段時間內冇變化,就觸發警報或者通知。
- 非阻塞計時器:整一個「看門狗」計時器,如果裝置冇反應就重置佢。
呢個要解決嘅核心問題就係delay()函數嘅限制。當你用delay(5000)嘅時候,Arduino會喺嗰五秒入面停止執行任何其他代碼。對於簡單嘅草圖嚟講冇問題,但係喺更複雜嘅項目入面,當你需要喺等待期間讀取感應器、更新顯示或者聽按鈕撳壓嘅時候,呢個就會變成一個大問題。millis()函數會計算板通電以嚟嘅毫秒數,令你可以檢查時間而唔使暫停程式。
所需硬件
- Arduino板(Uno、Nano、Mega等)
- 一個按鈕
- 杜邦線
接線指南
呢個例子嘅接線好簡單。佢用內部上拉電阻,所以按鈕唔需要外接電阻。
- 將按鈕嘅一隻腳連接到Arduino嘅GND針腳。
- 將按鈕嘅另一隻腳連接到Arduino嘅數碼針腳2。
因為我哋喺代碼入面用INPUT_PULLUP,所以當按鈕冇撳嘅時候針腳會讀到HIGH,撳住嘅時候會讀到LOW,因為針腳連咗去接地。(喺影片08:29)
理解代碼
呢段代碼示範咗一個簡單嘅事件計時器。程式會不斷將當前嘅millis()值打印去Serial Monitor。當按鈕撳住,而且Arduino已經運行咗至少五秒,佢就會打印「Take action」去Serial Monitor。重點係millis()嘅檢查唔會阻住時間嘅連續打印。
等我哋拆解吓代碼入面用戶可以設定嘅部分:
unsigned long event = 5000;// 5秒
呢個係最重要嘅變數去設定。佢定義你「事件」嘅持續時間,單位係毫秒。喺呢個例子入面,佢設定做5000,即係五秒。想改延遲時間,就簡單改呢個數字。例如,設定做10000就會令動作喺十秒之後觸發。一定要用unsigned long數據類型,因為millis()嘅值可以變得好大,最終會超過標準int變數嘅最大值,導致比較時出錯。(喺影片05:46)
pinMode(2,INPUT_PULLUP);
呢行將數碼針腳2設定做輸入,並啟動佢嘅內部上拉電阻。呢個係一個關鍵嘅設定步驟,令你可以唔使外接電阻就連接按鈕。針腳預設會讀到HIGH,當按鈕撳住、連去接地嘅時候就會變LOW。如果你想用另一個針腳,就改呢度嘅數字2,同埋改loop()入面digitalRead(2)嗰行。(喺影片08:46)
loop()入面嘅邏輯好直接。佢讀取按鈕嘅狀態。如果按鈕撳住(pb == LOW),佢就會檢查當前時間(millis())係咪大過或者等於你設定嘅event時間。如果兩個條件都成立,佢就會打印動作訊息。其餘嘅loop,即係打印時間嗰部分,會繼續唔受干擾咁運行,示範咗millis()比delay()優勝嘅地方。
呢個例子係由Arduino啟動嗰刻開始計時。影片系列入面嘅第三個例子會更進一步,記錄第一次撳按鈕嘅時間,然後只係喺至少五秒之後有第二次撳壓先觸發動作。嗰個邏輯喺第14課/31-3:Arduino編碼millis()例子3配按鈕入面有詳細講解。
現場項目示範
當你上傳代碼並打開Serial Monitor(喺9600波特率),你會見到一連串數字,代表板通電以嚟嘅毫秒數。如果你喺五秒之前撳住按鈕,就唔會有任何嘢發生。但係,如果你喺五秒之後撳住按鈕,你就會見到Serial Monitor打印「Take action」訊息。只要你一直撳住按鈕,動作就會繼續打印。呢個示範咗一個非阻塞計時器,令其他代碼(即打印)可以順暢咁運行。(喺影片10:52)
呢條影片嘅相關項目
呢條影片係一個關於Arduino計時同映射功能嘅多部分系列嘅一部分。探索其他由同一來源材料製作嘅教學:
- 第14/31-1課:Arduino Millis(無延遲)同map函數 | SunFounder Robojax
- 第14/31-3課:Arduino編碼millis()示例3,用按鈕
- 第14/31-4課:Arduino編碼map()示例1
- 第14/31-5課:Arduino編碼map()示例2
章節
- [00:00] millis()同SunFounder套件嘅介紹
- [01:19] 咩係millis(),點解要用佢而唔用delay()?
- [03:06] 實際示範:打印millis()嘅值
- [05:46] 用millis()同unsigned long建立事件
- [08:29] 用INPUT_PULLUP接線同編寫按鈕程式
- [10:52] 用按鈕運行事件示例
- [12:14] 示例3預覽:偵測第二次按鈕按下
- [17:20] map()函數嘅介紹
- [19:47] 用LED編寫同示範map()函數
/*
Lesson 14/31: Arduino coding millis() example 2 with event
Get this code and watch video Download and resource page https://robojax.com/RJT597
YouTube video https://www.youtube.com/watch?v=lqgzQohNiIM
* This code is "AS IS" without warranty or liability. Free to be used as long as you keep this note intact.*
* This code has been download from Robojax.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
unsigned long event = 5000;// 5 seconds
void setup() {
Serial.begin(9600);//initialize serial monitor
Serial.println("Introduction to millis");
pinMode(2,INPUT_PULLUP);
}
void loop() {
// Robojax.com millis() example 1
Serial.println(millis());
int pb = digitalRead(2);// read pin 2
if(pb ==LOW)
{
if(millis() >= event)
{
Serial.println("Take action");
}// if end
}// if end
}// loop end
你可能需要嘅嘢
-
亞馬遜SunFounder Arduino Learning Kit on AliExpresss.click.aliexpress.com
-
亞馬遜
-
亞馬遜
-
亞馬遜
-
其他
資源與參考資料
-
外部Purchase SunFounder's 3-in-1 Smart car learning kitsunfounder.com
文件📁
用户手册
-
SunFounder 3-in-1 Arduino Smart Car assembly manualThis document shows step by step assembly of SunFounder 3-in-1 Arduino Smart Car
SunFounder_car_assembly_manual.pdf1.20 MB