Andrejka ThinkPad
Andrejka ThinkPad

Reputation: 3

libgpiod and blink a led (heartbeat)

Maybe someone advice me how to add led blink (aka simple heartbeat) to following code? Code is looking for button event on GPIO pin using libgpiod then triggers shutdown (useful for headless SBCs)

/*
 * Monitor external button on GPIO pin, shutdown machine if pressed
 * Uses gpiod events to reduce CPU load
 */

#define SHUTDOWN_CHIP 2
#define SHUTDOWN_LINE 21     // NEO3 pin 23
#define SHUTDOWN_HOLD 3     // seconds to hold down button

#include <gpiod.h>          // sudo apt install libgpiod-dev
#include <stdio.h>
#include <unistd.h>
#include <syslog.h>

void shut_down() {
  syslog(LOG_NOTICE, "Safe shutdown triggered from GPIO button");
  system("/usr/bin/sudo /bin/gpioset 2 24=0");
  exit(EXIT_SUCCESS);
};

int main(int argc, char *argv[]) {
  struct gpiod_chip *chip;
  struct gpiod_line *button;

  void line_release() {
    gpiod_line_release(button);
    gpiod_chip_close(chip);
  }

  chip = gpiod_chip_open_by_number(SHUTDOWN_CHIP);
  button = gpiod_chip_get_line(chip, SHUTDOWN_LINE);
  if (button == NULL) {
    perror("Invalid GPIO chip/pin number");
    exit(EXIT_FAILURE);
  }
  // Use if your board doesn't use a pullup resistor by default (libgpiod v1.5+)
  // if (gpiod_line_request_both_edges_events_flags(button, "gpio-shutdown", GPIOD_LINE_REQUEST_FLAG_BIAS_PULL_UP) < 0) {
  if (gpiod_line_request_both_edges_events(button, "gpio-shutdown") < 0) {
    perror("Can't claim that GPIO pin (monitor already running?)");
    exit(EXIT_FAILURE);
  }
  syslog(LOG_INFO, "Monitoring GPIO button for safe shutdown requests");
  atexit(line_release);

  while (true) {
    if (gpiod_line_event_wait(button, NULL)) {
      struct gpiod_line_event ev;
      struct timespec t_held = {SHUTDOWN_HOLD,0};
      gpiod_line_event_read(button, &ev);
      if (ev.event_type == GPIOD_LINE_EVENT_FALLING_EDGE && !gpiod_line_event_wait(button, &t_held)) {
        shut_down();
      };
    };
  };

  return EXIT_SUCCESS;
}

Is some thoughts by break a loop by "timeout" option with libgpiod:

int gpiod_line_event_wait(struct gpiod_line *line, const struct timespec *timeout)  

Upvotes: 0

Views: 308

Answers (0)

Related Questions