Using the INT pin on a DS3231SN to power/kill an arduino

Hello all,

First off, let me thank Geir Andersen and Oddbot for their excellent work on datalogging shields, mosfet circuitry and other answers to my silent questions, reading through the articles was great fn and a good learning experience.

Presently, I'm trying to make an Arduino datalogger based around the Arduino Pro Mini, running 8Mhz on an external crystal/resonator. This, in conjunction with an LDO regulator, SD card and RTC should allow me to build a logger and lo and behold, it works!

By putting the arduino into a deep sleep and letting it wake up by the RTC works like a charm. Right now, I have a quiescent current of 0,32mA. However, since the arduino is picking its nose for the most part of the time interval, I tried what others are already doing (looking at you Geir :) ) and looked into using the RTC INT output to operate a Mosfet which in turns switches the loads on the 3V3 bus.

So I build the schematic Oddbot describes in the low power datalogger shield of Geir with the change that the DS3231SN uses an open drain N channel mosfet internally so I use a 4K7 pull-up on the INT pin to get good results. It works in the sleeping arduino set-up.

But when I connect the INT pin to the mosfet, things don't work our as I have planned and that's why I turn to you.

The basic idea is that the RTC is pre-programmed to pull the INT pin low in order to drive the gate of the mosfet to 0, allowing the voltage on the source to get to the drain. When I plug and pull wires to simulate, the mosfet does what it is supposed to do. When  plug it into the RTC, it doesn't.

 

After a lot of fiddling, maybe my nice plan of converting to this set-up is hitting snag in that when I program the arduino, I set the interval (in this case every minute, just for test), let the arduino do its thing and then clear the interrupt flag of the RTC, expecting the RTC to pull the pin high again and effectively killing the Arduino. Once its time register (seconds = 0) trips the alarm register, the INT pin is pulled low, mosfet kicks in and the show starts again, at least that what's it supposed to do.

I'll post my code here, I tried using tags to get a code block but couldn't get it to work..

//This sketch uses a mosfet connected to the RTC to turn the whole system on and off, no use of the sleep library necessary.

#include <avr/io.h>

#include <Wire.h>

#include <DS3231.h>

#include <Fat16.h>

#include <Fat16util.h>

#include <OneWire.h>

#include <DallasTemperature.h>

#include "Wire.h"

#include <EEPROM.h>

#include <Time.h>

 

#define NDevices 9                    // Number of DS18B20s

#define BUS 3                          // OneWire bus on pin 3

 

OneWire oneWire(BUS);

DallasTemperature sensors(&oneWire);    // pass to the DT library

 

DeviceAddress TAddress;                 // 8-bit T-sensor address

int EAddress;                           // EEPROM address pointer

 

 

DS3231 RTC; //Create RTC object for DS3231 RTC come Temp Sensor 

// static uint8_t prevSecond=0; 

static DateTime interruptTime;

SdCard card;

Fat16 file;

 

//int led = 13;

 

// store error strings in flash to save RAM

#define error(s) error_P(PSTR(s))

 

void error_P(const char* str) {

  PgmPrint("error: ");

  SerialPrintln_P(str);

  if (card.errorCode) {

    PgmPrint("SD error: ");

    Serial.println(card.errorCode, HEX);

  }

  while(1);

}

void setup () 

{

     /*Initialize INT0 pin for accepting interrupts */

     PORTD |= 0x04; 

     DDRD &=~ 0x04;

     pinMode(4,INPUT); //extern power

     DDRB = B00000000; // set pins 8 to 13 as inputs

     PORTB |= B11111111; // enable pullups on pins 8 to 13

 

     Wire.begin();

     Serial.begin(9600);

     RTC.begin();

 

     //attachInterrupt(0, INT0_ISR, LOW); //Only LOW level interrupt can wake up from PWR_DOWN

     //set_sleep_mode(SLEEP_MODE_PWR_DOWN);

 

     //Enable Interrupt 

     RTC.enableInterrupts(EveryMinute); //interrupt at  EverySecond, EveryMinute, EveryHour

     // or this

     //DateTime  start = RTC.now();

     //interruptTime = DateTime(start.get() + 60); //Add 1 minute in seconds to start time

     sensors.begin();

     //pinMode(led, OUTPUT);

}

 

