Subj : Re: how to write and read back GPIO pin states with lgpio To : All From : The Natural Philosopher Date : Mon Aug 05 2024 07:53:45 On 04/08/2024 21:13, Josef Möllers wrote: > Hi, > > I used to use the sysfs interface to the GPIO pins (/sys/class/gpio) but > I understand that is deprecated nowadays. So I tried to switch to lgpio > which looks OK. However, I have problems writing and reading back pin > states from different programs. > > My setup is as follows: > I have a couple of relays (solid state and mechanical ones) that control > various external devices. > I use one program to switch devices on and off and want to use another > program to read back the state of the device. > > Doing that with sysfs is easy: > 1) export the pin: >       echo $pin > /sys/class/gpio/export >       echo $direction > /sys/class/gpio/gpio$pin/direction >    this needs to be done only once. > 2) write the state of the pin, thus switching the device on/off: >       echo $newstate > /sys/class/gpio/gpio$pin/value >    this is done every time this is required > 3) read back the state of the pin >       value=$(    this is done every time I want to check the state of the device > > Now I switch a device on/off with lgpio as follows: > 1) open the GPIO chip: >       h = lgGpiochipOpen(0); > 2) claim the pin as an output: >       lgGpioClaimOutput(h, LG_SET_PULL_NONE, pin, value); >    which, to my understanding, already changes the pin's state?!? > 3) write the new state >       lgGpioWrite(h, pin, value); > 4) close the chip >       lgGpiochipClose(h); > > Reading back the state of the pin requires me to > 1) open the GPIO chip: >       h = lgGpiochipOpen(0); > 2) claim the pin as an input: >       lgGpioClaimInput(h, LG_SET_PULL_NONE, pin); > 3) read back the pin's state >       lgGpioRead(h, pin); > 4) close the chip >       lgGpiochipClose(h); > > However ... When I set the pin's state to "1", I still read back "0"! > > What am I doing wrong? Thanks in advance for any pointers. > > Josef TLDR Here is my C code to drive 4 relays from a Pi Zero W Adpapted frim someone elses that also works It works: /* relays.h 2023-04-30 Public Domain */ /* zone 1-4, command ON or OFF */ /* All clever stuff is done in relayio, any call to this * will initialise the hardware if it needs it. */ void relay(int zone, int command); #define RELAY1 6 #define RELAY2 13 #define RELAY3 19 #define RELAY4 26 --------------------------------------------------------------------------------------- /* relayio.c 2023-04-30 Public Domain */ #include #include #include #include #include #include #include #include #include "relays.h" #define GPSET0 7 #define GPSET1 8 #define GPCLR0 10 #define GPCLR1 11 #define GPLEV0 13 #define GPLEV1 14 #define GPPUD 37 #define GPPUDCLK0 38 #define GPPUDCLK1 39 // port numbers for relays unsigned piModel; unsigned piRev; static volatile uint32_t *gpioReg = MAP_FAILED; #define PI_BANK (gpio>>5) #define PI_BIT (1<<(gpio&0x1F)) /* gpio modes. */ #define PI_INPUT 0 #define PI_OUTPUT 1 #define PI_ALT0 4 #define PI_ALT1 5 #define PI_ALT2 6 #define PI_ALT3 7 #define PI_ALT4 3 #define PI_ALT5 2 static int initialized=0; void gpioSetMode(unsigned gpio, unsigned mode) { int reg, shift; reg=gpio/10; shift=(gpio%10) * 3; gpioReg[reg] = (gpioReg[reg] & ~(7<> shift) & 7; } /* Values for pull-ups/downs off, pull-down and pull-up. */ #define PI_PUD_OFF 0 #define PI_PUD_DOWN 1 #define PI_PUD_UP 2 void gpioSetPullUpDown(unsigned gpio, unsigned pud) { *(gpioReg + GPPUD) = pud; usleep(20); *(gpioReg + GPPUDCLK0 + PI_BANK) = PI_BIT; usleep(20); *(gpioReg + GPPUD) = 0; *(gpioReg + GPPUDCLK0 + PI_BANK) = 0; } int gpioRead(unsigned gpio) { if ((*(gpioReg + GPLEV0 + PI_BANK) & PI_BIT) != 0) return 1; else return 0; } void gpioWrite(unsigned gpio, unsigned level) { if (level == 0) *(gpioReg + GPCLR0 + PI_BANK) = PI_BIT; else *(gpioReg + GPSET0 + PI_BANK) = PI_BIT; } void gpioTrigger(unsigned gpio, unsigned pulseLen, unsigned level) { if (level == 0) *(gpioReg + GPCLR0 + PI_BANK) = PI_BIT; else *(gpioReg + GPSET0 + PI_BANK) = PI_BIT; usleep(pulseLen); if (level != 0) *(gpioReg + GPCLR0 + PI_BANK) = PI_BIT; else *(gpioReg + GPSET0 + PI_BANK) = PI_BIT; } /* Bit (1<Usenet Gateway (3:770/3) .