Pinchangeint does not work on pin 2

I have a DS3231 RTC what triggers alarm. I what the alarm pin of the rtc connected to digital pin 2 on an arduino mega2560 board. I use this library:

When i test the “intalarm” code from the example folder, it works great.

However, when i add the Pinchangeint library to the code and modify to trigger the alarms from the RTC, nothing happens.
I checked in the forum for others, but they seems to have the pinchangeint working in digital pin 2. So, why it does not work for me?

Any idea?

This is the working code:

#include <Wire.h>
#include <DS3231.h>

DS3231 clock;
RTCDateTime dt;
boolean isAlarm = false;
boolean alarmState = false;
int alarmLED = 24;

void alarmFunction()
{
  Serial.println("*** INT 0 ***"); 
  isAlarm = true;
}

void setup()
{
  Serial.begin(9600);
  
  // Initialize DS3231
  Serial.println("Initialize DS3231");;
  clock.begin();
 
  // Disarm alarms and clear alarms for this example, because alarms is battery backed.
  // Under normal conditions, the settings should be reset after power and restart microcontroller.
  clock.armAlarm1(false);
  clock.armAlarm2(false);
  clock.clearAlarm1();
  clock.clearAlarm2();

  // Manual (Year, Month, Day, Hour, Minute, Second)
  //clock.setDateTime(2014, 4, 25, 0, 0, 0);

  // Set Alarm1 - Every 20s in each minute
  // setAlarm1(Date or Day, Hour, Minute, Second, Mode, Armed = true)
  clock.setAlarm1(0, 0, 0, 10, DS3231_MATCH_S);

  // Attach Interrput 0. In Arduino UNO connect DS3231 INT to Arduino Pin 2
  attachInterrupt(0, alarmFunction, FALLING);

  // Setup LED Pin
  pinMode(alarmLED, OUTPUT);
}

void loop()
{
  dt = clock.getDateTime();
  Serial.println(clock.dateFormat("d-m-Y H:i:s - l", dt));
  if (isAlarm)
  {
    digitalWrite(alarmLED, alarmState);
    alarmState = !alarmState;
    clock.clearAlarm1();
  } 
  delay(1000);
}

and this one is the code what doesn´t work:

#include <Wire.h>
#include <DS3231.h>
#include <PinChangeInt.h>

DS3231 clock;
RTCDateTime dt;
boolean isAlarm = false;
boolean alarmState = false;
int alarmLED = 24;
const int selectPin = 2;

void alarmFunction()
{
  Serial.println("*** INT 0 ***");
  isAlarm = true;
}

void setup()
{
  Serial.begin(9600);
  
  // Initialize DS3231
  Serial.println("Initialize DS3231");;
  clock.begin();
 
  // Disarm alarms and clear alarms for this example, because alarms is battery backed.
  // Under normal conditions, the settings should be reset after power and restart microcontroller.
  clock.armAlarm1(false);
  clock.armAlarm2(false);
  clock.clearAlarm1();
  clock.clearAlarm2();

  // Set Alarm1 - Every 10s in each minute
  // setAlarm1(Date or Day, Hour, Minute, Second, Mode, Armed = true)
  clock.setAlarm1(0, 0, 0, 10, DS3231_MATCH_S);

  // Attach Interrput 0. In Arduino UNO connect DS3231 INT to Arduino Pin 2
  pinMode(selectPin, INPUT); digitalWrite(selectPin, HIGH);
  PCintPort::attachInterrupt(selectPin, &alarmFunction, FALLING);

  // Setup LED Pin
  pinMode(alarmLED, OUTPUT);
}

void loop()
{
  dt = clock.getDateTime();
  Serial.println(clock.dateFormat("d-m-Y H:i:s - l", dt));
  if (isAlarm)
  {
    digitalWrite(alarmLED, alarmState);
    alarmState = !alarmState;
    clock.clearAlarm1();
  } 
  delay(1000);
}

I know that the interrupt funcion contains a Serial.print, what is not a good thing. The example comes with this function. I deleted this line but the problem remains, and it works in the first code.

The code compiles, but it only shows the date and time… when the time rise 10 seconds, do nothing.
Any idea?

Thanks!

Pin change interrupts do not work on all the pins of the Mega, there are only
24 pins supported - section 15 of the datasheet explains more.

Oh, really?

I beleave you, but there are many examples on internet and this forum where the people use the pinchageint also in digital pin 2 .. i assumed that this should also work in arduino mega2560 boards.

Anyway, i used the normal interrupt in my code inpin 2 together with oinchangeint in other pins, and everything seems to work, so, solved!!

Thanks @MarkT

There are only 3 control registers in the architecture for pin-change interrupts, so only 24 pins are supported. That's enough for all the Uno pins, but not all the Mega pins.

On the datasheet pinout-diagrams you'll see all the pin-change capable pins have an alias of the form PCINTnn where nn can range from 0 to 23

You are right!

It was my fault to assume it was the same for both uno and mega boards. Thanks for your explanations.

You are using isAlarm in loop() and in alarmFunction(), yet isAlarm is not volatile. A bad idea omitting the volatile declaration.

You are doing interrupt-requiring things in an interrupt service routine, where interrupts are disabled. Hope you don't mind when the Arduino locks up.