espressif / arduino-esp32

Arduino core for the ESP32
GNU Lesser General Public License v2.1
13.76k stars 7.44k forks source link

Bluetooth Serial with Arduino IOT Cloud problem #8834

Closed jplavoiemtl closed 1 year ago

jplavoiemtl commented 1 year ago

Board

ESP32 TTGO T1

Device Description

TTGO T1 - ESP32

Hardware Configuration

No.

Version

latest master (checkout manually)

IDE Name

Arduino 2.2.1

Operating System

Windows 11

Flash frequency

80 MHz

PSRAM enabled

yes

Upload speed

921600

Description

In an Arduino IOT Cloud project if I want to use Bluetooth Serial with an ESP32 board, there seem to be a connection problem with the cloud. I see the connection to wifi but while connecting to Arduino cloud I get the error message:

MQTT Broker: mqtts-up.iot.arduino.cc:8884 WiFi.status(): 255 Connection to "jplavoie" failed Retrying in "4000" milliseconds Connected to "jplavoie" ArduinoIoTCloudTCP::handle_ConnectMqttBroker could not connect to mqtts-up.iot.arduino.cc:8884 ArduinoIoTCloudTCP::handle_ConnectMqttBroker 1 connection attempt at tick time 14955

My code is minimal to see if I can run Bluetooth Serial with Arduino cloud. I even tried using Bluetooth Serial on the other core than the cloud and I get the same error and no cloud connection. If I remove the Bluetooth Serial code it connects well to the cloud.

Sketch

#include "thingProperties.h"
#include "BluetoothSerial.h"

BluetoothSerial SerialBT;

void setup() {
  // Initialize serial and wait for port to open:
  Serial.begin(9600);
  // This delay gives the chance to wait for a Serial Monitor without blocking if none is found
  delay(1500); 

  // Start Bluetooth communication
  SerialBT.begin("ESP32_BLUETOOTH");
  Serial.println("Bluetooth initialized");  

  // Defined in thingProperties.h
  initProperties();

  // Connect to Arduino IoT Cloud
  ArduinoCloud.begin(ArduinoIoTPreferredConnection);

  /*
     The following function allows you to obtain more information
     related to the state of network and IoT Cloud connection and errors
     the higher number the more granular information you’ll get.
     The default is 0 (only errors).
     Maximum is 4
 */
  setDebugMessageLevel(2);
  ArduinoCloud.printDebugInfo();

  // Try to connect to Arduino IoT Cloud
  while (ArduinoCloud.connected() == false) {
    ArduinoCloud.update();
    delay(500);
  }

  Serial.println("Connected to Arduino IoT Cloud");  

}

void loop() {
  ArduinoCloud.update();
  // Your code here 
  // Check Bluetooth Serial for incoming data
  if (SerialBT.available()) {
    char c = SerialBT.read();
    Serial.write(c);
  }

  // Some delay to avoid constant polling
  delay(10);  

}

/*
  Since Message is READ_WRITE variable, onMessageChange() is
  executed every time a new value is received from IoT Cloud.
*/
void onMessageChange()  {
  // Add your code here to act upon Message change
}

Debug Message

MQTT Broker: mqtts-up.iot.arduino.cc:8884
WiFi.status(): 255
Connection to "jplavoie" failed
Retrying in  "4000" milliseconds
Connected to "jplavoie"
ArduinoIoTCloudTCP::handle_ConnectMqttBroker could not connect to mqtts-up.iot.arduino.cc:8884
ArduinoIoTCloudTCP::handle_ConnectMqttBroker 1 connection attempt at tick time 14955
ArduinoIoTCloudTCP::handle_ConnectMqttBroker could not connect to mqtts-up.iot.arduino.cc:8884
ArduinoIoTCloudTCP::handle_ConnectMqttBroker 2 connection attempt at tick time 20130
ArduinoIoTCloudTCP::handle_ConnectMqttBroker could not connect to mqtts-up.iot.arduino.cc:8884
ArduinoIoTCloudTCP::handle_ConnectMqttBroker 3 connection attempt at tick time 29315

Other Steps to Reproduce

Additional note: If I start only the cloud it connects fine. Then I wait many seconds on purpose to troubleshoot. Then as soon as we run the line:

SerialBT.begin("ESP32_BLUETOOTH"); The board resets with the following message:

Board successfully connected to Arduino IoT Cloud Thing Properties synchronised Guru Meditation Error: Core 0 panic'ed (StoreProhibited). Exception was unhandled.

