How to set Alarm mask on MCP7940M on minutes?

  alarm, atmega, c++, microchip, node-red

I’m following a tutorial on time interval wakeup and I’m stuck on setting the interval on minutes instead of seconds. I’m writing to the ALM0WKDAY register value 0x10 which from what i understand should set alarm to match on minutes, as specified in the chip documentantion here https://ww1.microchip.com/downloads/en/DeviceDoc/MCP7940M-Low-Cost%20I2C-RTCC-with-SRAM-20002292C.pdf, TABLE 4-5 p. 18. I’m missing something and wake up doesn’t hapen.

Any help is greatly appreciated!

//KEVIN DARRAH 2/21/17
//http://www.kevindarrah.com/wiki/index.php?title=RTC_Board

#include <Wire.h>

//functions
void rtcInit();
void rtcGetTime();
void checkSerial();
boolean checkAlarm();
void goToSleep(byte sleepTime);

//defines
#define RTCADDR B1101111//page11 datasheet
#define RTCSEC 0x00
#define RTCMIN 0x01
#define RTCHOUR 0x02
#define RTCWKDAY 0x03
#define RTCDATE 0x04
#define RTCMTH 0x05
#define RTCYEAR 0x06
#define CONTROL 0x07
#define OSCTRIM 0x08
#define ALM0SEC 0x0A
#define ALM0MIN 0x0B
#define ALM0HOUR 0x0C
#define ALM0WKDAY 0x0D
#define ALM0DATE 0x0E
#define ALM0MTH 0x0F
//#define ALM1SEC 0x11
//#define ALM1MIN 0x12
//#define ALM1HOUR 0x13
//#define ALM1WKDAY 0x14
//#define ALM1DATE 0x15
//#define ALM1MTH 0x16
//#define PWRDNMIN 0x18
//#define PWRDNHOUR 0x19
//#define PWRDNDATE 0x1A
//#define PWRDNMTH 0x1B
//#define PWRUPMIN 0x1C
//#define PWRUPHOUR 0x1D
//#define PWRUPDATE 0x1E
//#define PWRUPMTH 0x1F

//variables used here
byte rtcSeconds, rtcMinutes, rtcHours;
byte rtcWeekDay, rtcDay, rtcMonth, rtcYear;
boolean rtc12hrMode, rtcPM, rtcOscRunning, rtcPowerFail, rtcVbatEn;
String weekDay[] = {"SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"};
boolean mfpPinTriggered = false;


void setup() {//setup
  Serial.begin(9600);
  attachInterrupt(0, rtcMFP, FALLING);//interrupt for rtc Alarm
  rtcInit();//go initialize RTC

  for (int i = 0; i < 18; i++) {//set all pins LOW, to save power from floating pins
    if (i != 2) //using this pin for interrupt input
      pinMode(i, OUTPUT);
  }


  //Disable ADC - don't forget to flip back after waking up if using ADC in your application ADCSRA |= (1 << 7);
  ADCSRA &= ~(1 << 7);
  //ENABLE SLEEP - this enables the sleep mode
  SMCR |= (1 << 2); //power down mode
  SMCR |= 1;//enable sleep
}

void loop() {
  goToSleep(0x01);//minutes
  
  while (!checkAlarm()) {
    //BOD DISABLE - this must be called right before the __asm__ sleep instruction
    MCUCR |= (3 << 5); //set both BODS and BODSE at the same time
    MCUCR = (MCUCR & ~(1 << 5)) | (1 << 6); //then set the BODS bit and clear the BODSE bit at the same time
    __asm__  __volatile__("sleep");//in line assembler to go to sleep
  }
  for (int i = 0; i < 10; i++) {
    digitalWrite(3, !digitalRead(3)); //LED flash
    delay(50);
  }
}




