Home | pfodApps/pfodDevices | WebStringTemplates | Java/J2EE | Unix | Torches | Superannuation | | About Us

Forward Logo (image)      

Single Board BLE to WiFi Bridge
ESP32 C3 with BLE + WiFi running together

by Matthew Ford 14th Jan 2023 (originally posted 4th June 2022)
© Forward Computing and Control Pty. Ltd. NSW Australia
All rights reserved.

ESP32 C3 with BLE and WiFi running together
in Arduino for a single board BLE to WiFi Bridge

Update 14th Jan 2023 – installing ESP32 V2.0.6 board support seems to fix the previous problems with Adafruit QT Py ESP32-C3)
Update: 28
th June 2022 – Do not purchase the Adafruit QT Py ESP32-C3 with a USB-C as it is broken, see below.


The project demonstrates using a single single ESP32-C3 board as a BLE scanner, a web page server refreshing a web page every 5secs, a Telnet server and NTP UDP time client, all running at the same time.

Update 14th Jan 2023: Installing ESP32 V2.0.6 seems to fix the problems with Adafruit QT Py ESP32-C3
The Adafruit QT Py ESP32-C3 with a USB-C connector should also work, but on testing was found to be broken. Using ESP32 board support V3.0.2, the example Sketches LITTLEFS_test.ino and SPIFFS_Test.ino both fail to run. These example run fine on the ESP32-C3 which is the same price, so purchase that one instead.

Other reasons not to use the Adafruit QT Py ESP32-C3, the USB driver does now work on Windows 7, the ESP32C3 works fine. It is tricky to reconnect the Serial Monitor to the Adafruit QT Py ESP32-C3 after programming. Also see the Adafruit forum issue.

The ESP32 Sparkfun Thing was also tested but did work successful as a single board BLE to WiFi bridge

A number of other projects use a two board BLE to WiFi bridge, Simple WiFi to Bluetooth Low Energy (BLE) Bridge, BLE Room Temperature controlled Heater with Timer Switch and BLE Low Power Indoor/Outdoor Weather Station. Those projects use an Adafruit Feather nRF52 Bluefruit LE and a Adafruit HUZZAH ESP8266 Breakout for a total cost of ~US$35 for the boards plus a USB to TTL programming cable for the HUZZAH ESP8366 (~US$10). This project looks are replacing those boards with a single ESP32C3 (~US$10, no special programming cable needed). In the case of the BLE Room Temperature controlled Heater with Timer Switch, as single ESP32C3 with NTP can replace the Power Timer ( ESP-01 and a relay module) as well as replacing the Adafruit Feather nRF52 and Adafruit HUZZAH ESP8266.

The ESP32 documents RF Coexistence between BLE and WiFi (local copy 1/06/2022 here). Although that documentation is for ESP32's in general, this project only uses the ESP32 C3 coded via the Arduino IDE V1.18.19 with the ESP32 V2.0.3 board support installed. Other setups while their own set of bug/features. The ESP32 C3 only has on core. The RF Coexistence mentions a number of ESP32 menuconfig options none of which are configurable via the Arduino IDE. The existing settings in ESP32 board support V2.0.3 were used.

Parts List

ESP32-C3 Mini Development Board (with embedded flash) ~US$9 Note: this is NOT the slightly more expensive ESP32-C3 WROOM board
5V USB supply and cable – ~US$3 to ~US$8 from various sources, e.g. Wall Adapter Power Supply - 5.1V DC 2.5A from Sparkfun. The one used in this project is 5V DC 1A Ultra-Slim Power Supply – MP3144 from Jaycar
Small Plastic box – ~US$2.50 e.g. Jaycar HB6004.
Arduino IDE and the ESP32 V2.0.3 board support via the IDE board manager. This project used ESP32 V2.0.3. Other versions will their own set of features/bugs.
This source code also needs the following libraries:-
SafeString V4.1.21+ installed via the Arduino IDE Library Manager and
Download the ESPAutoWiFiConfig.zip, library zip file and install it using the
Sketch → Include Library → Add .ZIP File menu in the Arduino IDE .

Total cost, as at June 2021, excluding shipping – ~US$15.5 to ~US$20.5.

