Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Raspberry Pi GPIO with C/C++ using 3rd party library pigpio



  • Hello Everyone,

    I have a problem with using 3rd party library pigpio.

    The application works well, i saw gpio value via qDebug() in Application Output screen but i can't set ui widget values at aFunction().

    When i used ui->cdNumber->display(RPM) in aFunction() i get error "invalid use of member ‘ui’ in static member function"

    How do I fix this problem? or How should I go about solving this problem?

    My qt Application:

    I added .pro file at below code.

    LIBS += -lpigpio -lrt -lpthread
    

    Mainwindow.h

    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    
    #include <QMainWindow>
    #include "QDebug"
    #include <pigpio.h>
    #include <QTimer>
    
    
    namespace Ui {
    class MainWindow;
    }
    
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    
    public:
        explicit MainWindow(QWidget *parent = nullptr);
        ~MainWindow();
    
    public slots:
    
    
    private:
        Ui::MainWindow *ui;
        QTimer *ScreenRefreshing;
    
    
    private slots:
        static void aFunction(int gpio, int level, uint32_t tick);
    
        void Screen_Refreshing();
    };
    
    #endif // MAINWINDOW_H
    
    

    Mainwindow.cpp:

    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    
    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
    
        if (gpioInitialise() < 0)
        {
            qDebug() << "pigpio initialisation failed";
        }
        else
        {
            qDebug() << "pigpio initialised ok";
        }
    
        gpioSetMode(20, PI_INPUT);
        gpioSetPullUpDown(20, PI_PUD_OFF);
        gpioSetAlertFunc(20, aFunction);
    
        ScreenRefreshing = new QTimer(this);
        connect(ScreenRefreshing, SIGNAL(timeout()), this, SLOT(Screen_Refreshing()));
        ScreenRefreshing->start(100);
    
    }
    
    MainWindow::~MainWindow()
    {
        gpioTerminate();
        delete ui;
    }
    
    void MainWindow::aFunction(int gpio, int level, uint32_t tick)
    {
        double RPM = 0;
    
        if(gpio == 20)
        {
            if(level == 1)
            {
               static uint32_t lastTick = 0;
    
               if (lastTick)
               {
    
                   qDebug() << "GPIO = " << gpio << "LEVEL = " << level << "Tick = " << tick;
    
                   RPM = (double(tick - lastTick) / 1000000.0) * 3600;
                   qDebug() << "RPM = " << RPM;
    
                   // ui->lcdNumber_Distance->display(RPM);  // ->>>>>>>>> "invalid use of member ‘ui’ in static member function"
    
               }
               else
               {
                   //qDebug() << "2. Level = " << level;
                   //printf("%d 0.00\n", level);
               }
    
               lastTick = tick;
            }
        }
    }
    
    void MainWindow::Screen_Refreshing()
    {
        // for test
    }
    
    
    

    The function I use and its description:

    	
    int gpioSetAlertFunc(unsigned user_gpio, gpioAlertFunc_t f)
    Registers a function to be called (a callback) when the specified GPIO changes state.
    
    user_gpio: 0-31
            f: the callback function
    
    
    Returns 0 if OK, otherwise PI_BAD_USER_GPIO.
    
    One callback may be registered per GPIO.
    
    The callback is passed the GPIO, the new level, and the tick.
    
    Parameter   Value    Meaning
    
    GPIO        0-31     The GPIO which has changed state
    
    level       0-2      0 = change to low (a falling edge)
                         1 = change to high (a rising edge)
                         2 = no level change (a watchdog timeout)
    
    tick        32 bit   The number of microseconds since boot
                         WARNING: this wraps around from
                         4294967295 to 0 roughly every 72 minutes
    
    
    The alert may be cancelled by passing NULL as the function.
    
    The GPIO are sampled at a rate set when the library is started.
    
    If a value isn't specifically set the default of 5 us is used.
    
    The number of samples per second is given in the following table.
    
                  samples
                  per sec
    
             1  1,000,000
             2    500,000
    sample   4    250,000
    rate     5    200,000
    (us)     8    125,000
            10    100,000
    
    
    Level changes shorter than the sample rate may be missed.
    
    The thread which calls the alert functions is triggered nominally 1000 times per second. The active alert functions will be called once per level change since the last time the thread was activated. i.e. The active alert functions will get all level changes but there will be a latency.
    
    If you want to track the level of more than one GPIO do so by maintaining the state in the callback. Do not use gpioRead. Remember the event that triggered the callback may have happened several milliseconds before and the GPIO may have changed level many times since then.
    
    The tick value is the time stamp of the sample in microseconds, see gpioTick for more details.
    
    Example
    
    void aFunction(int gpio, int level, uint32_t tick)
    {
       printf("GPIO %d became %d at %d", gpio, level, tick);
    }
    
    // call aFunction whenever GPIO 4 changes state
    
    gpioSetAlertFunc(4, aFunction);
    

    Thanks in advance


  • Lifetime Qt Champion

    Hi and welcome to devnet,

    That's because you try to access a standard member variable from a static function.

    Take a look at the ir_receiver example of the pigpio project. It shows how to use a class with the callback with gpioSetAlertFuncEx.