Multiple function calls on one interrupt-generating button press - c++

So I have a c++ program here utilizing wiringPi to sleep a thread until a button press (on a rapsberryPi using the GPIO), but when the button is pressed it can often print the message multiple times. I tried to remedy this by sleeping for a few seconds within the loop but this didn't help leading me to believe that it has something to do with how the interrupt generation calls the function. Any advice for how I can solve this so the function is only ran once per button press?
#include <stdlib.h>
#include <iostream>
#include <wiringPi.h>
#include <unistd.h>
void printMessage(void) {
std::cout << "Button pressed! hooray" << std::endl;
}
int main(int argc, char const *argv[]) {
wiringPiSetup();
while(true) {
wiringPiISR(3, INT_EDGE_FALLING, &printMessage);//3 is the wiringPi pin #
sleep(3);
}
}

I think you only have to set the ISR once (call wiringPiISR once). After that just sleep forever (while(1)sleep(10);). You seem to have debounced your button using a print statement. Debouncing can often be a matter of timing, and printing takes a few microseconds causing the button to be "sort of" debounced. It can however still do some bouncing
For more debouncing info see this SO page

I am not familiar with the Raspberry-Pi, but if the code can directly sense the button state (instead of using a triggered interrupt) do something like this to react only on the enabling transition:
int main (...)
{
writingPiSetup ();
bool last_state = false;
while (true)
{
bool this_state = wiringPiDigital (3); // use correct function name
if (last_state == false && this_state == true) // button freshly pressed
{
std::cout << "Button freshly pressed" << std::endl;
}
last_state = this_state;
}
}
However, it is quite possible that the hardware is not debounced. So inserting a little bit of delay might be called for. I would experiment with delays in the 10 to 100 millisecond range depending on the particulars of the application.

Related

Starting/stopping function using QT GUI buttons

I am writing a simple Qt C++ GUI window for the user to input certain values for a USRP device to record (i.e. input start frequency, stop frequency, etc..). Once the user inputted the values, the "EXECUTE" button is clicked and the execute_run_usrp() function is called in its own thread (so not to block the GUI). Then the STOP button should be able to be clicked at any time to terminate the thread running the function that runs the USRP, execute_run_usrp(), thus terminating the USRP recording process.
The function run_usrp(x,y,z,etc) is defined in another *.cpp file in the Project.
The problem that I am having that the STOP button when clicked only seems to "pause" the function...doesn't actually kill it (like with CTRL-C, which works great here)
Here is my code from MainWindow.cpp for the EXECUTE button click:
// run the following when EXECUTE button is clicked
void MainWindow::on_button_EXECUTE_clicked()
{
if ( ui->calculated_StartTime->text() == "" )
{
QMessageBox messageBox;
messageBox.critical(0,"Error","Hit the \"CALCULATE SCHEDULE\" button first above!!");
messageBox.setFixedSize(500,200);
return;
}
ui->button_STOP->setVisible(true);
ui->button_EXECUTE->setVisible(false);
auto function = std::bind([this]{execute_run_usrp();});
QThread* temp = QThread::create(function);
temp->start();
connect( ui->button_STOP, SIGNAL(clicked()), temp, SLOT( terminate() ));
}
Here is the execute_run_usrp() function:
void MainWindow::execute_run_usrp()
{
float startFreq = ui->input_startFreq->text().toFloat();
float stopFreq = ui->input_stopFreq->text().toFloat();
float stepFreq = ui->input_stepFreq->text().toFloat();
int nRepeats = ui->input_numRepeats->text().toInt();
float ipp = ui->input_IPP->text().toFloat();
int sweepCadence = ui->calculated_sweepCadence->text().toInt();
int numSweeps = ui->input_numSweeps->text().toInt();
std::string schedule_run = ui->calculated_StartTime->text().toStdString();
std::cout << startFreq << std::endl;
std::cout << stopFreq << std::endl;
std::cout << stepFreq<< std::endl;
std::cout << nRepeats << std::endl;
std::cout << ipp << std::endl;
std::cout << sweepCadence << std::endl;
std::cout << numSweeps << std::endl;
run_usrp(startFreq, stopFreq, stepFreq, nRepeats, ipp, sweepCadence, numSweeps, schedule_run);
}
And here is the STOP button code:
void MainWindow::on_button_STOP_clicked()
{
ui->button_STOP->setVisible(false);
ui->button_EXECUTE->setVisible(true);
}
Clicking the STOP button only seems to pause the function, doesn't actually kill it like doing CTRL-C with the keyboard. I think the UHD library (that runs the USRPs) spwans its own thread for running.
Question: How do I 100% terminate the entire function (and including any spwaned children from UHD) when I hit the STOP button ?
Thank you very much!
How do I 100% terminate the entire function (and including any spwaned children from UHD) when I hit the STOP button ?
From the code you've shown there's no easy answer imho.
The shortest one is: by incorporating some inter-thread communication inside the USRP function, provided you want some sort of graceful exit.
As for terminate, QT's docs state:
This function is dangerous and its use is discouraged. The thread can be terminated at any point in its code path. Threads can be terminated while modifying data. There is no chance for the thread to clean up after itself, unlock any held mutexes, etc. In short, use this function only if absolutely necessary.
Alternatively, the whole USRP function can be run inside a separate process, that is then killed. Again, plain killing of the process is far from graceful, still it seems easier and safer than doing it to a thread. You may want to check QProcess for reference.

