Issues with BluetoothSerial.h library and string comparison

I spent 5 hours searching on stack overflow, reading through documentation, and asking people I know for help with this issue. Basically my code reads an input string, character by character, from a bluetooth serial device.

It appears to be equal when printed, although when compared using == or .equals it does not say they are equal. It doesn't say they are equal if I even convert them using .c_str and use strcmp == 0.

It turns out there is an invisible character at the end. I thought it might be a tab or new line initially, but it did not appear as anything when printed.

Anyways this is my code, and I just thought I would put it out there to help anyone with the same issue.

TLDR:

  • compare string lengths, and be sure there are no extra characters that are invisible in the string
  • you can remove the extra characters to fix this

Code:

#include "BluetoothSerial.h"

// Check if Bluetooth configs are enabled
#if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED)
#error Bluetooth is not enabled! Please run `make menuconfig` to and enable it
#endif

// Bluetooth Serial object
BluetoothSerial SerialBT;

// GPIO where LED is connected to
const int ledPin =  2;
// Handle received and sent messages
String message = "";
char incomingChar;

// Timer: auxiliar variables
unsigned long previousMillis = 0;    // Stores last time temperature was published
const long interval = 2000;         // interval at which to publish sensor readings

void setup() {
  pinMode(ledPin, OUTPUT);
  Serial.begin(115200);
  // Bluetooth device name
  SerialBT.begin("ESP32 with led hehe");
  Serial.println("The device started, now you can pair it with bluetooth!");
}

void loop() {
  unsigned long currentMillis = millis();
  // Send temperature readings
  if (currentMillis - previousMillis >= interval){
    previousMillis = currentMillis;
    SerialBT.println("Random number: " + String(random(100))); 
  }
  // Read received messages (LED control command)
  if (SerialBT.available()){
    message = "";
    char incomingChar = SerialBT.read();
    while (incomingChar != '\n'){
      message += String(incomingChar);
      if (SerialBT.available()){
        incomingChar = SerialBT.read();
      }
    }
    if (message.length()>1){//remove last invisible character
      message = message.substring(0,message.length()-1);
    }
    //Serial.flush();
    //Serial.write(incomingChar);  
  }
  // Check received message and control output accordingly
  if(!message.equals("")){ 
    Serial.println("message:" + message + ".");
    if (message.equalsIgnoreCase("on")){ 
      Serial.println("ONNNNN");
      digitalWrite(ledPin, HIGH);
      //message = "";
    }
    else if (message.equalsIgnoreCase("off")){
      Serial.println("OFFF");
      digitalWrite(ledPin, LOW);
      //message = "";
    }else{
      Serial.println("u typed something else");
    }
    message = "";
  }
}

Are you sure that the character is not a character caught on the first SerialBR.read()?

Also you are nestng two SerialBT.available(), SerialBT.Read() calls
Is this your problem?

I'm aware that this is not a question.

I would start by printing the received characters in hex to determine the invisable character; it might be a (0x0D).

  // Read received messages (LED control command)
  if (SerialBT.available())
  {
    message = "";
    char incomingChar = SerialBT.read();
    if (incomingChar < 0x10)
    {
      Serial.print("0");
    }
    Serial.println(incomingChar, HEX);

    ...
    ...
}

You might want to read Robin's Serial Input Basics - updated to find better ways of handling your communication. Having two blocks like below in the same part of the code is probably calling for problems.

if (SerialBT.available()){
incomingChar = SerialBT.read();