void goToSleep(byte sleepTime) {

  Wire.beginTransmission(RTCADDR);
  Wire.write(RTCSEC);
  Wire.write(0x80);//back to zero, but start counting
  Wire.endTransmission();

  Wire.beginTransmission(RTCADDR);//set the alarm time
  Wire.write(ALM0SEC);
  Wire.write(0x00);//seconds only
  Wire.write(0x01);//min
  Wire.write(0x00);//hour
  Wire.write(0x10);//clears flag, set match on minutes
  Wire.endTransmission();
  
//  Wire.beginTransmission(RTCADDR);//set the alarm time
//  Wire.write(ALM0MIN);
//  Wire.write(0x01);
//  Wire.endTransmission();
//  
//  Wire.beginTransmission(RTCADDR);//set the alarm time
//  Wire.write(ALM0HOUR);
//  Wire.write(0x00);
//  Wire.endTransmission();
//  
//  Wire.beginTransmission(RTCADDR);//set the alarm time
//  Wire.write(ALM0WKDAY);
//  Wire.write(0x10);
//  Wire.endTransmission();
  
  Wire.beginTransmission(RTCADDR);
  Wire.write(ALM0WKDAY);//check the RT Flag
  Wire.endTransmission();
  Wire.requestFrom(RTCADDR, 1);
  delay(2);
  byte printme = Wire.read();
  Serial.println();
  Serial.println(printme,BIN);
  Serial.println();
  delay(20);

  //BOD DISABLE - this must be called right before the __asm__ sleep instruction
  MCUCR |= (3 << 5); //set both BODS and BODSE at the same time
  MCUCR = (MCUCR & ~(1 << 5)) | (1 << 6); //then set the BODS bit and clear the BODSE bit at the same time
  __asm__  __volatile__("sleep");//in line assembler to go to sleep
}

void rtcInit() {// RTC Initialize
  //sets up I2C at 100kHz
  Wire.setClock(100000);
  Wire.begin();

  Wire.beginTransmission(RTCADDR);
  Wire.write(CONTROL);
  Wire.write(B00000000);//clear out the entire control register
  Wire.endTransmission();

  Wire.beginTransmission(RTCADDR);
  Wire.write(RTCWKDAY);
  Wire.endTransmission();
  Wire.requestFrom(RTCADDR, 1);
  delay(1);
  byte rtcWeekdayRegister = Wire.read();
  rtcWeekdayRegister |= 0x08;//enable Battery backup
  Wire.beginTransmission(RTCADDR);
  Wire.write(RTCWKDAY);
  Wire.write(rtcWeekdayRegister);
  Wire.endTransmission();


  Wire.beginTransmission(RTCADDR);
  Wire.write(RTCSEC);
  Wire.endTransmission();
  Wire.requestFrom(RTCADDR, 1);
  delay(1);
  byte rtcSecondRegister = Wire.read();//read out seconds
  rtcSecondRegister |= 0x80;// flip the start bit to ON
  Wire.beginTransmission(RTCADDR);
  Wire.write(RTCSEC);
  Wire.write(rtcSecondRegister);//write it back in... now the RTC is running
  Wire.endTransmission();

  Wire.beginTransmission(RTCADDR);//Enable Alarm0
  Wire.write(CONTROL);
  Wire.endTransmission();
  Wire.requestFrom(RTCADDR, 1);
  delay(1);
  byte rtcControlRegeister = Wire.read();
  rtcControlRegeister |= 0x10;//enable alm0
  Wire.beginTransmission(RTCADDR);
  Wire.write(CONTROL);
  Wire.write(rtcControlRegeister);
  Wire.endTransmission();
}

boolean checkAlarm() {
  if (mfpPinTriggered == true) {// RTC pin fell LOW
    mfpPinTriggered = false;
    Wire.beginTransmission(RTCADDR);
    Wire.write(ALM0WKDAY);//check the RT Flag
    Wire.endTransmission();
    Wire.requestFrom(RTCADDR, 1);
    delay(1);
    byte alarm0Check = Wire.read();
    Serial.println( (alarm0Check >> 3),BIN);
    if (((alarm0Check >> 3) & 0x01) == 1)//Set?
      return 1;
    else
      return 0;
  }
}

void rtcMFP() {
  mfpPinTriggered = true;
}

Source: Windows Questions C++

LEAVE A COMMENT