Prevent GetAsyncKeyState() from getting blocked by Antivirus Software

I'm trying to create an afk money bot for a game.
I'm using GetAsyncKeyState() to start and stop the bot.
I've run the code a few times to try out a few things. Then I added a delay between calling the GetAsyncKeyState() function using the clock() function. When I tried to run the new code, I got an error stating that the .exe file was missing. I tried rebuiding or cleaning the project but it didn't work. Then I deleted the project, created a new one and copied the code back into the project. This did not work either, but I noticed a notification by my antivirus program: The .exe was detected as a fugrafa threat. I'm pretty confident that this was somehow caused by the GetAsyncKeyState() function since keyloggers can be recognized as a fugrafa threat.
There's gotta be a way to prevent this from happening, since I've seen GetAsyncKeyState() being used a lot.
Or do I really need to disable the antivirus in order to be able to use GetAsyncKeyState()?
Here's the Code:
#include <chrono>
#include <iostream>
#include <windows.h>
bool botActive = false;
void timeout(int);
int main()
{
bool F3_CurrentKeyState = GetAsyncKeyState(VK_F3);
bool F3_PreviousKeyState = F3_CurrentKeyState;
while (true)
{
//F3 Key Edge detection
F3_PreviousKeyState = F3_CurrentKeyState;
F3_CurrentKeyState = GetAsyncKeyState(VK_F3);
if (GetAsyncKeyState(VK_F3) && (F3_CurrentKeyState != F3_PreviousKeyState)) botActive = !botActive;
if (botActive)
{
std::cout << "Bot Active" << std::endl;
}
else
{
std::cout << "Bot Inactive" << std::endl;
}
timeout(100/*ms*/);
}
}
void timeout(int delay_ms)
{
clock_t toutStart = clock();
while (((float)clock() - toutStart) < delay_ms);
}

The simplest possible example for a multi-threaded gtkmm application

