Как разбудить Arduino с помощью rtc?
Я делаю регистратор данных с Arduino Mega2560, и я хочу использовать код, чтобы заставить его спать, когда никакая мера не нужна, и разбудить его с помощью RTC, когда придет время. Причина, по которой я хочу этого, заключается в том, что я намерен запустить код на Pro Mini позже, поэтому мне нужно сэкономить как можно больше энергии. Я могу перевести arduino в спящий режим, используя прерывание сигнала тревоги, когда проходит минута, но после этого он не просыпается.
Вот код, который я использую:
#include <Wire.h>
#include <RtcDS3231.h>
#include <avr/sleep.h>
const byte interruptPin = 2;
volatile bool alarm = 0;
volatile byte counter = 0;
RtcDS3231<TwoWire> rtcObject(Wire);
void setup() {
Serial.begin(9600);
Serial.println("Initialisation");
pinMode(interruptPin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(interruptPin), handleInterrupt, FALLING);
rtcObject.Begin();
RtcDateTime timestamp = RtcDateTime(__DATE__, __TIME__);
rtcObject.SetDateTime(timestamp);
rtcObject.Enable32kHzPin(false);
rtcObject.SetSquareWavePin(DS3231SquareWavePin_ModeAlarmOne);
DS3231AlarmTwo alarm2(
0,
0,
0,
DS3231AlarmTwoControl_OncePerMinute);
rtcObject.SetAlarmTwo(alarm2);
rtcObject.LatchAlarmsTriggeredFlags();
}
void loop() {
if (alarm == true){
handleAlarm();
if (counter == 1){
mesure();
counter = 0;
delay(100);
sleepNow();
}
}
}
void handleInterrupt() {
alarm = true;
counter ++;
Serial.println(counter);
}
void handleAlarm() {
alarm = false;
rtcObject.LatchAlarmsTriggeredFlags();
}
void mesure(){
RtcDateTime timestamp = rtcObject.GetDateTime();
Serial.print("time interrupt at: ");
char time[10];
sprintf(time, "%d:%d:%d",
timestamp.Hour(),
timestamp.Minute(),
timestamp.Second()
);
Serial.println(time);
}
void sleepNow() {
Serial.println("Entering sleeping");
delay(100);
set_sleep_mode(SLEEP_MODE_PWR_DOWN); // sleep mode is set here
sleep_enable(); // enables the sleep bit in the mcucr register
attachInterrupt(digitalPinToInterrupt(interruptPin),wakeUpNow, FALLING); // use interrupt 0 (pin 2) and run function
sleep_mode(); // here the device is actually put to sleep!!
// THE PROGRAM CONTINUES FROM HERE AFTER WAKING UP
sleep_disable(); // first thing after waking from sleep: disable sleep...
detachInterrupt(digitalPinToInterrupt(interruptPin)); // disables interrupt 0 on pin 2 so the wakeUpNow code will not be executed during normal running time.
}
void wakeUpNow() {
// execute code here after wake-up before returning to the loop() function
// timers and code using timers (serial.print and more...) will not work here.
// we don't really need to execute any special functions here, since we
// just want the thing to wake up
Serial.println("Woke up");
delay(100);
}
Я хочу понять, как правильно его разбудить, чтобы потом заставить его сначала заснуть в цикле и разбудить только в том случае, если rtc обнаружит прерывание.
Спасибо вам за вашу помощь !
@JamesONeil, 👍3
Обсуждение2 ответа
Если вы используете библиотеку DS3232RTC, то вы можете настроить сигнал тревоги, который похож на сигнал тревоги. Я поместил хороший учебник о том, как это сделать, ниже.
https://thekurks.net/blog/2018/2/5/wakeup-rtc-datalogger
Есть также и другие темы arduino.cc вам следует проверить. У них могут быть дополнительные обходные пути.
https://forum.arduino.cc/index.php?topic=333654.0
https://forum.arduino.cc/index.php?topic=99588.0
Возможно, вам не понадобится использовать RTC для пробуждения. Jeelabs проделала обширную работу по снижению энергопотребления, возможно, вам просто нужно использовать библиотеку jeelib с Github. Они даже продавали (больше не продавали) устройства, оптимизированные для сверхнизкой мощности и совместимые с UNO (https://jeelabs.org/202x/jnc/). Вы найдете jeelib на github на странице, на которую вы ссылаетесь.
Посмотрите на Сонный класс. Он выполняет некоторую низкоуровневую магию энергосбережения непосредственно с оборудованием. Было бы интересно извлечь этот класс из портов.h и Ports.cpp и попробуйте, работает ли он автономно.
Вы просто используете его с: Sleepy::loseSomeTime(32); и он выключит весь микроконтроллер на некоторое время. https://github.com/jeelabs/jeelib/blob/635113edea74b1290713360649679c3a13016304/Ports.h#L346
Он использует сторожевой таймер микроконтроллеров:
ISR(WDT_vect) { Sleepy::watchdogEvent(); }
- Как получить время от RTC после пробуждения от сна?
- Как сгенерировать аппаратное прерывание в mpu6050 для пробуждения Arduino из режима SLEEP_MODE_PWR_DOWN?
- Возникла проблема с переобъявлением символа другого типа
- Датчик PIR и сон (прерывание) на Mega2560
- POWER_MODE_IDLE пробуждается при любом изменении ввода?
- attiny85 сбрасывает себя вместо процедуры пробуждения
- Как одной кнопкой с прерыванием включать и отключать спящий режим?
- Как подсчитать количество нарастающих фронтов на DS3231 rtc?
Попробуйте спать в режиме ожидания или подключить прерывание в режиме " LOW`., @Edgar Bonet
Я испробовал оба ваших совета, но ни один из них не сработал..., @JamesONeil