I've referred the following example on BLE heart listener application : http://doc.qt.io/qt-5/qtbluetooth-he...r-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?
Qt Code:
  1. #include "heartrate.h"
  2. #include <QtEndian>
  3. #include <stdio.h>
  4. Heartrate::Heartrate():
  5. m_currentDevice(QBluetoothDeviceInfo()),foundHeartRateService(false),m_control(0), m_service(0)
  6. {
  7. //! [devicediscovery-1]
  8. m_deviceDiscoveryAgent = new QBluetoothDeviceDiscoveryAgent(this);
  9. connect(m_deviceDiscoveryAgent, SIGNAL(deviceDiscovered(const QBluetoothDeviceInfo&)),
  10. this, SLOT(addDevice(const QBluetoothDeviceInfo&)));
  11. connect(m_deviceDiscoveryAgent, SIGNAL(error(QBluetoothDeviceDiscoveryAgent::Error)),
  12. this, SLOT(deviceScanError(QBluetoothDeviceDiscoveryAgent::Error)));
  13. connect(m_deviceDiscoveryAgent, SIGNAL(finished()), this, SLOT(scanFinished()));
  14. //! [devicediscovery-1]
  15. }
  16. Heartrate::~Heartrate()
  17. {
  18. qDeleteAll(m_devices);
  19. m_devices.clear();
  20. }
  21. void Heartrate::deviceSearch()
  22. {
  23. qDeleteAll(m_devices);
  24. m_devices.clear();
  25. //! [devicediscovery-2]
  26. m_deviceDiscoveryAgent->start();
  27. //! [devicediscovery-2]
  28. setMessage("Scanning for devices...");
  29.  
  30. }
  31. void Heartrate::setMessage(QString message)
  32. {
  33. m_info = message;
  34. Q_EMIT messageChanged();
  35. }
  36. void Heartrate::addDevice(const QBluetoothDeviceInfo &device)
  37. {
  38. if (device.coreConfigurations() & QBluetoothDeviceInfo::LowEnergyCoreConfiguration) {
  39. qWarning() << "Discovered LE Device name: " << device.name() << " Address: "
  40. << device.address().toString();
  41. //! [devicediscovery-3]
  42. DeviceInfo *dev = new DeviceInfo(device);
  43. m_devices.append(dev);
  44. setMessage("Low Energy device found. Scanning for more...");
  45.  
  46. //! [devicediscovery-4]
  47. }
  48. //...
  49. }
  50. //! [devicediscovery-4]
  51. void Heartrate::deviceScanError(QBluetoothDeviceDiscoveryAgent::Error error)
  52. {
  53. if (error == QBluetoothDeviceDiscoveryAgent::PoweredOffError)
  54. setMessage("The Bluetooth adaptor is powered off, power it on before doing discovery.");
  55.  
  56. else if (error == QBluetoothDeviceDiscoveryAgent::InputOutputError)
  57. setMessage("Writing or reading from the device resulted in an error.");
  58.  
  59. else
  60. setMessage("An unknown error has occurred.");
  61.  
  62. }
  63. void Heartrate::scanFinished()
  64. {
  65. if (m_devices.size() == 0)
  66. setMessage("No Low Energy devices found");
  67.  
  68. Q_EMIT nameChanged();
  69. }
  70. void Heartrate::connectToService(const QString &address)
  71. {
  72. m_measurements.clear();
  73. bool deviceFound = false;
  74. for (int i = 0; i < m_devices.size(); i++) {
  75. if (((DeviceInfo*)m_devices.at(i))->getAddress() == address ) {
  76. m_currentDevice.setDevice(((DeviceInfo*)m_devices.at(i))->getDevice());
  77. setMessage("Connecting to device...");
  78. deviceFound = true;
  79. break;
  80. }
  81. }
  82.  
  83. if (m_control) {
  84. m_control->disconnectFromDevice();
  85. delete m_control;
  86. m_control = 0;
  87. }
  88. //! [Connect signals]
  89. m_control = new QLowEnergyController(m_currentDevice.getDevice(), this);
  90. connect(m_control, SIGNAL(serviceDiscovered(QBluetoothUuid)),
  91. this, SLOT(serviceDiscovered(QBluetoothUuid)));
  92. connect(m_control, SIGNAL(discoveryFinished()),
  93. this, SLOT(serviceScanDone()));
  94. connect(m_control, SIGNAL(error(QLowEnergyController::Error)),
  95. this, SLOT(controllerError(QLowEnergyController::Error)));
  96. connect(m_control, SIGNAL(connected()),
  97. this, SLOT(deviceConnected()));
  98. connect(m_control, SIGNAL(disconnected()),
  99. this, SLOT(deviceDisconnected()));
  100. m_control->connectToDevice();
  101. //! [Connect signals]
  102. }
  103. void Heartrate::serviceDiscovered(const QBluetoothUuid &gatt)
  104. {
  105. if (gatt == (QBluetoothUuid(QBluetoothUuid::HeartRate))) {
  106. setMessage("Heart Rate service discovered. Waiting for service scan to be done...");
  107.  
  108. explicit QBluetoothUuid(quint16)=gatt;
  109. foundHeartRateService = true;
  110. }
  111. }
  112. void Heartrate::serviceScanDone()
  113. {
  114. delete m_service;
  115. m_service = 0;
  116. //! [Filter HeartRate service 2]
  117. if (foundHeartRateService) {
  118. setMessage("Connecting to service...");
  119. // qDebug()<<"Connecting to service...";
  120. // printf("Connecting to service...");
  121. m_service = m_control->createServiceObject(
  122. QBluetoothUuid(QBluetoothUuid::HeartRate), this);
  123. }
  124. if (!m_service) {
  125. setMessage("Heart Rate Service not found.");
  126.  
  127. return;
  128. }
  129. connect(m_service, SIGNAL(stateChanged(QLowEnergyService::ServiceState)),
  130. this, SLOT(serviceStateChanged(QLowEnergyService::ServiceState)));
  131. connect(m_service, SIGNAL(characteristicChanged(QLowEnergyCharacteristic,QByteArray)),
  132. this, SLOT(updateHeartRateValue(QLowEnergyCharacteristic,QByteArray)));
  133. connect(m_service, SIGNAL(descriptorWritten(QLowEnergyDescriptor,QByteArray)),
  134. this, SLOT(confirmedDescriptorWrite(QLowEnergyDescriptor,QByteArray)));
  135. m_service->discoverDetails();
  136. //! [Filter HeartRate service 2]
  137. }
  138. void Heartrate::serviceStateChanged(QLowEnergyService::ServiceState s)
  139. {
  140. switch (s) {
  141. case QLowEnergyService::ServiceDiscovered:
  142. {
  143. const QLowEnergyCharacteristic hrChar = m_service->characteristic(
  144. QBluetoothUuid(QBluetoothUuid::HeartRateMeasurement));
  145. if (!hrChar.isValid()) {
  146. setMessage("HR Data not found.");
  147.  
  148. break;
  149. }
  150. const QLowEnergyDescriptor m_notificationDesc = hrChar.descriptor(
  151. QBluetoothUuid::ClientCharacteristicConfiguration);
  152. if (m_notificationDesc.isValid()) {
  153. m_service->writeDescriptor(m_notificationDesc, QByteArray::fromHex("0100"));
  154. setMessage("Measuring");
  155.  
  156. m_start = QDateTime::currentDateTime();
  157. }
  158. break;
  159. }
  160. default:
  161. //nothing for now
  162. break;
  163. }
  164. }
  165. [B]void Heartrate::updateHeartRateValue(const QLowEnergyCharacteristic &c,
  166. const QByteArray &value)
  167. {
  168. // ignore any other characteristic change -> shouldn't really happen though
  169. if (c.uuid() != QBluetoothUuid(QBluetoothUuid::HeartRateMeasurement))
  170. return;
  171. const quint8 *data = reinterpret_cast<const quint8 *>(value.constData());
  172. quint8 flags = data[0];
  173. //value=data[0];
  174.  
  175. }[/B]
  176. void Heartrate::confirmedDescriptorWrite(const QLowEnergyDescriptor &d,
  177. const QByteArray &value)
  178. {
  179. if (d.isValid() && d == m_notificationDesc && value == QByteArray("0000")) {
  180. //disabled notifications -> assume disconnect intent
  181. m_control->disconnectFromDevice();
  182. delete m_service;
  183. m_service = 0;
  184. }
  185. }
  186. //! [Error handling]
  187. void Heartrate::controllerError(QLowEnergyController::Error error)
  188. {
  189. setMessage("Cannot connect to remote device.");
  190.  
  191. qWarning() << "Controller Error:" << error;
  192. }
  193. //! [Error handling]
  194. void Heartrate::deviceConnected()
  195. {
  196. m_control->discoverServices();
  197. }
  198. void Heartrate::deviceDisconnected()
  199. {
  200. setMessage("Heart Rate service disconnected");
  201. qWarning() << "Remote device disconnected";
  202. }
  203. void Heartrate::disconnectService()
  204. {
  205. foundHeartRateService = false;
  206. m_stop = QDateTime::currentDateTime();
  207. if (m_devices.isEmpty()) {
  208. return;
  209. }
  210. //disable notifications
  211. if (m_notificationDesc.isValid() && m_service) {
  212. m_service->writeDescriptor(m_notificationDesc, QByteArray::fromHex("0000"));
  213. } else {
  214. m_control->disconnectFromDevice();
  215. delete m_service;
  216. m_service = 0;
  217. }
  218. }
  219. int Heartrate::numDevices() const
  220. {
  221. return m_devices.size();
  222. }
  223. QString Heartrate::deviceAddress() const
  224. {
  225. return m_currentDevice.getAddress();
  226. }
  227. QVariant Heartrate::name()
  228. {
  229. return QVariant::fromValue(m_devices);
  230. }
  231. QString Heartrate::message() const
  232. {
  233. return m_info;
  234. }
To copy to clipboard, switch view to plain text mode