Qt串口异步通信案例(从机线程)

串口线程类

SlaveThread(从机线程)

目的:等待并响应来自主机的请求,然后发送预设的响应数据。
关键行为:
    线程启动后,通过串口监听请求数据。
    当检测到有数据可读时,读取请求数据。
    读取完毕后,向串口写入预设的响应数据。
    如果写入成功,通过信号 request(QString) 发送接收到的请求信息给外部监听者。
    如果在读取请求或写入响应时发生超时,会触发 timeout(QString) 信号。
同步机制:使用 QMutex 保证线程安全,检查和更新串口号、等待超时时间以及响应内容,但没有使用 QWaitCondition,因为它是一个被动监听请求的线程,不需要主动唤醒机制。

SlaveThread (从机线程) 示例

假设在一个自动化仓库管理系统中,有多个库存检查站,每个站点装备了一个读取条形码的扫描枪作为从设备(Slave)。这些从设备并不主动发起操作,而是等待仓库管理系统(主设备)的指令来执行任务。
场景描述:

任务:当一个物品进入或离开仓库时,仓库管理系统需要记录该物品的条形码信息。
流程:主设备(如中央服务器)通过网络向各个站点的从机发送请求,要求读取条形码。从机(SlaveThread实例)不断监听串口,一旦接收到请求,立刻激活扫描枪读取条形码,然后通过串口将条形码数据作为响应发回给主设备。
特点:在这个场景中,SlaveThread体现为被动响应设备的职责,等待主设备的指令,执行读取任务并反馈结果。

SlaveThread 更适用于那些需要持续监听并响应外部指令的场景,如传感器数据采集、远程控制设备的响应等。(只采集数据,并不需要主动发送请求,而是始终监听并响应数据的到来)

class SlaveThread : public QThread
{
   
   
    Q_OBJECT

public:
    explicit SlaveThread(QObject *parent = nullptr);//
    ~SlaveThread();

    void startSlave(const QString &portName, int waitTimeout, const QString &response);//初始化串口及启动线程

signals:
    void request(const QString &s);//请求消息
    void error(const QString &s);//串口错误消息
    void timeout(const QString &s);//串口连接超时消息

private:
    void run() override;//串口通信

    QString m_portName;
    QString m_response;
    int m_waitTimeout = 0;
    QMutex m_mutex;
    bool m_quit = false;
};

初始化串口类

void SlaveThread::startSlave(const QString &portName, int waitTimeout, const QString &response)
{
   
   
    const QMutexLocker locker(&m_mutex);//初始化线程锁
    m_portName = portName;//设置串口号
    m_waitTimeout = waitTimeout;//设置串口的等待时间
    m_response = response;//设置串口的相应参数
    if (!isRunning())//判断线程是否运行
        start();//启动线程
}

打开串口并发送数据

void SlaveThread::run()
{
   
   
    bool currentPortNameChanged = false;

    // 加锁以安全地访问和更新线程间共享的数据
    m_mutex.lock();
    
    // 获取并记录当前配置与上次是否有变
    QString currentPortName;
    if (currentPortName != m_portName) {
   
    // 检查端口名是否变更
        currentPortName = m_portName;
        currentPortNameChanged = true; // 标记端口变更
    }

    int currentWaitTimeout = m_waitTimeout; // 获取超时时间
    QString currentResponse = m_response; // 获取响应信息
    m_mutex.unlock(); // 解锁,释放互斥锁

    QSerialPort serial; // 创建QSerialPort对象用于串口通信

    // 主循环,持续运行直到收到退出信号
    while (!m_quit) {
   
   
        // 如果端口设置发生变更
        if (currentPortNameChanged) {
   
   
            serial.close(); // 关闭旧端口
            serial.setPortName(currentPortName); // 设置新端口名

            // 尝试打开新的串口,失败则发送错误信号并退出
            if (!serial.open(QIODevice::ReadWrite)) {
   
   
                emit error
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值