void loop () 

{

    DateTime now = RTC.now(); //get the current date-time

    sensors.requestTemperatures(); // Send out a global "check temperatures" command 

    Serial.println("busy");

    //|||||||||||||||||||Write to Disk||||||||||||||||||||||||||||||||||

    // initialize the SD card

    if (!card.init()) error("card.init");

 

    // initialize a FAT16 volume

    if (!Fat16::init(&card)) error("Fat16::init");

 

    char name[] = "DATALOG.CSV";

    // clear write error

    file.writeError = false;

 

    // O_CREAT - create the file if it does not exist

    // O_APPEND - seek to the end of the file prior to each write

    // O_WRITE - open for write

    if (!file.open(name, O_CREAT | O_APPEND | O_WRITE))

        error("error opening file");

    if (now.date() < 10)

      file.print("0");

    file.print(now.date(), DEC);

    file.print('/');

    if (now.month() < 10)

      file.print("0");

    file.print(now.month(), DEC);

    file.print('/');

    file.print(now.year(), DEC);    

    file.print(';');

    if (now.hour() < 10)

      file.print("0");

    file.print(now.hour(), DEC);

    file.print(':');

    if (now.minute() < 10)

      file.print("0");

    file.print(now.minute(), DEC);

    file.print(':');

    file.print(now.second(), DEC);

    file.print(';');

    RTC.convertTemperature();             //convert current temperature into registers

    file.print(RTC.getTemperature()); //read registers and display the temperature

    file.print(';');

 

 

    // Now get those temperatures

    EAddress = 0;

    for (byte j=0;j<NDevices;j++) {     // loop over devices

        for (byte k=0;k<8;k++) {        // loop over address bytes

            TAddress[k] = EEPROM.read(EAddress);

            EAddress += 1;

 

      }

    file.print(sensors.getTempC(TAddress));

    file.print(";");

    }

    file.print("\n");  

    if (!file.close()) 

        error("error closing file");

    //digitalWrite(led, HIGH);   // turn the LED on (HIGH is the voltage level)

    //delay(1000);               // wait for a second

    //digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW

 

    //|||||||||||||||||||Write to Disk||||||||||||||||||||||||||||||||||

    Serial.println("bye!");

    delay(1000);

    RTC.clearINTStatus(); //This function call is  a must to bring /INT pin HIGH after an interrupt.

    //RTC.enableInterrupts(interruptTime.hour(),interruptTime.minute(),interruptTime.second());    // set the interrupt at (h,m,s)

    //attachInterrupt(0, INT0_ISR, LOW);  //Enable INT0 interrupt (as ISR disables interrupt). This strategy is required to handle LEVEL triggered interrupt

 

    ////////////////////////END : Application code //////////////////////////////// 

 

 

 

//Interrupt service routine for external interrupt on INT0 pin connected to DS3231 /INT

//void INT0_ISR()

//{

  //Keep this as short as possible. Possibly avoid using function calls

  //  detachInterrupt(0); 

    //interruptTime = DateTime(interruptTime.get() + 60);  //decide the time for next interrupt, configure next interrupt

//}

I'll see if I can upload a schematic to make things a bit more clear. I can't shake the thought I'm missing something major or that I need to (re)program the arduino differently the moment the RTC is connected to the Mosfet.

Reading through the library

Reading through the library files, it seems the INT is a one-shot deal and I have to include an extra line to re-enable the interupt status. Will do later tonight and see if it works.

Yes! I got it to work. It

Yes! I got it to work. It was the RTC.begin() which re-initilazes the RTC and when that happens, the RTC immediately pulls the int line high again, depriving my arduino of much needed 3V3. 

Ran a few tests and it looks good now.

 

Hello Leroy2007 - You mentioned you would post a schematic, I know you solved your own issue pretty fast, but I could use some guidance.

Thank you,

Anthony