nkolban / esp32-snippets

Sample ESP32 snippets and code fragments
https://leanpub.com/kolban-ESP32
Apache License 2.0
2.35k stars 712 forks source link

esp32 BLE Client notification data storing previous values #959

Closed CLDiego closed 4 years ago

CLDiego commented 4 years ago

Hi, I'm trying to use the esp32 as a BLE client that connects to an RN4870. The RN module has a transparent UART service. While I can connect to the service and get notifications, at some point I start getting repeated notifications. For example, the RN module runs a calibration routine that outputs the status, I should be getting the following string:

serial peripheral interface up...... returning to initial state.... OK general purpose timer running..... OK

But the esp32 after two or three notifications starts outputting new data mixed with old one, so I start seeing:

rming upral interface up...... returning to initial state.... OK temperature calibration...OK p...... returning to initial state.... OK general purpose timer running..... core temperature: 25 C....

I'm thinking that this might be a buffer issue, is there a way to clear the pData?

I'm sure is not a problem on the server-side as connecting to my phone gets the correct messages.

I'm not sure how to use the esp32 logging to debug as I only started using it. Any ideas on how to solve this issue would be appreciated.

chegewara commented 4 years ago

Hi, ive been using esp32 to make OTA update over BLE few times. I am using either notifications or indications in this process and never failed, which mean there is no problem with it. I am suspecting you may have problem with printing output to serial log.

CLDiego commented 4 years ago

Hi chegewara,

Thanks for the reply. I'm using the client example just modifying some of it to connect to my BLE server.

I added a serial read to get some commands from the user and send it over.

I'm printing the data directly from the callback using:

static void notifyCallback(
  BLERemoteCharacteristic* pBLERemoteCharacteristic,
  uint8_t* pData,
  size_t length,
  bool isNotify) {

    Serial.print((char*)pData);

}

Is this the wrong way to do it?

This is my main loop, where I get the users input to send the command to the characteristic:

void loop() {

  if (doConnect == true) {
    if (connectToServer()) {
      Serial.println("We are now connected");
    } else {
      Serial.println("We have failed to connect to the server");
    }
    doConnect = false;
  }

  if (connected) {

  if (Serial.available() > 0) {
      // read the incoming byte:
      String cmd = Serial.readString() + "%";
      Serial.print("Sending: ");
      Serial.println(cmd);
      pRemoteCharacteristic->writeValue(cmd.c_str(), cmd.length());
    }
  }else if(doScan){
    BLEDevice::getScan()->start(0);  
  }

  delay(1000); // Delay a second between loops.
} // End of loop
chegewara commented 4 years ago

Everything seems to looks fine.

CLDiego commented 4 years ago

I'm sure it's not a problem of my BLE server as I tested it with gattool, pygatt and bluepy and I get the right output.

I't seems to me like the esp32 is not clearing the Rx buffer or losing the pointer position. My server sends different sizes of data, it doesn't send the same packet size all the time. Could it be that the esp32 can't handle fast notifications and thus trying to handle a different callback when it hasn't finish reading the previous one?

I get different behaviour when using indications instead of notifications, but I still get repeated data and in the wrong order