Blinking and LED with libgpiod

2021-05-03 hardware raspberry-pi

In the previous post we introduced libgpiod. In this post we’ll use the command line tools to blink and LED. Finally, we’ll write some C code to blink the LED using the libgpiod library.

LED Driver Circuit

Skip this section if you already have a good circuit to drive an LED. Here is what I used which is a simple NPN Transistor, two resistors and the LED.

LED Drive Circuit

Let’s say you have an LED like this. This LED can take a maximum of \( 30mA \), so let’s reduce to \( 20mA \). The LED has a Forward Voltage of \( V_f=1.8V \) typical. The current going through the LED is:

\( 20mA = \frac{5V - 1.8V}{ R_2 } \)

Solving for \( R_2 \) we have:

\( R_2 = \frac{3.2V}{20mA} = 160\Omega \).

For \( R_1 \) let’s just drive \( 1mA \) out the GPIO Pin 21 so we have:

\( 1mA = \frac{3.3V - 0.7V}{R_1} \).

Solving for \( R_1 \) we have:

\( R_1 = \frac{2.6V}{16mA} = 2600 \Omega \).

For both values \( R_1 \) and \( R_2 \) rounding down gives less current and going up risks damaging the LED and Rasberry Pi. Thus, we can use \( 2.7k\Omega \) for a standard value. The value of \( 160 \Omega \) is already standard.

You can easily plug the values for a different LED into the equations above to get the right resistor values.

Blinking the LED with gpioset

We can turn the LED on using the gpioset command:

$ gpioset gpiochip0 21=1

and turn it off again with:

$ gpioset gpiochip0 21=0

or we can turn it on for a duration:

$ gpioset --mode=time --mode=time --sec=3 gpiochip0 21=1

C Code to Blink the LED

// file blink.c
#include <gpiod.h>
#include <error.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>

struct gpiod_chip *chip;
struct gpiod_line_request_config config;
struct gpiod_line_bulk lines;

int
main(int argc, char *argv[])
{
  unsigned int offsets[1];

  int values[1];
  int err;

  chip = gpiod_chip_open("/dev/gpiochip0");
  if(!chip)
  {
    perror("gpiod_chip_open");
    goto cleanup;
  }

  // set pin 21 to 1 (logic high)
  offsets[0] = 21;
  values[0] = 0;

  err = gpiod_chip_get_lines(chip, offsets, 1, &lines);
  if(err)
  {
    perror("gpiod_chip_get_lines");
    goto cleanup;
  }

  memset(&config, 0, sizeof(config));
  config.consumer = "blink";
  config.request_type = GPIOD_LINE_REQUEST_DIRECTION_OUTPUT;
  config.flags = 0;

  // get the bulk lines setting default value to 0
  err = gpiod_line_request_bulk(&lines, &config, values);
  if(err)
  {
    perror("gpiod_line_request_bulk");
    goto cleanup;
  }

  // output value 1 to turn on the led
  values[0] = 1;
  err = gpiod_line_set_value_bulk(&lines, values);
  if(err)
  {
    perror("gpiod_line_set_value_bulk");
    goto cleanup;
  }

  sleep(1);

  // output value 0 to turn off the led
  values[0] = 0;
  err = gpiod_line_set_value_bulk(&lines, values);
  if(err)
  {
    perror("gpiod_line_set_value_bulk");
    goto cleanup;
  }

cleanup:
  gpiod_line_release_bulk(&lines);
  gpiod_chip_close(chip);

  return EXIT_SUCCESS;
}

Building and Running

It’s easy to build and run:

$ gcc -o blink blink.o -lgpiod
$ ./blink

You should see an LED blink for 3 seconds.

comments powered by Disqus