Attachinterrupt0 and attachinterrupt1 doesn't work

Hi to everyone!

I'm developing a prototipe with arduino Leonardo and it's works perfectly.

But now I need to reduce the size and I bought a COMPATIBLE arduino mini pro (it's exactly that one: [Discontinued] STM32F103RBT6 ARM Cortex-M3 mini Development Board+Code – SainSmart.com) It's a ATMEGA328 the same thatn arduino original.

The problem is the function attachinterrupt doesn't works i try to use the pin 2 and 3 but it is not working.

It's like the attach interrupts pins aren't "configured" I've read that I can enable any pin for interrupt but i can understand so good.

I only need a pin to attachinterrupt(0, function, FALLING) for read a zero crossing dimmer signal.

Thank you very much for your help and sorry for my English I'm Spanish.

This is the code that I’m using:

int AC_pin = 13;
byte dim = 0; 
int state;

void setup() {
  Serial.begin(9600);
  pinMode(AC_pin, OUTPUT);
  attachInterrupt(0, light, FALLING);
}

void light() {
  if (Serial.available()) {
    dim = Serial.read();
    if (dim == 48) {
      digitalWrite(AC_pin, LOW);
    }
    if (dim == 49) {
      state = 45;
    }
    if (dim == 50) {
      state = 80;
    }
    if (dim == 51) {
      state = 120;
    }
    if (dim == 52) {
      state = 180;
    }
    if (dim == 53) {
      digitalWrite(AC_pin, HIGH);
    }
  }

  if (dim > 48 && dim < 53) {
    delayMicroseconds(34*(255-state));
    digitalWrite(AC_pin, HIGH);
    delayMicroseconds(500);
    digitalWrite(AC_pin, LOW);
  }
}
void loop() {
}

I may be wrong, but using any type of delay inside an interrupt is really bad. I think it has to do with the incrementation of the micros/millis being paused while in the interrupt. Therefore it will never "end" and causing your program to hang.

I used a 20k resistor on my interrupt pin as a pull else you get weirdo errors.

void light() {
  if (Serial.available()) {
    dim = Serial.read();

Once you enter the ISR, interrupts are disabled - you can't have an interrupt interrupting an interrupt - and Serial uses interrupts, so that will be an issue.

The serial.available itself isn't the issue, that returns a TRUE/FALSE, is there data in the serial buffer to be read, or isn't there.

There is a stack for interrupts that happen while processing a interrupt so that it can be done immediately after the current one is done but it can only hold so many before they are lost in the event of a long enough delay.

However it may be unavoidable while using both serial and pin interrupts in the same program, if the stack gets filled with serial interrupts while dealing with your pin interrupt, it will try to resolve them after a delay, at which point the data was already missed.

But I suspect the issue might actually be in you changing boards. I had a similar issue when I tried using 6 interrupt pins for a R/C receiver on a Leonardo. 4 worked perfect but two of them just couldn't detect the interrupts on pin 2 and pin 7, they are hardware interrupt pins but they won't work as interrupt pins unless you configure them as such.

Turns out the library wasn't/couldn't configuring those pins to be interrupts, which is why they didn't detect any interrupts. You''ll have to figure out if this is the case for you as well and how to manually configure them.

Could the fact that the Leonardo has the interrupts on pins 2 and 3 reversed compared with other Arduino boards be a factor here I wonder ?

The serial.available itself isn't the issue, that returns a TRUE/FALSE

IT DOES NOT! RTFM before spouting such nonsense.

Then tell us oh grand master who RFTM, what does it do.

harddrive123:
Then tell us oh grand master who RFTM, what does it do.

It returns an int, the number of bytes waiting in the buffer.

Yes exactly.
But when using a if statement it's only looking for a true/false.
When used in a if statement with no compare to its sum anything more then 0 will result In a return of TRUE.
So what is the problem with what I said?

So what is the problem with what I said?

It wasn't true. The function does not return true or false. It returns the number of characters available to read. That a non-zero value means true and a zero value means false is completely irrelevant.

Your nit picking. In this context the serial.available is only used as true/false check for data. I was clearly referring to the point that running it inside a interrupt , I don't believe it causes any conflicts.

Did you expect me to spell it out and give a half page explanation of it's other uses?

As Kalveo mentioned you cannot have a delay() inside an interrupt routine to create a delay.
Secondly the serial communication uses interrupts which, as CrossRoads mentioned : are disabled inside interrupt routine by default. You can enable them using sei(),but be careful it would also enable the interrupt for which the ISR itself is written for. So you have to disable the external interrupt first then enable global interrupts and after your operation enable the external interrupt once again.(you have to do these inside ISR. Its a little complex)

And to create the delay either you have to write it inside the loop() like below

void loop() 
{

  if(flag==1)
  {
    cli();//clear global interrupt flag
    if (dim > 48 && dim < 53) {
      delayMicroseconds(34*(255-state));
      digitalWrite(AC_pin, HIGH);
      delayMicroseconds(500);
      digitalWrite(AC_pin, LOW);
    }
    flag=0;
    sei();//enable global interrupt flag
  }

}

or you have to create delay by giving the CPU to do something(counting from a large number till zero or vice versa) but you may not get accurate delay.

And finally you have not declared the dim variable as ‘volatile’. This is necessary,since it gets modified inside ISR.

What is the maximum frequency of the zero crossing dimmer? may be you need not do all this(enabling and disabling interrupts), if the frequency is low and predictable.