第17/31課:如何喺Arduino中斷延遲同光敏電阻LDR | Robojax
喺呢個指南入面,我哋會探討兩個重要嘅Arduino概念:中斷同光敏電阻(LDR)。你會學識點樣中斷你程式碼入面嘅延遲,令你嘅Arduino可以即時回應按鈕撳掣,然後我哋會整一個感光電路,可以喺夜晚自動開蜂鳴器或者燈。呢個項目好適合任何想超越基本閃爍LED程式,開始整有反應、真實世界自動化項目嘅人。你可以運用呢啲技巧嚟整一個走廊嘅智能夜燈、一個門打開時會響嘅簡單防盜警報、一個喺黃昏啟動嘅太陽能花園燈,或者一個太陽落山時會自動關埋嘅窗簾。呢堂課係基於SunFounder 3合1 Arduino套件,但係呢啲概念適用於任何標準Arduino板。

硬件同零件
要跟住呢個項目做,你需要以下零件。一個標準嘅Arduino Uno或者Nano好適合呢個製作。
- Arduino Uno或者Nano
- 光敏電阻(LDR),例如Kweeds KM601
- 10k歐姆電阻
- 按鈕
- 蜂鳴器
- 麵包板同跳線
了解Arduino中斷
喺一個標準嘅Arduino程式入面,loop()函數會不斷運行,逐行執行任務。當你用delay()嘅時候,Arduino會喺嗰段時間停止做任何其他嘢。如果你需要喺另一個任務運行緊嘅時候回應一個重要事件,好似撳掣咁,呢個就係一個問題。例如,如果你用一秒延遲嚟閃爍LED,撳掣可能要等成秒先至被偵測到,感覺上好唔靈敏(喺影片08:13)。
Arduino中斷可以解決呢個問題。中斷係一個硬件功能,容許一個特定引腳「中斷」主程式,暫停佢做緊嘅嘢,然後運行一個叫做中斷服務常式(ISR)嘅特殊函數。咁樣你嘅Arduino就可以即時回應高優先級事件,無論其他嘢做緊乜都得。要注意嘅係,唔係所有引腳都支援中斷。喺Arduino Uno同Nano上面,只有引腳2同3可以用嚟做呢個用途(喺影片02:37)。其他板好似Mega有更多選擇,但係喺呢個項目入面,我哋會用引腳2。
中斷可以由引腳上唔同嘅狀態變化觸發:LOW、CHANGE、RISING同FALLING。CHANGE模式會喺引腳狀態由HIGH變LOW或者LOW變HIGH嘅時候觸發中斷,呢個好適合用嚟做按鈕切換。
接線指南
我哋會喺呢堂課整兩個電路。第一個示範用按鈕同蜂鳴器嘅中斷,第二個用LDR嚟感應光線水平。我哋由中斷電路開始。
電路1:用嚟示範中斷嘅按鈕同蜂鳴器
呢個電路好直接。按鈕連接到引腳2,即係我哋嘅中斷引腳。一個10k歐姆下拉電阻確保當按鈕冇撳嘅時候引腳讀到LOW,撳嘅時候讀到HIGH。蜂鳴器連接到引腳8。
對於中斷示範,跟以下方式連接零件:
- 按鈕:將一隻腳連接到5V,另一隻腳連接到數碼引腳2。由引腳2到GND連接一個10k歐姆電阻。
- 蜂鳴器:將負極連接到GND,正極連接到數碼引腳8。
電路2:用嚟感光嘅LDR同蜂鳴器
對於LDR電路,我哋用一個分壓器配置。LDR嘅電阻會隨光線改變,從而改變模擬引腳嘅電壓。當黑暗嘅時候,LDR有高電阻(大約10k歐姆),當光猛嘅時候,電阻會顯著下降(喺影片16:25)。呢個電阻變化就係我哋量度嘅嘢。
分壓器係必須嘅,因為Arduino只可以讀電壓,唔可以讀電阻。將LDR同一個固定10k歐姆電阻串聯,佢哋之間嗰點嘅電壓會按比例隨LDR嘅電阻變化。呢個電壓跟住被Arduino嘅模擬轉數碼轉換器(ADC)讀取。
對於LDR示範,跟以下方式連接零件:
- LDR:將一隻腳連接到5V,另一隻腳連接到模擬引腳A0。
- 10k歐姆電阻:由連去A0嘅LDR腳向下連接到GND。咁樣就形成分壓器。
- 蜂鳴器:將負極連接到GND,正極連接到數碼引腳8。
注意:確切嘅引腳分配喺程式碼入面定義,可以按你嘅設置更改。
程式碼解釋
我哋會集中睇提供嘅程式碼入面用戶可配置嘅部分,呢啲部分控制項目嘅行為。完整程式可以喺文章下面下載。
程式碼設計成容易修改。喺程式最頂部,你會搵到可以調整嘅主要變數。
const byte buzzerPin = 8;
const byte interruptPin = 2;
volatile byte state = LOW;
int count=0;
呢度,buzzerPin 設定做 pin 8,即係你連接蜂鳴器嘅位置。interruptPin 設定做 pin 2,即係用嚟監聽按鈕按下嘅引腳。state 變數係一個 volatile byte,用嚟保存蜂鳴器嘅當前狀態(HIGH 或者 LOW)。佢標記做 volatile 係因為佢會喺中斷服務常式(ISR)入面被修改,而呢個關鍵字確保 Arduino 永遠讀取最新嘅值。count 變數係一個簡單嘅計數器,會喺主迴圈入面遞增,用嚟示範當 interrupt 啟動時,主迴圈仍然喺度運行。
喺 setup() 函數入面,蜂鳴器引腳設定做 OUTPUT,而 interrupt 引腳設定做 INPUT。最關鍵嘅一行係 attachInterrupt(),即係你配置 interrupt 嘅地方。呢個函數話畀 Arduino 知要監視邊個引腳、當 interrupt 發生時要呼叫邊個函數,以及用咩觸發條件。
attachInterrupt(digitalPinToInterrupt(interruptPin), noisy, CHANGE);
呢一行將一個 interrupt 附加到指定嘅引腳。digitalPinToInterrupt() 函數將引腳號碼轉換成正確嘅 interrupt 號碼。noisy 係當 interrupt 被觸發時會呼叫嘅函數名稱。最後,CHANGE 係模式,即係喺引腳任何狀態改變時觸發 interrupt。你可以根據需要將佢改做 RISING、FALLING 或者 LOW。
noisy() 函數就係 ISR。佢係一個簡單嘅切換函數,用嚟翻轉蜂鳴器嘅狀態。當按鈕被按下時,interrupt 會觸發呢個函數,佢會反轉 state 變數並將佢寫入蜂鳴器引腳。咁樣你就可以每次按下按鈕時開關蜂鳴器,即使主迴圈忙緊計數同延遲。
要將項目嘅行為改做夜晚啟動蜂鳴器而唔係日頭,你需要修改主迴圈入面嘅條件邏輯,將 HIGH 同 LOW 狀態嘅 digitalWrite() 指令調轉。
實時項目同示範
喺示範入面,你會見到兩個關鍵實驗。首先,interrupt 電路冇載入 interrupt 程式碼嚟運行,其中迴圈入面嘅延遲令到按鈕反應遲鈍。呢個突顯咗 interrupt 要解決嘅問題。
然後,載入 interrupt 程式碼之後,序列監視器會顯示計數器每秒遞增。當按鈕被按下時,蜂鳴器會即時開關,無論主迴圈有咩延遲。呢個證明 interrupt 成功繞過等待時間並即時執行佢嘅任務(喺影片 14:07)。
對於 LDR 部分,序列監視器會打印原始模擬值。你可以見到喺光線充足時數值好高(大約 960),而當感測器被遮蓋時數值會大幅下降(到大約 400 或者更低)。呢個示範咗 LDR 嘅電阻點樣隨光強度改變。然後程式碼用一個閾值嚟判斷係「日頭」定「夜晚」,並相應控制蜂鳴器。透過遮蓋感測器嚟模擬夜晚,你可以觸發蜂鳴器,而將佢暴露喺光線下就可以關閉佢。
章節
- [00:00] Arduino Interrupt 同 LDR 簡介
- [01:43] Arduino 程式碼入面延遲嘅問題
- [03:37] 理解 Interrupt 引腳同模式
- [04:20] 接線按鈕同蜂鳴器電路
- [06:22] 延遲示範嘅程式碼解釋
- [07:48] 延遲問題嘅示範
- [09:26] 實現同編寫 Interrupt
- [11:50] Interrupt 函數點樣運作
- [14:26] 光敏電阻(LDR)簡介
- [15:44] 用萬用錶測量 LDR 電阻
- [17:22] 接線 LDR 同蜂鳴器電路
- [19:55] 讀取 LDR 數值嘅程式碼
- [20:49] LDR 數值變化嘅示範
- [22:08] 設定日頭同夜晚閾值
- [23:40] 用 LDR 控制蜂鳴器嘅程式碼
- [25:21] 自動夜燈嘅示範
/*
Lesson 20/31: interrupt a delay in Arduino and Light Dependent Resistor LDR
Get this code and watch video Download and resource page https://robojax.com/RJT600
YouTube video https://www.youtube.com/watch?v=N_L11m1v_yk
* 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/>.
*/
const byte buzzerPin = 8;
const byte interruptPin = 2;
volatile byte state = LOW;
int count=0;
void setup() {
pinMode(buzzerPin, OUTPUT);
pinMode(interruptPin, INPUT);
attachInterrupt(digitalPinToInterrupt(interruptPin), noisy, CHANGE);
Serial.begin(9600);
digitalWrite(buzzerPin, state);
}
void loop() {
count++;
Serial.println(count);
delay(1000);
}
void noisy() {
state = !state;
digitalWrite(buzzerPin, state);
}
Common Course Links
Common Course Files
你可能需要嘅嘢
-
亞馬遜SunFounder Arduino Learning Kit on AliExpresss.click.aliexpress.com
-
亞馬遜
-
亞馬遜
-
亞馬遜
資源與參考資料
-
文件记录Documentation for SunFounder 3 in 1 IoT/Smart Car/Learning Kitdocs.sunfounder.com
-
外部Purchase SunFounder's 3-in-1 Smart car learning kitsunfounder.com
文件📁
Arduino 函式庫 (zip)
-
SunFounder's 3-in-1 Smart Car learning kit source code
3in1-kit-main-v2.zip12.80 MB