Hello ........

I am writing some logging software running on raspberry pi using QT. I have successfully interfaced with all the sensors using a wired serial port and a standard bluetooth to serial device (HC-05) . The sensors all output text data via a serial port.

I now want to use a blue tooth low energy device, the module I am using is the BT4.0 HM-10, which acts a pass through device for the serial text data.


I have been partially successful in using the heartlistener code as a reference, however, as soon as I


Qt Code:
  1. m_control->connectToDevice();
To copy to clipboard, switch view to plain text mode 

I start to receive the following output in the console:

qt.bluetooth.bluez: cannot find matching characteristic for notification/indication

This is before I

Qt Code:
  1. m_control->discoverServices();
To copy to clipboard, switch view to plain text mode 


After doing service discovery and using a slot to catch characteristic changed signal I am able to output the line of text from the custom service of the HM-10 module BUT this happens even before I enable change notifications for the characteristic. i.e. if I take the code out from this function I still get notifications:

Qt Code:
  1. void leConnection::serviceStateChanged(QLowEnergyService::ServiceState s)
To copy to clipboard, switch view to plain text mode 


I should add all this code is being run on ubuntu and not the raspberry pi, for which I use a cross complier when I have the final code.


I have tried disabling notifications but I still get change notifications processed by:

Qt Code:
  1. void leConnection::updateSerialValue(const QLowEnergyCharacteristic &c, const QByteArray &value)
To copy to clipboard, switch view to plain text mode 


Any help or tips much appreciated.


Paul





Full code:


