diff --git a/ESPBMS.ino b/ESPBMS.ino index d464072..f2cfdf6 100644 --- a/ESPBMS.ino +++ b/ESPBMS.ino @@ -1,133 +1,57 @@ -/* - * Xiaoxiang BMS to MQTT via WiFi - * by Bas Vermulst - https://github.com/BeaverUI/ESP32-BluetoothBMS2MQTT - * - * Based on original work from https://github.com/kolins-cz/Smart-BMS-Bluetooth-ESP32/blob/master/README.md - * - - === configuring === - Using the #define parameters in the CONFIGURATION section, do the following: - 1) configure WiFi via WIFI_SSID and WIFI_PASSWORD - 2) configure MQTT broker via MQTTSERVER - 3) set unique node name via NODE_NAME - 4) ensure the BMS settings are OK. You can verify the name and address using the "BLE Scanner" app on an Android phone. - - - === compiling === - 1) Add ESP-WROVER to the board manager: - - File --> Preferences, add to board manager URLs: https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json - - Then, Tools --> Board --> Board manager... --> install ESP32 package v2.0.3 or later. - - - 2) Install required libraries: - - MQTT (by Joel Gaehwiler) - Install via "Manage Libraries..." under Tools. - - 3) Configure board: - Select Tools --> Board --> "ESP32 Arduino" --> "ESP WRover module" - - 4) Connect board via USB. - - 5) Configure programming options: - Select appropriate programming port under Tools --> Port - Select correct partitioning: 1.9MB app (with OTA) or 2MB app with 2 MB SPIFFS - otherwise it won't fit - - 6) Program and go! - - */ - -// ==== CONFIGURATION ==== -// BMS -#define BMS_MAX_CELLS 15 // defines size of data types -#define BMS_POLLING_INTERVAL 10*60*1000 // data output interval (shorter = connect more often = more battery consumption from BMS) in ms - -// BLE -#define BLE_MIN_RSSI -75 // minimum signal strength before connection is attempted -#define BLE_NAME "BMS 1.1" // name of BMS -#define BLE_ADDRESS "70:e3:97:d2:b0:bb" // address of BMS - -#define BLE_SCAN_DURATION 1 // duration of scan in seconds -#define BLE_REQUEST_DELAY 500 // package request delay after connecting - make this large enough to have the connection established in ms -#define BLE_TIMEOUT 10*1000 // timeout of scan + gathering packets (too short will fail collecting all packets) in ms - -#define BLE_CALLBACK_DEBUG true // send debug messages via MQTT & serial in callbacks (handy for finding your BMS address, name, RSSI, etc) - -// watchdog timeout -#define WATCHDOG_TIMEOUT (BLE_TIMEOUT+10*1000) // go to sleep after x seconds - - -// ==== MAIN CODE ==== -#include "datatypes.h" // for brevity the BMS stuff is in this file -#include // for BLE - -#include // to read ESP battery voltage -#include // to get reset reason - - -// Init BMS -static BLEUUID serviceUUID("0000ff00-0000-1000-8000-00805f9b34fb"); //xiaoxiang bms service -static BLEUUID charUUID_rx("0000ff01-0000-1000-8000-00805f9b34fb"); //xiaoxiang bms rx id -static BLEUUID charUUID_tx("0000ff02-0000-1000-8000-00805f9b34fb"); //xiaoxiang bms tx id - -const byte cBasicInfo = 3; //datablock 3=basic info -const byte cCellInfo = 4; //datablock 4=individual cell info -packBasicInfoStruct packBasicInfo; -packCellInfoStruct packCellInfo; -unsigned long bms_last_update_time=0; -bool bms_status; -#define BLE_PACKETSRECEIVED_BEFORE_STANDBY 0b11 // packets to gather before disconnecting - -// Other stuff -float battery_voltage=0; // internal battery voltage -String debug_log_string=""; -hw_timer_t * wd_timer = NULL; - -void debug(String s){ - Serial.println(s); -} - -void setup(){ - Serial.begin(115200); -} - - -// === Main stuff ==== -void loop(){ - bleGatherPackets(); -} - -/* - mqttclient.publish(GetTopic("ip"), IPAddressString(WiFi.localIP())); - mqttclient.publish(GetTopic("free-heap"), String(ESP.getFreeHeap())); - mqttclient.publish(GetTopic("maxalloc-heap"), String(xPortGetMinimumEverFreeHeapSize())); - mqttclient.publish(GetTopic("ssid"), WiFi.SSID()); - mqttclient.publish(GetTopic("rssi"), String(WiFi.RSSI())); - - mqttclient.publish(GetTopic("reset-reason"), String(GetResetReason(0)) + String(" | ") + String(GetResetReason(1))); - - mqttclient.publish(GetTopic("runtime"), String(millis()/1000)); - mqttclient.publish(GetTopic("battery-voltage"), String(battery_voltage,2)); - - mqttclient.publish(GetTopic("bms-status"), String(bms_status)); - mqttclient.publish(GetTopic("bms-status-age"), String( (millis()-bms_last_update_time)/1000 )); - - if(bms_status){ - mqttclient.publish(GetTopic("number-of-cells"), String(packCellInfo.NumOfCells)); - mqttclient.publish(GetTopic("current"), String((float)packBasicInfo.Amps / 1000,2)); - mqttclient.publish(GetTopic("voltage"), String((float)packBasicInfo.Volts / 1000,2)); - if(packCellInfo.NumOfCells != 0){ - mqttclient.publish(GetTopic("cell-voltage"), String((float)packBasicInfo.Volts /(1000*packCellInfo.NumOfCells), 2)); - } - mqttclient.publish(GetTopic("cell-diff"), String((float)packCellInfo.CellDiff, 0)); - mqttclient.publish(GetTopic("soc"), String((float)packBasicInfo.CapacityRemainPercent,1)); - - mqttclient.publish(GetTopic("temperature-1"), String((float)packBasicInfo.Temp1 / 10,1)); - mqttclient.publish(GetTopic("temperature-2"), String((float)packBasicInfo.Temp2 / 10,1)); - } - - MqttPublishDebug(); - - mqttclient.loop(); -} - -*/ +#include "BLEDevice.h" + +void setup() { + Serial.begin(115200); + BLEDevice::init(""); // Initialize BLE device + + BLEScan* pBLEScan = BLEDevice::getScan(); // Create new scan + pBLEScan->setActiveScan(true); // Active scan uses more power, but get results faster + BLEScanResults foundDevices = pBLEScan->start(30); // Scan for 30 seconds + + Serial.println("Scanning completed"); + Serial.println("Devices found: " + String(foundDevices.getCount())); + + for (int i = 0; i < foundDevices.getCount(); i++) { + BLEAdvertisedDevice advertisedDevice = foundDevices.getDevice(i); + Serial.println("\nFound Device: " + String(advertisedDevice.toString().c_str())); + + // Now connect to the device and then discover its services and characteristics + BLEClient* pClient = BLEDevice::createClient(); + Serial.println("Connecting to: " + String(advertisedDevice.getAddress().toString().c_str())); + + if (pClient->connect(&advertisedDevice)) { + Serial.println("Connected to device!"); + // Obtain references to all services + std::map* pRemoteServices = pClient->getServices(); + for (auto &myService : *pRemoteServices) { + Serial.println("Service: " + String(myService.first.c_str())); + BLERemoteService* pRemoteService = myService.second; + + // List all characteristics of this service + std::map* pChars = pRemoteService->getCharacteristics(); + for (auto &myChar : *pChars) { + String properties = getCharacteristicProperties(myChar.second); + Serial.println("\tCharacteristic: " + String(myChar.first.c_str()) + " | Properties: " + properties); + } + } + pClient->disconnect(); + } else { + Serial.println("Failed to connect."); + } + } +} + +String getCharacteristicProperties(BLERemoteCharacteristic* pChar) { + String propDesc = ""; + if (pChar->canRead()) propDesc += "read "; + if (pChar->canWrite()) propDesc += "write "; + if (pChar->canWriteNoResponse()) propDesc += "write_no_resp "; + if (pChar->canNotify()) propDesc += "notify "; + if (pChar->canIndicate()) propDesc += "indicate "; + propDesc.trim(); // This modifies propDesc in place + return propDesc; // Return the modified string +} + +void loop() { + // Nothing to do here +} diff --git a/BLE.ino b/old/BLE.ino similarity index 100% rename from BLE.ino rename to old/BLE.ino diff --git a/BMS_process_data.ino b/old/BMS_process_data.ino similarity index 100% rename from BMS_process_data.ino rename to old/BMS_process_data.ino diff --git a/old/ESPBMS.ino b/old/ESPBMS.ino new file mode 100644 index 0000000..d464072 --- /dev/null +++ b/old/ESPBMS.ino @@ -0,0 +1,133 @@ +/* + * Xiaoxiang BMS to MQTT via WiFi + * by Bas Vermulst - https://github.com/BeaverUI/ESP32-BluetoothBMS2MQTT + * + * Based on original work from https://github.com/kolins-cz/Smart-BMS-Bluetooth-ESP32/blob/master/README.md + * + + === configuring === + Using the #define parameters in the CONFIGURATION section, do the following: + 1) configure WiFi via WIFI_SSID and WIFI_PASSWORD + 2) configure MQTT broker via MQTTSERVER + 3) set unique node name via NODE_NAME + 4) ensure the BMS settings are OK. You can verify the name and address using the "BLE Scanner" app on an Android phone. + + + === compiling === + 1) Add ESP-WROVER to the board manager: + - File --> Preferences, add to board manager URLs: https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json + - Then, Tools --> Board --> Board manager... --> install ESP32 package v2.0.3 or later. + + + 2) Install required libraries: + - MQTT (by Joel Gaehwiler) + Install via "Manage Libraries..." under Tools. + + 3) Configure board: + Select Tools --> Board --> "ESP32 Arduino" --> "ESP WRover module" + + 4) Connect board via USB. + + 5) Configure programming options: + Select appropriate programming port under Tools --> Port + Select correct partitioning: 1.9MB app (with OTA) or 2MB app with 2 MB SPIFFS - otherwise it won't fit + + 6) Program and go! + + */ + +// ==== CONFIGURATION ==== +// BMS +#define BMS_MAX_CELLS 15 // defines size of data types +#define BMS_POLLING_INTERVAL 10*60*1000 // data output interval (shorter = connect more often = more battery consumption from BMS) in ms + +// BLE +#define BLE_MIN_RSSI -75 // minimum signal strength before connection is attempted +#define BLE_NAME "BMS 1.1" // name of BMS +#define BLE_ADDRESS "70:e3:97:d2:b0:bb" // address of BMS + +#define BLE_SCAN_DURATION 1 // duration of scan in seconds +#define BLE_REQUEST_DELAY 500 // package request delay after connecting - make this large enough to have the connection established in ms +#define BLE_TIMEOUT 10*1000 // timeout of scan + gathering packets (too short will fail collecting all packets) in ms + +#define BLE_CALLBACK_DEBUG true // send debug messages via MQTT & serial in callbacks (handy for finding your BMS address, name, RSSI, etc) + +// watchdog timeout +#define WATCHDOG_TIMEOUT (BLE_TIMEOUT+10*1000) // go to sleep after x seconds + + +// ==== MAIN CODE ==== +#include "datatypes.h" // for brevity the BMS stuff is in this file +#include // for BLE + +#include // to read ESP battery voltage +#include // to get reset reason + + +// Init BMS +static BLEUUID serviceUUID("0000ff00-0000-1000-8000-00805f9b34fb"); //xiaoxiang bms service +static BLEUUID charUUID_rx("0000ff01-0000-1000-8000-00805f9b34fb"); //xiaoxiang bms rx id +static BLEUUID charUUID_tx("0000ff02-0000-1000-8000-00805f9b34fb"); //xiaoxiang bms tx id + +const byte cBasicInfo = 3; //datablock 3=basic info +const byte cCellInfo = 4; //datablock 4=individual cell info +packBasicInfoStruct packBasicInfo; +packCellInfoStruct packCellInfo; +unsigned long bms_last_update_time=0; +bool bms_status; +#define BLE_PACKETSRECEIVED_BEFORE_STANDBY 0b11 // packets to gather before disconnecting + +// Other stuff +float battery_voltage=0; // internal battery voltage +String debug_log_string=""; +hw_timer_t * wd_timer = NULL; + +void debug(String s){ + Serial.println(s); +} + +void setup(){ + Serial.begin(115200); +} + + +// === Main stuff ==== +void loop(){ + bleGatherPackets(); +} + +/* + mqttclient.publish(GetTopic("ip"), IPAddressString(WiFi.localIP())); + mqttclient.publish(GetTopic("free-heap"), String(ESP.getFreeHeap())); + mqttclient.publish(GetTopic("maxalloc-heap"), String(xPortGetMinimumEverFreeHeapSize())); + mqttclient.publish(GetTopic("ssid"), WiFi.SSID()); + mqttclient.publish(GetTopic("rssi"), String(WiFi.RSSI())); + + mqttclient.publish(GetTopic("reset-reason"), String(GetResetReason(0)) + String(" | ") + String(GetResetReason(1))); + + mqttclient.publish(GetTopic("runtime"), String(millis()/1000)); + mqttclient.publish(GetTopic("battery-voltage"), String(battery_voltage,2)); + + mqttclient.publish(GetTopic("bms-status"), String(bms_status)); + mqttclient.publish(GetTopic("bms-status-age"), String( (millis()-bms_last_update_time)/1000 )); + + if(bms_status){ + mqttclient.publish(GetTopic("number-of-cells"), String(packCellInfo.NumOfCells)); + mqttclient.publish(GetTopic("current"), String((float)packBasicInfo.Amps / 1000,2)); + mqttclient.publish(GetTopic("voltage"), String((float)packBasicInfo.Volts / 1000,2)); + if(packCellInfo.NumOfCells != 0){ + mqttclient.publish(GetTopic("cell-voltage"), String((float)packBasicInfo.Volts /(1000*packCellInfo.NumOfCells), 2)); + } + mqttclient.publish(GetTopic("cell-diff"), String((float)packCellInfo.CellDiff, 0)); + mqttclient.publish(GetTopic("soc"), String((float)packBasicInfo.CapacityRemainPercent,1)); + + mqttclient.publish(GetTopic("temperature-1"), String((float)packBasicInfo.Temp1 / 10,1)); + mqttclient.publish(GetTopic("temperature-2"), String((float)packBasicInfo.Temp2 / 10,1)); + } + + MqttPublishDebug(); + + mqttclient.loop(); +} + +*/ diff --git a/EasyFunctions.ino b/old/EasyFunctions.ino similarity index 100% rename from EasyFunctions.ino rename to old/EasyFunctions.ino diff --git a/datatypes.h b/old/datatypes.h similarity index 100% rename from datatypes.h rename to old/datatypes.h