Installing the ESP32 C3 board support and running the Bridge

Install Arduino V1.8.19 and then follow these instructions to install the ESP32 board support. Adafruit has instructions on installing usb-com drivers if you need to.

Open the Arduino IDE and select the ESP32 C3 board and the Huge (3MB) Partition scheme.

The following libraries are also needed. SafeString V4.1.21+ installed via the Arduino IDE Library Manager and download the ESPAutoWiFiConfig.zip, library zip file and install it using the Sketch → Include Library → Add .ZIP File menu in the Arduino IDE .

Unzip ESP32C3_BLE_Scanner_ServerTCP_UDP_NTP.zip to your Arduino Sketch directory and open the ESP32C3_BLE_Scanner_ServerTCP_UDP_NTP.ino sketch and program the ESP32C3 board. This sketch has DEBUG #defined and will print lots of debug info.

The ESPAutoWiFiConfig will start flashing the onboard RGB led after a few seconds and setup a private access point WiFiConfig with the password 12345678 Connect to that access point and open to configure your network's SSID and password and to choose a static IP for the web server and telnet server. See ESPAutoWiFiConfig page for details. Note: after reprogramming the ESP32C3 the board often restarts in WiFiConfig mode (led flashing). Just press the reset push button to use the configured WiFi settings (led blinks and goes out, i.e. WiFi connected)

Here is some sample debug output

12:14:11.743 -> ESP-ROM:esp32c3-api1-20210207
12:14:11.782 -> Build:Feb  7 2021
12:14:11.782 -> rst:0x1 (POWERON),boot:0xc (SPI_FAST_FLASH_BOOT)
12:14:11.782 -> SPIWP:0xee
12:14:11.782 -> mode:DIO, clock div:1
12:14:11.782 -> load:0x3fcd6100,len:0x438
12:14:11.782 -> load:0x403ce000,len:0x90c
12:14:11.782 -> load:0x403d0000,len:0x2358
12:14:11.782 -> SHA-256 comparison failed:
12:14:11.782 -> Calculated: a9753a4fc647c6545c1b919ef08db429130a48592727edca270f1e5a3da0d0a9
12:14:11.782 -> Expected: 3bf6ef2cf3b9eefcd4b3c70cc5d1ce5138292d101a5cb1d5db6fbebf081b0a19
12:14:11.782 -> Attempting to boot anyway...
12:14:11.829 -> entry 0x403ce000
12:14:11.999 -> 
12:14:11.999 -> Using ESP32_WS2812Flasher 
12:14:11.999 -> Create double reboot flag 
12:14:11.999 -> loaded config
12:14:11.999 -> ssid:FCC-Wfi
12:14:11.999 -> password:z3uxhcrhs
12:14:11.999 -> staticIP:
12:14:12.143 ->    Connecting to WiFi
12:14:13.127 -> .
12:14:13.981 -> 
12:14:13.981 -> Connected to FCC-Wfi
12:14:13.981 -> IP address:
12:14:13.981 ->  connected to 
12:14:14.023 -> ssid:FCC-Wfi
12:14:14.023 -> password:z3uxhcrhs
12:14:14.023 -> staticIP:
12:14:14.023 -> initializeNtpSupport
12:14:14.023 -> Loaded config
12:14:14.023 -> utcTime:6
12:14:14.023 -> tzStr:AEST-10AEDT-11,M10.1.0/2,M4.1.0/3
12:14:14.023 -> TZ description
12:14:14.023 -> GMT+10
12:14:14.023 ->  Daylight Saving GMT+11 starts in the
12:14:14.023 -> 1st week of Oct on Sun at 02:00
12:14:14.023 ->  Daylight Saving ends in the
12:14:14.023 -> 1st week of Apr on Sun at 03:00
12:14:14.057 -> setTZfromPOSIXstr:AEST-10AEDT-11,M10.1.0/2,M4.1.0/3
12:14:14.057 -> setTZfromPOSIXstr:AEST-10AEDT-11,M10.1.0/2,M4.1.0/3
12:14:14.057 -> /timeZoneCfg.bin config saved.
12:14:14.057 -> utcTime:6
12:14:14.057 -> tzStr:AEST-10AEDT-11,M10.1.0/2,M4.1.0/3
12:14:14.057 -> webserver started
12:14:14.057 -> Ready! Use 'telnet 23' to connect
12:14:14.159 -> Sent NTP UDP request
12:14:14.668 -> responseCounter:1
12:14:14.668 -> Unix time = 1654136056
12:14:14.668 -> ShowTimeDebug
12:14:14.668 -> 
12:14:14.668 -> localtime: isdst=0 yday=152 wday=4 year=122 mon=5 mday=2 hour=12 min=14 sec=16
12:14:14.668 -> gmtime:    isdst=0 yday=152 wday=4 year=122 mon=5 mday=2 hour=2 min=14 sec=16
12:14:14.715 -> time:      1654136056
12:14:14.715 -> timezone:  AEST-10AEDT-11,M10.1.0/2,M4.1.0/3
12:14:14.715 -> GMT+10
12:14:14.715 ->  Daylight Saving GMT+11 starts in the
12:14:14.715 -> 1st week of Oct on Sun at 02:00
12:14:14.715 ->  Daylight Saving ends in the
12:14:14.715 -> 1st week of Apr on Sun at 03:00
12:14:14.715 -> ctime:     Thu Jun  2 12:14:16 2022
12:14:14.715 -> 
12:14:16.103 -> Device name: Office Temp/RH
12:14:16.103 -> Adding Device name: Office Temp/RH
12:14:16.153 -> Device name: Garage Light
12:14:16.153 -> Adding Device name: Garage Light
12:14:16.301 -> Devices found: 2
12:14:18.132 -> Device name: Office Temp/RH
12:14:18.302 -> Devices found: 1

