Estoy usando el RV8523 para despertar cada 2 minutos un arduino atmega328p. El rtc está cableado así:
Donde INT1 está conectado al pin 3 del puerto D. La resistencia de extracción interna está activada y, sin embargo, funciona correctamente. Se despierta a veces cada 2 minutos, pero a veces no.
Ahí está el código para programar el RTC:
#define I2C_ADDR (0xD0 >> 1)
#define TIMERA_CLK 0x03
#define TIMERA_PERIOD 0x02
void Rtc_init()
{
Wire.beginTransmission(I2C_ADDR);
Wire.write(byte(0x00)); //control 1 register
Wire.write(byte(0x00));
Wire.endTransmission();
Wire.beginTransmission(I2C_ADDR);
Wire.write(byte(0x01)); //control 2 register
Wire.write(byte(0x02));
Wire.endTransmission();
Wire.beginTransmission(I2C_ADDR);
Wire.write(byte(0x02)); //control 3 register
Wire.write(byte(0x00));
Wire.endTransmission();
Wire.beginTransmission(I2C_ADDR);
Wire.write(byte(0x10)); // Timer A Clock register
Wire.write(byte(TIMERA_CLK)); //
Wire.endTransmission();
Wire.beginTransmission(I2C_ADDR);
Wire.write(byte(0x11)); // Timer A register
Wire.write(byte(TIMERA_PERIOD)); //
Wire.endTransmission();
Wire.beginTransmission(I2C_ADDR);
Wire.write(byte(0x0F)); // Timer & Clkout register
Wire.write(byte(0xBA)); //
Wire.endTransmission();
pinMode(INT, INPUT_PULLUP); // <== Sleep mode from RTC
delay(100);
}
Y está el código "principal":
#define INT 1
void setup()
{
Serial.begin(9600);
while (!Serial){;}
mySerial.begin(9600);
mySerial.println("Start ");
// Setup RTC
Rtc_init();
mySerial.println("RTC Init Done");
}
void loop ()
{
mySerial.println("\n\nWAKE UP ");
delay(1000);
mySerial.println("\n\nGoing to sleep");
mySerial.flush();
attachInterrupt(INT, Push, FALLING);
LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF);
detachInterrupt(INT);
}
void Push()
{
}
Toda la biblioteca está incluida y está la señal del pin de interrupción rtc (INT1):
Si tiene alguna pista que me guíe en la dirección correcta para la depuración, no tengo ideas :-/
EDITAR: Debo precisar que el atmega se alimenta con un voltaje de 3.3V al igual que el RTC. EDICIÓN 2: la señal visible en el alcance se repite correctamente 1 vez cada 2 minutos PERO el atmega no se activa:
Solo se puede usar la interrupción de nivel para despertar por INT0/1. La interrupción por cambio de nivel no funciona.
Además, si es necesario procesar la interrupción (no solo la activación), debe mantenerse baja durante todo el tiempo de activación, que puede durar hasta 258 ciclos de reloj. De lo contrario, la MCU se activará pero se perderá la interrupción.
ACTUALIZAR
No está directamente relacionado con la pregunta, pero podría valer la pena considerarlo.
El límite de 8 segundos en el retraso del sueño que lo obligó a usar un temporizador externo es puramente artificial. Es el resultado directo de la biblioteca que está utilizando confiando en el temporizador de vigilancia como fuente de interrupción de activación. La razón por la que utilizan el mecanismo de vigilancia es que WDT es la única fuente de interrupción interna disponible en todos los modos de suspensión. Esto facilita la escritura de la biblioteca, pero no significa que el resultado final sea el mejor posible.
El modo de suspensión de energía más bajo es Power-down. Watchdog, interrupción externa y coincidencia TWI son las únicas posibles fuentes de interrupción disponibles. Esto lo obliga a usar una interrupción externa para retrasos de más de 8 segundos. El consumo de energía total es apagado + reloj externo, o 0.5uA + 0.13uA = 0.63uA
Echemos un vistazo al modo de ahorro de energía. La única diferencia con el apagado es que el reloj asíncrono está activo, lo que le permite usar un reloj de cristal de 32,768 kHz como fuente de reloj. Y se puede utilizar para la interrupción del despertar. El consumo total de energía es Power-save, que es Power-down + reloj interno. De acuerdo con la hoja de datos, la corriente de aproximadamente 0.95uA se puede lograr en este modo (aunque necesita hacer algunos trucos de software avanzados para esto, como deshabilitar el apagón, apagar ADC, etc.)
La diferencia entre estos modos es dos veces menor que la que consumen incluso los LDO de corriente de reposo ultrabaja (alrededor de 0,5 uA). Teniendo en cuenta que esto le permite deshacerse de todas esas partes externas, diría que es una opción bastante viable.
Hay dos inconvenientes a tener en cuenta. En primer lugar, dado que se utilizan los mismos pines para el cristal del reloj que para el oscilador de cristal normal, está limitado al oscilador RC interno como fuente de reloj del sistema. Tenga en cuenta que el RC interno puede ser calibrado por el usuario con una precisión de aproximadamente el 1%, lo que debería ser suficiente para la mayoría de las aplicaciones.
En segundo lugar, no hay copia de seguridad de celda de botón que haya mencionado antes. Sin embargo, dado que esta es una aplicación alimentada por batería (supongo que lo es, de lo contrario, controlaría el adaptador de alimentación por reloj, no por el modo de suspensión de MCU), entonces no veo la necesidad de una copia de seguridad. Una batería es una batería. Puede agregar interruptores mosfet simples para apagar el resto del circuito y conectar la batería al pin ADC. Luego, mediría el voltaje de la batería al despertar y deshabilitaría todo menos RTC si está bajando demasiado.
Arce
A.Jirafa
A.Jirafa
A.Jirafa
Arce
Arce
Arce
A.Jirafa
A.Jirafa
Arce
A.Jirafa
Arce
A.Jirafa
Arce
A.Jirafa
Arce
Arce