Qt平台低功耗蓝牙程序(使用Qt自带库)

本文介绍如何使用Qt自带库进行低功耗蓝牙编程,包括设备连接、服务发现、特征读写等操作。通过示例代码展示了从.pro文件到各个源文件的实现过程,同时涵盖了UI界面设计与交互。
摘要由CSDN通过智能技术生成

.pro

#-------------------------------------------------
#
# Project created by QtCreator 2020-07-22T11:13:26
#
#-------------------------------------------------

QT       += core gui serialport printsupport bluetooth

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = untitled
TEMPLATE = app

#CONFIG += console

# The following define makes your compiler emit warnings if you use
# any feature of Qt which has been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

CONFIG += c++11

SOURCES += \
        characteristic.cpp \
        device.cpp \
        graph.cpp \
        main.cpp \
        mainwindow.cpp \
        protocol.cpp \
        qcustomplot.cpp \
        serial.cpp \
        service.cpp

HEADERS += \
        characteristic.h \
        device.h \
        graph.h \
        mainwindow.h \
        protocol.h \
        qcustomplot.h \
        serial.h \
        service.h

FORMS += \
        mainwindow.ui

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
characteristic.h
#ifndef CHARACTERISTIC_H
#define CHARACTERISTIC_H

#include <QObject>
#include<QLowEnergyController>

class Characteristic : public QObject
{
    Q_OBJECT
public:
    explicit Characteristic(QLowEnergyService *service,QObject *parent = nullptr);

signals:

public slots:

private:
    QLowEnergyCharacteristic *m_chars;
    QLowEnergyService *m_service;
};

#endif // CHARACTERISTIC_H

device.h

