Skip to content
Frank Bauernöppel edited this page Jun 7, 2019 · 17 revisions

For available GPIO pins on the RasPi see expansion header.

For default pull-up/pull-down modes see Table 6-31 of BCM2835-ARM-Peripherals.pdf.

GPIO programming example

We use BCM pad 18 for testing with a LED + serial resistor. Connect the LED cathode (shorter wire) to GND (J8 pin 14) and LED anode (longer wire) via a serial resistor for current limiting to J8 pin 12 which is routed to BCM pin 18.

expansion header pin pin funcion SoC pin connect
12 GPIO 18 resistor -> LED anode
14 GND LED cathode

command line access

Note: the following uses the sysfs interface which is now deprecated. Since kernel 4.8 there is a new libgpiod interface. Todo: adapt to the new interface.

from the command prompt on your running Pi:

export (==make visible) GPIO pin 18:

root@raspberrypi3:~# echo 18 > /sys/class/gpio/export

make pin 18 an output:

root@raspberrypi3:~# echo out > /sys/class/gpio/gpio18/direction 

set its value to 1 (high), the LED should switch on:

root@raspberrypi3:~# echo 1 > /sys/class/gpio/gpio18/value

set its value to 0 (low), the LED should switch off:

root@raspberrypi3:~# echo 0 > /sys/class/gpio/gpio18/value

If you like bash hacking, let the LED blink from the console. A main loop could look like:

while :
do  
  echo 1 > /sys/class/gpio/gpio18/value
  sleep 1
  echo 0 > /sys/class/gpio/gpio18/value
  sleep 1
done

but it is still missing initialization and termination code:

  • export must be done only once in the beginning when /sys/class/gpio/gpio18/ does not yet exists
  • it is good style to unexport the pin if no longer needed (which also switches the LED off) In the shell script this can be achieved with a trap line.

A complete example looks like:

# /bin/sh

# signal handler containing termination code
trap "echo 18 > /sys/class/gpio/unexport; exit" SIGHUP SIGINT SIGTERM

# initialization code 
echo 18 > /sys/class/gpio/export
echo out > /sys/class/gpio/gpio18/direction 

# main loop
while :
do  
  echo 1 > /sys/class/gpio/gpio18/value
  sleep 1
  echo 0 > /sys/class/gpio/gpio18/value
  sleep 1
done

timing

Timing can hardly be controlled when using a shell for GPIO toggling. Try the shortest possible pulse:

echo 0 > /sys/class/gpio/gpio18/value
echo 1 > /sys/class/gpio/gpio18/value
echo 0 > /sys/class/gpio/gpio18/value

Using a scope you may see a 3..5 ms wide pulse. But, there is guarantee for timing! So, using the shell interface is mainly useful for testing and slow peripherals like switching a LED on. It cannot be used for PWM or motor control.

access from a C program

This code can be one-to-one translated into C code using POSIX style file access functions. For a complete example see: http://www.netzmafia.de/skripten/hardware/RasPi/RasPi_GPIO_C.html

Note: The C equivalent of a trap command is a signal handler.

timing

The timing may be faster, but remains rather unpredictable because the user mode C app may be interrupted by the Linux scheduler. Moreover, the sleep function and its friends only guarantee minimum timeouts.

GPIO interrupt handling

Example GPIO4 (header pin 7).

# export Pin
$ echo 4 > /sys/class/gpio/export

# activate falling edge interrupt
$ echo falling > /sys/class/gpio/gpio4/edge

# watch interrupts in shell
$ watch -n1 "cat /proc/interrupts"

using C code

#include <stdio.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <poll.h>

int main()
{
  // pin must already been exported and configured for interrupt (shell)
  int fd = open( "/sys/class/gpio/gpio4/value", O_RDONLY);
  if(fd < 0) {
    perror("fd");
  }
  struct pollfd pollfds;

  pollfds.fd = fd;
  pollfds.events = POLLPRI;

  static char buf[256];
  lseek(fd, 0, SEEK_SET);
  read(fd, buf, sizeof buf);

  while(1) {
    int result = poll (&pollfds, 1, 100);
    if( result > 0 ) {

      lseek(fd, 0, SEEK_SET); 
      read(fd, buf, sizeof buf);

      printf("!");
      fflush(stdout);
    }
  }
}

kernel module

For best timing control, interrupt handling etc. you should consider writing a Kernel Module.

automatic start

see autostart and daemon

Clone this wiki locally