1
\$\begingroup\$

I'm using the RV8523 to wake up every 2 minutes an arduino atmega328p. The rtc is wired like this :

Schematic of the RTC wired to the ATmega328p

Where INT1 is wired to Port D pin 3. The internal pull up resistor is activated and yet it's working properly. It wakes up sometimes every 2 minutes but sometimes not.

There is the code to program the 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);
}

ANd there is the "main" code :

#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()
{

}

All the library are included and there is the signal from the rtc interruption pin (INT1) : RTC signal ==> INT1. We  can see the interruption but the voltage seems really low.

If you have any clue to guide me to the right direction for debugging, I'm out of ideas :-/

EDIT : I should precise the atmega is powered up by a 3.3V voltage just like the RTC. EDIT 2 : The signal visible on the scope repeat correctly 1 times every 2minutes BUT the atmega doesn't wake up : On a larger temporal scale : we can see the patern repeating every 2 minutes

\$\endgroup\$
  • \$\begingroup\$ I'd start by verifying if that pulse is long enough to be detected by MCU. \$\endgroup\$ – Maple Jun 11 '18 at 10:05
  • \$\begingroup\$ I think so ! In fact, sometimes the atmega wake up and I verified the signal go right at 0V. There, it's not the case (the minimum is of 18mV) so I think it's more related to the voltage level than to the pulse timing. I will check the atmega datasheet just to be sure. \$\endgroup\$ – A.Girafe Jun 11 '18 at 11:52
  • \$\begingroup\$ After a quick check, I can only say the pulse duration is of 15ms. I didn't found any information about it in the atmega328p datasheet. As I said, I'm pretty sure it's not a timing related problem. \$\endgroup\$ – A.Girafe Jun 11 '18 at 12:41
  • \$\begingroup\$ I found out : "pulses that last longer than one clock period will generate an interrupt". I'm using an external oscillator of 8MHz so the clock period is 0.125us (not sure) and the pulse duration is about 15ms. I really think it's not the problem here :-/ \$\endgroup\$ – A.Girafe Jun 11 '18 at 13:25
  • \$\begingroup\$ The quote above is for normal operation. Here is the one you need: "Note:  If a level triggered interrupt is used for wake-up from Power-down, the required level must be held long enough for the MCU to complete the wake-up to trigger the level interrupt." \$\endgroup\$ – Maple Jun 11 '18 at 15:49
1
\$\begingroup\$

Only level interrupt can be used for waking up by INT0/1. Level change interrupt does not work.

Additionally, if there is a need to process interrupt (not just wake up), then it should be held low during entire wake-up time, which can be as long as 258 clock cycles. Otherwise the MCU will wake up but the interrupt will be lost.

UPDATE

Not directly related to the question but might be worth considering.

The 8 seconds limit on sleep delay that forced you to use external timer is pure artificial. It is direct result of the library that you are using relying on watchdog timer as wake up interrupt source. The reason they use watchdog is that WDT is the only internal interrupt source available in all sleep modes. This makes writing the library easier, but does not mean the end result is the best that could be.

The lowest power sleep mode is Power-down. Watchdog, external interrupt and TWI match are the only possible interrupt sources available. This forces you to use external interrupt for delays longer than 8s. Total power consumption is power-down + external clock, or 0.5uA + 0.13uA = 0.63uA

Let's take a look at Power-save mode. The only difference from Power-down is that asynchronous clock is active, allowing you to use 32.768 kHz watch crystal as clock source. And it can be used for wake-up interrupt. Total power consumption is Power-save, which is Power-down + internal clock. According to datasheet the current of about 0.95uA is achievable in this mode (although you need to do some advanced software tricks for this, like disabling brown-out, shutting down ADC etc.)

The difference between these modes is two times less than even ultra-low quiescent current LDOs consume (about 0.5uA). Considering that this allows you to get rid of all those external parts I'd say it is quite viable option.

There are two drawbacks to consider. First, since the same pins are used for watch crystal as for normal crystal oscillator you are limited to internal RC oscillator as system clock source. Note that internal RC can be calibrated by user to about 1% accuracy, which should be enough for most applications.

Second, there is no button cell backup you've mentioned before. However since this is battery-powered application (I assume it is, otherwise you'd control power adapter by the clock, not the MCU sleep mode) then I see no need in backup. A battery is a battery. You can add simple mosfet switches to shut off power from the rest of circuit and to connect battery to ADC pin. Then you'd measure battery voltage on wake-up and disable everything but RTC if it is getting too low.

| improve this answer | |
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.