/****************************************************************************
**
** Copyright (C) 2017 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtBluetooth module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** BSD License Usage
** Alternatively, you may use this file under the terms of the BSD license
** as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
**   * Redistributions of source code must retain the above copyright
**     notice, this list of conditions and the following disclaimer.
**   * Redistributions in binary form must reproduce the above copyright
**     notice, this list of conditions and the following disclaimer in
**     the documentation and/or other materials provided with the
**     distribution.
**   * Neither the name of The Qt Company Ltd nor the names of its
**     contributors may be used to endorse or promote products derived
**     from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/

#ifndef DEVICE_H
#define DEVICE_H

#include <qbluetoothlocaldevice.h>

#include <QObject>
#include <QVector>
#include "service.h"
#include <QTimer>

QT_FORWARD_DECLARE_CLASS(QBluetoothDeviceDiscoveryAgent)
QT_FORWARD_DECLARE_CLASS(QBluetoothDeviceInfo)

QT_USE_NAMESPACE

extern QVector<QBluetoothDeviceInfo> BDinfoList;

class Device : public QObject
{
    Q_OBJECT

public:
    Device(QObject *parent = 0);
    ~Device();

    void startScan();
    void ConnectDevice(QBluetoothDeviceInfo bdinfo);
    void DisconnectDevice();
    bool IsConnected();
    void writeChar(const QByteArray data);
    void readChar();

signals:
    void sig_add_device();
    void characteristicChanged(QLowEnergyCharacteristic c,QByteArray value);
    void characteristicRead(QLowEnergyCharacteristic c,QByteArray value);
    void signal_connected();
    void sig_scan_finish();
    void sig_disconnect();

public slots:
    void addDevice(const QBluetoothDeviceInfo&);
private slots:
    void scanFinished();
private:
    QBluetoothDeviceDiscoveryAgent *discoveryAgent;
    QBluetoothLocalDevice *localDevice;
    QLowEnergyController *m_control;

    Service *service;

    bool is_connected=0;
    QTimer timer;
};

#endif

graph.h

#ifndef GRAPH_H
#define GRAPH_H

#include <QMainWindow>
#include "qcustomplot.h"



#endif // GRAPH_H

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include "serial.h"
#include "graph.h"
#include "device.h"
#include "protocol.h"

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
    QVector<double> x,y0,y1,y2,y3,y4,y5,y6;
    void graph_save(QString filename,int8_t graph_index,uint32_t x1,uint32_t x2);

signals:
    void sig_StartMonitor(char mode);
    void sig_StopMonitor();

public slots:
    void displayPairingMenu(const QPoint &pos);
    void displayCustomPlotMenu(const QPoint &pos);
    void displayCustomPlotMenu_2(const QPoint &pos);
    void slot_graph(float g1,float g2,float g3,float g4,float g5,float g6,float g7);
    void slot_msgbox(QString title,QString text);

    void setxAxisRange(QCPRange);
    void setxAxisRange_2(QCPRange);
    void setxAxisRange_3(QCPRange);
    void setxAxisRange_4(QCPRange);
    void _setxAxisRange(QCustomPlot *pwidget,QCustomPlot *pwidget_2);

    void setyAxisRange(QCPRange);
    void setyAxisRange_2(QCPRange);
    void setyAxisRange_3(QCPRange);
    void setyAxisRange_4(QCPRange);
    void _setyAxisRange(QCustomPlot *pwidget);

private slots:
    void on_pushButton_clicked();

    void on_pushButton_2_clicked();

    void readyRead_slot(QByteArray data);

    void on_actionScan_triggered();

    void on_actionStartMonitor_triggered();

    void on_actionStopMonitor_triggered();

    void on_actionDisConnect_triggered();

    void on_actionserial_triggered(bool checked);

    void on_actionble_triggered(bool checked);

    void on_dockWidget_2_visibilityChanged(bool visible);

    void on_dockWidget_visibilityChanged(bool visible);

    void on_listWidget_doubleClicked(const QModelIndex &index);

    void on_actionmode_triggered(bool checked);

    void on_dockWidget_3_visibilityChanged(bool visible);

    void slot_mode_radio_clicked(QAbstractButton *button);

private:
    void graph_init();
    void customplot1_add_graph(void);
    void customplot2_add_graph(void);
    void customplot3_add_graph(void);
    void customplot4_add_graph(void);

    Ui::MainWindow *ui;
    serial *myserial;
    Device *device;

    Protocol *protocol;
    QThread *m_thread;

    QLabel *BleStatus;
    QLabel *Msglable;

    QMessageBox msgbox;

    QButtonGroup *mode_RadioGroup;
};

#endif // MAINWINDOW_H

protocol.h

#ifndef PROTOCOL_H
#define PROTOCOL_H

#include <QObject>
#include "device.h"
#include <QString>
#include <QTimer>
#include <QMessageBox>
#include <QThread>

#define MAX_PACKET_SIZE         20
#define WITHOUT_DATA_SIZE     sizeof(SYNC)+sizeof(STX)+sizeof(LEN)+1+sizeof(CRC1)+sizeof(CRC2)+sizeof(ETX)

namespace ms_MSG_ID
{
    enum MessageID_t
    {
        /*Command Codes */
        StartMonitor=0x01,
        StopMonitor=0x02,
        AutoAdjustLasers=0x03,
        GetDeviceStatus=0x04,
        SetAutoAdjustOption=0x07,
        GetAutoAdjustOption=0x08,
        SetLaserOutputPower=0x09,
        GetLaserOutputPower=0x0a,
        SetOperatingThresh=0x0b,
        GetOperatingThresh=0x0c,
        GetAutoAdjustLaserOutput=0x0d,
        GetFirmwareRevision=0x0e,
        SetAdcChannel=0x0f,
        SetPulseWidth=0x10,
        Reserved=0x11,
        EnableAllLasers=0x12,
        SetLaserInterval=0x13,
        SetContinuousPulse=0x14,
        GetBackgroundNoise=0x15,
        GetFirmwareVersion=0x16,
        PauseMonitor=0x17,
        ContinueMonitor=0x18,
        SignalPathCheck=0x19,
        EraseFlash=0x1a,
        ProgramFlash=0x1b,
        /*Data Messages*/
        DataMsg=0x20,
        /*Notification Messages*/
        RCV_CABLE_DISCONNECTED=0xf8,
        WATCHDOG_GOES_OFF=0xfa,
        FAIL_LASER_SAFETY_CHECK=0xfc,
        RESUME_LASER_OPERATION=0xfd,
        PC_COMMUNICATION_FAILURE=0xfe,
    };
}