Qt Code:
  1. #include "leconnection.h"
  2.  
  3. leConnection::leConnection()
  4. {
  5.  
  6. // connect(m_deviceDiscoveryAgent, SIGNAL(finished()), this, SLOT(scanFinished()));
  7.  
  8. hm10Name = "MainStart"; //HMSoft
  9.  
  10. hm10Address = "A4:D5:78:69:C0:AF"; //A4:D5:78:69:C0:AF
  11.  
  12. hm10ServiceId = "0000FFE0-0000-1000-8000-00805F9B34FB";
  13.  
  14. ptrHM10serial = new QBluetoothUuid(hm10ServiceId);
  15.  
  16. hm10CharId = "0000FFE1-0000-1000-8000-00805F9B34FB";
  17.  
  18. ptrHM10Char = new QBluetoothUuid(hm10CharId);
  19.  
  20.  
  21.  
  22. ptrQBluetoothDeviceInfo = new QBluetoothDeviceInfo(QBluetoothAddress(hm10Address),hm10Name,0);
  23.  
  24. qDebug() << "created ptrQBluetoothDeviceInfo Object :) ";
  25.  
  26. m_control = new QLowEnergyController(*ptrQBluetoothDeviceInfo, this);
  27.  
  28. m_control->connectToDevice();
  29.  
  30. m_service=0;
  31.  
  32.  
  33. connect(m_control, SIGNAL(connected()),
  34. this, SLOT(deviceConnected()));
  35.  
  36. connect(m_control, SIGNAL(error(QLowEnergyController::Error)),
  37. this, SLOT(controllerError(QLowEnergyController::Error)));
  38.  
  39.  
  40. connect(m_control, SIGNAL(serviceDiscovered(QBluetoothUuid)),
  41. this, SLOT(serviceDiscovered(QBluetoothUuid)));
  42.  
  43.  
  44. connect(m_control, SIGNAL(discoveryFinished()),
  45. this, SLOT(serviceScanDone()));
  46.  
  47.  
  48. connect(m_control, SIGNAL(disconnected()),
  49. this, SLOT(deviceDisconnected()));
  50.  
  51. }
  52.  
  53.  
  54. void leConnection::deviceConnected()
  55. {
  56. qDebug() << "Success Device Connected ....... " << ptrQBluetoothDeviceInfo->name();
  57.  
  58. m_control->discoverServices();
  59.  
  60. }
  61.  
  62. void leConnection::controllerError(QLowEnergyController::Error error)
  63. {
  64. qDebug() << "Cannot connect to remote device.";
  65.  
  66. qDebug() << "Controller Error:" << error;
  67. }
  68.  
  69.  
  70. void leConnection::serviceDiscovered(const QBluetoothUuid &gatt)
  71.  
  72. {
  73. qDebug() << "service" << gatt.toString();
  74.  
  75. }
  76.  
  77.  
  78.  
  79. void leConnection::connectToService(const QString &address)
  80.  
  81. {
  82.  
  83.  
  84. }
  85.  
  86.  
  87. void leConnection::serviceScanDone()
  88. {
  89.  
  90.  
  91. qDebug() << "Services Scan Done for ..... " << ptrHM10serial->toString();
  92.  
  93.  
  94. m_service = m_control->createServiceObject(*ptrHM10serial,this);
  95.  
  96. m_service->discoverDetails();
  97.  
  98.  
  99. connect(m_service, SIGNAL(characteristicChanged(QLowEnergyCharacteristic,QByteArray)),
  100. this, SLOT(updateSerialValue(QLowEnergyCharacteristic,QByteArray)));
  101.  
  102.  
  103. connect(m_service, SIGNAL(stateChanged(QLowEnergyService::ServiceState)),
  104. this, SLOT(serviceStateChanged(QLowEnergyService::ServiceState)));
  105.  
  106.  
  107. connect(m_service, SIGNAL(descriptorWritten(QLowEnergyDescriptor,QByteArray)),
  108. this, SLOT(confirmedDescriptorWrite(QLowEnergyDescriptor,QByteArray)));
  109. }
  110.  
  111.  
  112. void leConnection::serviceStateChanged(QLowEnergyService::ServiceState s)
  113.  
  114. {
  115.  
  116. qDebug() << "gets to here 4 " << s;
  117.  
  118. switch (s) {
  119.  
  120. case QLowEnergyService::ServiceDiscovered:
  121.  
  122. {
  123.  
  124.  
  125. const QLowEnergyCharacteristic hm10Char = m_service->characteristic(*ptrHM10Char);
  126.  
  127.  
  128. qDebug() << hm10Char.value() << "lllllllll";
  129.  
  130.  
  131. const QLowEnergyDescriptor m_notificationDesc =
  132.  
  133. hm10Char.descriptor(QBluetoothUuid::ClientCharacteristicConfiguration);
  134.  
  135. if (m_notificationDesc.isValid())
  136.  
  137. {
  138. qDebug() << "gets to here 4yyyyyyyyyyyyyyyyyyy ";
  139.  
  140. m_service->writeDescriptor(m_notificationDesc, QByteArray::fromHex("0100"));
  141.  
  142. }
  143.  
  144. break;
  145.  
  146.  
  147. }
  148. default:
  149.  
  150. //nothing for now
  151. break;
  152. }
  153.  
  154. }
  155.  
  156.  
  157.  
  158. void leConnection::updateSerialValue(const QLowEnergyCharacteristic &c, const QByteArray &value)
  159.  
  160.  
  161. {
  162.  
  163. qDebug() << c.uuid();
  164.  
  165.  
  166. qDebug() << value; // part victron line
  167.  
  168. }
  169.  
  170.  
  171.  
  172.  
  173. void leConnection::confirmedDescriptorWrite(const QLowEnergyDescriptor &d, const QByteArray &value)
  174. {
  175.  
  176. qDebug() << "gets to here 6 " << value ;
  177.  
  178. if (value == QByteArray("0100"))
  179. {
  180. qDebug() << " testing";
  181. }
  182.  
  183.  
  184. if (d.isValid() && d == m_notificationDesc && value == QByteArray("0000"))
  185.  
  186. {
  187. //disabled notifications -> assume disconnect intent
  188.  
  189. m_control->disconnectFromDevice();
  190.  
  191. delete m_service;
  192.  
  193. m_service = 0;
  194. }
  195.  
  196. }
  197.  
  198.  
  199.  
  200. void leConnection::deviceDisconnected()
  201. {
  202.  
  203. qDebug() << "Remote device disconnected";
  204. }
  205.  
  206.  
  207. leConnection::~leConnection()
  208. {
  209.  
  210. }
To copy to clipboard, switch view to plain text mode