Here is sample web page served by the web server

You can also open a Telnet connection to port 23 and text typed into the Arduino IDE Serial Monitor will arrive at the telnet terminal and vice versa.

Comments on the Code

The ESP32 RF Coexistence docs say
ESP32 has only one 2.4 GHz ISM band RF module, which is shared by Bluetooth (BT & BLE) and Wi-Fi, so Bluetooth can’t receive or transmit data while Wi-Fi is receiving or transmitting data and vice versa. Under such circumstances, ESP32 uses the time-division multiplexing method to receive and transmit packets.
and that it is better to run the BLE and WiFi on separate cores.

The ESP32 C3 only has one core so the BLE Scanner is run in a separate thread running with the same priority as the loop() thread so neither has priority over the other. The WiFi is connected first via ESPAutoWiFiConfig and then the WiFi services set up in setUpWiFiServices(). Then the BLE scanner thread is started which initializes the BLE and starts scanning. Trying to start the BLE thread first and then setting up the WiFi services gave continual reboots.

The NTP client is a low level time client based on https://www.arduino.cc/en/Tutorial/LibraryExamples/UdpNtpClient Attempts to use the ESP32 SNTP support resulted in exceptions when the BLE stack was initialized. To this was added the tz parsing and the LittleFS support from ESP-01 Timer Switch with TZ and Daylight saving adjustment

The current code only starts a BLE Scanner. The ESP32 RF Coexistence docs suggest you can also open a BLE connection. This has not been tested as the existing projects just scan to pick up the data broadcast.


This tutorial has shown how you can run both BLE and WiFi services together on an ESP32 C3. The code size requires using the Huge (3MB) Partition scheme instead of the default 1.2MB APP and 1.5MB SPIFFS partition. The WiFi services tested were simple WebServer, simple NTP client and a Telnet Server. Only a BLE scanner was tested, although the ESP32 documentation suggests you can also make BLE connections. In principle other ESP32 boards could be used but testing on an ESP32 Sparkfun Thing was not successful.

AndroidTM is a trademark of Google Inc. For use of the Arduino name see http://arduino.cc/en/Main/FAQ

The General Purpose Android/Arduino Control App.
pfodDevice™ and pfodApp™ are trade marks of Forward Computing and Control Pty. Ltd.

Forward home page link (image)

Contact Forward Computing and Control by
©Copyright 1996-2020 Forward Computing and Control Pty. Ltd. ACN 003 669 994