Как разбудить 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 обнаружит прерывание.

Спасибо вам за вашу помощь !

, 👍3

Обсуждение

Попробуйте спать в режиме ожидания или подключить прерывание в режиме " LOW`., @Edgar Bonet

Я испробовал оба ваших совета, но ни один из них не сработал..., @JamesONeil


2 ответа


0

Если вы используете библиотеку 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

,

1

Возможно, вам не понадобится использовать 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(); }
,