Offline
Newbie
Karma: 0
Posts: 11
|
 |
« on: June 25, 2012, 05:52:11 am » |
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: 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
|
|
|
|
|
Logged
|
|
|
|
|
UK
Offline
Edison Member
Karma: 45
Posts: 2244
What a host of balls she had seen: gaity, the brass buttons...
|
 |
« Reply #1 on: June 25, 2012, 05:55:44 am » |
It's probably button bounce. You should see this thread: http://arduino.cc/forum/index.php/topic,110756.0.html
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 11
|
 |
« Reply #2 on: June 25, 2012, 06:01:34 am » |
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!
|
|
|
|
|
Logged
|
|
|
|
|
Seattle, WA USA
Offline
Brattain Member
Karma: 316
Posts: 35566
Seattle, WA USA
|
 |
« Reply #3 on: June 25, 2012, 07:47:21 pm » |
Interrupt service routines are supposed to be very, very fast. void buttonHandler(){ Serial.println("BUTTON ON!!"); } Serial printing is NOT fast, by any stretch of the imagination, regardless of the baud rate. Enough said.
|
|
|
|
|
Logged
|
|
|
|
|
Grand Blanc, MI, USA
Offline
Faraday Member
Karma: 43
Posts: 2518
"We're a proud service of the Lost Electricity Reclamation Agency"
|
 |
« Reply #4 on: June 25, 2012, 07:55:46 pm » |
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.
|
|
|
|
|
Logged
|
|
|
|
|
Global Moderator
Melbourne, Australia
Offline
Shannon Member
Karma: 219
Posts: 13896
Lua rocks!
|
 |
« Reply #5 on: June 26, 2012, 02:01:29 am » |
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.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 11
|
 |
« Reply #6 on: June 27, 2012, 04:38:02 am » |
Ok, so what I should do is using Interrupts for really fast tasks. But how can I determine if is it fast enough?
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 11
|
 |
« Reply #7 on: June 27, 2012, 04:43:19 am » |
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
|
|
|
|
|
Logged
|
|
|
|
|
Global Moderator
UK
Offline
Brattain Member
Karma: 138
Posts: 19067
I don't think you connected the grounds, Dave.
|
 |
« Reply #8 on: June 27, 2012, 04:52:06 am » |
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. I am implementing a Domain Specific Language A what?
|
|
|
|
|
Logged
|
Pete, it's a fool looks for logic in the chambers of the human heart.
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 11
|
 |
« Reply #9 on: June 27, 2012, 05:17:15 am » |
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.
|
|
|
|
|
Logged
|
|
|
|
|
UK
Offline
Tesla Member
Karma: 89
Posts: 6400
-
|
 |
« Reply #10 on: June 27, 2012, 05:39:36 am » |
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.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 11
|
 |
« Reply #11 on: June 27, 2012, 05:44:21 am » |
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...
|
|
|
|
|
Logged
|
|
|
|
|
Global Moderator
Melbourne, Australia
Offline
Shannon Member
Karma: 219
Posts: 13896
Lua rocks!
|
 |
« Reply #12 on: June 27, 2012, 06:25:42 am » |
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.
|
|
|
|
|
Logged
|
|
|
|
|
Grand Blanc, MI, USA
Offline
Faraday Member
Karma: 43
Posts: 2518
"We're a proud service of the Lost Electricity Reclamation Agency"
|
 |
« Reply #13 on: June 27, 2012, 07:35:39 am » |
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_bounceAdditionally, 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.
|
|
|
|
« Last Edit: June 27, 2012, 07:42:03 am by Jack Christensen »
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 11
|
 |
« Reply #14 on: June 27, 2012, 09:51:22 am » |
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...
|
|
|
|
|
Logged
|
|
|
|
|
|