Hi,
I want to set up a Bluetooth connection between two argon boards. I read some tutorials and wrote the code shown below based on two tutorials and the connection was set up. But the data read from the receiver is a strange number. So I would like to ask some questions about how to use BLE APIs to get the data based on my codes.
Here is my code for receiver:
const size_t SCAN_RESULT_MAX = 30;
const char * serviceUuid = "2baa45e8-1ecc-46b8-ac73-d716bd18696e";
const char * valueUuid = "8b9c77e1-54a4-41c5-bc70-7b5cd4c037cc";
BleCharacteristic valueCharacteristic;
BleScanResult scanResults[SCAN_RESULT_MAX];
BlePeerDevice peer;
void onDataReceived(const uint8_t* data, size_t len, const
BlePeerDevice& peer, void* context);
void setup() {
Serial.begin();
valueCharacteristic.onDataReceived(onDataReceived, NULL);
}
void loop() {
if (BLE.connected())
{
//we are currently connected to the board
Serial.println("connected");
}
else
{
//we are not connected to the board, scan for it.
int count = BLE.scan(scanResults, SCAN_RESULT_MAX);
for (int ii = 0; ii < count; ii++)
{
uint8_t buf[BLE_MAX_ADV_DATA_LEN];
size_t len;
//we are looking for devices that have a the same uuid
len = scanResults[ii].advertisingData.get(BleAdvertisingDataType::SERVICE_UUID_128BIT_COMPLETE, buf, BLE_MAX_ADV_DATA_LEN);
if (len > 0)
{
for (size_t jj = 0; jj < len; jj += 1)
{ // it should be uint128_t, but it was not able to be complied, so using uint64_t here
if(*(uint64_t *)buf[jj] == *serviceUuid)
{
// Found the right device
peer = BLE.connect(scanResults[ii].address);
if (peer.connected())
{
Serial.println("successfully connected!");
//get the sensing data
valueCharacteristic = peer.getCharacteristicByUUID(BleUuid(valueUuid));
}
else
{
Serial.println("connection failed!");
}
}
}
}
}
}
}
void onDataReceived(const uint8_t* data, size_t len, const BlePeerDevice& peer, void* context) {
uint16_t value;
memcpy(&value, &data, sizeof(data));
Serial.println("this is the value:");
Serial.println(value);
}
Here is my code for transmitter:
const BleUuid serviceUuid("2baa45e8-1ecc-46b8-ac73-d716bd18696e");
const BleUuid valueUuid("8b9c77e1-54a4-41c5-bc70-7b5cd4c037cc");
BleCharacteristic *valueCharacteristic("value", BleCharacteristicProperty::NOTIFY, valueUuid, serviceUuid);
const unsigned long UPDATE_PERIOD_MS = 100;
unsigned long lastUpdate = 0;
void setup() {
Serial.begin();
// Advertising data
BLE.addCharacteristic(valueCharacteristic);
BleAdvertisingData advData;
advData.appendServiceUUID(serviceUuid);
// Start advertising!
BLE.advertise(&advData);
}
typedef union {
struct {
float x;
float y;
float z;
} sample;
uint8_t bytes[12];
} Sample;
void loop() {
if (BLE.connected()){
if (millis() - lastUpdate >= UPDATE_PERIOD_MS) {
lastUpdate = millis();
Sample sample;
sample.sample.x = 1;
sample.sample.y = 1;
sample.sample.z = 1;
valueCharacteristic.setValue(sample.bytes, sizeof(Sample));
}
Serial.println("connected");
}
else{
Serial.println("connecting");
}
}
Result:
In the transmitter code, I set the x, y z to be 1 respectively. But what the receiver printed out in onDataReceived() function is 41144.
Question:
In the transmitter code, I have valueCharacteristic, and I have this line:
valueCharacteristic.setValue(sample.bytes, sizeof(Sample));
based on this webpage, https://rickkas7.github.io/ble-imu/
But I dont quite understand this line. I am not sure whether the data (x, y, z) needs to be assigned to valueCharacteristic which makes more sense than assigned with a buffer. Not sure why not assign x, y, z to the valueCharacteristic in the tutorial.
Then in the receiver code, I called onDataReceived() based on the tutorial in this link: https://docs.particle.io/tutorials/device-os/bluetooth-le/#examples
But I am also not sure how to get the sensing data from it. I understand it is a callback function. I understand to use BLE.scan to check the match of Uuid. Then get the characteristic based on its Uuid once found the right service. Next, based on the tutorial, the data will be read from onDataReceived(). I am not sure the logic here. I thought the data should be read from the characteristic.
Secondly, I am not sure how to check the 128bit uuid, as it was not able to be compiled and I used uin64_t instead.
And I am not sure why in the tutorial, the for loop shown below is used to check uuid. Not quite sure the meaning of checking buf[jj] for the serviceUuid. scanResults[ii] is the iith scaned service and buf[] stores its serviceUuid through
advertisingData.get(BleAdvertisingDataType::SERVICE_UUID_128BIT_COMPLETE, ....)
Not sure why needs for loop.
for (size_t jj = 0; jj < len; jj += 1)
{ // it should be uint128_t, but it was not able to be complied, so using uint64_t here
if(*(uint64_t *)buf[jj] == *serviceUuid)
{
// Found the right device
...
Thank you for your time and help.