I'm developing a stopwatch application in c++ and gtkmm.The first approach was to integrate the stopwatch loop with main event loop,but that caused delays in the stopwatch loop,So I decided to use two threads , one for GUI the other is for the stopwatch counter.
the GUI thread and and stopwatch thread -which counts the number of seconds passed- , the stopwatch thread updates the label after each second. I've read that I've to use specific techniques to use multi threaded gtkmm program. I also checked this example which i didn't understand. Can any one tell me what shall I do in the stopwatch thread to make it update the GUI without crashing.
Here's the code,
#include <ctime>
#include <thread>
#include <iostream>
#include <sstream>
#include <gtkmm.h>
using namespace std;
using namespace Gtk;
using namespace std::chrono;
class Timer
{
bool condition;
Label *label_ptr;
private:
void startTimer()
{
condition = true;
auto t0 = high_resolution_clock::now();
int x = 0;
while (condition)
{
cout << condition << endl;
auto t1 = high_resolution_clock::now();
int duration = duration_cast<seconds>(t1 - t0).count();
if (duration - x == 1)
{
x = duration;
//cout << duration_cast<seconds>(t1 - t0).count() << "sec" << endl;
stringstream moment;
moment << to_string(duration_cast<seconds>(t1 - t0).count());
moment << ": 0 s";
label_ptr->set_label(moment.str());
}
if (g_main_context_pending(NULL))
{
g_main_context_iteration(NULL, true);
}
}
}
public:
//This is the function which start the thread
void start_timer(){
thread t0(sigc::mem_fun(this , &Timer::startTimer));
}
Timer(Label &label)
{
condition = 0;
label_ptr = &label;
}
void stop_timer()
{
label_ptr->set_text("0 : 0");
condition = false;
}
};
int main(int argc, char *argv[])
{
auto app = Application::create(argc, argv, "Timer");
if (!g_thread_supported())
g_thread_init(NULL);
gdk_threads_init();
gdk_threads_enter();
Window window;
HBox mainBox;
window.add(mainBox);
window.set_title("Timer & Stopwatch");
window.set_default_size(240, 100);
window.set_border_width(10);
Label label;
VButtonBox buttons;
Separator sep0;
mainBox.pack_start(buttons, PACK_EXPAND_PADDING, 20);
mainBox.pack_start(sep0, PACK_SHRINK);
mainBox.pack_end(label, PACK_EXPAND_PADDING);
label.set_size_request(120, 100);
Button start, stop;
buttons.add(start);
buttons.add(stop);
start.set_border_width(5);
stop.set_border_width(5);
start.set_label("Start");
stop.set_label("Stop");
label.set_text("0 : 0");
Timer timer(label);
start.signal_clicked().connect(sigc::mem_fun(timer, &Timer::start_timer));
window.show_all_children();
gdk_threads_leave();
return app->run(window);
}
if your requirement is just to count number of seconds elapsed, you do not need a worker thread. Also you cannot modify any GUI element (in your case the 'label') from a worker thread since Gdk is not thread safe. You will then need to use Glib::Dispatcher to notify the main thread of a 'tick' event and then increment a counter from the main loop.
Instead of all this you can simply use Glib::SignalTimeout and connect a function to it like below.
In the function that handles starting of the stop-watch
//Connect to timeout
m_connectionStopWatch = Glib::SignalTimeout::connect(sigc::mem_fun(*this, &CStopWatchClass::OneSecondElapsed), 1000);
//Reset counter
m_nCounter = 0;
The function that is called every second
bool CStopWatchClass::OneSecondElapsed(void)
{
//Increment counter
m_nCounter++;
//TODO Update label
return true;
}
In the function that stops the stop watch
m_connectionStopWatch.disconnect();
m_connectionStopWatch and m_nCounter shall be class private (or protected or even public though not preferred) members.
If you are not particular about having a delay of up to 0.99... seconds in starting your stop watch you can even use Glib::SignalTimeout::connect_seconds which loads your application even less. In any case a 1 second timeout is no problem at all, I myself am using a 20 millisecond timeout for a similar graphical application.

C++ get arrow key press while a thread is running

