Open Tom-Hirschberger opened 3 months ago
Having some issues with this one. It seems that while libgpiod does have the functionality for pull up/down and debounce, it doesn't seem to be exposed in the development headers from libgpiod-dev. The headers for the core cpp library do clearly have these parameters available. You'll notice in this file that internal bias for pull up/down is there: https://github.com/brgl/libgpiod/blob/master/bindings/cxx/gpiodcxx/line.hpp
But the header file that comes from libgpiod-dev doesn't have any availability for this, as reference here the section from the header file for line:
class line
{
public:
/**
* @brief Default constructor. Creates an empty line object.
*/
GPIOD_API line(void);
/**
* @brief Copy constructor.
* @param other Other line object.
*/
GPIOD_API line(const line& other) = default;
/**
* @brief Move constructor.
* @param other Other line object.
*/
GPIOD_API line(line&& other) = default;
/**
* @brief Assignment operator.
* @param other Other line object.
* @return Reference to this object.
*/
GPIOD_API line& operator=(const line& other) = default;
/**
* @brief Move assignment operator.
* @param other Other line object.
* @return Reference to this object.
*/
GPIOD_API line& operator=(line&& other) = default;
/**
* @brief Destructor.
*/
GPIOD_API ~line(void) = default;
/**
* @brief Get the offset of this line.
* @return Offet of this line.
*/
GPIOD_API unsigned int offset(void) const;
/**
* @brief Get the name of this line (if any).
* @return Name of this line or an empty string if it is unnamed.
*/
GPIOD_API ::std::string name(void) const;
/**
* @brief Get the consumer of this line (if any).
* @return Name of the consumer of this line or an empty string if it
* is unused.
*/
GPIOD_API ::std::string consumer(void) const;
/**
* @brief Get current direction of this line.
* @return Current direction setting.
*/
GPIOD_API int direction(void) const noexcept;
/**
* @brief Get current active state of this line.
* @return Current active state setting.
*/
GPIOD_API int active_state(void) const noexcept;
/**
* @brief Check if this line is used by the kernel or other user space
* process.
* @return True if this line is in use, false otherwise.
*/
GPIOD_API bool is_used(void) const;
/**
* @brief Check if this line represents an open-drain GPIO.
* @return True if the line is an open-drain GPIO, false otherwise.
*/
GPIOD_API bool is_open_drain(void) const;
/**
* @brief Check if this line represents an open-source GPIO.
* @return True if the line is an open-source GPIO, false otherwise.
*/
GPIOD_API bool is_open_source(void) const;
/**
* @brief Request this line.
* @param config Request config (see gpiod::line_request).
* @param default_val Default value - only matters for OUTPUT direction.
*/
GPIOD_API void request(const line_request& config, int default_val = 0) const;
/**
* @brief Release the line if it was previously requested.
*/
GPIOD_API void release(void) const;
/**
* @brief Check if this user has ownership of this line.
* @return True if the user has ownership of this line, false otherwise.
*/
GPIOD_API bool is_requested(void) const;
/**
* @brief Read the line value.
* @return Current value (0 or 1).
*/
GPIOD_API int get_value(void) const;
/**
* @brief Set the value of this line.
* @param val New value (0 or 1).
*/
GPIOD_API void set_value(int val) const;
/**
* @brief Wait for an event on this line.
* @param timeout Time to wait before returning if no event occurred.
* @return True if an event occurred and can be read, false if the wait
* timed out.
*/
GPIOD_API bool event_wait(const ::std::chrono::nanoseconds& timeout) const;
/**
* @brief Read a line event.
* @return Line event object.
*/
GPIOD_API line_event event_read(void) const;
/**
* @brief Get the event file descriptor associated with this line.
* @return File descriptor number.
*/
GPIOD_API int event_get_fd(void) const;
/**
* @brief Get the reference to the parent chip.
* @return Reference to the parent chip object.
*/
GPIOD_API const chip& get_chip(void) const;
/**
* @brief Reset the state of this object.
*
* This is useful when the user needs to e.g. keep the line_event object
* but wants to drop the reference to the GPIO chip indirectly held by
* the line being the source of the event.
*/
GPIOD_API void reset(void);
/**
* @brief Check if two line objects reference the same GPIO line.
* @param rhs Right-hand side of the equation.
* @return True if both objects reference the same line, fale otherwise.
*/
GPIOD_API bool operator==(const line& rhs) const noexcept;
/**
* @brief Check if two line objects reference different GPIO lines.
* @param rhs Right-hand side of the equation.
* @return False if both objects reference the same line, true otherwise.
*/
GPIOD_API bool operator!=(const line& rhs) const noexcept;
/**
* @brief Check if this object holds a reference to any GPIO line.
* @return True if this object references a GPIO line, false otherwise.
*/
GPIOD_API explicit operator bool(void) const noexcept;
/**
* @brief Check if this object doesn't reference any GPIO line.
* @return True if this object doesn't reference any GPIO line, true
* otherwise.
*/
GPIOD_API bool operator!(void) const noexcept;
/**
* @brief Possible direction settings.
*/
enum : int {
DIRECTION_INPUT = 1,
/**< Line's direction setting is input. */
DIRECTION_OUTPUT,
/**< Line's direction setting is output. */
};
/**
* @brief Possible active state settings.
*/
enum : int {
ACTIVE_LOW = 1,
/**< Line's active state is low. */
ACTIVE_HIGH,
/**< Line's active state is high. */
};
Not sure why, but can only think that this is newer functionality that isn't exposed in libgpiod-dev yet. But that's just a guess. Will see if it's possible to directly reference the header files from the core library instead of from libgpiod-dev.
Hi,
I do not have much knowledge of C++ but it looks like the last changes of the bindings are at least two years old.
https://github.com/brgl/libgpiod/blob/master/bindings/cxx/line.cpp
Thought it might be cause of the change to version 2 of the lib but the bias and pull settings are included into the 1.6.x branch, too.
I noticed found devs that seemed to be working on dev bindings for version 2, which is why I also suspected that the current dev bindings were for an older version. I'll try include version 2 as a git submodule and use the header files directly from there. I'm traveling for work this week, so I'll probably only get onto this again next week.
@Tom-Hirschberger I'm back from my work trip and I've had a look into this. I was able to add libgpiod as a submodule to the package. Thankfully it doesn't require any external dependancies so the project build pipeline works just fine. However, the version 2.1.x structure is not compatible with the headers exposed by libgpiod 1.6.x, so the compiler throws a bunch of errors.
Thankfully tho, version 2 seems relatively straight forward so I should be able to reuse the majority of the existing opengpio.cpp code with changes mostly around how c++ requests the chip and line objects. I was able to get a striped down version of the file to compile.
I'm working on this on the branch version/libgpiod_v2.1.x. It's probably going to take a bit of work still, but once done, we'll be able to make use of all the features within version 2 of libgpiod. I'll keep you updated.
Thank you very much for your affort.
@Tom-Hirschberger I managed to get it working for input, output, and watching. Debounce and Bias appear to be working. I need to finish up PWM still. The only thing that I need to really work on setting up is to automate the download, build, and install of libgpiod v2.1.x. I can't find a prebuilt version of this that can be installed via apt install, so for now it seems that the easiest is that it builds and installs on the device from the source code. This seems fine because it doesn't require any dependancies, but that downside is it takes several minutes to install. In future, prebuilt binaries could be packaged with the library.
Once I've finished up the install side of things I'll send you details on how to try it out.
@Tom-Hirschberger I've completed the setup of the library.
Would you mind to give it a try? You can install using npm install "https://github.com/ExplorationSystems/opengpio.git#version/libgpiod_v2.1.x"
Note that it will take a while to install since it's building from source code and you'll probably think the install has jammed, but just let it be. Even for like 15 minutes. If this works, I'll probably look at packaging the prebuild binaries atleast for ARM.
Do not know when I have time to test. But I will do as fast as I can.
@Tom-Hirschberger no stress. Are you using an ARM based system?
@Tom-Hirschberger after much trial and error I opted to remove auto building of libgpiod version 2 from being embedded in the library. Rather, I added instructions on how to build the prerequisites into the readme. It's easy enough for people to do anyway.
I've pushed the latest version to: https://github.com/ExplorationSystems/opengpio/tree/version/libgpiod_v2.1.x You can follow the instructions in the README to install libgpiod v2.1.
After you've installed it successfully, you can run npm install "https://github.com/ExplorationSystems/opengpio.git#version/libgpiod_v2.1.x"
to install the library.
Everything should work as before, expect there are new additions to use the built in debounce and bias. Here's an example:
import { NanoPi_NEO3, Edge, Bias } from 'opengpio';
const watch = NanoPi_NEO3.watch(NanoPi_NEO3.bcm.GPIO2_B7, Edge.Both, {
debounce: 20,
bias: Bias.PullDown
});
No rush, but once you've given this new version a try and can confirm that it works then I'll pull it into main and deploy it to npm as a new version.
I've also setup a script to automate the install process for libgpiod, you can execute the following to use it:
curl https://raw.githubusercontent.com/ExplorationSystems/opengpio/version/libgpiod_v2.1.x/install-libgpiod.sh | bash
Hi and thank you very much.
Maybe i will have time to test at the next weekend. Need to setup a example.
Edit: I use Raspberry Pis mostly. 32Bit and 64Bit OS.
Hi, had some minutes and tried the installation. The script quits with an error during compilation of the library.
pi@mirror-dev:~ $ curl https://raw.githubusercontent.com/ExplorationSystems/opengpio/version/libgpiod_v2.1.x/install-libgpiod.sh | bash
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 522 100 522 0 0 1955 0 --:--:-- --:--:-- --:--:-- 1962
Cleaning directory
Ensure build dependancies
Paketlisten werden gelesen… Fertig
Abhängigkeitsbaum wird aufgebaut… Fertig
Statusinformationen werden eingelesen… Fertig
tar ist schon die neueste Version (1.34+dfsg-1.2+deb12u1).
gzip ist schon die neueste Version (1.12-1).
build-essential ist schon die neueste Version (12.9).
autoconf ist schon die neueste Version (2.71-3).
curl ist schon die neueste Version (7.88.1-10+deb12u5).
Die folgenden Pakete wurden automatisch installiert und werden nicht mehr benötigt:
libcamera0.1 libssl1.1 linux-headers-6.1.0-rpi7-common-rpi
Verwenden Sie »sudo apt autoremove«, um sie zu entfernen.
0 aktualisiert, 0 neu installiert, 0 zu entfernen und 104 nicht aktualisiert.
Fetching libgpiod v2.1
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 206k 0 206k 0 0 560k 0 --:--:-- --:--:-- --:--:-- 562k
Build and install libgpiod
autoreconf: export WARNINGS=
autoreconf: Entering directory '.'
autoreconf: configure.ac: not using Gettext
autoreconf: running: aclocal --force -I m4
aclocal: warning: couldn't open directory 'm4': No such file or directory
autoreconf: configure.ac: tracing
autoreconf: configure.ac: creating directory autostuff
autoreconf: configure.ac: not using Libtool
autoreconf: configure.ac: not using Intltool
autoreconf: configure.ac: not using Gtkdoc
autoreconf: running: /usr/bin/autoconf --force
configure.ac:75: warning: The macro `AC_HEADER_STDC' is obsolete.
configure.ac:75: You should run autoupdate.
./lib/autoconf/headers.m4:704: AC_HEADER_STDC is expanded from...
configure.ac:75: the top level
configure.ac:203: error: Unexpanded AX_ macro found. Please install GNU autoconf-archive.
If this token and others are legitimate, please use m4_pattern_allow.
See the Autoconf documentation.
autoreconf: error: /usr/bin/autoconf failed with exit status: 1
make: *** Es wurden keine Ziele angegeben und keine „make“-Steuerdatei gefunden. Schluss.
make: *** Keine Regel, um „install“ zu erstellen. Schluss.
@Tom-Hirschberger thanks for checking. Seems like a build dependency is missing, I'll add it to the script.
@Tom-Hirschberger could you try two things:
I've added an additional build lib that seems to be missing based on the logs you provided. Can you try run curl https://raw.githubusercontent.com/ExplorationSystems/opengpio/version/libgpiod_v2.1.x/install-libgpiod.sh | bash
again and see what happens? I feel this approach might be a big of trial and error tho.
If the above still fails can you try following the build script at the lib's readme? Easiest is to clone this repo locally git clone -b v2.1.x https://github.com/brgl/libgpiod.git
and follow the readme. If you encounter any missing libs, try install them and let me know which ones were missing and I'll add them to the automated script. Also, from your logs it says you might need to run autoupdate. If installing fails after trying all the above, I'd recommend running the autoupdate
command in the cloned repo's root directory. Send over any logs.
Last thing... What version of linux are you on?
Hi, I had the plan to debug further to provide more information to you already but had not found any time yet. But I will try to in the next days.
I am running two systems at the moment. One is Debian Bullseye 32bit, one is Debian Bookworm 64bit.
No stress @Tom-Hirschberger. Also been very busy my side the last week. 👍
Hi,
i had to modify your installer slightly:
# Clean directory
echo "Cleaning directory"
rm -rf libgpiod-2.1
#autoupdate package does not exist
#
echo "Update apt cache"
sudo apt -y update
# Ensure build dependancies
echo "Ensure build dependancies"
sudo apt -y install tar gzip build-essential autoconf curl autoconf-archive libtool
# Fetch libgpiod on branch 2.1.x
echo "Fetching libgpiod v2.1"
curl -o libgpiod-2.1.tar.gz 'https://git.kernel.org/pub/scm/libs/libgpiod/libgpiod.git/snapshot/libgpiod-2.1.tar.gz'
tar xf libgpiod-2.1.tar.gz
cd libgpiod-2.1
# Build and install libgpiod
echo "Build and install libgpiod"
./autogen.sh --enable-bindings-cxx
make
sudo make install
apt update
before the apt install-y
option to apt commandsautoupdate
package did not exist so i removed it of apt installlibtool
to apt installsudo
to make installWith the libtool
dependency installed the lib gets compiled and is installed but although i removed my node_modules
directory and the package-lock.json
before re-run the npm install
i get the following error if run my test script:
node index.js
node: symbol lookup error: /home/pi/test/node_modules/opengpio/build/Release/opengpio.node: undefined symbol: _ZN5gpiod13line_settingsC1Ev
Tried to run sudo ldconfig
after the compile to make sure the system recognized the new lib but it does not make any difference.
That's super helpful. Thanks a ton.
The linker issue is an odd one. I'll take a look into this. The only thing that initially comes to mind is if it's somehow utilising a file from the old version of libgpiod. I think I'll try install debian on my device and run this to see if I can reproduce the linker issue.
I might send a few questions but I think this sufficient information for me to dig further.
Hi, switched to your library recently as Kernel 6.6 broke one of my MagicMirror modules. Would be grate to be able to set pull-up or pull-down for pins while registering them.