如何让 Qt 中的程序不断向我的 Arduino 发送字符串? [英] How Do I Make My Program in Qt Continually Send A String to My Arduino?

查看:41
本文介绍了如何让 Qt 中的程序不断向我的 Arduino 发送字符串?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我按住一个按钮时,我无法让我的程序连续发送字符串 "move 200".我将按钮设置为自动重复,但是它只在按钮被释放时发送,而不是在按住时发送.然而,当被按住时,计数器正在添加消息应该发送的次数.我迷路了.

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.

ma​​inwindow.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++;

}

ma​​inwindow.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

根据@dtech 建议添加的代码

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!";}
    }

松开按钮后,Arduino 中的串行监视器会显示发送的所有内容并且机器人移动

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

推荐答案

我建议你稍微扩展一下你的设计:

I suggest you expand on your design somewhat:

  • 有一个重复的 QTimer,其间隔取决于您想要发送字符串的速率,以及发送字符串的函数的定时器
  • 连接按钮的按下信号以启动计时器
  • 连接按钮的释放信号以停止计时器
  • 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

事件只发送一次,因此处理程序只会执行一次,如果你想继续重复它,你将不得不使用计时器或其他一些事件驱动的方式.您不能使用循环,因为这会阻塞 GUI 线程并且您的应用程序将停止响应.

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.

当然,您可以使用按钮的自动重复,并且可以选择调整触发和重复间隔,但在逻辑和 GUI 之间划一条线的解决方案更好.您应该真正依靠 GUI 来存储数据或控制内部逻辑.GUI 应该只是一个前端.

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.

不过,您需要在串行端口上做更多工作.如果要从 GUI 线程使用它,则必须使用非阻塞 API.这将需要更多地扩展您的实现.有一个 关于如何实现这一目标的好例子,您只需要修改它即可在成功发送前一个有效负载后简单地启用发送更多有效负载.在伪代码中:

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.

这篇关于如何让 Qt 中的程序不断向我的 Arduino 发送字符串?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