syssi / esphome-jk-bms

ESPHome component to monitor and control a Jikong Battery Management System (JK-BMS) via UART-TTL or BLE
Apache License 2.0
442 stars 148 forks source link

esp 32 -- jkBMS - Bluetooth #322

Closed sralus closed 1 year ago

sralus commented 1 year ago

So I got a new JKBMS B2A20S20P

in the const char device name = "JK-B2A20S20P"; it had to be changed so that the ESP connects to the JK via bluetooth: constchar device name = "JKB2A20S20P"; so instead of -. My JK-BMS has the hardware ver V11.XW - software ver V11.26 and version V4.10.1 If I now establish a connection, only the cell data is displayed to me, everything else is no longer filled with data. {"Cell":{"0":3.409,"1":3.408,"2":3.407,"3":3.407,"4":3.406,"5":3.407,"6":3.408,"7":3.408,"8":3.408,"9":3.407,"10":3.407,"11":3.406,"12":3.407,"13":3.406,"14":3.407,"15":3.407},"Battery":{"Battery_Voltage":0.000,"Delta_Cell_Voltage":0.000,"MOS_Temp":0.000,"Battery_T1":0.000,"Battery_T2":0.000,"Battery_Power":0.000,"Charge_Current":0.000,"Percent_Remain":0,"Cycle_Count":455,"Balance_Current":0.000,"Uptime_Sec":27,"Uptime_Min":9,"Uptime_Hr":20,"Uptime_Day":185,"Charge":"off","Discharge":"off"}}

