Hello everybody,
I apologie for treating again this argument, but i haven't be able to find a solution yet.
I'm programming an Arduino Uno for control (not in the sense of PDI or other controller) an old knitting machine. I'm using interrupts for signal coming from the limitswitchs or emergency stop button, so i really need interrupts. Once i get those signals i'd like to play an acoustic signal and make a light blinking. Here come my difficulty since once in ISR i cant use anymore any other interrupt-based function, I could use delayMicroseconds and loop it for bigger delay but is not really clean to spend much time into ISR, and i still have the problem with the tone function. Flags are not a good solutions since signals can occurs in any moment, and the stop has to be fast, I would have to put flag check everywhere in my code.
That is VERY unlikely. Proper, that is non-blocking, code means that loop() iterates 1000's of times a second, and can poll the switches very quickly.
but is not really clean to spend much time into ISR
No, it isn't.
Flags are not a good solutions since signals can occurs in any moment
There you are wrong. A non-blocking code will detect the signals soon enough.
That you are even considering how to delay() in an ISR, or ANYWHERE in your code, means that you have not grasped the fact that you MUST write non-blocking code. That means, quite simply, NO DELAYS.
and the stop has to be fast
An E-stop button should cut power to the motors AND tell the Arduino that that happened. The E-stop button should NOT tell the Arduino to cut power.
That you are thinking along those lines means that you do not understand what an E-stop switch is for.
Robin2 has several tutorials that should be mandatory reading. One of them is an extension of the blink without delay technique to do a lot more than blink one LED on a regular basis. Well worth searching for.
ZenoM:
Hello everybody,
I apologie for treating again this argument, but i haven't be able to find a solution yet.
I'm programming an Arduino Uno for control (not in the sense of PDI or other controller) an old knitting machine. I'm using interrupts for signal coming from the limitswitchs or emergency stop button, so i really need interrupts. Once i get those signals i'd like to play an acoustic signal and make a light blinking. Here come my difficulty since once in ISR i cant use anymore any other interrupt-based function, I could use delayMicroseconds and loop it for bigger delay but is not really clean to spend much time into ISR, and i still have the problem with the tone function. Flags are not a good solutions since signals can occurs in any moment, and the stop has to be fast, I would have to put flag check everywhere in my code.
Thank you for any solution or advice.
Is your ISR running continuously (that is, fired by the system clock divided by "factor")?
If so, this code snippet should give you an idea how to do delays without hogging the ISR:
// ISR vars must be declared "volatile"
volatile uint8_t busy; // ISR busy flag
volatile uint16_t count; // counter
// the ISR
ISR (TIMER0_COMPA_vect)
{
if (count) {
count--; // decrement count
} else {
busy = 0; // flag ISR is done
}
}
void delay_msec (uint16_t msec) // delay 1 to 65535 msec - use uint32_t if you need more
{
while (msec--) { // for each millisecond
cli(): // interrupts off while changing ISR
busy = 1; // flag ISR busy
count = (ISR_RATE / 1000); // constant for 1 msec
sei(); // interrupts back on
while (busy); // wait for count to finish
}
}
As far as "emergency stop" switches... you should NEVER trust the computer to cut power or stop a machine. The computer could crash. Use a hard wired mechanical switch wired directly to the thing you want to stop. Even build in redundancy by using a double pole e-stop switch and wire it in series so that in the (very unlikely) event one set of contacts are stuck closed, the other will do the job.
Thank you for the replies.
About the Emergency stop i would never use it just for send an information to the mcu, in fact is already mounted and working on the machine.
For let the program flow I've relayed on Ivan Seidel "threading" library, anyway I'm using some inner for and while loops, the reason i wanted to use interrupt is for not check one button in any loop and avoid to do it also with the interrupt-flag. I don't have thousand loops, so nothing bad in this, was just for a different solution.