namespace ms_RSP_REE
{
    enum ResponseErrorCodes
    {
        STATUS_OK=0x00,//系统校验通过。
        RESPONSE_ACK=0x05,//命令成功,状态OK。
        INVALID_COMMAND=0xf1,//无效的命令代码
        FAIL_CRC=0xf2,//从PC发送的消息的CRC字节不匹配在固件中计算的CRC。
        INVALID_ETX=0xf3,//固件期望但没有收到ETX字节(消息的最后一个字节)基于消息的长度。消息可能不同步。
        INVALID_ARG=0xf4,//命令的参数无效,很可能超出了允许的范围。
        INVALID_NUM_ARG=0xf5,//为命令提供的参数数目不正确。
        SEQ_NUM_OUT_OF_SYNC=0xf6,//返回时,序列号在随后的消息(每一个数据程序到设备闪存)发送升级固件变得不同步。
        AUTO_ADJUST_FAIL=0xf7,//返回,如果设备未能自动调整激光器开始监测。
        RCV_CABLE_DISCONNECTED=0xf8,//如果接收电缆断开,作为“开始监视”的响应返回。也发送作为一个固件错误消息通知PC,接收器电缆连接不能被检测。
        RCV_SIGNAL_NOT_DETECTED=0xf9,//作为系统检查的结果返回。
        INITIAL_ADC_TOO_HIGH=0xfb,//如果背景噪音不低于预设阈值,则返回作为“开始监控”的响应。补丁可能不能正确地屏蔽环境光。
        FAIL_LASER_SAFETY_CHECK=0xfc,//返回作为一个响应“开始监控”或发送作为固件错误消息,以通知PC的设备没有通过激光安全检查。
    };
}

enum DeviceStatus
{
    STANDBY=0,
    SETUP=1,
    RUNNING=2,
    PAUSED=3,
    SUSPENDED=4,
    AUTO_RECOVERING=5
};

enum RcvFlag_t
{
    RCV_HEAD,
    RCV_MID,
    RCV_END,
};

class Protocol : public QObject
{
    Q_OBJECT
public:
    explicit Protocol(Device *device,QThread *m_thread,QObject *parent = nullptr);
    ~Protocol();

    bool ReceiveMsgExtract(QByteArray &value);
    bool ReceiveMsgCk(QByteArray &value);
    uint8_t Get_Mode();
signals:
    void sig_msgbox(QString title,QString text);
    void sig_graph(float g1,float g2,float g3,float g4,float g5,float g6,float g7);

public slots:
    void StartMonitor(char mode);
    void StopMonitor();
    void GetDeviceStatus();

private slots:
    void BleSend();
    void timeout();
    void RcvFirmwareMsg(QLowEnergyCharacteristic c,QByteArray value);

private:
    void RcvFirmwareMsgCb();
    void DataMsg_Handle();

    bool Status=0;

    QTimer timer;

    Device *m_device;

    QByteArray packet;
    const uint8_t SYNC=0x54;
    const uint8_t STX=0x02;
    uint8_t LEN=0;
    ms_MSG_ID::MessageID_t MSG_ID;
    QByteArray Data;
    uint8_t CRC1=0;
    uint8_t CRC2=0;
    const uint8_t ETX=0x03;

    QByteArray RcvDataBuf;
    RcvFlag_t RcvFlag=RCV_END;

    uint32_t Serial=0;
    float HbO2ShortDistance;
    float HbO2LongDistance;
    float StO2ShortDistance;
    float StO2LongDistance;

    char Mode=0x00;

    bool msgboxV;
};

#endif // PROTOCOL_H

qcustomplot.h

serial.h

#ifndef SERIAL_H
#define SERIAL_H

#include <QObject>
#include <QSerialPort>
#include <QSerialPortInfo>
#include "qserialport.h"
#include "QString"


class serial:public QObject
{
    Q_OBJECT

public:
    serial(QObject *o=0);
    ~serial();
    bool openPort(QString portName,qint32 baudRate,QSerialPort::DataBits dataBits,
                  QSerialPort::Parity parity,QSerialPort::StopBits stopBits,
                  QSerialPort::FlowControl flowControl);
    bool isOpen();
    void closePort();
    QStringList getAvailablePortNameList();

    void write(QString str);
    void write(const char *data, qint64 len);
    QString ByteArrayToHexString(QByteArray data);

signals:
    void readyRead(QByteArray data);

private:
    QSerialPort *m_port;

    void readyRead_slot();



};

#endif // SERIAL_H

service.h

