diff --git a/README.md b/README.md index 8cee72a..438092d 100644 --- a/README.md +++ b/README.md @@ -2,44 +2,47 @@ ![A picture of a cat](/assets/_MG_6227.JPG) -VescBLEBridge is a project that lets you add Bluetooth connectivity to your Vesc Controller for only 3€. It utilizes the ESP32 C3 microcontroller as a cost-effective BLE (Bluetooth Low Energy) module. It allows seamless communication between your Vesc controllers and the Vesc Tool App. +VescBLEBridge is a project that lets you add Bluetooth connectivity to your Vesc Controller for only 3€. It utilizes cheap, readily available microcontrollers like the ESP32-C3 and ESP32-C6 as cost-effective BLE (Bluetooth Low Energy) modules. It allows seamless communication between your VESC controllers and the official Vesc Tool App. ## Features -- **Compact Design:** The ESP32 C3's small form factor makes it an ideal choice for applications where space is a constraint. - -- **Cost-Effective:** Utilizing the ESP32 C3 as a BLE module provides a budget-friendly alternative to an NRF module for integrating Bluetooth connectivity into Vesc controllers. - -- **User-Friendly:** VescBLEBridge is designed to be easy to use, with straightforward setup and configuration. Prebuild versions with flashed firmware and soldered connectors are also planned. +- **Compact Design:** The small form factor of ESP32 dev boards makes them an ideal choice for applications where space is a constraint (skateboards, e-bikes, e-SUPs). +- **Cost-Effective:** Utilizing an ESP32 as a BLE module provides a budget-friendly alternative to an NRF module for integrating Bluetooth connectivity. +- **Multi-Board Support:** Fully supports both the generic ESP32-C3 and the ultra-compact Seeed Studio XIAO ESP32-C6 out of the box. +- **User-Friendly:** Designed to be easy to use with straightforward setup and configuration via PlatformIO. ## Getting Started -### Hardware Setup: +### Hardware Setup **What you need:** -- [ESP32 C3 Dev Board](https://de.aliexpress.com/item/1005005967641936.html) -- Some Wires -- Fitting connector for your Vesc Uart port (Most likely JST-PH2.0) -- USB C Cable +- An ESP32 Dev Board (e.g., [ESP32-C3](https://de.aliexpress.com/item/1005005967641936.html) or Seeed XIAO ESP32-C6) +- Some wires +- Fitting connector for your VESC UART port (Most likely JST-PH2.0) +- USB-C Cable -Connect the ESP32 C3 to your Vesc controller following the table below. +Connect the ESP32 to your VESC controller following the table below based on which board you are using. *(Remember: TX goes to RX, and RX goes to TX!)* -| ESP32 C3 || VESC | -| ----------- |-| -------------| -| 5V |->| 5V | -| GND |->| GND | -| 20 |->| RX | -| 21 |->| TX | +| VESC | ESP32-C3 (Generic) | ESP32-C6 (Seeed XIAO) | +| :--- | :--- | :--- | +| **5V** | 5V | 5V | +| **GND** | GND | GND | +| **RX** | TX (Pin 21) | TX (Pin D9) | +| **TX** | RX (Pin 20) | RX (Pin D10) | -If it doesnt work you can try swapping rx and tx pins cause they are swapped on some vesc controllers. +*Note: If it doesn't work, try swapping the RX and TX pins, as the labeling convention can vary on some VESC controllers.* -### Flashing Firmware: -To flash the firmware to the esp you need the following prerequisites: +### Flashing Firmware +To flash the firmware to the ESP, you need the following prerequisites: - [Visual Studio Code](https://code.visualstudio.com/) -- [PlattformIO IDE](https://marketplace.visualstudio.com/items?itemName=platformio.platformio-ide) extension for VSCode +- [PlatformIO IDE](https://marketplace.visualstudio.com/items?itemName=platformio.platformio-ide) extension for VSCode -Once you have VSCode and its PlattformIO extension installed, you need to open this git repo in VSCode. Then connect the esp32 to your computer and hit upload. +Once you have VSCode and its PlatformIO extension installed: +1. Open this git repo folder in VSCode. +2. Connect the ESP32 to your computer via USB. +3. PlatformIO is configured with multiple environments. Select your target board (`esp32-c3-devkitm-1` or `seeed_xiao_esp32c6`) from the project tasks menu. +4. Hit **Upload**. -If you have trouble you can read the official [PlattformIO docs](https://docs.platformio.org/en/latest/integration/ide/vscode.html#ide-vscode) +If you have trouble, you can read the official [PlatformIO docs](https://docs.platformio.org/en/latest/integration/ide/vscode.html#ide-vscode). ## Contributing @@ -47,6 +50,6 @@ We welcome contributions from the community! If you have ideas for improvements, ## Support -For any questions or issues, feel free open an issue. +For any questions or issues, feel free to open an issue. -Happy riding! +Happy riding! \ No newline at end of file diff --git a/platformio.ini b/platformio.ini index 9678c5f..2c52ea7 100644 --- a/platformio.ini +++ b/platformio.ini @@ -8,12 +8,24 @@ ; Please visit documentation for the other options and examples ; https://docs.platformio.org/page/projectconf.html +; Original C3 Environment (Upgraded to NimBLE v2) [env:esp32-c3-devkitm-1] platform = espressif32 board = esp32-c3-devkitm-1 framework = arduino build_flags = - -DARDUINO_USB_MODE=1 - -DARDUINO_USB_CDC_ON_BOOT=1 + -DARDUINO_USB_MODE=1 + -DARDUINO_USB_CDC_ON_BOOT=1 monitor_speed = 115200 -lib_deps = h2zero/NimBLE-Arduino@^1.4.1 +lib_deps = h2zero/NimBLE-Arduino@^2.0.0 + +; seeed_xiao_esp32c6 Environment (Upgraded to NimBLE v2) +[env:seeed_xiao_esp32c6] +platform = https://github.com/pioarduino/platform-espressif32/releases/download/stable/platform-espressif32.zip +board = seeed_xiao_esp32c6 +framework = arduino +build_flags = + -DARDUINO_USB_MODE=1 + -DARDUINO_USB_CDC_ON_BOOT=1 +monitor_speed = 115200 +lib_deps = h2zero/NimBLE-Arduino@^2.0.0 \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index d3c0c05..5bd1a1d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -20,28 +20,37 @@ uint8_t txValue = 0; #define VESC_CHARACTERISTIC_UUID_RX "6E400002-B5A3-F393-E0A9-E50E24DCCA9E" #define VESC_CHARACTERISTIC_UUID_TX "6E400003-B5A3-F393-E0A9-E50E24DCCA9E" +#define LOG_TAG_BLESERVER "BleServer" + + +// Detect if the board is the Seeed XIAO C6 +#if defined(ARDUINO_SEEED_XIAO_ESP32C6) + #define VESC_RX_PIN D10 + #define VESC_TX_PIN D9 +// Otherwise, default to the original C3 pins +#else + #define VESC_RX_PIN 20 + #define VESC_TX_PIN 21 +#endif + /** None of these are required as they will be handled by the library with defaults. ** ** Remove as you see fit for your needs */ -class MyServerCallbacks : public BLEServerCallbacks -{ - void onConnect(NimBLEServer *pServer, ble_gap_conn_desc *desc) - { - ESP_LOGI(LOG_TAG_BLESERVER, "Client connected: %s", NimBLEAddress(desc->peer_ota_addr).toString().c_str()); +class MyServerCallbacks : public NimBLEServerCallbacks { + void onConnect(NimBLEServer *pServer, NimBLEConnInfo& connInfo) override { + ESP_LOGI(LOG_TAG_BLESERVER, "Client connected: %s", connInfo.getAddress().toString().c_str()); ESP_LOGI(LOG_TAG_BLESERVER, "Multi-connect support: start advertising"); deviceConnected = true; NimBLEDevice::startAdvertising(); } - void onDisconnect(NimBLEServer *pServer) - { + void onDisconnect(NimBLEServer *pServer, NimBLEConnInfo& connInfo, int reason) override { ESP_LOGI(LOG_TAG_BLESERVER, "Client disconnected - start advertising"); deviceConnected = false; NimBLEDevice::startAdvertising(); } - void onMTUChange(uint16_t MTU, ble_gap_conn_desc *desc) - { - ESP_LOGI(LOG_TAG_BLESERVER, "MTU changed - new size %d, peer %s", MTU, NimBLEAddress(desc->peer_ota_addr).toString().c_str()); + void onMTUChange(uint16_t MTU, NimBLEConnInfo& connInfo) override { + ESP_LOGI(LOG_TAG_BLESERVER, "MTU changed - new size %d, peer %s", MTU, connInfo.getAddress().toString().c_str()); MTU_SIZE = MTU; PACKET_SIZE = MTU_SIZE - 3; } @@ -63,19 +72,14 @@ void dumpBuffer(std::string header, std::string buffer) ESP_LOGD(LOG_TAG_BLESERVER, "%s", tmpbuf); } -class MyCallbacks : public BLECharacteristicCallbacks -{ - void onWrite(BLECharacteristic *pCharacteristic) - { +class MyCallbacks : public NimBLECharacteristicCallbacks { + void onWrite(NimBLECharacteristic *pCharacteristic, NimBLEConnInfo& connInfo) override { ESP_LOGD(LOG_TAG_BLESERVER, "onWrite to characteristics: %s", pCharacteristic->getUUID().toString().c_str()); std::string rxValue = pCharacteristic->getValue(); - if (rxValue.length() > 0) - { - if (pCharacteristic->getUUID().equals(pCharacteristicVescRx->getUUID())) - { + if (rxValue.length() > 0) { + if (pCharacteristic->getUUID().equals(pCharacteristicVescRx->getUUID())) { dumpBuffer("BLE/UART => VESC: ", rxValue); - for (int i = 0; i < rxValue.length(); i++) - { + for (int i = 0; i < rxValue.length(); i++) { Serial1.write(rxValue[i]); } } @@ -86,7 +90,7 @@ class MyCallbacks : public BLECharacteristicCallbacks void setup() { Serial.begin(115200); - Serial1.begin(115200, SERIAL_8N1, 20, 21); // RX=20, TX=21 + Serial1.begin(115200, SERIAL_8N1, VESC_RX_PIN, VESC_TX_PIN); // Create the BLE Device NimBLEDevice::init("VescBLEBridge"); @@ -95,8 +99,10 @@ void setup() // Create the BLE Server pServer = NimBLEDevice::createServer(); pServer->setCallbacks(new MyServerCallbacks()); - auto pSecurity = new NimBLESecurity(); - pSecurity->setAuthenticationMode(ESP_LE_AUTH_BOND); + //auto pSecurity = new NimBLESecurity(); + //pSecurity->setAuthenticationMode(ESP_LE_AUTH_BOND); + + NimBLEDevice::setSecurityAuth(true, false, false); // Enable bonding // Create the BLE Service BLEService *pService = pServer->createService(VESC_SERVICE_UUID); @@ -115,15 +121,10 @@ void setup() pCharacteristicVescRx->setCallbacks(new MyCallbacks()); - // Start the VESC service - pService->start(); // Start advertising NimBLEAdvertising *pAdvertising = NimBLEDevice::getAdvertising(); pAdvertising->addServiceUUID(VESC_SERVICE_UUID); - // pAdvertising->setAppearance(0x00); - // pAdvertising->setScanResponse(true); - // pAdvertising->setMinPreferred(0x0); // set value to 0x00 to not advertise this parameter pAdvertising->start(); ESP_LOGI(LOG_TAG_BLESERVER, "waiting a client connection to notify...");