PDA

View Full Version : How to write to BLE Characteristic?



BB
20th August 2019, 18:39
Please refer my code


#include "bluetoothupdater.h"

BluetoothUpdater::BluetoothUpdater()
{
QBluetoothDeviceDiscoveryAgent* discovery = new QBluetoothDeviceDiscoveryAgent();

connect(discovery, &QBluetoothDeviceDiscoveryAgent::deviceDiscovered, [&] (const QBluetoothDeviceInfo &device)
{
if(device.name() == "Targ")
{
qDebug() << "Found new device:" << device.name();
ptrQBluetoothDeviceInfo = new QBluetoothDeviceInfo(QBluetoothAddress(device.addr ess()), device.name(), 0);
m_control = new QLowEnergyController(*ptrQBluetoothDeviceInfo);
m_control->connectToDevice();
m_control->discoverServices();
//connect(m_control, &QLowEnergyService::stateChanged, this, &BluetoothUpdater::service serviceDiscovered, this, &BluetoothUpdater::serviceDiscovered);
connect(m_control, &QLowEnergyController::serviceDiscovered, this, &BluetoothUpdater::serviceDiscovered);
connect(m_control, &QLowEnergyController::discoveryFinished, this, &BluetoothUpdater::serviceScanDone);
}
});

//connect(discovery, &QBluetoothDeviceDiscoveryAgent::deviceDiscovered, this, &BluetoothUpdater::addDevice);
discovery->setLowEnergyDiscoveryTimeout(5000);
discovery->start(QBluetoothDeviceDiscoveryAgent::LowEnergyMet hod);
}

void BluetoothUpdater::serviceScanDone()
{
qDebug() << "Service scan done.";

if (m_foundHeartRateService)
{
qDebug() << m_foundHeartRateService;
m_service = m_control->createServiceObject(QBluetoothUuid(DFUService));
qDebug() << m_service;
}

if (m_service)
{
qDebug() << "DFU Service found";
m_service->discoverDetails();
connect(m_service, &QLowEnergyService::stateChanged, this, &BluetoothUpdater::serviceStateChanged);
connect(m_service, &QLowEnergyService::characteristicChanged, this, &BluetoothUpdater::updateValue);
connect(m_service, &QLowEnergyService::descriptorWritten, this, &BluetoothUpdater::confirmedDescriptorWrite);
}
else
{
qDebug() << "DFU Service not found.";
}
}

void BluetoothUpdater::serviceDiscovered(const QBluetoothUuid &gatt)
{
if (gatt == QBluetoothUuid(DFUService))
{
qDebug() << "DFU service discovered.";
m_foundHeartRateService = true;
}
}

void BluetoothUpdater::serviceStateChanged(QLowEnergySe rvice::ServiceState state)
{
if(state == QLowEnergyService::ServiceDiscovered)
{
ControlPointChar = m_service->characteristic(QBluetoothUuid(ControlPointUUID));
if(ControlPointChar.isValid())
{
qDebug() << "Control Point Characteristic Found";
m_service->writeCharacteristic(ControlPointChar, QByteArray::fromHex("0601"), QLowEnergyService::WriteWithResponse);
}
else
{
qDebug() << "Control Point Characteristic Not Found";
}
ControlPointDesc = ControlPointChar.descriptor(QBluetoothUuid::Client CharacteristicConfiguration);
if (ControlPointDesc.isValid())
{
qDebug() << "Descriptor";
m_service->writeDescriptor(ControlPointDesc, QByteArray::fromHex("0100"));
}
}
}

void BluetoothUpdater::updateValue(const QLowEnergyCharacteristic &c, const QByteArray &value)
{
qDebug() << "updateValue, c.uuid:" << c.uuid();
qDebug() << "updateValue, value:" << value;
}

