Deutsch   English   Français   Italiano  
<v8pstp$hqci$2@dont-email.me>

View for Bookmarking (what is this?)
Look up another Usenet article

Path: ...!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: The Natural Philosopher <tnp@invalid.invalid>
Newsgroups: comp.sys.raspberry-pi
Subject: Re: how to write and read back GPIO pin states with lgpio
Date: Mon, 5 Aug 2024 07:53:45 +0100
Organization: A little, after lunch
Lines: 318
Message-ID: <v8pstp$hqci$2@dont-email.me>
References: <lha5o3Ff6g3U1@mid.individual.net>
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 8bit
Injection-Date: Mon, 05 Aug 2024 08:53:46 +0200 (CEST)
Injection-Info: dont-email.me; posting-host="d73562cd6fc154a5b5717f47374ed1a2";
	logging-data="584082"; mail-complaints-to="abuse@eternal-september.org";	posting-account="U2FsdGVkX1+HJzXlL0Zq3dN5AqZHQYhVAI/hu8cGB2s="
User-Agent: Mozilla Thunderbird
Cancel-Lock: sha1:VXuJGltXr7oQ74l7En4DhDoYGOE=
Content-Language: en-GB
In-Reply-To: <lha5o3Ff6g3U1@mid.individual.net>
Bytes: 8604

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=$(</sys/class/gpio/gpio$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 <stdio.h>
#include <unistd.h>
#include <stdint.h>
#include <string.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#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)) | (mode<<shift);
	}

int gpioGetMode(unsigned gpio)
	{
	int reg, shift;
	reg   =  gpio/10;
	shift = (gpio%10) * 3;
	return (*(gpioReg + reg) >> 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
========== REMAINDER OF ARTICLE TRUNCATED ==========