/****************************************************************************
**
** Copyright (C) 2017 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtBluetooth module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** BSD License Usage
** Alternatively, you may use this file under the terms of the BSD license
** as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
**   * Redistributions of source code must retain the above copyright
**     notice, this list of conditions and the following disclaimer.
**   * Redistributions in binary form must reproduce the above copyright
**     notice, this list of conditions and the following disclaimer in
**     the documentation and/or other materials provided with the
**     distribution.
**   * Neither the name of The Qt Company Ltd nor the names of its
**     contributors may be used to endorse or promote products derived
**     from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/

#ifndef SERVICE_H
#define SERVICE_H

#include <QObject>
#include "characteristic.h"

#include <qbluetoothaddress.h>
#include<QLowEnergyController>


QT_FORWARD_DECLARE_CLASS(QBluetoothAddress)
QT_FORWARD_DECLARE_CLASS(QBluetoothServiceInfo)
QT_FORWARD_DECLARE_CLASS(QBluetoothServiceDiscoveryAgent)

QT_USE_NAMESPACE

//#define SERVICETYPE       //另一种查询服务方法

class Service : public QObject
{
    Q_OBJECT

public:
    Service(QLowEnergyController *control, QObject *parent=0);
    ~Service();
    void openService(const QBluetoothUuid &newServiceUuid);
    void writeChar(const QByteArray data);
    void readChar();
    bool isValid();

signals:
    void characteristicChanged(QLowEnergyCharacteristic c,QByteArray value);
    void characteristicRead(QLowEnergyCharacteristic c,QByteArray value);

public slots:
    void addService(const QBluetoothUuid &);
    void serviceScanDone();
#ifdef SERVICETYPE
    void serviceDiscovered(const QBluetoothServiceInfo &service);
#endif

private:
    QBluetoothServiceDiscoveryAgent *discoveryAgent;
    QLowEnergyController *m_control;

    QLowEnergyService *m_service;
    QBluetoothUuid ServiceUuidList[4];
    uint8_t ServiceNumb=0;

    Characteristic *chars;
    QLowEnergyCharacteristic m_chars;

    bool isV=0;
};

#endif

characteristic.cpp

#include "characteristic.h"

Characteristic::Characteristic(QLowEnergyService *service,QObject *parent) : QObject(parent),m_service(service),m_chars(new QLowEnergyCharacteristic)
{
    *m_chars = m_service->characteristic(QBluetoothUuid(quint16(0xfff6)));
    if(!m_chars->isValid())
    {
        qDebug() << "characteristic fff6 error:::";
    }
    // 设置特征对象可用
    //enable the chracteristic notification by write 0x01 to client characteristic configuration
    QLowEnergyDescriptor m_notificationDesc = m_chars->descriptor(QBluetoothUuid::ClientCharacteristicConfiguration);
    if (m_notificationDesc.isValid())
    {
       if(m_chars->properties() & QLowEnergyCharacteristic::Notify)
       {
           qDebug() << "ok";
       }
       //m_service->writeDescriptor(m_notificationDesc, QByteArray::fromHex("0100"));
    }
}

device.cpp

/****************************************************************************
**
** Copyright (C) 2017 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtBluetooth module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** BSD License Usage
** Alternatively, you may use this file under the terms of the BSD license
** as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
**   * Redistributions of source code must retain the above copyright
**     notice, this list of conditions and the following disclaimer.
**   * Redistributions in binary form must reproduce the above copyright
**     notice, this list of conditions and the following disclaimer in
**     the documentation and/or other materials provided with the
**     distribution.
**   * Neither the name of The Qt Company Ltd nor the names of its
**     contributors may be used to endorse or promote products derived
**     from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "device.h"
#include "service.h"

#include <qbluetoothaddress.h>
#include <qbluetoothdevicediscoveryagent.h>
#include <QLowEnergyController>
#include <QMenu>
#include <QDebug>
#include <QProcess>
#include <Windows.h>
#include <QTimer>

QVector<QBluetoothDeviceInfo> BDinfoList;

Device::Device(QObject *parent)
:   QObject(parent)
{

    /*
     * In case of multiple Bluetooth adapters it is possible to set adapter
     * which will be used. Example code:
     *`
     * QBluetoothAddress address("XX:XX:XX:XX:XX:XX");
     * discoveryAgent = new QBluetoothDeviceDiscoveryAgent(address);
     *
     **/

    discoveryAgent = new QBluetoothDeviceDiscoveryAgent();
    localDevice = new QBluetoothLocalDevice();
    localDevice->setHostMode(QBluetoothLocalDevice::HostConnectable);
    connect(localDevice,&QBluetoothLocalDevice::deviceConnected,this,
            [this]
    {
        qDebug()<<"deviceConnected";
    },Qt::UniqueConnection);
    connect(localDevice,&QBluetoothLocalDevice::hostModeStateChanged,this,
            [this]
    {
        qDebug()<<"hostModeStateChanged";
    },Qt::UniqueConnection);

    if(localDevice->hostMode() == QBluetoothLocalDevice::HostPoweredOff)
    {
        qDebug()<<"blue closed";
    }
    else
    {
        qDebug()<<"blue opened";
    }
    QString name_info("本机蓝牙:");
    name_info+=localDevice->name();
    qDebug()<<"name_info"<<name_info;

    connect(discoveryAgent, SIGNAL(deviceDiscovered(QBluetoothDeviceInfo)),
            this, SLOT(addDevice(QBluetoothDeviceInfo)),Qt::UniqueConnection);
    connect(discoveryAgent, SIGNAL(finished()), this, SLOT(scanFinished()),Qt::UniqueConnection);


    discoveryAgent->setInquiryType(QBluetoothDeviceDiscoveryAgent::LimitedInquiry);//有限扫描
    discoveryAgent->setLowEnergyDiscoveryTimeout(1000);

    connect(&timer, &QTimer::timeout, this,
            [this]
    {
        if(service->isValid())
        {
            timer.stop();
            emit signal_connected();
        }
        else
        {
            timer.start(200);
        }
    });
}

