cannot convert (void MainWindow::*) to void(*)() for argument '3' to int wiringPiISR(int,int,void(*)())



  • #include "mainwindow.h"
    #include "ui_mainwindow.h"
    #include <wiringPi.h>
    #include<QLabel>
    #include <QDesktopWidget>
    #include <QPixmap>
    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    #include <QTimer>
    #include <QTime>
    #include <QTextEdit>
    #include <QMessageBox>
    #include <stdio.h>
    #include <fcntl.h>
    #include <getopt.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <errno.h>
    #include <string.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <stdio.h>
    #include <string.h>
    #include <errno.h>
    #include <stdlib.h>
    #include <wiringPi.h>
    void myInterrupt();
    #define BUTTON_PIN 0
    volatile int eventCounter = 0;
    // -------------------------------------------------------------------------
    // myInterrupt:  called every time an event occurs
    
    
    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
           setenv("WIRINGPI_GPIOMEM", "1", 1);
        ui->setupUi(this);
        wiringPiSetup () ;
        pinMode (0, OUTPUT) ;
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    
    
    
    
    
    void MainWindow::on_pushButton_clicked()
    {
        ui->flow2->setText("Hello");
    
    
    if(wiringPiISR(BUTTON_PIN, INT_EDGE_FALLING, &MainWindow::myInterrupt)<0)
    {
        printf("cant\n");
    
    
    }
    
        while ( 1 ) {
            printf( "%d\n", eventCounter );
            eventCounter = 0;
            delay( 1000 ); // wait 1 second
    
    
        }
    
    }
     void MainWindow::myInterrupt()
    {
       eventCounter++;
    }
    

    error occurs in wiringPiISR function as above title.

    [Added code tags ~kshegunov]


  • Qt Champions 2016

    Hi
    I think you try to use something that want a callback to a c function

    And you try to give it a member function of a class.

    That is not the same. ( for a member function, there is a "this")

    &MainWindow::myInterrupt will give you the address of a member function.

    If the wiringPiISR ask for a normal function pointer this cannot work

    Only if the MainWindow::myInterrupt is static.

    http://stackoverflow.com/questions/400257/how-can-i-pass-a-class-member-function-as-a-callback

    Easy fix. just use a function that is NOT part of main window/any class

    Also, as a not for later

    while ( 1 ) {}

    Is evil and will 100% lag your application.
    So when you press button and it calls
    on_pushButton_clicked()
    it will never respond again.

    Do not use such loops in the main thread.



  • @mrjj
    i seen the post as in above link
    and use simple function
    Like

    static void myInterrupt();
      #define BUTTON_PIN 0
      volatile int eventCounter = 0;
       // -------------------------------------------------------------------------
      // myInterrupt:  called every time an event occurs
    
    
    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
           setenv("WIRINGPI_GPIOMEM", "1", 1);
        ui->setupUi(this);
        wiringPiSetup () ;
        pinMode (0, OUTPUT) ;
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    
    
    
    
    
    void MainWindow::on_pushButton_clicked()
    {
        ui->flow2->setText("Hello");
    
    
    if(wiringPiISR(BUTTON_PIN, INT_EDGE_FALLING, &myInterrupt)<0)
    {
        printf("cant\n");
    
    
    }
    
        while ( 1 ) {
            printf( "%d\n", eventCounter );
            eventCounter = 0;
            delay( 1000 ); // wait 1 second
    
    
        }
    
    }
     static void myInterrupt()
    {
       eventCounter++;
    }
    

    But same error occurs


  • Moderators

    @gauravsharma0190 Now that you took myInterrupt out of your class you should drop the static.. It should be just defined as:
    void myInterrupt();

    Show us the header or function definition for the wiringPiISR function and we should be able to get it fixed for you.

    Also that while (1) loop as mentioned by @mrjj is not going to work at all. You will stall your GUI/event loop, and your entire program. There is no way for the callback to work either unless wiringPiISR puts it in a separate thread. You need to remove that or put it in a thread protected by a mutex or something. Or just use Qt signals and set a timer for 1s that will print your eventCounter. Then there is no while(1) blocking things. And of course you can do it even better and use a signal when the value is changed that will print the new value. Then there is no sleep 1000 at all, which is bad coding. ;)



  • @ambershark
    int wiringPiISR (int pin, int edgeType, void (*function)(void)) ;
    This function registers a function to received interrupts on the specified pin. The edgeType parameter is either INT_EDGE_FALLING, INT_EDGE_RISING, INT_EDGE_BOTH or INT_EDGE_SETUP. If it is INT_EDGE_SETUP then no initialisation of the pin will happen – it’s assumed that you have already setup the pin elsewhere (e.g. with the gpio program), but if you specify one of the other types, then the pin will be exported and initialised as specified. This is accomplished via a suitable call to the gpio utility program, so it need to be available.

    The pin number is supplied in the current mode – native wiringPi, BCM_GPIO or Sys modes.

    This function will work in any mode, and does not need root privileges to work.

    The function will be called when the interrupt triggers. When it is triggered, it’s cleared in the dispatcher before calling your function, so if a subsequent interrupt fires before you finish your handler, then it won’t be missed. (However it can only track one more interrupt, if more than one interrupt fires while one is being handled then they will be ignored)

    This function is run at a high priority (if the program is run using sudo, or as root) and executes concurrently with the main program. It has full access to all the global variables, open file handles and so on.

    See the isr.c example program for more details on how to use this feature.
    https://github.com/ngs/wiringPi/blob/master/examples/isr.c


  • Moderators

    @gauravsharma0190 Try removing the & when passing your myInterrupt function.

    I.e.
    if(wiringPiISR(BUTTON_PIN, INT_EDGE_FALLING, myInterrupt)<0)



  • @ambershark
    it runs
    now i want to run the whole thing which is in while loop everytime
    so where should i edit it.


  • Moderators

    @gauravsharma0190 Well you need to get rid of that while loop entirely.

    You can duplicate the while loop's functionality by just adding an output to your interrupt function. Or you could add a GUI label that had a count incremented when the interrupt happened. There are tons of things you could do. They all use signals/slots so no polling which is what you were doing with that while loop (incorrectly, as a loop like that needs a thread, and is still a bad idea even in a thread).

    So remove the while loop completely.. and change your interrupt function to this:

    void myInterrupt()
    {
       qDebug() << "event counter is " << ++eventCounter;
    }
    

    Make sure to #include <QDebug>. That should give you console output of any time the event occurs.

    Personally I feel the better way is to add a QLabel to your GUI and update it with the current count on every interrupt.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.