Odd behaviour with multiple 'InterruptIn's

30 Mar 2011

I have published a program at http://mbed.org/users/Kemp/programs/interruptin_test/ which demonstrates my problem. Basically, it sets up three InterruptIn objects for different pins, to which buttons are attached. I observe the following behaviour:

Button 1 pressed: It prints out "Button 1" every time and occasionally also "Button 2".

Button 2 pressed: It prints out "Button 1Button 2" every time.

Button 3 pressed: It prints out "Button 3Button 2" almost every time, occasionally I get lucky and it only prints "Button 3".

I have confirmed that only the pin associated with the correct button actually goes high. Can anyone confirm this behaviour on their own boards or offer a possible explanation?

30 Mar 2011

You might try moving the printfs into the main loop, and debouncing the switches.

As it stands, the bouncing switches will call the isrs in rapid fire, which will probably overwhelm the attempted printfs.

In other words, try something like this:

//setup code omitted...

int button1flag = 0;
int button2flag = 0;
int button3 flag = 0;

void button1_pressed() {button1flag = 1;}
void button2_pressed() {button2flag = 1;}
void button3_pressed() {button3flag = 1;}

int main()
{
    // Set up buttons
    button1.mode(PullDown);
    button1.rise(&button1_pressed);
     
    button2.mode(PullDown);
    button2.rise(&button2_pressed);
     
    button3.mode(PullDown);
    button3.rise(&button3_pressed);
     
    while (1) {
       if(button1flag) {
          pc.printf("Button 1\n");
          button1flag = 0;
          wait_ms(50);       // debounce
       }
       if(button2flag) {
          pc.printf("Button 1\n");
          button2flag = 0;
          wait_ms(50);       // debounce
       }
       if(button3flag) {
          pc.printf("Button 1\n");
          button3flag = 0;
          wait_ms(50);       // debounce
       }
    }
 }

Or, for a much more elegant approach, look up Andy Kirkham's input handling library. It does the debouncing for you, among other things.

30 Mar 2011

Import libraryPinDetect

InterruptIn style DigitalIn debounced with callbacks for pin state change and pin state hold.

[Edit, oh, and as Hexley said, move the printfs out of the callbacks. For more on this please read this article.

30 Mar 2011

I should clarify that I was seeing this behaviour without the printfs. They were in this program as a simple demonstration of what was happening. I don't understand bouncing causing the effect I'm seeing as even if I just start the program and press Button 2 once, I see the print for Button 1 as well as the print for Button 2. Is the interrupt handling really so sensitive that completely the wrong interrupt can be triggered by 2-3 rapid calls occurring (that's approximately how many I see when pressing this type of switch without debouncing)?

I will try out Andy's library, but I'd like to know why this is occurring (for reason of curiosity if nothing else).

30 Mar 2011

It sounds like some sort of cross-coupling between the signal lines. Can you give us some details on how you have wired the pushbuttons? (E.g., how long are the leads? Are they bundled together? Are you using any external resistors to pull up or down? Are the switches hooked straight to +3.3?)

30 Mar 2011

I did it via the simplest method possible - one side of the switch goes to +3.3V, one side goes directly into the mbed pin. The wires are bundled together and are approximately 10-15cm long. I hooked a scope up to the pins and don't see any noise on (for example) the pin for button 1 when button 2 is pressed. Pull down is provided internally by the mbed, I don't provide my own.

30 Mar 2011

The wiring looks correct.

The only thing that might be suspect is reliance on the internal pulldown. The spec sheet says that the pulldown current is typically 50uA (can be between 10uA and 150uA). That's a pretty soft pull down - equivalent to a 66K ohm resistor.

I have cases where human-body-coupled AC noise from the powerline would drive an such an input, just by bringing a finger near a switch. That is, the high impedance input node would be driven by a few volts of AC hum, and would take that as a valid input signal.

To see if this is the sort of problem you are having, try making the input node much lower impedance.

For example, you could add external pulldown resistors of, say, 330 ohms. That should make the inputs much less sensitive to noise, yet still only require 10mA from the pushbutton. You could also add 10nF capacitors to ground, if you really wanted to nail things down.

30 Mar 2011

Thanks for the suggestions, I'll try that out tomorrow and report my findings. Hopefully if I nail this down then it will become more reliable, even if I switch to using PinDetect.

30 Mar 2011

You could also try setting the pin to pullup mode and then having one side of the switch connected to ground and the other to the pin. But then a button press becomes a "falling edge" as opposed to a rising edge.

PinDetect was really designed for mechanical switches anyway. InterruptIn's are really for being driven by a logic input that isn't going to "wobble" (mech switches always do to some extent). Also, if you decide to go with using the pin pullup and connecting switches to ground PinDetect has the handy feature of "inverting the logic" so that high on the pin is reported as zero and 0v on the pin is reported as one (additionally, the rising and faling edge detection is also swapped). This is to allow you to wire up a switch "inverted" and still use "normal" sense when writing the your program.

30 Mar 2011

Thanks Andy. I have looked at your library and saw that it offers several more features than available from the InterruptIn class.