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

查看:269
本文介绍了如何在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.

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

根据@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天全站免登陆