搜尋程式碼

第14/31-2課:Arduino編程 millis() 示例2 帶事件

第14/31-2課:Arduino編程 millis() 示例2 帶事件

喺呢個教學入面,你會學到點樣用 Arduino millis() 函數嚟喺指定時間過去之後先觸發一個動作,而且唔會阻住你程式嘅其餘部分。呢個係一個基本技巧,用嚟整啲反應靈敏嘅 Arduino 項目,等佢可以同時處理多個任務,例如閃LED燈嘅同時讀取感應器或者監察按鈕撳壓。呢個具體例子係集中喺五秒之後觸發一個事件,但係呢個邏輯可以應用喺好多真實世界嘅場景度。

組裝好嘅Sunfounder車

以下係一啲實際例子,話你知點樣喺自己嘅項目入面用呢個模式:

  • 延遲啟動:喺系統運行咗一段設定時間之後先開風扇或者水泵。
  • 安全聯鎖:要求按鈕要撳住一段時間先可以做危險動作,例如啟動摩打。
  • 基於時間嘅警報:如果感應器讀數喺某段時間內冇變化,就觸發警報或者通知。
  • 非阻塞計時器:整一個「看門狗」計時器,如果裝置冇反應就重置佢。

呢個要解決嘅核心問題就係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計時同映射功能嘅多部分系列嘅一部分。探索其他由同一來源材料製作嘅教學:

章節

  • [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()函數

圖片

Sunfounder car assembled
Sunfounder car assembled
Sunfounder car assembled
Sunfounder car assembled
917-Lesson 14/31-2: Arduino coding millis() example 2 with event
語言: C++
/*
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

資源與參考資料

文件📁

用户手册