Raspberry Pi IoT In C - Events & Interrupts
Written by Harry Fairhead   
Monday, 02 November 2020
Article Index
Raspberry Pi IoT In C - Events & Interrupts
Events And The BCM 2835 Library
Measuring Pulses With Events
An Edgy Button

Measuring Pulses With Events

Now we have all of the functions we need to implement a pulse measurement program using events. In this case we can measure the width of any pulse as the distance between a rising and a falling edge or a falling and a rising edge.  The main difference between this and the previous program that measured the width of a pulse is that now we are using the hardware to detect the state transitions, i.e. the “edges” of the signal.

To do this we need to set the rising and falling edge detection for the pin:

bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_07,
BCM2835_GPIO_FSEL_INPT); bcm2835_gpio_fen(RPI_BPLUS_GPIO_J8_07); bcm2835_gpio_ren(RPI_BPLUS_GPIO_J8_07);

Now Pin 7 will trigger an edge event if it goes from low to high or high to low. So now all we have to do is test the status register for the event and clear it after it has been detected.

The complete program is:

#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>
#include <unistd.h>
int main(int argc, char** argv) {
    if (!bcm2835_init()) return 1;
    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_07, BCM2835_GPIO_FSEL_INPT);
    bcm2835_gpio_fen(RPI_BPLUS_GPIO_J8_07);
    bcm2835_gpio_ren(RPI_BPLUS_GPIO_J8_07);
    volatile int i;
    uint64_t t;
    while (1) {
        bcm2835_gpio_set_eds(RPI_BPLUS_GPIO_J8_07);
        while (0 == bcm2835_gpio_eds(RPI_BPLUS_GPIO_J8_07));
        t = bcm2835_st_read();
        bcm2835_gpio_set_eds(RPI_BPLUS_GPIO_J8_07);
        for (i = 0; i < 5000; i++) {
            if (1 == bcm2835_gpio_eds(RPI_BPLUS_GPIO_J8_07)) break;
        }
        t = bcm2835_st_read() - t;
        printf("%d,%llu\n\r", i, t);
        fflush(stdout);
    }
    return (EXIT_SUCCESS);
}

You can include a call to checkIRQ at the start if you don’t want to disable interrupts permanently.

Notice that we clear the edge event, then wait for another and use the number of loops as a measure of the pulse time. This program produces very similar results to those of the previous program that simply read the inputs on the GPIO line. In this case there is no real advantage in using the events approach to polling as we are reading data as fast as we can anyway. However, if you had multiple GPIO lines, and perhaps multiple conditions, to test you could set all the events you were interested in and then check to see if any of them had happened with a single bcm2835_gpio_eds_multi() function call. Notice that there is no “multi” function direct read of line states.  

How Fast Are Events

If we simple poll on rising edge events we can get an estimate of how fast we can read data by toggling another GPIO line at the end of the event loop:

#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>
#include <unistd.h>
int main(int argc, char** argv) {
    if (!bcm2835_init()) return 1;
    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_07, BCM2835_GPIO_FSEL_INPT);
    bcm2835_gpio_fen(RPI_BPLUS_GPIO_J8_07);
    bcm2835_gpio_clr_fen(RPI_BPLUS_GPIO_J8_07);
    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_11, BCM2835_GPIO_FSEL_OUTP);
    bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_11, LOW);
    uint64_t t;
    while (1) {
        bcm2835_gpio_set_eds(RPI_BPLUS_GPIO_J8_07);
        t = bcm2835_st_read();
        for (;;) {
            if (1 == bcm2835_gpio_eds(RPI_BPLUS_GPIO_J8_07)) break;
        }
        t = bcm2835_st_read() - t;
        bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_11, HIGH);
        bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_11, LOW);
    }
    return (EXIT_SUCCESS);
}

Reading the time of the rising edge is included to add some minima
l processing of the signal. A logic analyzer trace indicates that around 1.2MHz is the upper limit on input using events in a polling loop:

events1

You can see that the event takes about 0.5µs to process and this leaves just enough time to catch the next rising edge on a 1.2MHz pulse. In practice, throughput would be lower than this. This is about the same speed as the level-reading program given in Chapter 6, but there are far fewer missed pulses due to the latching effect of using events.

RiPiCIOT2nd



Last Updated ( Saturday, 07 November 2020 )