void BluetoothUpdater::confirmedDescriptorWrite(const QLowEnergyDescriptor &d, const QByteArray &value)
{
qDebug() << "confirmedDescriptorWrite:" << value;
if (d.isValid() && d == ControlPointDesc && value == QByteArray::fromHex("0000"))
{
qDebug() << "Inside confirmedDescriptorWrite";
m_control->disconnectFromDevice();
delete m_service;
m_service = nullptr;
}
}


This line
m_service->writeCharacteristic(ControlPointChar, QByteArray::fromHex("0601"), QLowEnergyService::WriteWithResponse); does not work

d_stranz
20th August 2019, 22:27
does not work

Doesn't compile?
Doesn't link?
Doesn't execute?
Doesn't produce the desired result?
Or is just tired and didn't want to work?

Sorry, I can't be of more help, but my crystal ball is out of service today.

BB
21st August 2019, 00:12
My bad!!


#include "bluetoothupdater.h"

BluetoothUpdater::BluetoothUpdater()
{
QBluetoothDeviceDiscoveryAgent* discovery = new QBluetoothDeviceDiscoveryAgent();

connect(discovery, &QBluetoothDeviceDiscoveryAgent::deviceDiscovered, [&] (const QBluetoothDeviceInfo &device)
{
if(device.name() == "Targ")
{
qDebug() << "Found new device:" << device.name();
ptrQBluetoothDeviceInfo = new QBluetoothDeviceInfo(QBluetoothAddress(device.addr ess()), device.name(), 0);
m_control = new QLowEnergyController(*ptrQBluetoothDeviceInfo);
m_control->connectToDevice();
m_control->discoverServices();
connect(m_control, &QLowEnergyController::serviceDiscovered, this, &BluetoothUpdater::serviceDiscovered);
connect(m_control, &QLowEnergyController::discoveryFinished, this, &BluetoothUpdater::serviceScanDone);
}
});

discovery->setLowEnergyDiscoveryTimeout(5000);
discovery->start(QBluetoothDeviceDiscoveryAgent::LowEnergyMet hod);
}

void BluetoothUpdater::serviceScanDone()
{
qDebug() << "Service scan done.";

if (m_foundHeartRateService)
{
qDebug() << m_foundHeartRateService;
m_service = m_control->createServiceObject(QBluetoothUuid(DFUService));
qDebug() << m_service;
}

if (m_service)
{
qDebug() << "DFU Service found";
m_service->discoverDetails();
connect(m_service, &QLowEnergyService::stateChanged, this, &BluetoothUpdater::serviceStateChanged);
connect(m_service, &QLowEnergyService::characteristicChanged, this, &BluetoothUpdater::updateValue);
connect(m_service, &QLowEnergyService::descriptorWritten, this, &BluetoothUpdater::confirmedDescriptorWrite);
}
else
{
qDebug() << "DFU Service not found.";
}
}

void BluetoothUpdater::serviceDiscovered(const QBluetoothUuid &gatt)
{
if (gatt == QBluetoothUuid(DFUService))
{
qDebug() << "DFU service discovered.";
m_foundHeartRateService = true;
}
}

