Trouble with sending byte array trough ble from arduino nano 33 ble to extern ble device

Hi i'm having trouble sending hex data trough ble, hope someone can help me. So I want to send a byte array of uint16_t = 0x0b00, I devided it in 2 seperate uint8_t veriables and tried sending it with the big endian and little endian way (both don't work). My code will be below, with this code I'm succesfully able to connect and to change the name of the extern ble device but not send the byte array. I tried this code by connecting the nano 33 ble to another nano 33 ble and it works fine while sending to another arduino but not the extern device. When I send the hex commands to the other nano 33 ble I'm perfectly able to receive them. Also when I send the hex commands trough my phone with the nRF connect app I'm able to send the commands to the extern device with the characteristic 99fa0002-338a-1024-8a49-009c0215f78a, (see screen shots below) so what does my phone do that the arduino doesn't?


I narrowed down the problem allot witch I will explain below my code, so here is my code first:

#include <ArduinoBLE.h>

const uint16_t Comp_Id = 0x00A4;
const uint8_t UUID_BASE[16] = {0x8A, 0xF7, 0x15, 0x02, 0x9c, 0x00, 0x49, 0x8A, 0x24, 0x10, 0x8A, 0x33, 0x00, 0x00, 0xFA, 0x99};
int loops = 0;

// The custom service en characteristic UUIDs from my arduino nano 33 ble test
//#define CUSTOM_SERVICE_UUID "12345678-1234-5678-1234-56789abcdef0"
//#define CUSTOM_CHARACTERISTIC_UUID "abcdef01-1234-5678-1234-56789abcdef0"

// The custom service and characteristic UUIDs from the extern ble device
#define CUSTOM_SERVICE_UUID "99fa0001-338a-1024-8a49-009c0215f78a"
#define CUSTOM_CHARACTERISTIC_UUID "99fa0002-338a-1024-8a49-009c0215f78a"

void setup() {
  Serial.begin(9600);
  while(!Serial);

  if(!BLE.begin()){
    Serial.println("starting BLE failed");
    while(1); // stop running
  }
  BLE.setManufacturerData(Comp_Id, UUID_BASE, 16);
  Serial.println("starting scan");
}

void loop() {
  BLE.scanForName("SEAT 8036"); // Name of the extern device
  //BLE.scanForName("BLE_Slave"); // Name from test arduino
  BLEDevice peripheral = BLE.available();
  if (peripheral) {
    BLE.stopScan();
    Serial.println("Found peripheral");

    if (peripheral.connect()) {
      Serial.println("Connected to peripheral");

      while(peripheral.connected()){
        if(loops < 1){
          if (peripheral.discoverAttributes()){
            Serial.println("Attributes discovered");
          }
          Serial.println(peripheral.deviceName());

          // changing name
          if (peripheral.service("1800").characteristic("2a00").canWrite()){
            Serial.println("Name writable");
            if (peripheral.service("1800").characteristic("2a00").writeValue("SEAT 8036")){
              Serial.println("Name changed");
            }
          } else {
            Serial.println("Name not writable");
          }
        }
        // Trying to write value
        // characteristic is write and write without responce
        if (peripheral.service(CUSTOM_SERVICE_UUID).characteristic(CUSTOM_CHARACTERISTIC_UUID).canWrite()){
          Serial.println("Value writable");
          uint16_t byteArray = 0x0B00;
          // change to big endian
          uint8_t bigEndianArray[2];
          bigEndianArray[0] = (byteArray >> 80) & 0xFF;
          bigEndianArray[1] = byteArray & 0xFF;
          if (peripheral.service(CUSTOM_SERVICE_UUID).characteristic(CUSTOM_CHARACTERISTIC_UUID).writeValue(bigEndianArray, 2/*, false*/)){
            Serial.println("Value written");
          } else{
            Serial.println("Value not written");
          }

        } else {
          Serial.println("Value not writable");
        }

        // Check RSSI to monitor connection quality
        int rssi = peripheral.rssi();
        Serial.print("RSSI: ");
        Serial.println(rssi);

        loops++;
        delay(400);
      }
    } else {
      Serial.println("Failed to connect to peripheral");
    }
  }
}

As you can see, I wrote a lot of debug commands in my code so I will show you my serial monitor:
starting scan
Found peripheral
Connected to peripheral
Attributes discovered
SEAT 8036
Name writable
Name changed
Value writable
Value not written
RSSI: -59
Value writable
Value not written
RSSI: -60
Value writable
Value not written
RSSI: -60

As we can tell by the debug commands, the function .writeValue doensn't work when I'm connected to the extern device. To understand why it doesn't work I checked the arduino ble librarie, this is the github link: https://github.com/arduino-libraries/ArduinoBLE/tree/master
The problem begins in the BLECharacteristic.cpp file (link) where I found that the device is remote, because when force returning a 1 here and the other functions forcing a zero, my code says value written but doesn't write anything, nor does it when trying this while sending it to another nano 33 ble, so the withResponce has to return true (or a number) here for the signal to work. See screenshot below for the function:

So I went to the BLERemoteCharacteristic.cpp file (link) where I found that resp[0] == 0x01 always returns 0 because it always it 0x01, see screen shot below:


When removing this from the code it again says value written but is doesn't actually write anything.
After this I went deeper into the librariem, to the ATT.cpp file (link) and here is where I got kinda lost. I think it has something to do with this section of the code:

Where the responce buffer doenst return anything but I honestly don't know why it does this and why it doens't return anything while the arduino does this with no problem.

1 Like

= 0

Hi, thanks for the reply, I have changed the code:

          bigEndianArray[0] = (byteArray >> 8) & 0xFF;
          bigEndianArray[1] = byteArray & 0xFF;

But like I said the code does work when sending to another arduino nano 33 ble because I'm receiving 0x0b 0x00 there. The problem is with the .writeValue function because I'm never actually writing something witch I think can be concluded after my debug text in the serial monitor

there are some new discoveries I made, I found that resp[0] is set to 0x01 in this piece of code int the ATT.cpp file.


Here _pendingResp.buffer[0] is set to ATT_OP_ERROR witch equals 0x01 and therefore is the reason im getting the error. So the error is created because of this if statement:

  if (_pendingResp.connectionHandle == connectionHandle && (_pendingResp.op - 1) == attError->opcode) {
    _pendingResp.buffer[0] = ATT_OP_ERROR;
    memcpy(&_pendingResp.buffer[1], data, dlen);
    _pendingResp.length = dlen + 1;
  }

Does anyone have any idea why this is not giving a error while sending variables to another arduino nano 33 ble but when trying to send variables to the extern device it does give the error.

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.