flemingp
4th May 2016, 21:01
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
m_control->connectToDevice();
I start to receive the following output in the console:
qt.bluetooth.bluez: cannot find matching characteristic for notification/indication
This is before I
m_control->discoverServices();
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:
void leConnection::serviceStateChanged(QLowEnergyServic e::ServiceState s)
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:
void leConnection::updateSerialValue(const QLowEnergyCharacteristic &c, const QByteArray &value)
Any help or tips much appreciated.
Paul
Full code:
#include "leconnection.h"
leConnection::leConnection()
{
// connect(m_deviceDiscoveryAgent, SIGNAL(finished()), this, SLOT(scanFinished()));
hm10Name = "MainStart"; //HMSoft
hm10Address = "A4:D5:78:69:C0:AF"; //A4:D5:78:69:C0:AF
hm10ServiceId = "0000FFE0-0000-1000-8000-00805F9B34FB";
ptrHM10serial = new QBluetoothUuid(hm10ServiceId);
hm10CharId = "0000FFE1-0000-1000-8000-00805F9B34FB";
ptrHM10Char = new QBluetoothUuid(hm10CharId);
ptrQBluetoothDeviceInfo = new QBluetoothDeviceInfo(QBluetoothAddress(hm10Address ),hm10Name,0);
qDebug() << "created ptrQBluetoothDeviceInfo Object :) ";
m_control = new QLowEnergyController(*ptrQBluetoothDeviceInfo, this);
m_control->connectToDevice();
m_service=0;
connect(m_control, SIGNAL(connected()),
this, SLOT(deviceConnected()));
connect(m_control, SIGNAL(error(QLowEnergyController::Error)),
this, SLOT(controllerError(QLowEnergyController::Error)) );
connect(m_control, SIGNAL(serviceDiscovered(QBluetoothUuid)),
this, SLOT(serviceDiscovered(QBluetoothUuid)));
connect(m_control, SIGNAL(discoveryFinished()),
this, SLOT(serviceScanDone()));
connect(m_control, SIGNAL(disconnected()),
this, SLOT(deviceDisconnected()));
}
void leConnection::deviceConnected()
{
qDebug() << "Success Device Connected ....... " << ptrQBluetoothDeviceInfo->name();
m_control->discoverServices();
}
void leConnection::controllerError(QLowEnergyController ::Error error)
{
qDebug() << "Cannot connect to remote device.";
qDebug() << "Controller Error:" << error;
}
void leConnection::serviceDiscovered(const QBluetoothUuid &gatt)
{
qDebug() << "service" << gatt.toString();
}
void leConnection::connectToService(const QString &address)
{
}
void leConnection::serviceScanDone()
{
qDebug() << "Services Scan Done for ..... " << ptrHM10serial->toString();
m_service = m_control->createServiceObject(*ptrHM10serial,this);
m_service->discoverDetails();
connect(m_service, SIGNAL(characteristicChanged(QLowEnergyCharacteris tic,QByteArray)),
this, SLOT(updateSerialValue(QLowEnergyCharacteristic,QB yteArray)));
connect(m_service, SIGNAL(stateChanged(QLowEnergyService::ServiceStat e)),
this, SLOT(serviceStateChanged(QLowEnergyService::Servic eState)));
connect(m_service, SIGNAL(descriptorWritten(QLowEnergyDescriptor,QByt eArray)),
this, SLOT(confirmedDescriptorWrite(QLowEnergyDescriptor ,QByteArray)));
}
void leConnection::serviceStateChanged(QLowEnergyServic e::ServiceState s)
{
qDebug() << "gets to here 4 " << s;
switch (s) {
case QLowEnergyService::ServiceDiscovered:
{
const QLowEnergyCharacteristic hm10Char = m_service->characteristic(*ptrHM10Char);
qDebug() << hm10Char.value() << "lllllllll";
const QLowEnergyDescriptor m_notificationDesc =
hm10Char.descriptor(QBluetoothUuid::ClientCharacte risticConfiguration);
if (m_notificationDesc.isValid())
{
qDebug() << "gets to here 4yyyyyyyyyyyyyyyyyyy ";
m_service->writeDescriptor(m_notificationDesc, QByteArray::fromHex("0100"));
}
break;
}
default:
//nothing for now
break;
}
}
void leConnection::updateSerialValue(const QLowEnergyCharacteristic &c, const QByteArray &value)
{
qDebug() << c.uuid();
qDebug() << value; // part victron line
}
void leConnection::confirmedDescriptorWrite(const QLowEnergyDescriptor &d, const QByteArray &value)
{
qDebug() << "gets to here 6 " << value ;
if (value == QByteArray("0100"))
{
qDebug() << " testing";
}
if (d.isValid() && d == m_notificationDesc && value == QByteArray("0000"))
{
//disabled notifications -> assume disconnect intent
m_control->disconnectFromDevice();
delete m_service;
m_service = 0;
}
}
void leConnection::deviceDisconnected()
{
qDebug() << "Remote device disconnected";
}
leConnection::~leConnection()
{
}
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
m_control->connectToDevice();
I start to receive the following output in the console:
qt.bluetooth.bluez: cannot find matching characteristic for notification/indication
This is before I
m_control->discoverServices();
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:
void leConnection::serviceStateChanged(QLowEnergyServic e::ServiceState s)
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:
void leConnection::updateSerialValue(const QLowEnergyCharacteristic &c, const QByteArray &value)
Any help or tips much appreciated.
Paul
Full code:
#include "leconnection.h"
leConnection::leConnection()
{
// connect(m_deviceDiscoveryAgent, SIGNAL(finished()), this, SLOT(scanFinished()));
hm10Name = "MainStart"; //HMSoft
hm10Address = "A4:D5:78:69:C0:AF"; //A4:D5:78:69:C0:AF
hm10ServiceId = "0000FFE0-0000-1000-8000-00805F9B34FB";
ptrHM10serial = new QBluetoothUuid(hm10ServiceId);
hm10CharId = "0000FFE1-0000-1000-8000-00805F9B34FB";
ptrHM10Char = new QBluetoothUuid(hm10CharId);
ptrQBluetoothDeviceInfo = new QBluetoothDeviceInfo(QBluetoothAddress(hm10Address ),hm10Name,0);
qDebug() << "created ptrQBluetoothDeviceInfo Object :) ";
m_control = new QLowEnergyController(*ptrQBluetoothDeviceInfo, this);
m_control->connectToDevice();
m_service=0;
connect(m_control, SIGNAL(connected()),
this, SLOT(deviceConnected()));
connect(m_control, SIGNAL(error(QLowEnergyController::Error)),
this, SLOT(controllerError(QLowEnergyController::Error)) );
connect(m_control, SIGNAL(serviceDiscovered(QBluetoothUuid)),
this, SLOT(serviceDiscovered(QBluetoothUuid)));
connect(m_control, SIGNAL(discoveryFinished()),
this, SLOT(serviceScanDone()));
connect(m_control, SIGNAL(disconnected()),
this, SLOT(deviceDisconnected()));
}
void leConnection::deviceConnected()
{
qDebug() << "Success Device Connected ....... " << ptrQBluetoothDeviceInfo->name();
m_control->discoverServices();
}
void leConnection::controllerError(QLowEnergyController ::Error error)
{
qDebug() << "Cannot connect to remote device.";
qDebug() << "Controller Error:" << error;
}
void leConnection::serviceDiscovered(const QBluetoothUuid &gatt)
{
qDebug() << "service" << gatt.toString();
}
void leConnection::connectToService(const QString &address)
{
}
void leConnection::serviceScanDone()
{
qDebug() << "Services Scan Done for ..... " << ptrHM10serial->toString();
m_service = m_control->createServiceObject(*ptrHM10serial,this);
m_service->discoverDetails();
connect(m_service, SIGNAL(characteristicChanged(QLowEnergyCharacteris tic,QByteArray)),
this, SLOT(updateSerialValue(QLowEnergyCharacteristic,QB yteArray)));
connect(m_service, SIGNAL(stateChanged(QLowEnergyService::ServiceStat e)),
this, SLOT(serviceStateChanged(QLowEnergyService::Servic eState)));
connect(m_service, SIGNAL(descriptorWritten(QLowEnergyDescriptor,QByt eArray)),
this, SLOT(confirmedDescriptorWrite(QLowEnergyDescriptor ,QByteArray)));
}
void leConnection::serviceStateChanged(QLowEnergyServic e::ServiceState s)
{
qDebug() << "gets to here 4 " << s;
switch (s) {
case QLowEnergyService::ServiceDiscovered:
{
const QLowEnergyCharacteristic hm10Char = m_service->characteristic(*ptrHM10Char);
qDebug() << hm10Char.value() << "lllllllll";
const QLowEnergyDescriptor m_notificationDesc =
hm10Char.descriptor(QBluetoothUuid::ClientCharacte risticConfiguration);
if (m_notificationDesc.isValid())
{
qDebug() << "gets to here 4yyyyyyyyyyyyyyyyyyy ";
m_service->writeDescriptor(m_notificationDesc, QByteArray::fromHex("0100"));
}
break;
}
default:
//nothing for now
break;
}
}
void leConnection::updateSerialValue(const QLowEnergyCharacteristic &c, const QByteArray &value)
{
qDebug() << c.uuid();
qDebug() << value; // part victron line
}
void leConnection::confirmedDescriptorWrite(const QLowEnergyDescriptor &d, const QByteArray &value)
{
qDebug() << "gets to here 6 " << value ;
if (value == QByteArray("0100"))
{
qDebug() << " testing";
}
if (d.isValid() && d == m_notificationDesc && value == QByteArray("0000"))
{
//disabled notifications -> assume disconnect intent
m_control->disconnectFromDevice();
delete m_service;
m_service = 0;
}
}
void leConnection::deviceDisconnected()
{
qDebug() << "Remote device disconnected";
}
leConnection::~leConnection()
{
}