ESP32 DOIT Dev Kit Built-in bluetooth vs HC-05 time to send packets

wbadry
Posts: 4
Joined: Mon Dec 14, 2020 8:23 pm

ESP32 DOIT Dev Kit Built-in bluetooth vs HC-05 time to send packets

Postby wbadry » Wed Jan 20, 2021 3:28 pm

Hello,
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.
  1.  
  2.  
  3. // LED to toggle when streaming
  4. const int LedLight = LED_BUILTIN;
  5.  
  6. // LED Status (ON-OFF)
  7. bool LedStatus = false;
  8.  
  9. // Start Flag to avoid re-enable timer if it is already on
  10. bool StartFlag = false;
  11.  
  12. // Stop Flag to avoid re-disable timer if it is already off
  13. bool StopFlag = false;
  14.  
  15. // Byte array to hold float conversion
  16. byte ByteData[4];
  17.  
  18. // Sampling time
  19. long SamplingTimeInMilliseconds = 10;
  20.  
  21. // Variable to hold the number of increments needed to change the LED every second
  22. int_fast16_t  ChangeLedStatusCount = 0;
  23.  
  24. // Sample index of EKG, PPG
  25. int_fast8_t SampleIndex = 0;
  26.  
  27. // Flag to be 1 to push new sample
  28. volatile bool updateFlag = false;
  29.  
  30. // Hardware timer
  31. hw_timer_t * timer = nullptr;
  32.  
  33. // Lock for critical section of shared variable (updateFlag)
  34. portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED;
  35.  
  36. unsigned long tb = 0;
  37.  
  38. // Change LED Status every 1 second = 10 ms* 100 counts
  39. void changeBlinkingLed()
  40. {
  41.   ChangeLedStatusCount += 1;
  42.   if (ChangeLedStatusCount == 100)
  43.   {
  44.     LedStatus = !(LedStatus);
  45.     digitalWrite(LedLight, LedStatus);
  46.     ChangeLedStatusCount = 0;
  47.   }
  48. }
  49.  
  50. // Convert float number into bytes
  51. void float2Bytes(byte ByteData[4], float FloatData)
  52. {
  53.   memcpy(ByteData, reinterpret_cast<unsigned char*>(&FloatData), 4);
  54. }
  55.  
  56. // Send float as byte array big endian
  57. void sendHexData(const float FloatData)
  58. {
  59.   float2Bytes(ByteData, FloatData);
  60.   Serial2.write(ByteData[3]);
  61.   Serial2.write(ByteData[2]);
  62.   Serial2.write(ByteData[1]);
  63.   Serial2.write(ByteData[0]);
  64. }
  65.  
  66. // Packet Header
  67. void sendHeader()
  68. {
  69.   Serial2.write(0xAA);
  70.   Serial2.write(0xBB);
  71. }
  72.  
  73. // Send Payload Byte
  74. void sendPayload(byte NumberOfChannels)
  75. {
  76.   const byte Size = NumberOfChannels * 4;
  77.   Serial2.write(Size);
  78. }
  79.  
  80.  
  81. // On Timer Event
  82. void IRAM_ATTR onTimer()
  83. {
  84.   // Enter critical section
  85.   portENTER_CRITICAL_ISR(&timerMux);
  86.  
  87.   // Set flag
  88.   updateFlag = true;
  89.  
  90.   // Exit critical section
  91.   portEXIT_CRITICAL_ISR(&timerMux);
  92. }
  93.  
  94. void setup()
  95. {
  96.     const uint32_t Freq = 80;
  97.     //Set CPU clock to 240 MHz fo example
  98.     setCpuFrequencyMhz(Freq);
  99.  
  100.     // Set Serial2 baudrate
  101.     Serial2.begin(115200);
  102.  
  103.     // LED as output
  104.     pinMode(LedLight, OUTPUT);
  105.  
  106.     /* Use 1st timer of 4 */
  107.     /* 1 tick takes 80 MHZ/prescaler (80) = 1us so we set the divider 80 and count up */
  108.     timer = timerBegin(0, Freq, true);
  109.  
  110.     /* Attach onTimer function to our timer */
  111.     timerAttachInterrupt(timer, &onTimer, true);
  112.  
  113.     /* Set alarm to call onTimer function every second 1 tick is 1us
  114.       => 1 second is 10000us */
  115.     /* Repeat the alarm (third parameter) */
  116.     timerAlarmWrite(timer, 10000, true);
  117. }
  118.  
  119.  
  120. void loop()
  121. {
  122.     if (updateFlag == true)
  123.     {
  124.         changeBlinkingLed();
  125.  
  126.         tb = micros();
  127.         sendHeader();
  128.         sendPayload(8);
  129.         sendHexData(1.0);
  130.         sendHexData(2.0);
  131.         sendHexData(3.0);
  132.         sendHexData(4.0);
  133.         sendHexData(5.0);
  134.         sendHexData(6.0);
  135.         sendHexData(7.0);
  136.         tb = micros() - tb;
  137.         sendHexData(tb);
  138.        
  139.         SampleIndex++;
  140.         SampleIndex = (SampleIndex > 99) ? 0 : SampleIndex;
  141.  
  142.         portENTER_CRITICAL_ISR(&timerMux);
  143.         updateFlag = false;
  144.         portEXIT_CRITICAL_ISR(&timerMux);
  145.     }
  146.     if (Serial2.available() > 0)
  147.     {
  148.         const auto IncomingCommand = Serial2.read();
  149.         switch (IncomingCommand)
  150.         {
  151.         case '*':
  152.             if (!StartFlag)
  153.             {
  154.                 StartFlag = true;
  155.                 StopFlag = false;
  156.                 /* Start an alarm */
  157.                 timerAlarmEnable(timer);
  158.             }
  159.             break;
  160.         case '#':
  161.             if (!StopFlag)
  162.             {
  163.                 StopFlag = true;
  164.                 StartFlag = false;
  165.                 timerAlarmDisable(timer);
  166.             }
  167.             break;
  168.         default:
  169.             Serial2.flush();
  170.         }
  171.     }
  172. }

