Raspberry BASIC > General Discussion
LG Library
John Spikowski:
I was able to compile the lg library under Ubuntu 20.04 LTS 64 bits on the RPi 4B 8GB with no errors or complaints with the make file included.
Since I don't have anything connected to my GPIO bus I wanted to see if the lgGpiochipOpen() fuction would return anything. A positive response is zero or greater. I got a -78
as a response. I assume since there is no chips on the bus it's returning an error code. There is an example for the DHT11 which I have that is going to be my next test.
--- Code: C ---#include <stdio.h>#include <stdlib.h> #include <lgpio.h> #define LFLAGS 0 int main(int argc, char *argv[]){ int h; h = lgGpiochipOpen(0); printf("%i\n", h); if (h >= 0) {printf("Got Here\n");} lgGpiochipClose(h);}
DHT11 Example
--- Code: C ---/*dhtxx.c2020-11-18Public Domain http://abyz.me.uk/lg/lgpio.html gcc -Wall -o dhtxx dhtxx.c -llgpio ./dhtxx gpio ...*/ #include <stdio.h>#include <stdint.h>#include <stdlib.h>#include <unistd.h>#include <inttypes.h> #include <lgpio.h> #define DHTAUTO 0#define DHT11 1#define DHTXX 2 #define DHT_GOOD 0#define DHT_BAD_CHECKSUM 1#define DHT_BAD_DATA 2#define DHT_TIMEOUT 3 /*gcc -o dhtxx dhtxx.c -llg*/ #define MAX_GPIO 32 static int decode_dhtxx(uint64_t reading, int model, float *rh, float *temp){/* +-------+-------+ | DHT11 | DHTXX | +-------+-------+Temp C| 0-50 |-40-125| +-------+-------+RH% | 20-80 | 0-100 | +-------+-------+ 0 1 2 3 4 +------+------+------+------+------+DHT11 |check-| 0 | temp | 0 | RH% | |sum | | | | | +------+------+------+------+------+DHT21 |check-| temp | temp | RH% | RH% |DHT22 |sum | LSB | MSB | LSB | MSB |DHT33 | | | | | |DHT44 | | | | | | +------+------+------+------+------+ */ uint8_t byte[5]; uint8_t chksum; float div; float t, h; int valid; int status; byte[0] = (reading ) & 255; byte[1] = (reading>> 8) & 255; byte[2] = (reading>>16) & 255; byte[3] = (reading>>24) & 255; byte[4] = (reading>>32) & 255; chksum = (byte[1] + byte[2] + byte[3] + byte[4]) & 0xFF; valid = 0; if (chksum == byte[0]) { if (model == DHT11) { if ((byte[1] == 0) && (byte[3] == 0)) { valid = 1; t = byte[2]; if (t > 60.0) valid = 0; h = byte[4]; if ((h < 10.0) || (h > 90.0)) valid = 0; } } else if (model == DHTXX) { valid = 1; h = ((float)((byte[4]<<8) + byte[3]))/10.0; if (h > 110.0) valid = 0; if (byte[2] & 128) div = -10.0; else div = 10.0; t = ((float)(((byte[2]&127)<<8) + byte[1])) / div; if ((t < -50.0) || (t > 135.0)) valid = 0; } else /* AUTO */ { valid = 1; /* Try DHTXX first. */ h = ((float)((byte[4]<<8) + byte[3]))/10.0; if (h > 110.0) valid = 0; if (byte[2] & 128) div = -10.0; else div = 10.0; t = ((float)(((byte[2]&127)<<8) + byte[1])) / div; if ((t < -50.0) || (t > 135.0)) valid = 0; if (!valid) { /* If not DHTXX try DHT11. */ if ((byte[1] == 0) && (byte[3] == 0)) { valid = 1; t = byte[2]; if (t > 60.0) valid = 0; h = byte[4]; if ((h < 10.0) || (h > 90.0)) valid = 0; } } } if (valid) { status = DHT_GOOD; *rh = h; *temp = t; } else status = DHT_BAD_DATA; } else status = DHT_BAD_CHECKSUM; return status;} static int status;static float h=0, t=0; void afunc(int e, lgGpioAlert_p evt, void *data){ int i; uint64_t edge_len, now_tick; static int bits = 0; static uint64_t reading = 0; static uint64_t last_tick = 0; for (i=0; i<e; i++) { if (evt[i].report.level != LG_TIMEOUT) { now_tick = evt[i].report.timestamp; edge_len = now_tick - last_tick; last_tick = now_tick; if (edge_len > 1e6) // a millisecond { reading = 0; bits = 0; } else { reading <<= 1; if (edge_len > 1e5) reading |= 1; // longer than 100 micros ++bits; } } else { status = decode_dhtxx(reading, DHTAUTO, &t, &h); reading = 0; bits = 0; } }} int main(int argc, char *argv[]){ int i, g; int v; int loop; int fd; int chip; int num_gpio; int gpio[MAX_GPIO]; int err; int count; chip = lgGpiochipOpen(0); if (argc > 1) { num_gpio=argc-1; if (num_gpio > MAX_GPIO) num_gpio = MAX_GPIO; for (g=0; g<num_gpio; g++) gpio[g] = atoi(argv[g+1]); } else { num_gpio = 1; gpio[0] = 4; } if (chip >= 0) { lgGpioSetUser(chip, "niagra"); lgGpioSetSamplesFunc(afunc, (void*)123456); for (g=0; g<num_gpio; g++) { lgGpioSetWatchdog(chip, gpio[g], 1000); /* millisecond watchdog */ } for (loop=0; loop<200000; loop++) { for (g=0; g<num_gpio; g++) { err = lgGpioClaimOutput(chip, 0, gpio[g], 0); if (err) fprintf(stderr, "set out err %d\n", err); usleep(15000); err = lgGpioClaimAlert( chip, 0, LG_RISING_EDGE, gpio[g], -1); if (err) fprintf(stderr, "set event err %d\n", err); count = 0; status = DHT_TIMEOUT; while ((status == DHT_TIMEOUT) && (++count<11)) usleep(1000); printf("%d %.1f %.1f (g=%d)\n", status, t, h, gpio[g]); fflush(NULL); } sleep(3); } lgGpiochipClose(chip); } else { fprintf(stderr, "open /dev/gpiochip0 failed (%d)\n", chip); }}
John Spikowski:
Here is a list of exported functions from the lg GPIO library.
GPIO
lgGpiochipOpen Opens a gpiochip device
lgGpiochipClose Closes a gpiochip device
lgGpioGetChipInfo Gets gpiochip information
lgGpioGetLineInfo Gets gpiochip line information
lgGpioGetMode Gets the mode of a GPIO
lgGpioSetUser Notifies Linux of the GPIO user
lgGpioClaimInput Claims a GPIO for input
lgGpioClaimOutput Claims a GPIO for output
lgGpioClaimAlert Claims a GPIO for alerts
lgGpioFree Frees a GPIO
lgGroupClaimInput Claims a group of GPIO for inputs
lgGroupClaimOutput Claims a group of GPIO for outputs
lgGroupFree Frees a group of GPIO
lgGpioRead Reads a GPIO
lgGpioWrite Writes a GPIO
lgGroupRead Reads a group of GPIO
lgGroupWrite Writes a group of GPIO
lgTxPulse Starts pulses on a GPIO
lgTxPwm Starts PWM pulses on a GPIO
lgTxServo Starts Servo pulses on a GPIO
lgTxWave Starts a wave on a group of GPIO
lgTxBusy See if tx is active on a GPIO or group
lgTxRoom See if more room for tx on a GPIO or group
lgGpioSetDebounce Sets the debounce time for a GPIO
lgGpioSetWatchdog Sets the watchdog time for a GPIO
lgGpioSetAlertsFunc Starts a GPIO callback
lgGpioSetSamplesFunc Starts a GPIO callback for all GPIO
I2C
lgI2cOpen Opens an I2C device
lgI2cClose Closes an I2C device
lgI2cWriteQuick SMBus write quick
lgI2cReadByte SMBus read byte
lgI2cWriteByte SMBus write byte
lgI2cReadByteData SMBus read byte data
lgI2cWriteByteData SMBus write byte data
lgI2cReadWordData SMBus read word data
lgI2cWriteWordData SMBus write word data
lgI2cReadBlockData SMBus read block data
lgI2cWriteBlockData SMBus write block data
lgI2cReadI2CBlockData SMBus read I2C block data
lgI2cWriteI2CBlockData SMBus write I2C block data
lgI2cReadDevice Reads the raw I2C device
lgI2cWriteDevice Writes the raw I2C device
lgI2cProcessCall SMBus process call
lgI2cBlockProcessCall SMBus block process call
lgI2cSegments Performs multiple I2C transactions
lgI2cZip Performs multiple I2C transactions
NOTIFICATIONS
lgNotifyOpen Request a notification
lgNotifyClose Close a notification
lgNotifyPause Pause notifications
lgNotifyResume Start notifications
SERIAL
lgSerialOpen Opens a serial device
lgSerialClose Closes a serial device
lgSerialReadByte Reads a byte from a serial device
lgSerialWriteByte Writes a byte to a serial device
lgSerialRead Reads bytes from a serial device
lgSerialWrite Writes bytes to a serial device
lgSerialDataAvailable Returns number of bytes ready to be read
SPI
lgSpiOpen Opens a SPI device
lgSpiClose Closes a SPI device
lgSpiRead Reads bytes from a SPI device
lgSpiWrite Writes bytes to a SPI device
lgSpiXfer Transfers bytes with a SPI device
THREADS
lgThreadStart Start a new thread
lgThreadStop Stop a previously started thread
UTILITIES
lguVersion Gets the library version
lguSbcName Gets the host name of the SBC
lguGetInternal Get an internal configuration value
lguSetInternal Set an internal configuration value
lguSleep Sleeps for a given time
lguTimestamp Gets the current timestamp
lguTime Gets the current time
lguErrorText Gets a text description of an error code
lguSetWorkDir Set the working directory
lguGetWorkDir Get the working directory
John Spikowski:
I modified mytest.c to generate the text for the error code. I'm assuming since I don't have anything connected to the GPIO bus it may be working. :)
--- Code: Script BASIC ---#include <stdio.h>#include <stdlib.h> #include <lgpio.h> #define LFLAGS 0 int main(int argc, char *argv[]){ int h; h = lgGpiochipOpen(0); printf("%s\n", lguErrorText(h)); if (h >= 0) {printf("Got Here\n");} lgGpiochipClose(h);}
ubuntu@rpi4b:~/lg/EXAMPLES/lgpio$ gcc mytest.c -o mytest -llgpio
ubuntu@rpi4b:~/lg/EXAMPLES/lgpio$ ./mytest
can not open gpiochip
ubuntu@rpi4b:~/lg/EXAMPLES/lgpio$
John Spikowski:
I hooked up my DHT11 to the GPIO bus and ran the example provided. It failed with the chip not found like in mytest.c. My guess is like the WiringPi library hasn't been updated to handle the RPi 4B. Please chime in if you have any ideas. I'm going to try this library on my RPi 3B with 32 Bit Raspian OS just to see if the library works there,
ubuntu@rpi4b:~/lg/EXAMPLES/lgpio$ ./dhtxx
open /dev/gpiochip0 failed (-78)
ubuntu@rpi4b:~/lg/EXAMPLES/lgpio$
John Spikowski:
I took a peek at the lgpio.c source and the reason it can't find a chip is /dev/gpiochip0 is a null file. The open() function must be returning the error. Seems I've hit a dead end on Ubuntu 64 if this device doesn't exist.
--- Code: C ---sprintf(chipName, "/dev/gpiochip%d", gpioDev); fd = open(chipName, O_RDWR | O_CLOEXEC); if (fd < 0) PARAM_ERROR(LG_CANNOT_OPEN_CHIP, "can't open gpiochip (%s)", chipName);
Navigation
[0] Message Index
[#] Next page
Go to full version