PDA

View Full Version : Qt Quick: help required in plotting the data in real-time



user03
22nd August 2016, 16:26
I've referred the following example on BLE heart listener application : http://doc.qt.io/qt-5/qtbluetooth-heartlistener-example.html & require some help in plotting the data in real-time.
Below is my code (same as in heartrate.cpp file in the example but I've removed any extra functions like energy, calories calculation). My intention is to just connect to the specific BLE device and find the service and characteristic, set the notification for characteristic value change and plot a graph in real time of all the values that are being received w.r.t time.
The function that is responsible for providing the relevant values is highlighted (updateHeartRateValue). Can someone advise on how can i plot the values received in this function, should i create another class, use any specific library?

#include "heartrate.h"
#include <QtEndian>
#include <stdio.h>
Heartrate::Heartrate():
m_currentDevice(QBluetoothDeviceInfo()),foundHeart RateService(false),m_control(0), m_service(0)
{
//! [devicediscovery-1]
m_deviceDiscoveryAgent = new QBluetoothDeviceDiscoveryAgent(this);
connect(m_deviceDiscoveryAgent, SIGNAL(deviceDiscovered(const QBluetoothDeviceInfo&)),
this, SLOT(addDevice(const QBluetoothDeviceInfo&)));
connect(m_deviceDiscoveryAgent, SIGNAL(error(QBluetoothDeviceDiscoveryAgent::Error )),
this, SLOT(deviceScanError(QBluetoothDeviceDiscoveryAgen t::Error)));
connect(m_deviceDiscoveryAgent, SIGNAL(finished()), this, SLOT(scanFinished()));
//! [devicediscovery-1]
}
Heartrate::~Heartrate()
{
qDeleteAll(m_devices);
m_devices.clear();
}
void Heartrate::deviceSearch()
{
qDeleteAll(m_devices);
m_devices.clear();
//! [devicediscovery-2]
m_deviceDiscoveryAgent->start();
//! [devicediscovery-2]
setMessage("Scanning for devices...");

}
void Heartrate::setMessage(QString message)
{
m_info = message;
Q_EMIT messageChanged();
}
void Heartrate::addDevice(const QBluetoothDeviceInfo &device)
{
if (device.coreConfigurations() & QBluetoothDeviceInfo::LowEnergyCoreConfiguration) {
qWarning() << "Discovered LE Device name: " << device.name() << " Address: "
<< device.address().toString();
//! [devicediscovery-3]
DeviceInfo *dev = new DeviceInfo(device);
m_devices.append(dev);
setMessage("Low Energy device found. Scanning for more...");

//! [devicediscovery-4]
}
//...
}
//! [devicediscovery-4]
void Heartrate::deviceScanError(QBluetoothDeviceDiscove ryAgent::Error error)
{
if (error == QBluetoothDeviceDiscoveryAgent::PoweredOffError)
setMessage("The Bluetooth adaptor is powered off, power it on before doing discovery.");

else if (error == QBluetoothDeviceDiscoveryAgent::InputOutputError)
setMessage("Writing or reading from the device resulted in an error.");

else
setMessage("An unknown error has occurred.");

}
void Heartrate::scanFinished()
{
if (m_devices.size() == 0)
setMessage("No Low Energy devices found");

Q_EMIT nameChanged();
}
void Heartrate::connectToService(const QString &address)
{
m_measurements.clear();
bool deviceFound = false;
for (int i = 0; i < m_devices.size(); i++) {
if (((DeviceInfo*)m_devices.at(i))->getAddress() == address ) {
m_currentDevice.setDevice(((DeviceInfo*)m_devices. at(i))->getDevice());
setMessage("Connecting to device...");
deviceFound = true;
break;
}
}

if (m_control) {
m_control->disconnectFromDevice();
delete m_control;
m_control = 0;
}
//! [Connect signals]
m_control = new QLowEnergyController(m_currentDevice.getDevice(), this);
connect(m_control, SIGNAL(serviceDiscovered(QBluetoothUuid)),
this, SLOT(serviceDiscovered(QBluetoothUuid)));
connect(m_control, SIGNAL(discoveryFinished()),
this, SLOT(serviceScanDone()));
connect(m_control, SIGNAL(error(QLowEnergyController::Error)),
this, SLOT(controllerError(QLowEnergyController::Error)) );
connect(m_control, SIGNAL(connected()),
this, SLOT(deviceConnected()));
connect(m_control, SIGNAL(disconnected()),
this, SLOT(deviceDisconnected()));
m_control->connectToDevice();
//! [Connect signals]
}
void Heartrate::serviceDiscovered(const QBluetoothUuid &gatt)
{
if (gatt == (QBluetoothUuid(QBluetoothUuid::HeartRate))) {
setMessage("Heart Rate service discovered. Waiting for service scan to be done...");

explicit QBluetoothUuid(quint16)=gatt;
foundHeartRateService = true;
}
}
void Heartrate::serviceScanDone()
{
delete m_service;
m_service = 0;
//! [Filter HeartRate service 2]
if (foundHeartRateService) {
setMessage("Connecting to service...");
// qDebug()<<"Connecting to service...";
// printf("Connecting to service...");
m_service = m_control->createServiceObject(
QBluetoothUuid(QBluetoothUuid::HeartRate), this);
}
if (!m_service) {
setMessage("Heart Rate Service not found.");

return;
}
connect(m_service, SIGNAL(stateChanged(QLowEnergyService::ServiceStat e)),
this, SLOT(serviceStateChanged(QLowEnergyService::Servic eState)));
connect(m_service, SIGNAL(characteristicChanged(QLowEnergyCharacteris tic,QByteArray)),
this, SLOT(updateHeartRateValue(QLowEnergyCharacteristic ,QByteArray)));
connect(m_service, SIGNAL(descriptorWritten(QLowEnergyDescriptor,QByt eArray)),
this, SLOT(confirmedDescriptorWrite(QLowEnergyDescriptor ,QByteArray)));
m_service->discoverDetails();
//! [Filter HeartRate service 2]
}
void Heartrate::serviceStateChanged(QLowEnergyService:: ServiceState s)
{
switch (s) {
case QLowEnergyService::ServiceDiscovered:
{
const QLowEnergyCharacteristic hrChar = m_service->characteristic(
QBluetoothUuid(QBluetoothUuid::HeartRateMeasuremen t));
if (!hrChar.isValid()) {
setMessage("HR Data not found.");

break;
}
const QLowEnergyDescriptor m_notificationDesc = hrChar.descriptor(
QBluetoothUuid::ClientCharacteristicConfiguration) ;
if (m_notificationDesc.isValid()) {
m_service->writeDescriptor(m_notificationDesc, QByteArray::fromHex("0100"));
setMessage("Measuring");

m_start = QDateTime::currentDateTime();
}
break;
}
default:
//nothing for now
break;
}
}
void Heartrate::updateHeartRateValue(const QLowEnergyCharacteristic &c,
const QByteArray &value)
{
// ignore any other characteristic change -> shouldn't really happen though
if (c.uuid() != QBluetoothUuid(QBluetoothUuid::HeartRateMeasuremen t))
return;
const quint8 *data = reinterpret_cast<const quint8 *>(value.constData());
quint8 flags = data[0];
//value=data[0];

}
void Heartrate::confirmedDescriptorWrite(const QLowEnergyDescriptor &d,
const QByteArray &value)
{
if (d.isValid() && d == m_notificationDesc && value == QByteArray("0000")) {
//disabled notifications -> assume disconnect intent
m_control->disconnectFromDevice();
delete m_service;
m_service = 0;
}
}
//! [Error handling]
void Heartrate::controllerError(QLowEnergyController::E rror error)
{
setMessage("Cannot connect to remote device.");

qWarning() << "Controller Error:" << error;
}
//! [Error handling]
void Heartrate::deviceConnected()
{
m_control->discoverServices();
}
void Heartrate::deviceDisconnected()
{
setMessage("Heart Rate service disconnected");
qWarning() << "Remote device disconnected";
}
void Heartrate::disconnectService()
{
foundHeartRateService = false;
m_stop = QDateTime::currentDateTime();
if (m_devices.isEmpty()) {
return;
}
//disable notifications
if (m_notificationDesc.isValid() && m_service) {
m_service->writeDescriptor(m_notificationDesc, QByteArray::fromHex("0000"));
} else {
m_control->disconnectFromDevice();
delete m_service;
m_service = 0;
}
}
int Heartrate::numDevices() const
{
return m_devices.size();
}
QString Heartrate::deviceAddress() const
{
return m_currentDevice.getAddress();
}
QVariant Heartrate::name()
{
return QVariant::fromValue(m_devices);
}
QString Heartrate::message() const
{
return m_info;
}