void BluetoothUpdater::serviceStateChanged(QLowEnergySe rvice::ServiceState state)
{
if(state == QLowEnergyService::ServiceDiscovered)
{
ControlPointChar = m_service->characteristic(QBluetoothUuid(ControlPointUUID));
if(ControlPointChar.isValid())
{
qDebug() << "Control Point Characteristic Found";
ControlPointDesc = ControlPointChar.descriptor(QBluetoothUuid::Client CharacteristicConfiguration);
if (ControlPointDesc.isValid())
{
qDebug() << "Control Point Descriptor";
m_service->writeDescriptor(ControlPointDesc, QByteArray::fromHex("0100"));
}
WriteControl = 1;
}
else
{
qDebug() << "Control Point Characteristic Not Found";
WriteControl = 0;
}

PacketChar = m_service->characteristic(QBluetoothUuid(PacketUUID));
if(PacketChar.isValid())
{
qDebug() << "Packet Characteristic Found";
WritePacket = 1;
}
else
{
qDebug() << "Packet Characteristic Not Found";
WritePacket = 0;
}

if((WriteControl == 1) && (WritePacket == 1))
{
QFile InitFS("C:/Users/Sonal/Documents/data_glove_editor/res/firmwareUpdate/app.dat"); // Init dat file
if (!InitFS.open(QIODevice::ReadOnly))
{
qDebug() << "Init file cannot be opened";
return;
}
else
{
qDebug() << "File opened";

m_service->writeCharacteristic(ControlPointChar, QByteArray::fromHex("0601"), QLowEnergyService::WriteWithResponse);
QThread::msleep(100);

m_service->writeCharacteristic(ControlPointChar, QByteArray::fromHex("01018E000000"), QLowEnergyService::WriteWithResponse);
QThread::msleep(100);

qDebug() << "Init File Length = " << InitFS.size();

int NoOfInitFilePackets = InitFS.size() / BLEPacketLength;
qDebug() << "No Of Init File Packets = " << NoOfInitFilePackets;

int InitFileBytesRemaining = InitFS.size() % BLEPacketLength;
qDebug() << "Init File Bytes Remaining = " << InitFileBytesRemaining;

for (InitFilePacketCounter = 0, InitFilePointer = 0; InitFilePacketCounter < NoOfInitFilePackets; InitFilePacketCounter++, InitFilePointer += 20)
{
InitFS.seek(InitFilePointer);
InitBuffer = InitFS.read(BLEPacketLength);
//qDebug() << "InitFilePointer = " << InitFilePointer;
qDebug() << "InitBuffer = " << InitBuffer.toHex();
m_service->writeCharacteristic(PacketChar, QByteArray::fromHex(InitBuffer), QLowEnergyService::WriteWithoutResponse);
QThread::msleep(100);
}

InitFS.seek(InitFilePointer);
InitFileBytesLeft = InitFS.read(InitFileBytesRemaining);
qDebug() << "InitFileBytesLeft = " << InitFileBytesLeft.toHex();

m_service->writeCharacteristic(PacketChar, QByteArray::fromHex(InitFileBytesLeft), QLowEnergyService::WriteWithoutResponse);
QThread::msleep(100);

m_service->writeCharacteristic(ControlPointChar, QByteArray::fromHex("03"), QLowEnergyService::WriteWithResponse);
QThread::msleep(100);

m_service->writeCharacteristic(ControlPointChar, QByteArray::fromHex("04"), QLowEnergyService::WriteWithResponse);
QThread::msleep(100);
}
}
}
}

void BluetoothUpdater::updateValue(const QLowEnergyCharacteristic &c, const QByteArray &value)
{
//qDebug() << "updateValue, c.uuid:" << c.uuid();
qDebug() << " updateValue, value:" << value.toHex();
}

void BluetoothUpdater::confirmedDescriptorWrite(const QLowEnergyDescriptor &d, const QByteArray &value)
{
qDebug() << "confirmedDescriptorWrite:" << value.toHex();
if (d.isValid() && d == ControlPointDesc && value == QByteArray::fromHex("0000"))
{
qDebug() << "Inside confirmedDescriptorWrite";
m_control->disconnectFromDevice();
delete m_service;
m_service = nullptr;
}
}


I moved a step further. New code is pasted above. I'm not getting responses for the last 2 "m_service->writeCharacteristic(ControlPointChar,....". If I comment "m_service->writeCharacteristic(PacketChar, ... ", then I get responses for "m_service->writeCharacteristic(ControlPointChar, ...". I always get responses for first 2 "m_service->writeCharacteristic(ControlPointChar, ...". Is there some problem with creating the handles to 2 different characteristics using "m_service->writeCharacteristic"?? When I say I'm getting responses, it means that "updateValue" is being called each time I write to ControlPointChar. What am I missing here? Why multiple writes to multiple characteristics is failing??