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.
Code: HC_05.ino Select all
// 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
Code: Built_In_ESP.c Select all
#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