Hola a todos,
recientemente he comprado un reloj DS3231 con la intención de programar una alarma que provoque una interrupción cada 60 min y haga despertar mi arduino, tome datos de los sensores, los envíe a través de Xbee y vuelva a dormir hasta que pasen otros 60 min. Necesito este modo de funcionamiento ya que el sistema, formado por tres sensores de humedad (FC28) y uno de temperatura (DS18b20) no estarán conectados a la corriente sino a dos pilas ion-Li (3.7V / 2400mA) que a su vez están conectados a dos celdas fotovoltaicas (5,5V / 180mA cada una). Como resulta evidente necesita que el sistema sea lo más energeticamente eficiente posible y la mejor forma de conseguirlo es utilizando un reloj DS3231 que despierte el Arduino en el momento preciso.
El problema es que he indagado bastante al respecto y encuentro poca información al respecto, en el foro en español apenas se ha debatido este tema, en el foro inglés si se ha hablado bastante más y he podido encontrar un código que, en teoría, debería cumplir mis expectativas:
#include <DS3231.h>
#include <Wire.h>
#include <avr/sleep.h>
DS3231 Clock;
byte year, month, date, DoW, hour, minute, second;
int INTERRUPT_PIN = 2;
int RTC_ON = 9; // D5 DHT PIN (ON - OFF)
//digitalWrite (RTC_ON, HIGH);
volatile int flag = 0;
void setup () {
digitalWrite (RTC_ON, HIGH);
pinMode (RTC_ON, OUTPUT);
pinMode(INTERRUPT_PIN, INPUT);
//pull up the interrupt pin
digitalWrite(INTERRUPT_PIN, HIGH);
Serial.begin(19200);
Wire.begin();
Clock.getTime(year, month, date, DoW, hour, minute, second);
Clock.setA1Time(DoW, hour, minute+1, second, 0x0, true, false, false);
// set A2 to two minutes past, on current day of month.
Clock.setA2Time(date, hour, minute+2, 0x0, false, false,false);
// Turn on both alarms, with external interrupt
Clock.turnOnAlarm(1);
Clock.turnOnAlarm(2);
if (Clock.checkAlarmEnabled(1) && Clock.checkAlarmEnabled(2)) {
Serial.println("Alarms Enabled");
}
attachInterrupt(0, SendReport, LOW);
}
void loop () {
// power up clock chip
digitalWrite (RTC_ON, HIGH);
pinMode (RTC_ON, OUTPUT);
// activate I2C
Wire.begin();
//DateTime now = RTC.now();
if (Clock.checkIfAlarm(1) )
{
Serial.println("Alarm 1 Triggered");
}
if (Clock.checkIfAlarm(2))
{
Serial.println("Alarm 2 Triggered");
}
if(flag ==1)
{
Serial.println("FLAG = 1");
delay(2000);
}
else
{
Serial.println("FLAG = 0");
delay(2000);
}
// Display the time once more as a test of the getTime() function
Clock.getTime(year, month, date, DoW, hour, minute, second);
Serial.print(year, DEC);
Serial.print("/");
Serial.print(month, DEC);
Serial.print("/");
Serial.print(date, DEC);
Serial.print("day of the week :");
Serial.println(DoW, DEC);
Serial.print(hour, DEC);
Serial.print(":");
Serial.print(minute, DEC);
Serial.print(":");
Serial.println(second, DEC);
// finished with clock Turn it Off
pinMode (RTC_ON ,INPUT);
digitalWrite (RTC_ON, LOW);
// turn off I2C
TWCR &= ~(bit(TWEN) | bit(TWIE) | bit(TWEA));
// turn off I2C pull-ups
digitalWrite (A4, LOW);
digitalWrite (A5, LOW);
Serial.println("Going to Sleep");
delay(600);
sleepNow();
Serial.println("AWAKE");
}
void sleepNow() {
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sleep_enable();
attachInterrupt(0,SendReport, LOW);
sleep_mode();
//HERE AFTER WAKING UP
sleep_disable();
detachInterrupt(0);
}
void SendReport() {
//do something quick, flip a flag, and handle in loop();
flag =1 ;
}
El código compila correctamente pero al cargarlo, el funcionamiento no es el deseado. Se imprime la fecha y la hora, se escribe "Going to sleep" e inmediatamente "AWAKE" sin respetar los márgenes de 1 min y 2 min establecidos en las alarmas del código.
Las conexiones de los pines son:
DS3231 ARDUINO UNO R3
GND GND
VCC PIN 9
SDA PIN A4
SCL PIN A5
SQW PIN 2
Los link que me han sido de mas ayuda son los siguientes:
https://forum.arduino.cc/index.php?topic=346940.0
Si alguien ha tiene experiencia en el tema o ha desarrollado algo parecido le agradecería me ilustrase al respecto.
Un saludo!