Go Down

Topic: External Interrupt crash (Read 2198 times) previous topic - next topic

Mirco_b

Hello, I am trying to raise an interrupt when a button connected to pin 3 is pressed, so on the RISING edge of pin 3. The code I run is:
Code: [Select]

int buttonPin=3;
int button;

void setup(){
  Serial.begin(9600);
  pinMode(buttonPin,INPUT);
 
  // Attach interrupt routine to pin 3. Raised on RISING edge!
  attachInterrupt(1,buttonHandler,RISING);
}

void loop(){
  button=digitalRead(buttonPin);
  Serial.print("button:");
  Serial.println(button);
  delay(40);
}

void buttonHandler(){
  Serial.println("BUTTON ON!!");
}


So I control button value in each loop and when it turns ON the routine buttonHandler should be executed.

The problem is that sometimes it is executed more than once and it always let arduino crash, in the sense that arduino stops running after the execution of the routine. I need then to reset it.

How is that possible? Does anyone have any suggestion?

Thanks

majenko


Mirco_b

Thanks a lot, I guess it was that problem. I tried to disable interrupts and the re-enable them and it seems to work, even though it still executes the routine twice on Rising edges.
By now I do not have the components to try the debounce circuit, but I will try when I'll got them.

Thanks again!

PaulS

Interrupt service routines are supposed to be very, very fast.

Code: [Select]
void buttonHandler(){
  Serial.println("BUTTON ON!!");
}


Serial printing is NOT fast, by any stretch of the imagination, regardless of the baud rate. Enough said.

Jack Christensen

Is there some reason that the button must be read via an interrupt, as opposed to polling it? A software debounce algorithm could then be used as well, eliminating the need for additional circuitry.
MCP79411/12 RTC ... "One Million Ohms" ATtiny kit ... available at http://www.tindie.com/stores/JChristensen/

Nick Gammon


Serial printing is NOT fast, by any stretch of the imagination, regardless of the baud rate. Enough said.


The serial buffer isn't particularly large. With bounces it might try to send that message 20 times. The buffer fills up, it waits for an interrupt to empty it, that doesn't happen inside an ISR so it "crashes". Really, it is just waiting forever for interrupts to be enabled again.
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

Mirco_b

Ok, so what I should do is using Interrupts for really fast tasks. But how can I determine if is it fast enough?

Mirco_b

Quote
Is there some reason that the button must be read via an interrupt, as opposed to polling it? A software debounce algorithm


The problem is that I am implementing a Domain Specific Language to automatically generate Arduino code, and in the language I defined the concept of Interrupt. But when the user declares an Interrupt then I have no control on what will be written in the handler.
So I need to know what is allowed and what is not, so to report it to the user.

What do you mean with software debounce algorithm?

Thanks

AWOL

Quote
So I need to know what is allowed and what is not, so to report it to the user.

Anything that takes a long time or messes with other interrupts.

Quote
I am implementing a Domain Specific Language

A what?
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Mirco_b

It's a specification language in which a user can specificy how the system is composed (which sensors, actuators...) and how they behave (interrupts, polling, tasks..). Then the interpreter automatically generates all the Arduino code needed, leaving to the user the specification of small parts of the code (the business logic). Basically I generate the skeleton and the user adds some little parts once everything is generated.

PeterH


It's a specification language in which a user can specificy how the system is composed (which sensors, actuators...) and how they behave (interrupts, polling, tasks..). Then the interpreter automatically generates all the Arduino code needed, leaving to the user the specification of small parts of the code (the business logic). Basically I generate the skeleton and the user adds some little parts once everything is generated.



It seems to me that neither you nor your users are taking responsibility for timing control, so I suggest you need to design your architecture so that no control is needed. To start with, I'd say that nothing user defined should happen within an interrupt. I don't know what you're using interrupts for, but look for ways to do it without involving interrupts.
I only provide help via the forum - please do not contact me for private consultancy.

Mirco_b

Yes it's true, when I was implementing the interpreter I couldn't try interrupts because I did not have enouh components and in Arduino documentation there is no reference to these kind of problems.
Of course I should re-think their usage...

Nick Gammon


Ok, so what I should do is using Interrupts for really fast tasks. But how can I determine if is it fast enough?


...


Yes it's true, when I was implementing the interpreter I couldn't try interrupts because I did not have enouh components and in Arduino documentation there is no reference to these kind of problems.


The meaning of these words strangely eludes me.
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

Jack Christensen

#13
Jun 27, 2012, 02:35 pm Last Edit: Jun 27, 2012, 02:42 pm by Jack Christensen Reason: 1

What do you mean with software debounce algorithm?


Buttons and switches, being mechanical beasties that involve springs, levers, etc., often do not cleanly make or break a circuit. For example, when closing a switch, it may not just be open one moment and closed the next, but it goes through a transition phase where the contacts open and close rapidly (bounce); this may last some milliseconds. This is of course the opposite of what is usually desired in a logic circuit, where we want a single, clean transition from one state to the other. Most logic circuits are fast enough to react to each bounce, so a single actuation of the switch may be seen as dozens of state transitions by the circuit. Mitigating this behavior and transforming it into a single, clean transition is called debouncing, and can be addressed with either hardware or software. See http://en.wikipedia.org/wiki/Switch#Contact_bounce

Additionally, a microcontroller circuit may handle a switch in various ways. One way is via interrupts, another way is "polling" or frequently reading the switch state.

I'm not familiar with writing DSLs, but in this case, if the language is intended to address more than fairly simple use of common sensors, etc., it will need to comprehend various applications of said sensors. Another example with switches, depending on how they are wired, the logic may be inverted or not. So a button switch could give a high logic level when pressed if wired one way, or a low logic level when pressed if wired differently. It's also possible for a switch to be used in multiple modes in a single circuit. I have a couple projects where a button generates an interrupt in one state, but is polled when the circuit is in another state. For the DSL to be really robust, it would have to allow for such things.
MCP79411/12 RTC ... "One Million Ohms" ATtiny kit ... available at http://www.tindie.com/stores/JChristensen/

Mirco_b

Ok thanks.
I will try with hardware debounce and I will look for a sotware algorithm too. If I succeed to implement it via SW I can let the user define small interrupt routines and that should be one more feature of my language...

Go Up