8 years, 8 months ago.

Problem with InterruptIn Example (FRDM KL25Z)

I'm trying to use an external pulse to trigger an action. I enter a pulse from a function generator (1 Hz, 0 to 3V, 20% duty cycle). The LED on the board is switching but erratically (not with the rising edge of the pulses). I measure with the osciloscope and I don't see much noise. I tried on different pins on port A and D, which are supossed to work with InterruptIn on the FRDM-KL25Z. I tried connecting the reference wire to 3 different GND pins available on this board, but the LED toggles in irregularly.

What could be happening? Am I missing something?

#include "mbed.h"
 
InterruptIn button(PTD6);
DigitalOut led(LED1);

 void flip() {
    led = !led;
}
 
int main() {
    button.rise(&flip);  // attach the address of the flip function to the rising edge
    while(1) {           // wait around, interrupts will interrupt this!
        wait_us(25);
    }
}

1 Answer

8 years, 8 months ago.

This is another way to test the button state, it will set IRQ to '1' if the button is pressed. The while loop will test if IRQ is '1' on every pass. Generally it is best practice to keep interrupt call back code as small as possible and test a flag in you main program. This is very important if you have other parts of your program communicating with a display over serial port for instance where you must not interrupt the data flow to the display until finished. Also the KL25 does not have 'pulldown' so we use 'pullup' and switch to ground to detect button state, saves external pull resistor on your switch.

snip - untested

#include "mbed.h"
 
InterruptIn button(PTD6);
DigitalOut led(LED1);


int IRQ;

void flip() {
    IRQ=1;
}

int main(){        
    
    button.mode(PullUp);  // Use pullup as we do not have a pulldown on the KL25
    button.fall(&flip);  // attach the address of the flip function to the falling edge
    
    IRQ=0;
    
    while(1) {      
        
        if(IRQ==1){
            while(button==0){}  // wait until button has been released, PTD6 pin goes high.
            wait_ms(10); // add some switch de-bounce delay. But not essential.
            led = !led;
            IRQ=0;  // set IRQ to 0 again to wait for next button press.
        }  
     
      // You can do something else here and the led will flip if IRQ == 1 (true) on each pass of the loop.
      // you don't need any wait here, but if you do put a wait(5); for instance, you will see a delay before the led flips.      
        
    }
}

Accepted Answer

Paul, I tried your code with minor changes, using a signal generator with a pulse to test it (instead of a button). It seems to work with a flaw: not only it toggles the led on the falling edge of the pulse, but also on the rising edge (the LED time on and off changes with the duty cycle of the pulse).

Also it works better when a wait is used before the if statement. There is very low noise on the pulse. I also tried on different pins of port A and D. Any idea of what could be wrong? Thank you, Paul.

Edit: if I attach another function to the other edge it works!

works better!

#include "mbed.h"
 
InterruptIn button(PTD7);
DigitalOut led(LED1); 
 
int IRQ;

void flip() {
    IRQ=1;
}

void no_flip(){
    IRQ = 0;
    }
    
    
int main(){        
    
    button.mode(PullUp);
    button.rise(&flip);  // attach the function to the raising edge
    button.fall(&no_flip);  // attach function to the falling edge
    IRQ=0;
    
    while(1) {
        wait_ms(50);  // a shorter wait_ms causes erratics toggles (are my wires really ok?)
        if(IRQ==1){
            led = !led;
            IRQ=0;
        }  // end if
    } // end while
}
posted by Diego Fainstein 20 Apr 2016