| 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 ==========