c++raspberry-pilibgpiod

How do I set the internal pull up of a given line on a Raspberry Pi 4?


I'm using Raspberry Pi 4, and I want to set my line to use the internal PULL_UP (default Raspberry lines above 8 are all pull_down):

Using C++ and libgpiod V1:

try {
    gpiod::chip chip("gpiochip0");
    gpiod::line_bulk lines;

    const std::vector<io_gpio_t> offsets = {
        {1, 21},
        {2, 26},
        {3, 16},
        {4, 19}};

    for (io_gpio_t offset : offsets) {
        auto line = chip.get_line(offset.gpio_line);
        line.set_bias(gpiod::line::bias::pull_up); // <<---- ERROR HERE!!!!
        line.request({"io", gpiod::line_request::EVENT_BOTH_EDGES, 100000});
        lines.append(line);
    }

    while (true) {
        gpiod::line_bulk changed_lines = lines.event_wait(std::chrono::seconds(10));
        for (gpiod::line line : changed_lines) {
            auto event = line.event_read();
            int offset = line.offset();
            process_digital_in(offset, event); // Process event
        }
    }
} catch (const std::exception &e) {
    std::cerr << "Error: " << e.what() << std::endl;
}

It seems that version 1.6 of libgpiod does not support set_bias:

src/IO.cpp:79:18: error: ‘class gpiod::line’ has no member named ‘set_bias’; did you mean ‘set_flags’?
   79 |             line.set_bias(gpiod::line::bias::pull_up);
      |                  ^~~~~~~~
      |                  set_flags
src/IO.cpp:79:40: error: ‘gpiod::line::bias’ is not a class, namespace, or enumeration
   79 |             line.set_bias(gpiod::line::bias::pull_up);
      |                                        ^~~~

The compiler suggests set_flags, but I cannot find docs on that.

How to properly set the input to use the internal pull up programmatically?


Solution

  • Firstly, set_bias() is a libgpiod v2 call, not v1, so it looks like you are trying to apply v2 documentation or examples to v1. That wont work - the APIs are very different.

    It is possible to set bias with libgpiod v1, as long as you have a recent version of both libgpiod (1.5+) and the kernel (5.5+).

    You need to set the appropriate flag in the struct line_request passed to the request - where you pass the "100000" - whatever that means. It should be:

    line.request({"io", gpiod::line_request::EVENT_BOTH_EDGES, gpiod::line_request::FLAG_BIAS_PULL_UP});
    

    The consumer label should be set to something to identify the user of the lines, unless your app is called "io"? But it is just a label, so whatever.

    Do yourself a favour and switch to libgpiod v2 which has a nicer API, better documentation and examples, and is actively developed. It isn't packaged for Raspberry PiOS yet, but isn't difficult to install from source. The kernel API that libgpiod v1 uses is deprecated, like the old sysfs interface, and will eventually be removed. New developments should use the current API and so libgpiod v2.