qt 程序中读取 DXL360 倾角仪的数据

最近需要测量水平倾角,就从网上找了个 DXL360 倾角仪。就是下面照片里这东西。
这里写图片描述

这东西说实话挺山寨的,我现在也没搞明白网上那么多品牌到底是谁山寨谁。反正就是买了几个,凑合用吧。

这东西提供了个 USB 接口,插在电脑上之后会虚拟出个Serial port。因此读取数据就是从串口中获取数据之后解析一下。没什么难度,代码放这里做个备忘,希望对大家也能有用。

DXL360 通过串口传来的数据格式为 X+0000Y+0000, 其中 “+” 可以为“+” 或 “-”。表示的是角度的正负号。
“0000” 是具体的数据,实际的角度值为这个数除以 100,单位为度。
DXL360 通电之后就发送数据,数据间隔大约为 0.5s。串口设置为 9600,N,8,1

下面是头文件。具体的用法请读注释。

#ifndef DXL360COMM_H
#define DXL360COMM_H

/// @file dxl360comm.h
/// @details DXL360 是一款双轴倾角仪,也可以叫做数显角度尺。DXL360Comm 是用来接收 DXL360 发送的数据的软件模块。
/// DXL360 本身无法与电脑直接相连,需要额外配置通讯模块,常见的通讯模块为蓝牙模块和 232 串口模块。
/// 蓝牙模块实际上也是模拟了电脑上的一个 232 串口,对于软件来说还是只需要读取串口的数据。
/// DXL360 通过串口传来的数据格式为 X+0000Y+0000, 其中 “+” 可以为“+” 或 “-”。表示的是角度的正负号。
/// “0000” 是具体的数据,实际的角度值为这个数除以 100,单位为度。
/// DXL360 通电之后就发送数据,数据间隔大约为 0.5s。串口设置为 9600,N,8,1

#include <QSerialPort>
#include <QPair>
#include <QDateTime>
/**
 * @brief The DXL360Comm class
 */
class DXL360Comm: public QObject
{
    Q_OBJECT
public:
    DXL360Comm();
    ~DXL360Comm();
    /**
     * @brief value 获取倾角仪的数据
     * @param x X 轴的角度
     * @param y Y 轴的角度
     * @return  true 表示返回的值是在 1s 之内获得的数值。
     *          false 表示获得数值是更早时刻的,正常情况下 DXL360每隔 0.5s 返回一组数据。1s 之内都没有数据表明通讯出了问题。
     */
    bool value(double &x, double &y);
public slots:
    /**
     * @brief setPortName 指定读取那个串口,格式类似:"COM1"、"COM2"
     * @param name,串口号,取值可为:"COM1"、"COM2"、"COM3"、"COM4"...
     */
    void setPortName(QString name);
    /**
     * @brief start 打开串口,开始收取数据
     */
    bool start();
    /**
     * @brief stop 关闭串口,不再接收数据
     */
    void stop();
signals:
    /**
     * @brief dataReady 每次收到一组数据时就会发出这个信号
     * @param x
     * @param y
     */
    void dataReady(double x, double y);
private slots:
    void on_readyRead();
private:
    void stateMachine(char x);
    QSerialPort m_port;
    int m_state;
    int m_count;
    char m_bufferX[6];
    char m_bufferY[6];
    QDateTime m_time;
    double m_x;
    double m_y;
};

#endif // DXL360COMM_H

下面是 cpp 文件:

#include "dxl360comm.h"

DXL360Comm::DXL360Comm()
    :m_state(0),
      m_x(NAN),
      m_y(NAN)
{
    m_bufferX[5] = 0;
    m_bufferY[5] = 0;
    connect(&m_port, SIGNAL(readyRead()), this, SLOT(on_readyRead()));
}

void DXL360Comm::stop()
{
    m_port.close();
}

void DXL360Comm::setPortName(QString name)
{
    m_port.setPortName(name);
}

bool DXL360Comm::value(double &x, double &y)
{
    x = m_x;
    y = m_y;
    QDateTime t = QDateTime::currentDateTime();
    return (t.msecsTo(m_time) > -1000);
}


DXL360Comm::~DXL360Comm()
{
    m_port.close();
    disconnect(&m_port, SIGNAL(readyRead()), this, SLOT(on_readyRead()));
}

bool DXL360Comm::start()
{
    m_port.setBaudRate(QSerialPort::Baud9600);
    return m_port.open(QIODevice::ReadOnly);

}

void DXL360Comm::stateMachine(char x)
{
    switch (m_state)
    {
    case 0:
        if(x == 'X')
        {
            m_state = 'X';
            m_count = 0;
        }
        break;
    case 'X':
        if(x == 'Y')
        {
            m_state = 'Y';
            m_count = 0;
        }
        else if(m_count >= 5) //
        {
            m_state = 0; //到这里说明有问题了。
            m_count = 0;
        }
        else
        {
            m_bufferX[m_count] = x;
            m_count++;
        }
        break;
    case 'Y':
        m_bufferY[m_count] = x;
        m_count++;
        if(m_count == 5)
        {
            m_state = 0;
            m_x = atoi(m_bufferX) / 100.0;
            m_y = atoi(m_bufferY) / 100.0;
            m_time = QDateTime::currentDateTime();
            emit dataReady(m_x, m_y);
        }
        break;
    default:
        m_state = 0;
        break;
    }
}

void DXL360Comm::on_readyRead()
{
    QByteArray data = m_port.readAll();
    QByteArray::const_iterator it;
    for (it = data.constBegin(); it != data.constEnd(); ++it)
    {
          stateMachine(*it);
    }
}

猜你喜欢

转载自blog.csdn.net/liyuanbhu/article/details/78379378
今日推荐