I was conducting a comparison in terms of speed to send Bluetooth packets using both HC-05 and the built-in Bluetooth.
I was shocked that the legacy HC-05 is 70% faster than the Built-In Bluetooth on ESP32.
- // LED to toggle when streaming
- const int LedLight = LED_BUILTIN;
- // LED Status (ON-OFF)
- bool LedStatus = false;
- // Start Flag to avoid re-enable timer if it is already on
- bool StartFlag = false;
- // Stop Flag to avoid re-disable timer if it is already off
- bool StopFlag = false;
- // Byte array to hold float conversion
- byte ByteData[4];
- // Sampling time
- long SamplingTimeInMilliseconds = 10;
- // Variable to hold the number of increments needed to change the LED every second
- int_fast16_t ChangeLedStatusCount = 0;
- // Sample index of EKG, PPG
- int_fast8_t SampleIndex = 0;
- // Flag to be 1 to push new sample
- volatile bool updateFlag = false;
- // Hardware timer
- hw_timer_t * timer = nullptr;
- // Lock for critical section of shared variable (updateFlag)
- portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED;
- unsigned long tb = 0;
- // Change LED Status every 1 second = 10 ms* 100 counts
- void changeBlinkingLed()
- {
- ChangeLedStatusCount += 1;
- if (ChangeLedStatusCount == 100)
- {
- LedStatus = !(LedStatus);
- digitalWrite(LedLight, LedStatus);
- ChangeLedStatusCount = 0;
- }
- }
- // Convert float number into bytes
- void float2Bytes(byte ByteData[4], float FloatData)
- {
- memcpy(ByteData, reinterpret_cast<unsigned char*>(&FloatData), 4);
- }
- // Send float as byte array big endian
- void sendHexData(const float FloatData)
- {
- float2Bytes(ByteData, FloatData);
- Serial2.write(ByteData[3]);
- Serial2.write(ByteData[2]);
- Serial2.write(ByteData[1]);
- Serial2.write(ByteData[0]);
- }
- // Packet Header
- void sendHeader()
- {
- Serial2.write(0xAA);
- Serial2.write(0xBB);
- }
- // Send Payload Byte
- void sendPayload(byte NumberOfChannels)
- {
- const byte Size = NumberOfChannels * 4;
- Serial2.write(Size);
- }
- // On Timer Event
- void IRAM_ATTR onTimer()
- {
- // Enter critical section
- portENTER_CRITICAL_ISR(&timerMux);
- // Set flag
- updateFlag = true;
- // Exit critical section
- portEXIT_CRITICAL_ISR(&timerMux);
- }
- void setup()
- {
- const uint32_t Freq = 80;
- //Set CPU clock to 240 MHz fo example
- setCpuFrequencyMhz(Freq);
- // Set Serial2 baudrate
- Serial2.begin(115200);
- // LED as output
- pinMode(LedLight, OUTPUT);
- /* Use 1st timer of 4 */
- /* 1 tick takes 80 MHZ/prescaler (80) = 1us so we set the divider 80 and count up */
- timer = timerBegin(0, Freq, true);
- /* Attach onTimer function to our timer */
- timerAttachInterrupt(timer, &onTimer, true);
- /* Set alarm to call onTimer function every second 1 tick is 1us
- => 1 second is 10000us */
- /* Repeat the alarm (third parameter) */
- timerAlarmWrite(timer, 10000, true);
- }
- void loop()
- {
- if (updateFlag == true)
- {
- changeBlinkingLed();
- tb = micros();
- sendHeader();
- sendPayload(8);
- sendHexData(1.0);
- sendHexData(2.0);
- sendHexData(3.0);
- sendHexData(4.0);
- sendHexData(5.0);
- sendHexData(6.0);
- sendHexData(7.0);
- tb = micros() - tb;
- sendHexData(tb);
- SampleIndex++;
- SampleIndex = (SampleIndex > 99) ? 0 : SampleIndex;
- portENTER_CRITICAL_ISR(&timerMux);
- updateFlag = false;
- portEXIT_CRITICAL_ISR(&timerMux);
- }
- if (Serial2.available() > 0)
- {
- const auto IncomingCommand = Serial2.read();
- switch (IncomingCommand)
- {
- case '*':
- if (!StartFlag)
- {
- StartFlag = true;
- StopFlag = false;
- /* Start an alarm */
- timerAlarmEnable(timer);
- }
- break;
- case '#':
- if (!StopFlag)
- {
- StopFlag = true;
- StartFlag = false;
- timerAlarmDisable(timer);
- }
- break;
- default:
- Serial2.flush();
- }
- }
- }
And this is the Built-In Bluetooth
- #include "esp32-hal-cpu.h"
- #include "BluetoothSerial.h"
- // Verify Bluetooth is enabled
- #if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED)
- #error Bluetooth is not enabled! Please run `make menuconfig` to and enable it
- #endif
- // ESP32 header
- BluetoothSerial SerialBT;
- // LED to toggle when streaming
- const int LedLight = LED_BUILTIN;
- // LED Status (ON-OFF)
- bool LedStatus = false;
- // Start Flag to avoid re-enable timer if it is already on
- bool StartFlag = false;
- // Stop Flag to avoid re-disable timer if it is already off
- bool StopFlag = false;
- // Byte array to hold float conversion
- byte ByteData[4];
- // Sampling time
- long SamplingTimeInMilliseconds = 10;
- // Variable to hold the number of increments needed to change the LED every second
- int_fast16_t ChangeLedStatusCount = 0;
- // Sample index of EKG, PPG
- int_fast8_t SampleIndex = 0;
- // Flag to be 1 to push new sample
- volatile bool updateFlag = false;
- // Hardware timer
- hw_timer_t * timer = nullptr;
- // Lock for critical section of shared variable (updateFlag)
- portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED;
- // Time to send
- unsigned long bt = 0.0;
- // Change LED Status every 1 second = 10 ms* 100 counts
- void changeBlinkingLed()
- {
- ChangeLedStatusCount += 1;
- if (ChangeLedStatusCount == 100)
- {
- LedStatus = !(LedStatus);
- digitalWrite(LedLight, LedStatus);
- ChangeLedStatusCount = 0;
- }
- }
- // Convert float number into bytes
- void float2Bytes(byte ByteData[4], float FloatData)
- {
- memcpy(ByteData, reinterpret_cast<unsigned char*>(&FloatData), 4);
- }
- // Send float as byte array big endian
- void sendHexData(const float FloatData)
- {
- float2Bytes(ByteData, FloatData);
- SerialBT.write(ByteData[3]);
- SerialBT.write(ByteData[2]);
- SerialBT.write(ByteData[1]);
- SerialBT.write(ByteData[0]);
- }
- // Packet Header
- void sendHeader()
- {
- SerialBT.write(0xAA);
- SerialBT.write(0xBB);
- }
- // Send Payload Byte
- void sendPayload(byte NumberOfChannels)
- {
- const byte Size = NumberOfChannels * 4;
- SerialBT.write(Size);
- }
- // On Timer Event
- void IRAM_ATTR onTimer()
- {
- // Enter critical section
- portENTER_CRITICAL_ISR(&timerMux);
- // Set flag
- updateFlag = true;
- // Exit critical section
- portEXIT_CRITICAL_ISR(&timerMux);
- }
- void setup()
- {
- const uint32_t Freq = 80;
- //Set CPU clock to 240 MHz fo example
- //setCpuFrequencyMhz(Freq);
- // Set Serial2 baudrate
- Serial2.begin(115200);
- // LED as output
- pinMode(LedLight, OUTPUT);
- // Populate ESP32 bluetooth name
- SerialBT.begin("BT-ESP32"); //Bluetooth device name
- /* Use 1st timer of 4 */
- /* 1 tick takes 80 MHZ/prescaler (80) = 1us so we set the divider 80 and count up */
- timer = timerBegin(0, Freq, true);
- /* Attach onTimer function to our timer */
- timerAttachInterrupt(timer, &onTimer, true);
- /* Set alarm to call onTimer function every second 1 tick is 1us
- => 1 second is 10000us */
- /* Repeat the alarm (third parameter) */
- timerAlarmWrite(timer, 10000, true);
- }
- void loop()
- {
- if (updateFlag == true)
- {
- changeBlinkingLed();
- bt = micros();
- sendHeader();
- sendPayload(8);
- sendHexData(1.0);
- sendHexData(2.0);
- sendHexData(3.0);
- sendHexData(4.0);
- sendHexData(5.0);
- sendHexData(6.0);
- sendHexData(7.0);
- bt = micros() - bt;
- sendHexData(bt);
- SampleIndex++;
- SampleIndex = (SampleIndex > 99) ? 0 : SampleIndex;
- portENTER_CRITICAL_ISR(&timerMux);
- updateFlag = false;
- portEXIT_CRITICAL_ISR(&timerMux);
- }
- if (SerialBT.available() > 0)
- {
- const auto IncomingCommand = SerialBT.read();
- switch (IncomingCommand)
- {
- case '*':
- if (!StartFlag)
- {
- StartFlag = true;
- StopFlag = false;
- /* Start an alarm */
- timerAlarmEnable(timer);
- }
- break;
- case '#':
- if (!StopFlag)
- {
- StopFlag = true;
- StartFlag = false;
- timerAlarmDisable(timer);
- }
- break;
- default:
- SerialBT.flush();
- }
- }
- }
The problem is on HC-05, I am getting an average of 500us, and using the Built-In BT it is 1500us