Tutorial: Interrupt-Driven Event-Counter on the Raspberry Pi
--D. Thiebaut (talk) 19:57, 23 July 2013 (EDT)
This page is under construction. Its purpose is to illustrate how to implement a user-level interrupt in C on a Raspberry Pi to count events. You may want to start with the very first tutorial of this series, here.
Contents
Getting the Environment Ready
Install the WiringPi Library
- Get the WiringPi library from drogon.net
- Follow the directions on the Web site to download to the Pi. In my case the Pi is connected to my Mac through an ethernet cable, so I downloaded the tgz archive from https://git.drogon.net/?p=wiringPi;a=summary and sftp it over to the pi. I renamed the actual library to wiring.tgz, which is easier to type than its actual name.
sftp pi@169.254.0.2 sftp> pwd Remote working directory: /home/pi sftp> put wiring.tgz Uploading wiring.tgz to /home/pi/wiring.tgz wiring.tgz 100% 108KB 107.8KB/s 00:00 sftp> quit
- Connect to the RPI and build the library
tar -xzvf wiring.tgz cd wiringPi-cbf6d64/ ./build wiringPi Build script ===================== WiringPi Library make: Warning: File `Makefile' has modification time 1.4e+07 s in the future [UnInstall] [Compile] wiringPi.c [Compile] wiringSerial.c ... [Compile] drc.c [Link (Dynamic)] [Install Headers] [Install Dynamic Lib] make: warning: Clock skew detected. Your build may be incomplete. WiringPi Devices Library make: Warning: File `Makefile' has modification time 1.4e+07 s in the future [UnInstall] [Compile] ds1302.c ... [Link (Dynamic)] [Install Headers] [Install Dynamic Lib] make: warning: Clock skew detected. Your build may be incomplete. GPIO Utility make: Warning: File `Makefile' has modification time 1.4e+07 s in the future [Compile] gpio.c [Compile] extensions.c [Compile] readall.c [Link] make: warning: Clock skew detected. Your build may be incomplete. make: Warning: File `Makefile' has modification time 1.4e+07 s in the future [Install] make: warning: Clock skew detected. Your build may be incomplete. All Done. NOTE: This is wiringPi v2, and if you need to use the lcd, Piface, Gertboard, MaxDetext, etc. routines then you must change your compile scripts to add -lwiringPiDev
- Add the new library to the libray path, as explained in the INSTALL file of the wiringPi distribution.
sudo nano /etc/ld.so.conf
- and add the following line to it:
/usr/local/lib
- Tell the system to configure the libraries:
sudo ldconfig
Hardware Setup
- Our hardware setup is the same as that presented in Introduction to accessing the Raspberry Pi’s GPIO in C++ (Linux Way / SYSFS) on hertaville.com. We have connected the switch only. The printf statements will provide the feedback about whether activating the button triggers the ISR or not.
- We use PIN 17 of the GPIO, available on the RPI 26-pin connector Pin 11.
- Connecting the momentary switch is simple:
- 1 lead connected to GND
- other lead connected to two places:
- to one side of a a 10Kω resistor, the other side of the resistor to 3.3V
- to Pin 17 of the GPIO
Interrupt Service Routine
Picking the Right Constant for GPIO Pin 17
- The wiringPi library labels GPIO Pin 17 as Pin 0 (see drogon.net), as illustrated in the table below taken from their Web site:
- Our switch is connected to Pin 17 of the GPIO, so we'll use 0 to refer to this pin when using the wiringPi library.
ISR Code
The code for the Interrupt Service Routine is given below. Its operation is simple:
- it defines Pin 0 (GPIO Pin 17) as the pin which will receive the events
- it defines a function that will be called by the interrupt triggered by Pin 0.
- it initializes the wiringPi library
- it attaches
/*
isr4pi.c
D. Thiebaut
based on isr.c from the WiringPi library, authored by Gordon Henderson
https://github.com/WiringPi/WiringPi/blob/master/examples/isr.c
Compile as follows:
gcc -o isr4pi isr4pi.c -lwiringPi
Run as follows:
sudo ./isr4pi
*/
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <wiringPi.h>
// Use GPIO Pin 17, which is Pin 0 for wiringPi library
#define BUTTON_PIN 0
// the event counter
volatile int eventCounter = 0;
/*
* myInterrupt:
*/
void myInterrupt (void) {
eventCounter++;
}
/*
* main
*/
int main (void) {
if (wiringPiSetup () < 0) {
fprintf (stderr, "Unable to setup wiringPi: %s\n", strerror (errno));
return 1;
}
if ( wiringPiISR (BUTTON_PIN, INT_EDGE_FALLING, &myInterrupt) < 0 ) {
fprintf (stderr, "Unable to setup ISR: %s\n", strerror (errno));
return 1;
}
while ( 1 ) {
// display # of events in past second
printf( "%d\n", eventCounter );
// reset counter to 0
eventCounter = 0;
// wait 1 second doing nothing...
delay( 1000 ); // wait 1 second
}
return 0;
}
Compilation
- Compile the code above against the WiringPi library as follows:
gcc -o isr4pi isr4pi.c -lwiringPi