interrupts issues from UNO to MEGA

Hello,

I rebuilt a simple sketch to detail my issue.

I built a counter from RTC SQW in int1(pin3) and Anemometer interrupt on int0(pin2)
The both interrupts control blink.

This running very well on UNO board.
On MEGA board, with the same sketch and same shield, interrupt on pin 3 is disturb by the activity over interrupt on pin 2.

Have you an explanation?
today, to run correctly, I must replace int-pin2 over pin19. It’s strange and not acceptable because for my project i lost one essential interrupt.

An additional question could be: why the delay in FLASH_RTC is not respected?

#include <Wire.h>
#define DS1307_I2C_ADDRESS 0x68
int top;

void setup() {
  Serial.begin(9600);
  Wire.begin();
  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.write(0x07);
  Wire.write(0x10);
  Wire.endTransmission();
  pinMode(3,INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(19), Flash_ANEMOMETER , FALLING); 
  attachInterrupt(digitalPinToInterrupt(3), Flash_RTC , RISING); 
}

void loop() {}

void Flash_RTC ()
{
  digitalWrite(8,HIGH); 
  top = top + 1; 
  Serial.println(top);
  delay(500);
  digitalWrite(8,LOW);
}

void Flash_ANEMOMETER ()
{
  digitalWrite(7,HIGH);
  Serial.println("---------TOP----------");
  delay(100);
  digitalWrite(7,LOW);
}

You can not use Serial print or delay within an ISR. They both rely on interrupts, and interrupts are disabled within an ISR. Set flags within the isr, and process in loop based on the flag.

See nick Gammon's tutorial on interrupts http://www.gammon.com.au/interrupts

OK.

I knew the reference page from N.Gammon, but it's a little bit to complex for me.

You are right delay an functions in relation with millis doesn't work in a interrupt. But obviously Serial.print work. In my sketch it's the case. I need also to change int top; to volatile int top; but it's running without.

I don't understand exactly what is the difference between the interrupt and an ISR ? (I never used it)

Do you think this could be the reason of my perturbations between int0 and int1 on Mega board?

Could show me how keep on a led 200ms (digitalPin 8 in my sketch) from the interrupt 1 (SQW RTC)?

I discovered that pins 2, 3 and 5 are tied to timer3 (on MEGA Board) and this could create some conflicts with interrupts... I'm going to replace my wiring to avoid it, and test again

this is the correction of interrupts address, and it’s running without conflicts.

however my blinks management doesn’t work…

#include <Wire.h>
#define DS1307_I2C_ADDRESS 0x68
volatile int top;

void setup() {
  Serial.begin(9600);
  Wire.begin();
  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.write(0x07);
  Wire.write(0x10);
  Wire.endTransmission();
  pinMode(18,INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(3), Flash_ANEMOMETER , FALLING); 
  attachInterrupt(digitalPinToInterrupt(18), Flash_RTC , RISING); 
}

void loop() 
  {
  if (digitalRead(7)==HIGH) {delay(200);digitalWrite(7,LOW);}
  if (digitalRead(8)==HIGH) {delay(200);digitalWrite(8,LOW);}
  }

void Flash_RTC ()
{
  digitalWrite(8,HIGH); 
  top = top + 1; 
  Serial.println(top);

}

void Flash_ANEMOMETER ()
{
  digitalWrite(7,HIGH);
  Serial.println("---------TOP----------");

}

But obviously Serial.print work

Not really. The output is buffered and printing after the interrupt routine is finished and interrupts are reenabled. You can get into all types of strange problems trying to serial print from an iSR(interrupt service routine).

Could show me how keep on a led 200ms (digitalPin 8 in my sketch) from the interrupt 1 (SQW RTC)?

I did not test this with the RTC SQW, but used a different one second square wave on pin3. This should give you an example of blinks management

#include <Wire.h>
#define DS1307_I2C_ADDRESS 0x68
volatile int top;

volatile boolean flashLED = false;
volatile unsigned long startTime;
int LedOnTime = 200;

void setup() {
  Serial.begin(9600);
  Wire.begin();
  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.write(0x07);
  Wire.write(0x10);
  Wire.endTransmission();
  pinMode(3, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(19), Flash_ANEMOMETER , FALLING);
  attachInterrupt(digitalPinToInterrupt(3), Flash_RTC , RISING);
  
  pinMode(8,OUTPUT);//need to add this
}

void loop()
{
  //testPulse(3,500);//my test pulse
  //Serial.println(digitalRead(8));//verify toggle pin8

  if (flashLED == true)
  {
    if (millis() - startTime >= LedOnTime)
    {
      digitalWrite(8, LOW);
      flashLED = false;
    }
  }
}
void Flash_RTC ()
{
  top = top + 1;
  flashLED = true;
  startTime = millis();
  digitalWrite(8, HIGH);
  //delay(500);
  //digitalWrite(8,LOW);
}

void Flash_ANEMOMETER ()
{
  digitalWrite(7, HIGH);
  Serial.println("---------TOP----------");
  delay(100);
  digitalWrite(7, LOW);
}

void testPulse(byte pin, int toggleTime)
{
  pinMode(pin, OUTPUT);
  static unsigned long lastMillis;
 
  if (millis() - lastMillis >= toggleTime)
  {
    static boolean output = HIGH;
    lastMillis += toggleTime;
    digitalWrite(pin, output);
    output = !output;
  }
}

Thanks so much now it's clear and the sketch run normally.

For my first question, the answer is PWM & Timers. Timers gather several pins and these associations are not compatible with interrupts... this mean there is just 5 interrupts on MEGA which can run in same time. Pin 2 and 3 can't together.

For my first question, the answer is PWM & Timers.
Timers gather several pins and these associations are not compatible with interrupts.

Not true. External interrupts can respond to pins doing other things. It’s called a software interrupt.

From the Data Sheet section on external interrupts:

“The External Interrupts are triggered by the INT0 and INT1 pins or any of the PCINT23…0 pins.
Observe that, if enabled, the interrupts will trigger even if the INT0 and INT1 or PCINT23…0 pins
are configured as outputs.”

In other words, a program can trigger any one of these interrupts by writing to an interrupt-enabled pin.

Here’s an example of pwm and an interrupt on the same pin.

volatile int count;

void setup() {
  pinMode(13, OUTPUT);
  attachInterrupt(1, blink, RISING);
  analogWrite(3, 127);
}

void loop() {}

void blink ()
{
  count++;
  if (count == 200)
  {
    digitalWrite(13, !digitalRead(13));
    count = 0;
  }
}