This commit is contained in:
James 2024-04-23 21:16:30 +01:00
parent 28f86e8ecc
commit 7dbdf8a27b
7 changed files with 199 additions and 199 deletions

View File

@ -1,66 +1,133 @@
#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<std::string, BLERemoteService*>* 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<std::string, BLERemoteCharacteristic*>* pChars = pRemoteService->getCharacteristics();
for (auto &myChar : *pChars) {
String properties = getCharacteristicProperties(myChar.second);
Serial.print("\tCharacteristic: " + String(myChar.first.c_str()) + " | Properties: " + properties);
// Read descriptors of the characteristic
std::map<std::string, BLERemoteDescriptor*>* pDescs = myChar.second->getDescriptors();
for (auto &desc : *pDescs) {
std::string descValue = desc.second->readValue();
Serial.print(" | Descriptor: " + String(desc.first.c_str()) + " Value: " + String(descValue.c_str()));
}
Serial.println();
}
}
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();
return propDesc;
}
void loop() {
// Nothing to do here
}
/*
* 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 <BLEDevice.h> // for BLE
#include <driver/adc.h> // to read ESP battery voltage
#include <rom/rtc.h> // 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();
}
*/

View File

@ -1,133 +0,0 @@
/*
* 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 <BLEDevice.h> // for BLE
#include <driver/adc.h> // to read ESP battery voltage
#include <rom/rtc.h> // 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();
}
*/

66
test/ESPBMS.ino Normal file
View File

@ -0,0 +1,66 @@
#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<std::string, BLERemoteService*>* 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<std::string, BLERemoteCharacteristic*>* pChars = pRemoteService->getCharacteristics();
for (auto &myChar : *pChars) {
String properties = getCharacteristicProperties(myChar.second);
Serial.print("\tCharacteristic: " + String(myChar.first.c_str()) + " | Properties: " + properties);
// Read descriptors of the characteristic
std::map<std::string, BLERemoteDescriptor*>* pDescs = myChar.second->getDescriptors();
for (auto &desc : *pDescs) {
std::string descValue = desc.second->readValue();
Serial.print(" | Descriptor: " + String(desc.first.c_str()) + " Value: " + String(descValue.c_str()));
}
Serial.println();
}
}
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();
return propDesc;
}
void loop() {
// Nothing to do here
}