I flashed the 96=11923-JKBMS_BLE_connection to my ESP32 742 times. `#include

include

include "BLEDevice.h"

include

include

include

include

include

include

include "driver/gpio.h"

define SW_Version "1.1"

bool debug_flg = true; bool debug_flg_full_log = false;

//########### Settings beginnen #########

//OTA Setting

define OTA_Hostname "JK-BMS" // -> hier ändern wenn OTA Name anders sein soll

define OTA_Passwort "xxxxx" // -> hier ändern wenn OTA Passwort anders sein soll

// MQTT Setting const bool MQTT_ENABLE = true; const char mqtt_server = "192.168.0.69"; // -> hier die IP des MQTT Server eingeben
const int mqtt_port = 1883; // -> hier den Port einstellen für den MQTT Server const char
mqtt_username = ""; // -> hier MQTT Benutzername eintragen const char* mqtt_passwort = ""; // -> hier MQTT Passwort eingeben
String mqttname = "BMS_Publisher"; // -> hier wird der MQTT Gerätename festgelegt const int mqttpublishtime_offset = 5000; //-> hier einstellen wie oft Danten gesnedet werden sollen 1000 = jede Sekunde

//W-LAN Setting const char ssid = "LSTT"; const char password = "xxxxxxxxx";

//BMS-BLE Settings const char* Geraetename = "JK_B2A20S20P"; //JK-B2A24S20P JK-B2A24S15P JK_B2A8S20P const bool protocol_32 = false; // true for JK_B2A8S20P else false

//########### Ende der "User" Settings #########

// WebServer WebServer server(80);

static BLEUUID serviceUUID("ffe0"); // The remote service we wish to connect to. static BLEUUID charUUID("ffe1"); //ffe1 // The characteristic of the remote service we are interested in. BLEClient pClient; BLEScan pBLEScan; byte getdeviceInfo[20] = {0xaa, 0x55, 0x90, 0xeb, 0x97, 0x00, 0xdf, 0x52, 0x88, 0x67, 0x9d, 0x0a, 0x09, 0x6b, 0x9a, 0xf6, 0x70, 0x9a, 0x17, 0xfd}; // Device Infos //byte getInfo[20] = {0xaa, 0x55, 0x90, 0xeb, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}; byte getInfo[20] = {0xaa, 0x55, 0x90, 0xeb, 0x96, 0x00, 0x79, 0x62, 0x96, 0xed, 0xe3, 0xd0, 0x82, 0xa1, 0x9b, 0x5b, 0x3c, 0x9c, 0x4b, 0x5d}; //byte balancer_an[20] = {0xaa, 0x55, 0x90, 0xeb, 0x1f, 0x04, 0x01, 0x00, 0x00, 0x00, 0xd3, 0x27, 0x86, 0x3b, 0xe2, 0x12, 0x4d, 0xb0, 0xb6, 0x00};

unsigned long sendingtime = 0; unsigned long bleScantime = 0; unsigned long mqttpublishtime = 0; unsigned long newdatalasttime = 0; unsigned long ble_connection_time = 0;

const int num_bytes = 320; byte receivedBytes_main[num_bytes]; int frame = 0; bool received_start = false; bool received_start_frame = false; bool received_complete = false; bool new_data = false; byte BLE_Scan_counter = 0;

//BMS Werte float cellVoltage[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; float Average_Cell_Voltage = 0; float Delta_Cell_Voltage = 0; float Current_Balancer = 0; float Battery_Voltage = 0; float Battery_Power = 0; float Charge_Current = 0; float Battery_T1 = 0; float Battery_T2 = 0;

float MOS_Temp = 0; int Percent_Remain = 0; float Capacity_Remain = 0; float Nominal_Capacity = 0; String Cycle_Count = ""; float Capacity_Cycle = 0; uint32_t Uptime; uint8_t sec, mi, hr, days; float Balance_Curr = 0; String charge = "off"; String discharge = "off";

bool charge_over_temp_alarm = false; bool charge_under_temp_alarm = false; bool cell_under_voltage_alarm = false;

String HTML = "";

static bool doConnect = false; static bool ble_connected = false; static BLERemoteCharacteristic pRemoteCharacteristic; static BLEAdvertisedDevice myDevice;

void MQTTCallback(char topic, byte payload, unsigned int length) { String Command = "";

if(strcmp(topic, "BMS_Watchdog/parameter/debugging_aktive") == 0) { for (int i = 0; i < length; i++) { Command = Command + (char)payload[i]; }
if(Command == "true") { debug_flg = true; Serial.println("Debugging: true"); } else if(Command == "false") { debug_flg = false; Serial.println("Debugging: false"); } }

if(strcmp(topic, "BMS_Watchdog/parameter/debugging_Full_Log_aktive") == 0) { for (int i = 0; i < length; i++) { Command = Command + (char)payload[i]; }
if(Command == "true") { debug_flg_full_log = true; Serial.println("Debugging Full Log: true"); } else if(Command == "false") { debug_flg_full_log = false; Serial.println("Debugging Full Log: false"); } }

}

//MQTT WiFiClient espClient; WiFiClient webserverClient; PubSubClient client(mqtt_server, mqtt_port, MQTTCallback, espClient); long lastReconnectAttempt = 0;

static void notifyCallback(BLERemoteCharacteristic pBLERemoteCharacteristic, uint8_t pData, size_t length, bool isNotify) {

if(debug_flg_full_log) { Serial.print("Notify callback for characteristic "); Serial.print(pBLERemoteCharacteristic->getUUID().toString().c_str()); Serial.print(" of data length "); Serial.println(length); Serial.print("data: "); for (int i = 0; i < length; i++) { Serial.print(pData[i],HEX); Serial.print(", "); } Serial.println(""); } if(pData[0] == 0x55 && pData[1] == 0xAA && pData[2] == 0xEB && pData[3] == 0x90 && pData[4] == 0x02) { //Serial.println("Daten anerkannt !"); int newlen=length; if(newlen>num_bytes){newlen=num_bytes;} //Prevents writing outside the array received_start = true; received_start_frame = true; received_complete = false; frame = 0; for (int i = 0; i < newlen; i++) { receivedBytes_main[frame] = pData[i]; frame++; } }

if(received_start && !received_start_frame && !received_complete) {
  Serial.println("Daten erweitert !");

// int newlenadd = length; // Serial.println(frame); // Serial.println(length); int newlenadd=300-(frame+length); //Prevents writing outside the array // Serial.println(newlenadd); if(newlenadd>=0){newlenadd=length;} //Prevents writing outside the array if(newlenadd<0){newlenadd=300-frame;} //Prevents writing outside the array for (int i = 0; i < newlenadd; i++) { receivedBytes_main[frame] = pData[i]; frame++; }

  if(frame == 300) {
    Serial.println("New Data for Analyse Complete...");
    received_complete = true;
    received_start = false;
    new_data = true;
    BLE_Scan_counter = 0;    
  }
  if((frame > 300)) {

    Serial.println("Fehlerhafte Daten !!");     
    frame = 0;
    received_start = false;
    new_data = false;    
  }

}
//Serial.print("frame: ");
//Serial.println(frame);   
received_start_frame = false;

}

class MyClientCallback : public BLEClientCallbacks {

void onConnect(BLEClient* pclient) { }

void onDisconnect(BLEClient* pclient) { ble_connected = false; //pclient->disconnect(); Serial.println("BLE-Disconnect"); String topic = mqttname + "/BLEconnection"; client.publish(topic.c_str(),"disconnected & Rebooting"); delay(200); client.loop(); delay(200); Serial.println("BLE was Disconnected ... and no BLE reconnection possible, Reboot ESP..."); ESP.restart(); } };

/**

// Handle root url (/) void handle_root() { server.send(200, "application/json", HTML); }

void setup() { Serial.begin(115200); Serial.print("BMS Publisher V "); Serial.println(SW_Version); Serial.println("Booting");

//WIFI Setup initWiFi();

//OTA ArduinoOTA.setPort(3232); ArduinoOTA.setHostname(OTA_Hostname); ArduinoOTA.setPassword(OTA_Passwort); // Password can be set with it's md5 value as well // MD5(admin) = 21232f297a57a5a743894a0e4a801fc3 // ArduinoOTA.setPasswordHash("21232f297a57a5a743894a0e4a801fc3");
ota_call(); ArduinoOTA.begin();

//BLE Setup BLEDevice::init(""); pClient = BLEDevice::createClient(); Serial.println(" - Created client");

pBLEScan = BLEDevice::getScan(); pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks()); pBLEScan->setInterval(1349); pBLEScan->setWindow(449); pBLEScan->setActiveScan(true);

// WebServer server.on("/", handle_root); server.begin(); Serial.println("Webserver gestartet");

} // End of setup.

void loop() { ArduinoOTA.handle();

//WIFI Check if(WiFi.status() != WL_CONNECTED) { Serial.println("WIFI Connection is Lost! Try to Reconnect..."); initWiFi(); } else {

//MQTT Check if WIFI is There if (MQTT_ENABLE) { if (!client.connected()) { if ((millis() - lastReconnectAttempt) > 5000) { // reconnect nach 5 sekunden if(debug_flg) { Serial.println("MQTT Client not connected"); Serial.println("MQTT time for reconnect"); } lastReconnectAttempt = millis(); // Attempt to reconnect if (reconnect()) { lastReconnectAttempt = 0; } else{ if(debug_flg) { Serial.println("MQTT reconnect Error"); } } } } else { client.loop(); } } }

//BLE if (doConnect == true) { if(!connectToBLEServer()) { Serial.println("We have failed to connect to the server; there is nothin more we will do."); String topic = mqttname + "/BLEconnection"; if (MQTT_ENABLE) { client.publish(topic.c_str(),"BLE_Connection_error!"); } delay(500); ble_connected = false; doConnect = false; } }

if (ble_connected) {

if(received_complete) { // for (int i = 0; i < 319; i++) { // Serial.print(receivedBytes_main[i],HEX); // Serial.print(", "); // } // Serial.println(""); if(new_data) { Datenanalyse(); newdatalasttime = millis(); }

 if(mqttpublishtime == 0 || (millis() >= (mqttpublishtime + mqttpublishtime_offset))) {
   mqttpublishtime = millis();
   Data_publish();

   String topic = mqttname + "/BLEconnection";
   if (MQTT_ENABLE) {
    client.publish(topic.c_str(),"connected");
    topic = mqttname + "/status";
    client.publish(topic.c_str(),"online");
   }
 }

}

// BLE Get Device Data Trigger ... if(((millis() - sendingtime) > 500) && sendingtime != 0) { // millis() > sendingtime + sendingtimer aktive_sending && sendingtime = 0; Serial.println("gesendet!"); //aktive_sending = false; pRemoteCharacteristic->writeValue(getInfo, 20); }

}

//BLE nicht verbunden if((!ble_connected && !doConnect && (millis() - bleScantime) > 15000)) {

Serial.println("BLE -> Reconnecting " + String(BLE_Scan_counter));
String topic = mqttname + "/BLEconnection"; 
String msg = "Reconnecting_" + String(BLE_Scan_counter);
client.publish(topic.c_str(),msg.c_str());
bleScantime = millis();
pBLEScan->start(5, false);
BLE_Scan_counter++;

}

// BLE verbidnugn ist da aber es kommen seit X Sekunden keine neuen Daten ! if(!doConnect && ble_connected && (millis() >= (newdatalasttime + 60000)) && newdatalasttime != 0){ ble_connected = false; delay(200); String topic = mqttname + "/BLEconnection"; client.publish(topic.c_str(),"terminated"); Serial.println("BLE-Disconnect/terminated"); newdatalasttime = millis(); pClient->disconnect(); }

//checker das nach max 5 Minuten und keiner BLE Verbidung neu gestartet wird... if(BLE_Scan_counter > 20) { String topic = mqttname + "/BLEconnection";
client.publish(topic.c_str(),"Rebooting"); delay(200); client.loop(); delay(200); Serial.println("BLE isn´t receiving new Data form BMS... and no BLE reconnection possible, Reboot ESP..."); ESP.restart(); }

server.handleClient(); } // End of loop `

