Как получить время от RTC после пробуждения от сна?
У меня есть настройка с Arduino Pro Mini, DS1307 RTC, microSD shield и микропереключателем. Я установил прерывание на микропереключатель, так что он разбудит Arduino, когда он изменит состояние. Вот некоторый соответствующий код:
void setup() {
rtc.begin();
pinMode(button, INPUT);
SD.begin(chipSelect);
/*Опущена та же запись в файл, что и в button_ISR()*/
}
void loop() {
delay(5000);
goToSleep();
}
void goToSleep() {
sleep_enable();
attachInterrupt(digitalPinToInterrupt(button), button_ISR, CHANGE);
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
delay(500);
sleep_cpu();
}
void button_ISR() {
sleep_disable();
detachInterrupt(0);
rtc.begin();
String data = (digitalRead(button))?"OPEN":"CLOSE";
File dataFile = SD.open("datalog.txt", FILE_WRITE);
if(dataFile) {
DateTime now = rtc.now();
dataFile.print(now.year(), DEC);
dataFile.print('.');
dataFile.print(now.month(), DEC);
dataFile.print('.');
dataFile.print(now.day(), DEC);
dataFile.print(". (");
dataFile.print(daysOfTheWeek[now.dayOfTheWeek()]);
dataFile.print(") ");
dataFile.print(now.hour(), DEC);
dataFile.print(":");
dataFile.print(now.minute(), DEC);
dataFile.print(":");
dataFile.print(now.second(), DEC);
dataFile.print(";");
dataFile.println(data);
dataFile.close();
}
delay(1000);
}
Если я не вызову rtc.now () и опущу печать DateTime, код отлично запишет "OPEN" и "CLOSE" в txt. У меня есть такая же запись DateTime внутри setup(), с "START", и она отлично записывает текущую дату/время.
Что я упускаю? Как я могу получить время от RTC после пробуждения?
@Rothens, 👍1
Обсуждение1 ответ
Лучший ответ:
Вы не должны задерживаться в ISR по двум причинам:
Прерывания отключаются во время работы ISR, а
функция delay()
полагается на прерывания.Прерывания используются для обработки критичных по времени задач. Чем дольше прерывания отключены, тем больше вероятность того, что одна из этих критичных по времени задач будет обработана слишком поздно. Таким образом, ISR должны выполняться как можно быстрее.
В данном конкретном случае, если мы попытаемся сделать ISR как можно короче, оптимальным вариантом будет следующий:
void button_ISR() {}
Поскольку прерывание предназначено для пробуждения Arduino, и ничего больше,
все, что делает ISR, может быть сделано при пробуждении, сразу после
sleep_cpu();
.
Еще несколько замечаний и предложений:
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
может быть сделано раз и навсегда вsetup()
вместо объединения
sleep_enable()
,sleep_cpu()
иsleep_disable ()
вы можете использовать один вызовsleep_mode ().
скорее всего, вам не нужно повторно инициализировать RTC и повторно открывать файл на каждой итерации цикла: сделайте это только один раз, в
setup()
Строковые
объекты не дружелюбны к памяти небольшого Arduino; в этом случае вы можете избавиться от них, просто заменив словоString
сconst char *
если вы используете RTClib, вы можете использовать Метод
DateTime::toString()
, который может сделать ваш код короче и проще.
- Как разбудить Arduino с помощью rtc?
- Как сгенерировать аппаратное прерывание в mpu6050 для пробуждения Arduino из режима SLEEP_MODE_PWR_DOWN?
- Возникла проблема с переобъявлением символа другого типа
- Датчик PIR и сон (прерывание) на Mega2560
- POWER_MODE_IDLE пробуждается при любом изменении ввода?
- attiny85 сбрасывает себя вместо процедуры пробуждения
- Как одной кнопкой с прерыванием включать и отключать спящий режим?
- Спящий режим Arduino на 12 часов с модулем rtc1302
Вы не должны спать в ISR. Вы также не должны писать в файл. На самом деле, лучшее, что вы можете сделать, это оставить ISR пустым и переместить все его содержимое сразу после
sleep_cpu();
., @Edgar Bonet@EdgarBonet да, это было решение :) Если вы дадите мне ответ, я его приму. Спасибо!, @Rothens