一、喚醒
在Arduino IDE框架中進行Arduino Uno開發時,可以使用SLEEP_MODE_PWR_DOWN
模式來實現最深層次的休眠,以降低功耗。在這種模式下,Arduino Uno會關閉大部分微控制器功能,包括定時器中斷,因此通常需要一個外部中斷來喚醒裝置。
為了使用一個按鈕來喚醒Arduino Uno,你需要將按鈕連線到Arduino Uno的一個外部中斷引腳,並配置該引腳以在低電平或高電平變化時產生中斷。
以下是喚醒開關連線和程式碼配置的步驟:
連線喚醒開關
-
選擇一個外部中斷引腳。Arduino Uno上的外部中斷引腳是數字引腳2(INT0)和數字引腳3(INT1)。
-
將喚醒開關的一個腳連線到GND(地)。
-
將喚醒開關的另一個腳連線到你選擇的外部中斷引腳(INT0或INT1)。
程式碼配置
下面是一個示例程式碼,展示如何配置外部中斷並使用按鈕來喚醒Arduino Uno:
#include <avr/sleep.h> #include <avr/power.h> // 假設使用INT0,即數字引腳2作為喚醒引腳 const byte wakePin = 2; // INT0 // 喚醒中斷服務程式 void wakeUpNow() { // 這裡什麼也不做,只是中斷睡眠模式 } void setup() { pinMode(wakePin, INPUT_PULLUP); // 設定為輸入並啟用內部上拉電阻 attachInterrupt(0, wakeUpNow, LOW); // 使用INT0,當引腳電平為低時喚醒 // 初始化序列通訊 Serial.begin(9600); Serial.println("Going to sleep..."); } void loop() { // 進入休眠模式 set_sleep_mode(SLEEP_MODE_PWR_DOWN); // 設定休眠模式為最深睡眠 sleep_enable(); // 啟用休眠模式 // 確保外部中斷可以喚醒裝置 attachInterrupt(0, wakeUpNow, LOW); // 再次確認外部中斷配置 // 現在進入休眠模式 sleep_mode(); // 喚醒後,會從這裡繼續執行 // 禁用休眠模式 sleep_disable(); // 清除外部中斷標誌位(如果有的話) EIFR = bit(INTF0); // 對於INT0 // 干擾處理程式後可能需要執行的程式碼 Serial.println("Woke up!"); // 這裡可以新增你的程式碼,例如檢查按鈕狀態或執行其他任務 // 延遲一下,防止按鈕去抖導致的立即再次喚醒 delay(100); }
二、過壓斷路保護模組
三、測量電源壓降,計算電量百分比
如果您的供電是4節5號電池,最高電壓大約是6V,那麼您可以直接將這個電壓連線到Arduino Uno的VIN引腳,因為這是在VIN引腳接受的電壓範圍內(7V到12V)。
由於電池組的電壓低於VIN引腳可以接受的最高電壓,您不需要使用電阻分壓器來測量電壓。您可以直接使用一個模擬引腳來測量電池電壓,但是要注意,Arduino Uno的模擬引腳最大隻能測量到5V。
為了測量6V以下的電池電壓,您可以使用一個簡單的電路,比如一個電壓分壓器,或者如果您知道電池組的電壓不會超過5V,您可以直接連線到模擬引腳。
以下是修改後的程式碼,用於測量最高6V的電池電壓:
// 定義模擬輸入引腳,這裡我們使用A0 const int voltagePin = A0; void setup() { // 初始化序列通訊 Serial.begin(9600); } void loop() { // 讀取VIN引腳的模擬電壓值 int voltageValue = analogRead(voltagePin); // 對於Arduino Uno,模擬讀數範圍是0到1023,對應於0V到5V // 使用以下公式將模擬讀數轉換為實際的電壓值 float voltage = (voltageValue * 5.0) / 1023.0; // 列印電壓值 Serial.print("Battery Voltage: "); Serial.println(voltage); // 等待一段時間,避免快速連續讀取導致的序列通訊問題 delay(1000); }
但是,由於您的電池組最高電壓為6V,您可能想要使用一個簡單的電壓分壓器來確保不會超過Arduino的模擬輸入電壓範圍。例如,如果您使用10kΩ和5kΩ的電阻來構建電壓分壓器,那麼您可以透過以下方式計算實際電壓:
// 定義模擬輸入引腳,這裡我們使用A0 const int voltagePin = A0; const float resistorDivisor = 5.0 / (5.0 + 10.0); // 5kΩ / (5kΩ + 10kΩ) void setup() { // 初始化序列通訊 Serial.begin(9600); } void loop() { // 讀取VIN引腳的模擬電壓值 int voltageValue = analogRead(voltagePin); // 將模擬值轉換為實際的電壓值 float voltage = (voltageValue * 5.0) / 1023.0; // 分壓後的電壓 float actualVoltage = voltage / resistorDivisor; // 實際電池電壓 // 列印電壓值 Serial.print("Battery Voltage: "); Serial.println(actualVoltage); // 等待一段時間 delay(1000); }