Device::~Device()
{
    delete discoveryAgent;
    delete localDevice;
}

void Device::addDevice(const QBluetoothDeviceInfo &info)
{
    BDinfoList.push_back(info);
    memcpy(BDinfoList.end(),&info,sizeof(info));
    qDebug()<<localDevice->allDevices().size();
    qDebug()<<localDevice->connectedDevices().size();
    emit sig_add_device();
}

void Device::startScan()
{
    qDebug()<<"startScan";
    discoveryAgent->start(QBluetoothDeviceDiscoveryAgent::LowEnergyMethod);
    //QProcess::startDetached("E:\\work\\QT\\ble_no_qt\\build-untitled-Desktop_Qt_5_12_3_MSVC2015_64bit-Debug\\debug\\untitled.exe",QStringList());
}

void Device::scanFinished()
{
    qDebug()<<"scanFinished";
    emit sig_scan_finish();
}

void Device::ConnectDevice(QBluetoothDeviceInfo bdinfo)
{
    qDebug()<<"start link";
    m_control=new QLowEnergyController(bdinfo,this);
    m_control = QLowEnergyController::createCentral(bdinfo, this);//创建中央控制器
    connect(m_control, static_cast<void (QLowEnergyController::*)(QLowEnergyController::Error)>(&QLowEnergyController::error),this,
            [this]
    {
        qDebug()<<"errconnect";
    },Qt::UniqueConnection);
    connect(m_control, &QLowEnergyController::connected,this,
            [this]
    {
        qDebug()<<"state"<<m_control->state();
        is_connected=1;

        service=new Service(m_control);
        connect(service, &Service::characteristicChanged, this,
                [this](QLowEnergyCharacteristic c,QByteArray value)
                {
                    emit characteristicChanged(c,value);
                },Qt::UniqueConnection
        );
        connect(service, &Service::characteristicRead, this,
                [this](QLowEnergyCharacteristic c,QByteArray value)
                {
                    emit characteristicRead(c,value);
                },Qt::UniqueConnection
        );

        timer.start(200);
    },Qt::UniqueConnection);
    connect(m_control, &QLowEnergyController::destroyed,this,
            [this]
    {
        qDebug()<<"destroyed";
    },Qt::UniqueConnection);
    connect(m_control, &QLowEnergyController::stateChanged,this,
            [this]
    {
        //qDebug()<<"stateChanged";
    },Qt::UniqueConnection);
    m_control->connectToDevice();//建立连接
}