Core 0 register dump: PC : 0x40091968 PS : 0x00060230 A0 : 0x80125375 A1 : 0x3fffcca0
A2 : 0x00000000 A3 : 0x00000000 A4 : 0x000002d0 A5 : 0x00000000
A6 : 0x00000002 A7 : 0x0000002d A8 : 0x8009af0c A9 : 0x3fffcc70
A10 : 0x00000000 A11 : 0x00000000 A12 : 0x3ffce5cc A13 : 0x3fffef24
A14 : 0x3fffef38 A15 : 0x3fffedb8 SAR : 0x0000001d EXCCAUSE: 0x0000001d
EXCVADDR: 0x00000000 LBEG : 0x40091968 LEND : 0x40091973 LCOUNT : 0x0000002c
There seems to be a conflict when beginning Serial Bluetooth. If I do not connect to Arduino IOT cloud and run the Serial Bluetooth code, Serial Bluetooth works fine. The problem seems that I can do one thing or the other, but not together. If someone as a clue because this is frustrating since a few days.

I have checked existing issues, online documentation and the Troubleshooting Guide

lbernstone commented 1 year ago

If you are not getting a backtrace, then it is very likely you are running out of memory. If you are getting a backtrace, then please decode it It will take at least 32k of contiguous free memory to establish a TLS connection. You can use ESP.getMaxAllocHeap() to get the free memory block size. https://github.com/espressif/arduino-esp32/issues/6892#issuecomment-1161514645

SuGlider commented 1 year ago

@jplavoiemtl

Guru Meditation Error: Core 0 panic'ed (StoreProhibited). Exception was unhandled.

@lbernstone gave you a very possible reason: it ESP32 is running out of memory. It is very possible that Arduino IOT Cloud library or SerialBT does not check if the allocated memory returns a valid pointer.

EXCVADDR: 0x00000000 says that the code is trying to store data in a NULL pointer.

Possible solution: check if the sketch is allocating memory or declaring big arrays. Test the pointers to check if those are NULL.

Alternative solution: Change the SoC to one with PSRAM, like the ESP32-WROVER. Arduino will try to use as much as possible PSRAM and leave SRAM free for other use. This may solve the problem by extending the hardware capabilities.

SuGlider commented 1 year ago

Alternative Solution 3: Use 2 ESP32 communicating to each other using SPI or UART. The first ESP32 will work the WiFi/MQTT and the second will work the Bluetooth Serial communication. If this is a valid solution, then the first ESP32 could be anyone with WiFi, like an S2 or a C3, for instance.

SuGlider commented 1 year ago

Alternative Solution 4: If possible, there may be a way to manage to make it work only using WiFi, with ESP-NOW or WiFi-Mesh instead of SerialBT... I've no information about how the project should work, but using some other way to communicate instead of Bluetooth may help.

Alternative Solution 5: If possible, close SerialBT, release related memory, start Arduino Cloud IoT communication, send all data, close it, release WiFi related memory, start the SerialBT and so on... In other words, run WiFi or SerialBT, each at a time, not both at the same time.

SuGlider commented 1 year ago

Alternative Solution 6: Try to find another MQTT library (lighter) that also works with Arduino IoT Cloud... Not sure if there is any. This other lighter library may use less memory resources and allow it to work along with SerialBT.

jplavoiemtl commented 1 year ago

These are great suggestions @SuGlider Thanks!

Indeed I could use 2 ESP32 modules and share data. But in my car related project to send info back to my lab via the internet, I decided to use only one ESP32 with the LCD screen (TTGO-T1) because of the space constraint.

I need to use serial Bluetooth over other suggestions like ESP-NOW or WiFi-Mesh because my ESP32 is talking to a standard OBDII Bluetooth dongle in the car.

Alternating Bluetooth and Wifi may be indeed a solution but may be painfull to use. My system is sending data every 5 seconds to base so alternating that much and establish the Arduino cloud connection in itself is a matter of seconds, so it would not be practical in my project.

For my case I ended up by not using Arduino IOT Cloud and use Wifi and my regular MQTT broker like I was doing before. It works great. To transmit the information between the Cloud and my lab computer I am using an Ngrok tunnel via MQTT. My goal was to ditch the Ngrok service and use Arduino cloud instead which may have been simpler because I do not need to have an Ngrok tunnel going on with a separate Ngrok agent running somewhere else.

The reason I was interested in using Arduino IOT cloud was that I could modify a cloud variable between the project in my car and the base station and rely on Arduino Cloud to share that variable like I do without using an Ngrok tunnel, agent and all that jazz. I ended up not using Arduino Cloud because of this incompatibility of the serial bluetooth and Arduino cloud libraries unfortunately.

This is a bit of deception because I would have thought that Serial Bluetooth could work well with Arduino Cloud on a small device like the ESP32 TTGO. Like I said if I use my "own cloud" solution with Wifi and my MQTT broker it works well. Sadly, I do not have any control on the internal MQTT broker used by Arduino Cloud, I am supposed to open their service and have it work, but apparently it is not straightforward if I want to use Bluetooth Serial as well. I suppose we could close this issue since I did not pursue to try to make it work.