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.
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.
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?
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.