void Device::DisconnectDevice()
{
    connect(m_control, &QLowEnergyController::disconnected, this,
            [this]
    {
        qDebug()<<"state"<<m_control->state();
        is_connected=0;
        delete service;
        m_control->deleteLater();
        qDebug()<<"disconnect";
        emit sig_disconnect();
    },Qt::UniqueConnection);
    m_control->disconnectFromDevice();
}

bool Device::IsConnected()
{
    return is_connected;
}

void Device::writeChar(const QByteArray data)
{
    service->writeChar(data);
}

void Device::readChar()
{
    service->readChar();
}

graph.cpp

#include "graph.h"
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QVector>
#include <QFile>
#include "protocol.h"
#include <stdio.h>

/*-------------------------------------------*/
//画动态曲线时,传入数据采用addData,通过定时器多次调用,并在之后调用ui->widget->replot();
//动态曲线可以通过另一种设置坐标的方法解决坐标问题:
//setRange ( double  position, double  size, Qt::AlignmentFlag  alignment  )
//参数分别为:原点,偏移量,对其方式,有兴趣的读者可自行尝试,欢迎垂询
/*-------------------------------------------*/

void MainWindow::graph_init()
{
    x.resize(1);
    y0.resize(1);
    y1.resize(1);
    y2.resize(1);
    y3.resize(1);
//    y4.resize(1);
//    y5.resize(1);
//    y6.resize(1);

    ui->widget->setContextMenuPolicy(Qt::CustomContextMenu);
    connect(ui->widget, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(displayCustomPlotMenu(QPoint)),Qt::UniqueConnection);
    connect(ui->widget->xAxis,SIGNAL(rangeChanged(QCPRange)),this,SLOT(setxAxisRange(QCPRange)));
    connect(ui->widget->yAxis,SIGNAL(rangeChanged(QCPRange)),this,SLOT(setyAxisRange(QCPRange)));

    ui->widget_2->setContextMenuPolicy(Qt::CustomContextMenu);
    connect(ui->widget_2, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(displayCustomPlotMenu_2(QPoint)),Qt::UniqueConnection);
    connect(ui->widget_2->xAxis,SIGNAL(rangeChanged(QCPRange)),this,SLOT(setxAxisRange_2(QCPRange)));
    connect(ui->widget_2->yAxis,SIGNAL(rangeChanged(QCPRange)),this,SLOT(setyAxisRange_2(QCPRange)));

    ui->widget_3->setContextMenuPolicy(Qt::CustomContextMenu);
    connect(ui->widget_3, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(displayCustomPlotMenu(QPoint)),Qt::UniqueConnection);
    connect(ui->widget_3->xAxis,SIGNAL(rangeChanged(QCPRange)),this,SLOT(setxAxisRange_3(QCPRange)));
    connect(ui->widget_3->yAxis,SIGNAL(rangeChanged(QCPRange)),this,SLOT(setyAxisRange_3(QCPRange)));

    ui->widget_4->setContextMenuPolicy(Qt::CustomContextMenu);
    connect(ui->widget_4, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(displayCustomPlotMenu_2(QPoint)),Qt::UniqueConnection);
    connect(ui->widget_4->xAxis,SIGNAL(rangeChanged(QCPRange)),this,SLOT(setxAxisRange_4(QCPRange)));
    connect(ui->widget_4->yAxis,SIGNAL(rangeChanged(QCPRange)),this,SLOT(setyAxisRange_4(QCPRange)));

        //设定背景为黑色
        //ui->widget->setBackground(QBrush(Qt::black));
        //设置X轴文字标注
        ui->widget->xAxis->setLabel("time");
        ui->widget_2->xAxis->setLabel("time");
        ui->widget_3->xAxis->setLabel("time");
        ui->widget_4->xAxis->setLabel("time");
        //设置Y轴文字标注
        ui->widget->yAxis->setLabel("short HbO2");
        ui->widget_2->yAxis->setLabel("long HbO2");
        ui->widget_3->yAxis->setLabel("short Hb");
        ui->widget_4->yAxis->setLabel("long Hb");
        //设置X轴坐标范围
        ui->widget->xAxis->setRange(0,800);
        ui->widget_2->xAxis->setRange(0,800);
        ui->widget_3->xAxis->setRange(0,800);
      
  • 1
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 12
    评论
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值