Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
152 views
in Technique[技术] by (71.8m points)

c++ - How Do I Make My Program in Qt Continually Send A String to My Arduino?

I am having trouble trying to get my program to continually send the string "move 200" while I hold down a button. I have the button set to auto repeat however it only sends once the button is released not while it is holding down. However while being held down the counter is adding how many times the message should have been sent. I am at a lost.

mainwindow.cpp

void MainWindow::on_forwardButton_clicked()
{
    if(arduino->isWritable()){

        arduino->write(command.toStdString().c_str());

        qDebug() << i;

    }else{
        qDebug() << "Couldn't write to serial!";
    }

    ui->label->setText("Moving");
    i++;

}

mainwindow.h

ifndef MAINWINDOW_H
define MAINWINDOW_H
include <QMainWindow>
include <QDialog>
include <QSerialPort>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private slots:

    void on_forwardButton_clicked();

private:
    Ui::MainWindow *ui;
    QSerialPort *arduino; //makes arduino a pointer to the SerialPort
    bool arduino_is_available;
    QString command = "move 200";
    bool buttonReleased = false;
};

endif // MAINWINDOW_H

Code added following @dtech suggestion

    pButtonTimer = new QTimer;
            connect(pButtonTimer, SIGNAL(timeout()), this, SLOT(sendData()));

       int i = 0;
void MainWindow::on_forwardButton_pressed()
{
    pButtonTimer->start(1000);
    ui->label->setText("Moving");
    qDebug() << "Button Pushed";
}

void MainWindow::on_forwardButton_released()
{
    pButtonTimer->stop();
} 


void MainWindow::sendData(){
        i++; //used to count how many times the command should have been sent
        qDebug() << i << "sendData is running"; //notifies me the function has been called
        if(arduino->isWritable()){
            arduino->write(command.toStdString().c_str());
            qDebug() << i << "arduino is writable with command " << command; //lets me know the Arduino is writable
        }
        else{qDebug() << "Couldn't write to serial!";}
    }

After releasing the button the serial monitor in the Arduino then shows everything sent and the robot moves

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

I suggest you expand on your design somewhat:

  • have a repeating QTimer with an interval depending on the rate you want to send the string at, and the timer to the function that sends the string
  • connect the button's pressed signal to start the timer
  • connect the button's released signal to stop the timer

Events are sent only once, thus the handlers will be executed only once, if you want to keep on repeating it, you will have to use a timer or some other event driven way. You cannot use a loop as that would block the GUI thread and your application will stop responding.

Sure, you could use the button's auto repeat, and there is the option to adjust the triggering and repeating intervals, but a solution that puts a line between logic and GUI is better. You should really rely on the GUI for storing data or controlling the internal logic. The GUI should only be a front end.

You need more work on the serial port though. If you are going to use it from the GUI thread, you will have to use the non-blocking API. Which will require to extend on your implementation a little bit more. There is a good example on how to achieve that, you only need to modify it to simply enable the sending of further payloads once the previous payload has been successfully sent. In pseudo code:

on button press
  start timer
on button release
  stop timer
onTimeout
  if (can send) 
    send
    can send = false
onBytesWritten
  accumulate bytes
  if (payload is completed)
    can send = true
    reset payload byte counter

Of course, you will also have to do some error checking, you can't just expect it to work. The example linked contains basic error handling.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...