Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Mobile and Embedded
  4. Using Qt with QSocketNotifier for GPIO attached interrupting buttons.
Forum Updated to NodeBB v4.3 + New Features

Using Qt with QSocketNotifier for GPIO attached interrupting buttons.

Scheduled Pinned Locked Moved Mobile and Embedded
9 Posts 3 Posters 9.5k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • K Offline
    K Offline
    kenaaker
    wrote on last edited by
    #1

    I wanted to use some real buttons connected through GPIO on a Beaglebone Black with interrupts instead of polling.
    After digging around for a while and a few false starts I found something that seems to work pretty well, with almost no processor load.

    The trickiest part of the problem was that the Linux GPIO driver always is "ready" when the value file is read. That means that the select() function returns immediately and the code turns into a CPU driven poll. This was not useful.
    The documentation for the Linux kernel gpio driver indicated that the GPIO value file needed to be in the exception group of file descriptors in order to get interrupt driven behavior.

    So, in short the answer is to set up the GPIO for the button in the usual way that GPIOs are, then set the direction to "in", the edge to "both" (to get the button press and release). and open the GPIO value file and add the GPIO value file to the QSocketNotifier::Exception set of file descriptors.

    The constructor that I have for this uses a C++ library modelled on the Adafruit C code. The commentary for QSocketNotifier discourages using QSocketNotifier::Exception. I'm not exactly certain why.

    @
    gpio_keypad::gpio_keypad(QString sw_pin, QString in_key_name) {

    this_gpio = new Adafruit_bbio_gpio(sw_pin.toStdString());
    if (!this_gpio) {
        abort();
    } else {
        QString gpio_value_path;
        key_name = in_key_name;
        gpio_value_path = QString::fromStdString(this_gpio->gpio_get_path());
        qDebug() << "keypad path=" &lt;&lt; gpio_value_path;
        keypad_value.setFileName(gpio_value_path); /* Set up the value file */
        this_gpio-&gt;gpio_set_direction("in");
        this_gpio->gpio_set_edge("both"); /* Interrupt on rising edge */
        keypad_value.open(QFile::ReadOnly);
        keypad_notifier = new QSocketNotifier(keypad_value.handle(), QSocketNotifier::Exception);
        keypad_notifier->setEnabled(true);
        connect(keypad_notifier, SIGNAL(activated(int)), this, SLOT(ready_read(int)));
    } /* endif */
    

    }
    @

    1 Reply Last reply
    0
    • T Offline
      T Offline
      topocc
      wrote on last edited by
      #2

      use Qtnetwork(server and client).

      1 Reply Last reply
      0
      • K Offline
        K Offline
        kenaaker
        wrote on last edited by
        #3

        There was no networking involved. QSocketNotifier seems to have been somewhat over-specificly named. It will work with any file descriptor, not just sockets.

        1 Reply Last reply
        0
        • H Offline
          H Offline
          Harsh0505
          wrote on last edited by
          #4

          I am bit new to C++,
          While trying to do above steps i have error at:
          keypad_notifier = new QSocketNotifier(keypad_value.handle(), QSocketNotifier::Exception);
          saying keypad_notifier not declared in the scope.

          What should be the solution for it.

          Also i want to know what should be the contents of below functions:

          1. keypad_value.handle()
          2. ready_read(int).

          What i consider for ready_read(int) is that it will contain the activity that needs to be performed after the interrupt is raised.

          We have configured GPIO0_7 of BeagleBone Black as input with both edges for interrupt.

          Thanks in Advance.
          Harsh

          1 Reply Last reply
          0
          • K Offline
            K Offline
            kenaaker
            wrote on last edited by
            #5

            Hello Harsh,

            I wasn't sure how general the code I created was. The .h file for my gpio_keypad contains the keypad_notifier and the keypad_value QFile variables. The keypad_value.handle() is the file descriptor of the gpio value file for the keypad.

            @#ifndef GPIO_KEYPAD_H
            #define GPIO_KEYPAD_H

            #include <QObject>
            #include <QSocketNotifier>
            #include <QString>
            #include <QFile>
            #include "adafruit_bbio_gpio.h"

            class gpio_keypad : public QObject {
            Q_OBJECT
            public:
            gpio_keypad(QString sw_pin, QString in_key_name);
            ~gpio_keypad();
            int keypad_fd(void); /* Return the file descriptor for the keypad interrupt device /
            QString const keyname(void); /
            Return the name of the key for this object */
            signals:
            void button_pushed(int on_off);
            private:
            Adafruit_bbio_gpio this_gpio; / GPIO object for this pin /
            QFile keypad_value; /
            GPIO keypad value file for keypad file. /
            QString key_name; /
            User name for this key */
            QSocketNotifier keypad_notifier;
            char current_value; /
            The last value read from the GPIO */
            public slots:
            void ready_read(int);
            };

            -=-=-=-=-=-=-- end of keypad.h -=-=-=-=-=-=-=-=

            void gpio_keypad::ready_read(int) {
            QByteArray line;
            keypad_value.seek(0);
            char last_value = current_value;
            line = keypad_value.readAll();
            qDebug() << "bytes_read=" << line.size();
            if (line.size() < 1) {
            abort();
            } else {
            current_value = line[0];
            emit button_pushed(current_value);
            } /* endif /
            if (current_value != last_value) {
            qDebug() << "key" << key_name << "switch value changed, old=" << last_value << "current_value" << current_value;
            } /
            endif /
            } /
            ready_read */

            @

            1 Reply Last reply
            0
            • H Offline
              H Offline
              Harsh0505
              wrote on last edited by
              #6

              Hello,
              Thanks for your responce, i have dont changes said by you, after that i still have problem saif below

              Error:
              No match for call to (QFile)()
              Error for line:
              keypad_notifier = new QSocketNotifier(keypad_value(), QSocketNotifier::Exception);

              h file

              private:
              Ui::MainWindow ui;
              unsigned int IP_PIN;
              unsigned int OP_PIN;
              QFile keypad_value; /
              GPIO keypad value file for keypad file. /
              QString key_name; /
              User name for this key */
              QSocketNotifier keypad_notifier;
              char current_value; /
              The last value read from the GPIO */

              C File

              keypad_notifier = new QSocketNotifier(keypad_value(), QSocketNotifier::Exception);
              keypad_notifier->setEnabled(true);
              connect(keypad_notifier, SIGNAL(activated(int)), this, SLOT(ready_read(int)));
              
              1 Reply Last reply
              0
              • K Offline
                K Offline
                kenaaker
                wrote on last edited by
                #7

                Hello,

                You missed a small piece of code. The keypad_value() should be keypad_value.handle(). The QSocketNotifier constructor needs the Linux file handle as an argument. That should get rid of the error message.

                Ken

                1 Reply Last reply
                0
                • H Offline
                  H Offline
                  Harsh0505
                  wrote on last edited by
                  #8

                  Thanks Ken,
                  I missed handle(), in keypad_value.handle(), so the error is fixed and i can compile my project.

                  I am using Beagle Bone Black with Angstrom Linux.
                  Linux beaglebone 3.8.13 # 1 SMP Mon 20 17:07:58 CEST 2013 armv7l GNU/linux.

                  When i run the project in BeagleBone Black,
                  $ ./Intr -qws
                  QSocketNotifier: Invalid socket specified.

                  Can you please help me.

                  Thanks in Advance.
                  Harsh

                  1 Reply Last reply
                  0
                  • K Offline
                    K Offline
                    kenaaker
                    wrote on last edited by
                    #9

                    That looks like the keypad GPIO file didn't open (and I didn't check for that failure in that piece of code). The file names I wind up using on my bbb look like this

                    keypad path= "/sys/class/gpio/gpio76/value"
                    keypad path= "/sys/class/gpio/gpio11/value"
                    keypad path= "/sys/class/gpio/gpio9/value"
                    keypad path= "/sys/class/gpio/gpio81/value"
                    keypad path= "/sys/class/gpio/gpio8/value"
                    keypad path= "/sys/class/gpio/gpio79/value"
                    keypad path= "/sys/class/gpio/gpio78/value"

                    Yours will almost certainly be different.

                    All the C++ code I have done for the Beaglebone Black is in github at

                    https://github.com/kenaaker/BeagleBoneBlack

                    Some of the stuff is somewhat redundant, but it does make a functioning application.

                    Ken

                    1 Reply Last reply
                    0

                    • Login

                    • Login or register to search.
                    • First post
                      Last post
                    0
                    • Categories
                    • Recent
                    • Tags
                    • Popular
                    • Users
                    • Groups
                    • Search
                    • Get Qt Extensions
                    • Unsolved