And this is the Built-In Bluetooth
  1. #include "esp32-hal-cpu.h"
  2. #include "BluetoothSerial.h"
  3.  
  4. // Verify Bluetooth is enabled
  5. #if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED)
  6. #error Bluetooth is not enabled! Please run `make menuconfig` to and enable it
  7. #endif
  8.  
  9. // ESP32 header
  10. BluetoothSerial SerialBT;
  11.  
  12. // LED to toggle when streaming
  13. const int LedLight = LED_BUILTIN;
  14.  
  15. // LED Status (ON-OFF)
  16. bool LedStatus = false;
  17.  
  18. // Start Flag to avoid re-enable timer if it is already on
  19. bool StartFlag = false;
  20.  
  21. // Stop Flag to avoid re-disable timer if it is already off
  22. bool StopFlag = false;
  23.  
  24. // Byte array to hold float conversion
  25. byte ByteData[4];
  26.  
  27. // Sampling time
  28. long SamplingTimeInMilliseconds = 10;
  29.  
  30. // Variable to hold the number of increments needed to change the LED every second
  31. int_fast16_t  ChangeLedStatusCount = 0;
  32.  
  33. // Sample index of EKG, PPG
  34. int_fast8_t SampleIndex = 0;
  35.  
  36. // Flag to be 1 to push new sample
  37. volatile bool updateFlag = false;
  38.  
  39. // Hardware timer
  40. hw_timer_t * timer = nullptr;
  41.  
  42. // Lock for critical section of shared variable (updateFlag)
  43. portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED;
  44.  
  45. // Time to send
  46. unsigned long bt = 0.0;
  47.  
  48. // Change LED Status every 1 second = 10 ms* 100 counts
  49. void changeBlinkingLed()
  50. {
  51.   ChangeLedStatusCount += 1;
  52.   if (ChangeLedStatusCount == 100)
  53.   {
  54.     LedStatus = !(LedStatus);
  55.     digitalWrite(LedLight, LedStatus);
  56.     ChangeLedStatusCount = 0;
  57.   }
  58. }
  59.  
  60. // Convert float number into bytes
  61. void float2Bytes(byte ByteData[4], float FloatData)
  62. {
  63.   memcpy(ByteData, reinterpret_cast<unsigned char*>(&FloatData), 4);
  64. }
  65.  
  66. // Send float as byte array big endian
  67. void sendHexData(const float FloatData)
  68. {
  69.   float2Bytes(ByteData, FloatData);
  70.   SerialBT.write(ByteData[3]);
  71.   SerialBT.write(ByteData[2]);
  72.   SerialBT.write(ByteData[1]);
  73.   SerialBT.write(ByteData[0]);
  74. }
  75.  
  76. // Packet Header
  77. void sendHeader()
  78. {
  79.     SerialBT.write(0xAA);
  80.     SerialBT.write(0xBB);
  81. }
  82.  
  83. // Send Payload Byte
  84. void sendPayload(byte NumberOfChannels)
  85. {
  86.   const byte Size = NumberOfChannels * 4;
  87.   SerialBT.write(Size);
  88. }
  89.  
  90. // On Timer Event
  91. void IRAM_ATTR onTimer()
  92. {
  93.   // Enter critical section
  94.   portENTER_CRITICAL_ISR(&timerMux);
  95.  
  96.   // Set flag
  97.   updateFlag = true;
  98.  
  99.   // Exit critical section
  100.   portEXIT_CRITICAL_ISR(&timerMux);
  101. }
  102.  
  103. void setup()
  104. {
  105.     const uint32_t Freq = 80;
  106.     //Set CPU clock to 240 MHz fo example
  107.     //setCpuFrequencyMhz(Freq);
  108.  
  109.     // Set Serial2 baudrate
  110.     Serial2.begin(115200);
  111.  
  112.     // LED as output
  113.     pinMode(LedLight, OUTPUT);
  114.  
  115.     // Populate ESP32 bluetooth name
  116.     SerialBT.begin("BT-ESP32"); //Bluetooth device name
  117.  
  118.     /* Use 1st timer of 4 */
  119.     /* 1 tick takes 80 MHZ/prescaler (80) = 1us so we set the divider 80 and count up */
  120.     timer = timerBegin(0, Freq, true);
  121.  
  122.     /* Attach onTimer function to our timer */
  123.     timerAttachInterrupt(timer, &onTimer, true);
  124.  
  125.     /* Set alarm to call onTimer function every second 1 tick is 1us
  126.       => 1 second is 10000us */
  127.     /* Repeat the alarm (third parameter) */
  128.     timerAlarmWrite(timer, 10000, true);
  129. }
  130.  
  131.  
  132. void loop()
  133. {
  134.     if (updateFlag == true)
  135.     {
  136.         changeBlinkingLed();
  137.         bt = micros();
  138.        
  139.         sendHeader();
  140.         sendPayload(8);
  141.         sendHexData(1.0);
  142.         sendHexData(2.0);
  143.         sendHexData(3.0);
  144.         sendHexData(4.0);
  145.         sendHexData(5.0);
  146.         sendHexData(6.0);
  147.         sendHexData(7.0);
  148.         bt = micros() - bt;
  149.         sendHexData(bt);
  150.  
  151.         SampleIndex++;
  152.         SampleIndex = (SampleIndex > 99) ? 0 : SampleIndex;
  153.  
  154.         portENTER_CRITICAL_ISR(&timerMux);
  155.         updateFlag = false;
  156.         portEXIT_CRITICAL_ISR(&timerMux);
  157.     }
  158.     if (SerialBT.available() > 0)
  159.     {
  160.         const auto IncomingCommand = SerialBT.read();
  161.         switch (IncomingCommand)
  162.         {
  163.         case '*':
  164.             if (!StartFlag)
  165.             {
  166.                 StartFlag = true;
  167.                 StopFlag = false;
  168.                 /* Start an alarm */
  169.                 timerAlarmEnable(timer);
  170.             }
  171.             break;
  172.         case '#':
  173.             if (!StopFlag)
  174.             {
  175.                 StopFlag = true;
  176.                 StartFlag = false;
  177.                 timerAlarmDisable(timer);
  178.             }
  179.             break;
  180.         default:
  181.             SerialBT.flush();
  182.         }
  183.     }
  184. }

The problem is on HC-05, I am getting an average of 500us, and using the Built-In BT it is 1500us

Who is online

Users browsing this forum: Google [Bot] and 135 guests