I can read out all the data via the app on my iPhone.

when I connect to the GPS port, all data is read out (use solar display for this)

Do you have any idea why this is now?

Mqtt shows: BMS_Publisher/Data/Zelle_01 3.409 BMS_Publisher/Data/Zelle_02 3.408 BMS_Publisher/Data/Zelle_03 3.407 BMS_Publisher/Data/Zelle_04 3.407 BMS_Publisher/Data/Zelle_05 3.407 BMS_Publisher/Data/Zelle_06 3.408 BMS_Publisher/Data/Zelle_07 3.407 BMS_Publisher/Data/Zelle_08 3.408 BMS_Publisher/Data/Zelle_09 3.408 BMS_Publisher/Data/Zelle_10 3.407 BMS_Publisher/Data/Zelle_11 3.407 BMS_Publisher/Data/Zelle_12 3.406 BMS_Publisher/Data/Zelle_13 3.407 BMS_Publisher/Data/Zelle_14 3.406 BMS_Publisher/Data/Zelle_15 3.406 BMS_Publisher/Data/Zelle_16 3.407 BMS_Publisher/Data/Battery_Voltage 0.000 BMS_Publisher/Data/Delta_Cell_Voltage 0.000 BMS_Publisher/Data/MOS_Temp 0.000 BMS_Publisher/Data/Battery_T1 0.000 BMS_Publisher/Data/Battery_T2 0.000 BMS_Publisher/Data/Battery_Power 0.000 BMS_Publisher/Data/Charge_Current 0.000 BMS_Publisher/Data/Percent_Remain 0 BMS_Publisher/Data/Cycle_Count 456 BMS_Publisher/Data/Balance_Current 0.000 BMS_Publisher/Uptime/Sekunde 11 BMS_Publisher/Uptime/Minuten 57 BMS_Publisher/Uptime/Stunden 1 BMS_Publisher/Uptime/Tage 185 BMS_Publisher/Data/Charge off BMS_Publisher/Data/Discharge off BMS_Publisher/BLEconnection connected BMS_Publisher/status online

I would be happy about an info Sralus

syssi commented 1 year ago

Your question is about a foreign implementation!? Let's flash the implementation from this project to your ESP32.

sralus commented 1 year ago

OK So I would like to read out my JK-BMS with the ESP32 via Bluetooth and send it to the iobroker on my Raspberry pi via MQTT. Could you tell me which file I have to flash. Kind regards

syssi commented 1 year ago

This one: https://github.com/syssi/esphome-jk-bms/blob/main/esp32-ble-example.yaml

Please change the MAC address at line 5 to the MAC address of your BMS: https://github.com/syssi/esphome-jk-bms/blob/main/esp32-ble-example.yaml#L5

sralus commented 1 year ago

i flash my esp32 with arduino ide 2.1.0. Is it possible to flash your file like this?

syssi commented 1 year ago

The Arduino IDE isn't an option here. You have to use ESPHome to flash your ESP. See https://esphome.io/guides/installing_esphome.html