I am trying to make a snake game in c++. I have a thread that moves the snake's head in the direction that the user specifies with the arrow keys. if I press the up arrow key I need the head to move up and continue moving (this is done by the thread) without me pressing the arrow keys.
The issue is i can't get the keyboard input to work together with the thread, its either one function works or its the other, they can't work together
Keyboard input function:
void moveSnake()
{
while(true)
{
int key = getch();
switch(key)
{
case 72:
{
//UP
break;
}
case 80:
{
// DOWN
break;
}
case 77:
{
// RIGHT
break;
}
case 75:
{
// LEFT
break;
}
}
}
Thread function:
void thread_handler()
{
while(true)
{
// Move the snake
Sleep(500);
}
}
This is where i create the thread and call the keyboard function
int main()
{
moveSnake();
thread t(thread_handler);
t.join();
return 0;
}
I have tried
putting moveSnake() in a thread
executing the thread_handler function without a thread
tried to put both functions in a separate thread
tried switching the order with all these possible solutions
But none of these worked.
I need a way to get the keycode for the arrow keys while running the thread at the same time
Follow your source code like the compiler would, from top to bottom. Your debugger can help you step through it. You've went into a never ending loop in your main thread. What comes after that doesn't matter because you never get there.
Even if you switch the ordering of things, you've still got a never ending loop, so you cannot join properly after you call it.
You need to read up on some basic threading lessons.
Just because you are using threads doesn't mean you can stop worrying about whether loops exit or not. Loops should always have some exit condition.
For your program, I'd assume you'd want to start a thread to handle the input, lock some manner of storage and read key presses. Back in your main thread, you'd probably want to loop until some signal for exit, lock and get the stored key press/command (maybe use a thread safe queue?), and react to it.
Here is a very simple and naive example:
#include <mutex>
#include <thread>
#include <queue>
#include <conio.h>
#include <iostream>
class Application
{
public:
void Run()
{
// Start input thread
if (m_inputThread.joinable())
{
Shutdown();
}
auto thread = std::thread(std::bind(&Application::InputThreadProc, this));
m_inputThread.swap(thread);
while (!m_shutdown)
{
// React to the queued input, including checking for shutdown
// I'm just going to ignore the complex issue of timing
std::this_thread::sleep_for(std::chrono::milliseconds(33));
std::lock_guard<std::mutex> lock(m_mutex);
if( !m_keysPressed.empty() )
{
auto key = m_keysPressed.front();
m_keysPressed.pop();
switch (key)
{
case 75:
m_shutdown = true;
default:
std::cout << "I saw a key: " << key << std::endl;
break;
}
}
}
Shutdown();
}
private:
std::mutex m_mutex;
std::queue<int> m_keysPressed;
bool m_shutdown = false;
std::thread m_inputThread;
void Shutdown()
{
if (m_inputThread.joinable())
{
m_inputThread.join();
}
}
void InputThreadProc()
{
while (!m_shutdown)
{
std::this_thread::sleep_for(std::chrono::milliseconds(33));
std::lock_guard<std::mutex> lock(m_mutex);
// OS Specific. Better means of getting localized input exist.
// Also, timing is an issue. Is the key pressed when we are trying to read.
// Input is a complex topic and many libraries for it exist
m_keysPressed.emplace(_getch());
}
}
};
int main()
{
Application application;
application.Run();
return 0;
}
Change the order of your main to
int main()
{
thread t(thread_handler);
moveSnake();
t.join();
return 0;
}
this way the thread is started before your input loop (which is an endless loop). Make sure you leave the t.join() at the end.
With this said, you need to create a method that both the thread and input loop exit. Currently both are infinite loops.

Qt Creator crashes when using multiple threads

I'm writing a Qt (5.3) program which has a joystick test UI in it, but I need a separate thread for an infinite while loop looking for joystick axis/button value changes through SDL. That part of the code is working fine as I can have the thread qDebug() messages and it seems to work. But from the main window, when I try to open the test joystick UI, the program crashes. I've had the test joystick UI running separation WITHOUT the JoystickThread thread and it seems to open up fine.
The error messages are inconsistent though - some times, I just get
The program has unexpectedly finished.
/home/narendran/QtWorkspace/build-LinkControl-Desktop-Debug/LinkControl crashed
This has shown up once:
QXcbWindow: Unhandled client message: "_GTK_LOAD_ICONTHEMES"
And a few other times:
[xcb] Unknown sequence number while processing queue
[xcb] Most likely this is a multi-threaded client and XInitThreads has not been called
[xcb] Aborting, sorry about that.
star: ../../src/xcb_io.c:274: poll_for_event: Assertion `!xcb_xlib_threads_sequence_lost' failed.
I found that this was common if XInitThreads(); is not run in the main function, but even with it on there, it crashes with the same error(s).
main.cpp
#include <qsplashscreen.h>
#include "linkcontrol.h"
#include "configure.h"
#include <unistd.h>
#include <QApplication>
#include <QPixmap>
#include <QStyle>
#include <QDesktopWidget>
#include "linkports.h"
#include "joystickthread.h"
#include <X11/Xlib.h>
int main(int argc, char *argv[])
{
XInitThreads();
QApplication a(argc, argv);
QPixmap pix(":splash.png");
QSplashScreen splash(pix);
splash.show();
a.processEvents();
JoystickThread jsThread;
jsThread.start();
LinkControl linkcontrol;
usleep(1000000);
splash.finish(&linkcontrol);
usleep(100000);
linkcontrol.show();
linkcontrol.setGeometry(QStyle::alignedRect(Qt::LeftToRight, Qt::AlignCenter,linkcontrol.size(),a.desktop()->availableGeometry()));
return a.exec();
}
The actual thread is in joystickthread.cpp
#include "joystickthread.h"
#include "global.h"
#include "unistd.h"
/* JoystickThread::JoystickThread(int _interval)
{
this->interval_us = _interval;
} */
void JoystickThread::run()
{
while(1)
{
if(joystick->connected)
{
joystick->updateJSData();
// Check for changed values
for(int i=0; i<joystick->axis.count(); i++)
{
if(joystick->axis.value(i) != joystick->axis_last[i])
{
joystick->axisUpdateEmit(i);
// qDebug() << "AXIS: " << i << "\tVALUE: " << joystick->axis.value(i);
}
joystick->axis_last[i] = joystick->axis.value(i);
}
for(int i=0; i<joystick->button.count(); i++)
{
if(joystick->button.value(i) != joystick->button_last[i])
{
joystick->btnUpdateEmit(i);
// qDebug() << "BUTTON: " << i << "\tVALUE: " << joystick->button.value(i);
}
joystick->button_last[i] = joystick->button.value(i);
}
}
usleep(2500);
}
}
The function that causes the program to crash is in linkcontrol.cpp
void LinkControl::on_actionJoystick_Test_triggered()
{
qDebug() << "STARTING CHECK";
if(!js_test->initialized) {
qDebug() << "NOT INIT";
js_test = new TestJoystick();
js_test->initialized = true;
qDebug() << "FININSH INIT";
}
if(joystick->connected) {
qDebug() << "SHOWING UI";
js_test->show();
} else {
QMessageBox::critical(this, tr("No Joystick Connected!"), tr("Please connect a joystick first..."));
}
}
Where js_test is declared as a TestJoystick object in the linkcontrol.h file
public:
explicit LinkControl(QWidget *parent = 0);
QSlider *portSliders[16];
QLineEdit *setVals[16];
SerialTerminal *ser_term;
TestJoystick *js_test;
~LinkControl();
Thank you very much! Please let me know if you need anymore information.
QThreads are a little tricky to get used to initially, and have their share of gotchas.
You should construct and connect appropriate items at the top of your run function.
If you do it other places, you need to make sure that you don't use Qt::AutoConnection, but instead use Qt:QueuedConnection.
http://qt-project.org/doc/qt-5/qt.html#ConnectionType-enum
Certain elements are only accessible from the "GUI" thread or the main thread of the program. This is the thread that has QApplication::exec(); ran on. It has an event loop that propagates messages around.
Look at the Application output for runtime errors that Qt will tell you about.
When crossing thread boundaries, be sure to use signals and slots.
And if you are accessing a member of your thread class from outside that thread, be sure to use thread synchronization, practices, such as prefacing all access to these members with QMutexLocker locker(m_mutex);.
http://qt-project.org/doc/qt-5/threads.html
And as implied by the title "GUI thread", it is the only thread that is allowed to do certain things such as drawing QPixmaps and accessing certain parts of QWidgets.
Hope that helps.