In this project we connect a ESP32 wroom module to the UART connection from a Daly BMS, With Oled Display, and connection to DOMOTICZ !!!
Here Some pictures from the data we get from the BMS !
Total Cell Voltage, SOC, Amps, Highest and Lowest Cell voltage, Diff in cel voltage.
This is the simple schematic, Why i use an ESP32 !!! This module has 2 full serial ports, an Wemos D1 or node MCU only have 1 and a halve Uart Serial port !
The first port i use for connection to my PC for the serial monitor, and with the second i made a connection to the Daly BMS
The Lib you need in IDE arduino https://github.com/maland16/daly-bms-uart
New schematic you can use this with the usb connector from the Bluetooth module !
Also change the code, display and data will be sent to Domoticz Als add the Power value to the display and also sent hsi to domoticz
#include <daly-bms-uart.h> // This is where the library gets pulled in
#include <U8g2lib.h> // Library for display
#include <Wire.h> // i2c bus for display
#include <WiFi.h>
#include <WiFiMulti.h>
#include <HTTPClient.h>
#include <WiFiClient.h>
// WiFi settings van je eigen netwerk
#define wifi_ssid "Tenda_Spike"
#define wifi_password "johanveerle22"
const int buttonPin = 34; // Button to switch between screens !
// variables will change:
int buttonState = 0; // variable for reading the pushbutton status
// HTTP Domoticz settings
const char* host = "192.168.1.19";
const int port = 8080;
HTTPClient http;
float volts = 0;
float amps = 0;
float percentage = 0;
float minCellVoltage = 0;
float maxCellVoltage = 0;
uint8_t maxCellNumber = 0;
uint8_t minCellNumber = 0;
//By using a wroom you have 2 uart ports, you can't use an wemos D1
//or other esp 8266 board because the only have 1 and a half uart port
// Constructing the bms driver and passing in the Serial interface (Wroom 32 D16 and D17 for UART 2)
Daly_BMS_UART bms(Serial2);
//U8G2_SSD1306_128X64_NONAME_1_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
U8G2_SH1106_128X64_NONAME_1_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
void setup() {
// This is needed to print stuff to the serial monitor
Serial.begin(115200);
pinMode(buttonPin, INPUT);
u8g2.begin(); // start display
setup_wifi(); // Start Wifi
bms.Init(); // Start the BMS
u8g2.enableUTF8Print();
// By using this we just can use some print commando's to the display
// same as serial print, otherwise you got some problems with float and integers
}
void loop() {
// Grab those values from the BMS
bms.getPackMeasurements(volts, amps, percentage);
//just testing for the program vithout connection to bms
//amps=20;
//percentage=100;
// And print them out!
Serial.printf("V: %4.1f, I: %4.1f, \%:%4.1f\n",volts, amps, percentage);
Serial.println(buttonState); // The Button is used for changing the diplay status
bms.getMinMaxCellVoltage(minCellVoltage, minCellNumber, maxCellVoltage, maxCellNumber);
Serial.printf("Highest Cell Voltage: Cell #%d with voltage %4.3f\n",maxCellNumber,maxCellVoltage);
Serial.printf("Lowest Cell Voltage: Cell #%d with voltage %4.3f\n",minCellNumber,minCellVoltage);
buttonState = digitalRead(buttonPin);
u8g2.setDisplayRotation(U8G2_R0);
u8g2.setFlipMode(0);
//Scre
if (buttonState == LOW){
u8g2.firstPage();
do {
u8g2.setFont(u8g2_font_6x12_tr);
u8g2.setFont(u8g2_font_luBS18_tf);
u8g2.setCursor(0, 20);
u8g2.print(percentage);
u8g2.print(" %");
u8g2.setFont(u8g2_font_helvB12_tf);
u8g2.drawStr(4,44,"U: ");
u8g2.setCursor(30, 44);
u8g2.print(volts);
u8g2.setCursor(100, 44);
u8g2.print(" V");
u8g2.drawStr(7,60,"I :");
u8g2.setCursor(30, 60);
u8g2.print(amps);
u8g2.setCursor(100, 60);
u8g2.println(" A");
} while ( u8g2.nextPage() );
//delay(1000);
}
//Screen 2
if (buttonState == HIGH){
u8g2.firstPage();
do {
u8g2.setFont(u8g2_font_6x12_tr);
u8g2.setCursor(0, 12);
u8g2.print("SOC: ");
u8g2.print(percentage);
u8g2.print(" %");
u8g2.drawStr(0,22,"U: ");
u8g2.setCursor(30, 22);
//u8g2.print("U: ");
u8g2.print(volts);
u8g2.print(" V");
u8g2.drawStr(0,30,"I :");
u8g2.setCursor(30, 30);
u8g2.print(amps);
u8g2.println(" A");
u8g2.setFont(u8g2_font_6x12_tr);
u8g2.drawStr(4,38,"min");
u8g2.setCursor(30, 38);
u8g2.print(minCellVoltage);
u8g2.drawStr(4,48,"max");
u8g2.setCursor(30, 48);
u8g2.print(maxCellVoltage);
u8g2.drawStr(70,38,"cell");
u8g2.setCursor(100, 38);
u8g2.print(minCellNumber);
u8g2.drawStr(70,48,"cell");
u8g2.setCursor(100, 48);
u8g2.print(maxCellNumber);
u8g2.drawStr(4,58,"Dif");
u8g2.setCursor(30, 58);
u8g2.print(maxCellVoltage-minCellVoltage);
u8g2.drawStr(70,12,"Power:");
u8g2.setCursor(70, 22);
u8g2.print(amps*volts);
u8g2.setFont(u8g2_font_helvB12_tf);
} while ( u8g2.nextPage() );
}
setvar(); // variable zenden naar domotics
delay(1000);
}
//Connect to wifi
void setup_wifi()
{
delay(10);
u8g2.firstPage();
do {
//u8g2.setDisplayRotation(U8G2_R1);
// u8g2.setFont(u8g2_font_8x13_tr);
//u8g2.setFont(u8g2_font_luBS18_tf);
// u8g2.setFont(u8g2_font_6x13_tr);
u8g2.setFont(u8g2_font_6x10_tr);
u8g2.setCursor(0, 20);
u8g2.print(wifi_ssid);
Serial.println();
Serial.print("Connecting to ");
Serial.println(wifi_ssid);
WiFi.begin(wifi_ssid, wifi_password);
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connection Established");
Serial.print("IP Adress : ");
Serial.print(WiFi.localIP());
u8g2.setFont(u8g2_font_6x10_tr);
//u8g2.setFont(u8g2_font_6x13_tr);
u8g2.setCursor(0, 35);
u8g2.println("IP Adress : ");
u8g2.setCursor(0, 50);
u8g2.println(WiFi.localIP());;
} while ( u8g2.nextPage() );
}
// this is the part for the connection to domoticz
void setvar()
{
// waardes voor naar domoticz te zenden
// indien van BMS geen juiste waardes worden doorgegeven word er niets naar domoticz gestuurd !!!
if (((amps > -100) && (amps < 100)) && ((percentage > -1) && (percentage < 102))) {
// Here is the Json format th Domoticz expects
// /json.htm?type=command¶m=udevice&idx=IDX&nvalue=0&svalue=TEMP
// VAR1 versturen
String URLVAR1 = "/json.htm?type=command¶m=udevice&idx=";
URLVAR1 += String(326); // IDX van je Device in domoticz
URLVAR1 += "&nvalue=0&svalue=";
URLVAR1 += float(volts); // dit is de waarde die naar de IDX gestuurd word in domoticz
// VAR 2 versturen
String URLVAR2 = "/json.htm?type=command¶m=udevice&idx=";
URLVAR2 += String(324); // IDX van je Device in domoticz
URLVAR2 += "&nvalue=0&svalue=";
URLVAR2 += String(amps); // dit is de waarde die naar de IDX gestuurd word in domoticz
// VAR 3 versturen
String URLVAR3 = "/json.htm?type=command¶m=udevice&idx=";
URLVAR3 += String(325); // IDX van je Device in domoticz
URLVAR3 += "&nvalue=0&svalue=";
URLVAR3 += String(percentage); // dit is de waarde die naar de IDX gestuurd word in domoticz
// VAR 4 versturen
String URLVAR4 = "/json.htm?type=command¶m=udevice&idx=";
URLVAR4 += String(327); // IDX van je Device in domoticz
URLVAR4 += "&nvalue=0&svalue=";
URLVAR4 += float(minCellVoltage); // dit is de waarde die naar de IDX gestuurd word in domoticz
// VAR 5 versturen
String URLVAR5 = "/json.htm?type=command¶m=udevice&idx=";
URLVAR5 += String(328); // IDX van je Device in domoticz
URLVAR5 += "&nvalue=0&svalue=";
URLVAR5 += float(maxCellVoltage); // dit is de waarde die naar de IDX gestuurd word in domoticz
// VAR 6 versturen
String URLVAR6 = "/json.htm?type=command¶m=udevice&idx=";
URLVAR6 += String(332); // IDX van je Device in domoticz
URLVAR6 += "&nvalue=0&svalue=";
URLVAR6 += float(maxCellNumber); // dit is de waarde die naar de IDX gestuurd word in domoticz
// VAR 7 versturen
String URLVAR7 = "/json.htm?type=command¶m=udevice&idx=";
URLVAR7 += String(333); // IDX van je Device in domoticz
URLVAR7 += "&nvalue=0&svalue=";
URLVAR7 += float(minCellNumber); // dit is de waarde die naar de IDX gestuurd word in domoticz
// VAR / versturen
String URLVAR8 = "/json.htm?type=command¶m=udevice&idx=";
URLVAR8 += String(331); // IDX van je Device in domoticz
URLVAR8 += "&nvalue=0&svalue=";
URLVAR8 += float(maxCellVoltage-minCellVoltage); // dit is de waarde die naar de IDX gestuurd word in domoticz
// VAR / versturen
String URLVAR9 = "/json.htm?type=command¶m=udevice&idx=";
URLVAR9 += String(334); // IDX van je Device in domoticz
URLVAR9 += "&nvalue=0&svalue=";
URLVAR9 += float(amps*volts); // dit is de waarde die naar de IDX gestuurd word in domoticz
sendToDomoticz(URLVAR1);
sendToDomoticz(URLVAR2);
sendToDomoticz(URLVAR3);
sendToDomoticz(URLVAR4);
sendToDomoticz(URLVAR5);
sendToDomoticz(URLVAR6);
sendToDomoticz(URLVAR7);
sendToDomoticz(URLVAR8);
sendToDomoticz(URLVAR9);
delay (1000);
}
}
void sendToDomoticz(String URLVAR1)
{
Serial.print("Connecting to ");
Serial.println(host);
Serial.print("Requesting URLVAR1: ");
Serial.println(URLVAR1);
http.begin(host,port,URLVAR1);
int httpCode = http.GET();
if (httpCode)
{
if (httpCode == 200)
{
String payload = http.getString();
Serial.println("Domoticz response ");
Serial.println(payload);
}
}
Serial.println("closing connection");
http.end();
}
Disconnect the bluetooth adaptor from the cable
Connect the usb micro connector to your board
Add some external usb power to your Wroom ESP32 module
Now you have these value's in Domoticz