Raspi_gpiohelper

Difference between version 2 and 3 - Previous - Next
the GPIO subsystem on the Raspberry allows to set pins for "interrupt"
the created subsystem file becomes readable on any level change.
 
http://wiringpi.com/the-gpio-utility/%|%Raspberry GPIO utility%|%

Unfortunately I could not coerce tcl to ignore the eof condition.
So I expanded the sample c programm to handle multiple pins 
set up for interrupt notice to be watched over and 
handed in to a tcl file input.

the helper will first iterate over all configured inputs and report 
their current state.
then one line will be output for every event seen.
<pin>:<state>
which fits in nicely with the tcl event model.

Useage example ( here the gpio 23, 24 and 25 ) :
======
# config input:
proc Uevent fd {
        set line [gets $fd]
        puts stderr line:>>$line<<
        switch -- $line \
                  23:0 {
                        hands right
                } 23:1 {
                        hands right 0
                } 24:0 {
                        hands left
                } 24:1 {
                        hands left 0
                } 25:0 {
                        puts stderr Release
                } 25:1 {
                        set ::stop [ clock milliseconds ]
                        incr ::cont
                } default {
                }
}
set fd [ open "| ./gpioirq 23 24 25" RDONLY ]
fconfigure $fd -buffering none
fileevent $fd readable [list Uevent $fd]========
Then create a fileevent readable for $fd.
======
fileevent $fd readable [list Uevent $fd]
======



./gpioirq.c slightly expanded from an example give on the gpio project page.
======
// adapted from an example.
// i2016 Uwe Klein Habertwedt

#include <stdio.h>
#include <poll.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>

#define GPIO_FN_MAXLEN  32
#define POLL_TIMEOUT    1000
#define RDBUF_LEN       5

int main(int argc, char **argv) {
        char fn[GPIO_FN_MAXLEN];
        int fd[argc],ret, arg;
        struct pollfd pfd[argc];
        char rdbuf[RDBUF_LEN];

        memset(rdbuf, 0x00, RDBUF_LEN);
        memset(fn, 0x00, GPIO_FN_MAXLEN);

        if(argc<2) {
                printf("Usage: %s <GPIO>\nGPIO must be exported to sysfs and have enabled edge detection\n", argv[0]);
                return 1;
        }
        for (arg=1;(arg<argc);arg++) {
                snprintf(fn, GPIO_FN_MAXLEN-1, \
                        "/sys/class/gpio/gpio%s/value", argv[arg]);
                fd[arg]=open(fn, O_RDONLY);
                if(fd[arg]<0) {
                        perror(fn);
                        return 2;
                }
                pfd[arg].fd=fd[arg];
                pfd[arg].events=POLLPRI;

                ret=read(fd[arg], rdbuf, RDBUF_LEN-1);
                        if(ret<0) {
                        perror("read()");
                        return 4;
                        return 4;
                        }
                printf("%s:%s", argv[arg],rdbuf);
        }
        fflush(stdout);
        while(1) {
                memset(rdbuf, 0x00, RDBUF_LEN);
                for (arg=1; arg<argc;arg++) {
                        lseek(fd[arg], 0, SEEK_SET);
                }
                ret=poll(&pfd[1], argc-1, POLL_TIMEOUT);
                if(ret<0) {
                        perror("poll()");
                        close(fd);
                        return 3;
                }
                if(ret==0) {
                        // printf("timeout\n");
                        continue;
                }
                for (arg=1; arg<argc;arg++) {
                        if (pfd[arg].revents) {
                                ret=read(fd[arg], rdbuf, RDBUF_LEN-1);
                                printf("%s:%s", argv[arg], rdbuf);
                                fflush(stdout);
                        }
                }
                if(ret<0) {
                        perror("read()");
                        return 4;
                }
        }
        close(fd);
        return 0;
}


======

<<categories>>Enter Category Here