VCP(Virtual COM Port) to Bluetooth bridge for ESP-IDF.
ESP-IDF supports VCP hosts.
VCP hosts can communicate with VCP devices using the USB port.
Representative VCP devices include Arduino Uno and Arduino Mega, which have a UART-USB conversion chip.
I based it on this.
This project uses the following components.
Other UART-USB converter chips are not supported.
- https://components.espressif.com/components/espressif/usb_host_ch34x_vcp
- https://components.espressif.com/components/espressif/usb_host_cp210x_vcp
- https://components.espressif.com/components/espressif/usb_host_ftdi_vcp
ESP-IDF can use either the ESP-Bluedroid host stack or the ESP-NimBLE host stack.
The differences between the two are detailed here.
This project uses the ESP-NimBLE host stack.
ESP-IDF V5.0 or later.
ESP-IDF V4.4 release branch reached EOL in July 2024.
This project only works with ESP32S3.
The ESP32S3 has both USB and BLE capabilities.
The ESP32S2 also has USB capabilities, but does not have BLE capabilities.
USB connectors are available from AliExpress or eBay.
I used it by incorporating it into a Universal PCB.
We can buy this breakout on Ebay or AliExpress.
git clone https://github.com/nopnop2002/esp-idf-vcp2ble
cd esp-idf-vcp2ble
idf.py set-target esp32s3
idf.py menuconfig
idf.py flash
VCP communication stop bits. 0: 1 stopbit, 1: 1.5 stopbits, 2: 2 stopbits
VCP communication parity. 0: None, 1: Odd, 2: Even, 3: Mark, 4: Space
You can use any AtMega microcontroller that has a USB port.
unsigned long lastMillis = 0;
void setup() {
Serial.begin(115200);
}
void loop() {
while (Serial.available()) {
String command = Serial.readStringUntil('\n');
Serial.println(command);
}
if(lastMillis + 1000 <= millis()){
Serial.print("Hello World ");
Serial.println(millis());
lastMillis += 1000;
}
delay(1);
}
Strings from Arduino to ESP32 are terminated with CR(0x0d)+LF(0x0a).
I (1482) VCP: Receiving data through CdcAcmDevice
I (1482) VCP: 0x3fcba0a8 48 65 6c 6c 6f 20 57 6f 72 6c 64 20 36 36 30 30 |Hello World 6600|
I (1492) VCP: 0x3fcba0b8 30 0d 0a |0..|
The Arduino sketch inputs data with LF as the terminator.
So strings from the ESP32 to the Arduino must be terminated with LF (0x0a).
If the string output from the ESP32 to the Arduino is not terminated with LF (0x0a), the Arduino sketch will complete the input with a timeout.
The default input timeout for Arduino sketches is 1000 milliseconds.
The ESP32 SPP driver always sends data to the application with CR+LF as the termination character.
This project changes the termination character from CR+LF to LF and sends the data to Arduino.
The Arduino sketch will echo back the string it reads.
I (78212) VCP: Sending data through CdcAcmDevice
I (78222) VCP: 0x3fcb7930 61 62 63 64 65 66 67 0a |abcdefg.|
I (78232) VCP: Receiving data through CdcAcmDevice
I (78232) VCP: 0x3fcba0a8 61 62 63 64 65 66 67 0d 0a |abcdefg..|
Arduino Uno connects via USB connector.
The USB port on the ESP32S3 development board does not function as a USB-HOST.
+---------+ +-------------+ +-----------+
|ESP BOARD|==|USB CONNECTOR|==|Arduino Uno|
+---------+ +-------------+ +-----------+
ESP BOARD USB CONNECTOR (type A)
+--+
5V -------------> | || VCC
[GPIO19] -------------> | || D-
[GPIO20] -------------> | || D+
GND -------------> | || GND
+--+
I used this app.
-
pair with ESP_NIMBLE_SERVER
-
Launch the app and select device
Menu->Devices->Bluetooth LE -
Concurrent connection
Unlike ESP-Bluedroid host stack, ESP-NimBLE host stack allows concurrent connections.
The maximum number of simultaneous connections is specified here.
This might work, but I don't have iOS so I don't know.