Помощь с прерыванием режима ожидания Arduino и ватчдог таймера
Я хочу использовать функции сна и пробуждения Arduino, но столкнулся с препятствием и, похоже, не могу его преодолеть. Поскольку я только создаю прототип для окончательной системы, я не могу использовать маломощную библиотеку для реализации функциональности, поэтому я делаю это просто. Я могу перевести Arduino в спящий режим просто отлично, основная проблема связана со сторожевым таймером. У меня есть или, как мне кажется, я настроил его на 8-секундное прерывание, чтобы вывести Arduino из спящего режима, но Arduino выходит из спящего режима так же, как и входит в него без каких-либо задержек. Код таков
#include <Arduino.h>
#include <avr/sleep.h>
void goToSleep();
void setupWDT();
void stopWDT();
ISR(WDT_vect) {
sleep_disable(); // разбудить Arduino
}
void setup() {
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
stopWDT();
pinMode(LED_BUILTIN, OUTPUT);
Serial.begin(9600);
Serial.println("Uno is in setup funtion.");
bool ledState = 0;
while(millis()<3000){
digitalWrite(LED_BUILTIN, ledState);
ledState = !ledState;
delay(500);
}
}
void loop() {
Serial.println("Uno is awake.");
digitalWrite(LED_BUILTIN, HIGH);
delay(2000);
Serial.println("Going to sleep...");
digitalWrite(LED_BUILTIN, LOW);
delay(100);
setupWDT();
goToSleep();
stopWDT();
delay(100);
digitalWrite(LED_BUILTIN, HIGH);
}
void goToSleep() {
ADCSRA &= ~(1<<ADEN); // отключить АЦП
sleep_mode(); // переводит Arduino в спящий режим
}
void setupWDT() {
cli();
WDTCSR |= (1 << WDCE);
WDTCSR &= ~(1 << WDE);
WDTCSR |= (1 << WDCE) | (1 << WDIE) | (1 << WDP3) | (1 << WDP0); // настроен на 8 секунд задержки прерывания
sei();
}
void stopWDT() {
cli();
MCUSR &= ~(1 << WDRF); // снять флаг сброса
WDTCSR |= (1 << WDCE);
WDTCSR &= ~(1<<WDE);
WDTCSR = 0x00; // остановить WDT
sei();
}
@phizaics, 👍1
1 ответ
Попробуйте изменить это:
void setupWDT() {
cli();
WDTCSR |= (1 << WDCE);
WDTCSR &= ~(1 << WDE);
WDTCSR |= (1 << WDCE) | (1 << WDIE) | (1 << WDP3) | (1 << WDP0); // настроен на 8 секунд задержки прерывания
sei();
}
Для:
void setupWDT() {
cli();
WDTCSR = (1 << WDCE) | (1 << WDE) ;
WDTCSR = (1 << WDCE) | (1 << WDIE) | (1 << WDP3) | (1 << WDP0); // настроен на 8 секунд задержки прерывания
sei();
}
Похоже, что ваша конструкция нарушает окно с тактовым циклом 4, в котором бит разрешения изменения сторожевого таймера WDCE позволяет обновлять бит WDE.
- Как сгенерировать аппаратное прерывание в mpu6050 для пробуждения Arduino из режима SLEEP_MODE_PWR_DOWN?
- Светодиод не мигает - Arduino UNO+WiFi R3 ATmega328P+Плата ESP8266
- ATmega328P - проблема с использованием таймера 2 для генерации тона
- Точность синхронизации Arduino nano
- Интервальный таймер на Arduino: Сомнения по поводу библиотеки TimerOne
- Можно ли отсоединить прерывание на определенное время
- Заставить TCNT оставаться ниже OCRxA на ATmega328P
- Эмуляция Arduino Uno с помощью QEMU: прерывания не работают