baipin
New Member
- Joined
- Dec 25, 2020
- Messages
- 68
I've been messing around with an Arduinos and the UART serial from the BMS. After a lot of trial and error, I found that the BMS simply cannot be used with Arduinos which do not support hardware Serial1. Software.serial does not work. However, if you use an Arduino with an ATMega32U4 - I chose a Pro-Mini/Leonardo clone like this you will be able to connect no problem!
It's very simple; TX or T as marked on the BMS, connects to RX on the Arduino. RX or R on the BMS, connects to TX on the Arduino. Ground from the BMS connects to Ground on the Arduino. Supply the Arduino with 5V (note that the UART VCC from the BMS is 12V!!!) then wire up your 128x64 OLED, and you're good to go!
This is the first coding project I've ever shared with anyone; I only got into coding a few months ago and am learning...
It's very simple; TX or T as marked on the BMS, connects to RX on the Arduino. RX or R on the BMS, connects to TX on the Arduino. Ground from the BMS connects to Ground on the Arduino. Supply the Arduino with 5V (note that the UART VCC from the BMS is 12V!!!) then wire up your 128x64 OLED, and you're good to go!
This is the first coding project I've ever shared with anyone; I only got into coding a few months ago and am learning...
Python:
//Created by Baipin/BlPlN using Niel Jansen's Overkill Solar BMS library.
//Prints to display: SoC battery bitmap, current, error condition (error/status OK), If cells 1,2,3, or 4 are balancing.
//Must be used with a Arduino with Serial1 dedicated to UART. Will not work on any Arduino that shares UART Serial with USB.
//Arduino Pro-Mini/Leonardo with ATMega32u4 recommended.
//128x64 OLED recommended.
//Hardware: Connect TX pin from BMS to RX pin on Arduino. Connect RX pin from BMS to TX pin on Arduino. Connect BMS ground to Arduino ground. Supply with 5V. WARNING: BMS outputs 12V. Use buck or isolated PS.
//v1.0 11-04-2021
#include "bms.h"
#include "U8glib.h"
#include <Wire.h>
#include <Adafruit_SH1106.h>
#include <Fonts/FreeSansBold12pt7b.h>
//#include <Fonts/FreeSans9pt7b.h>
#define BRIGHTNESS 0x01//copy
#define BRIGHTNESSREG 0x81//copy
#define OLED_RESET 4//copy
Adafruit_SH1106 display(OLED_RESET);//copy
OverkillSolarBms bms = OverkillSolarBms();
uint32_t last_soc_check_time;
#define SOC_POLL_RATE 2000 // milliseconds
void setup() {
pinMode(LED_BUILTIN, OUTPUT);
Serial1.begin(9600);
while (!Serial1) { // Wait for the BMS serial port to initialize
}
bms.begin(&Serial1);
bms.set_query_rate(2000); // Set query rate to 2000 milliseconds (2 seconds)
last_soc_check_time = 0;
display.begin(SH1106_SWITCHCAPVCC, 0x3C);//copy
display.display();//copy
display.clearDisplay();//copy
}
void loop() {
bms.main_task();
uint8_t soc = bms.get_state_of_charge();
digitalWrite(LED_BUILTIN, HIGH);
display.clearDisplay();
//display.setTextSize(3);
//display.drawRoundRect(40, 5, 86, 27, 3, WHITE);
//display.drawRect(0, 0, 70, 24, 8, WHITE);
display.drawRoundRect(7, 0, 15, 6, 1, WHITE);
display.drawRoundRect(0, 5, 30, 59, 3, WHITE);
display.fillRoundRect(2, 7, 26, 55, 1, WHITE);
display.fillRoundRect(2, 7, 26, ((100 - (soc)) / 1.8), 2, BLACK);
//display.fillRoundRect(2, 7, 26, (50 / 1.8), 2, BLACK); //TESTING (uncomment for 80%SoC test image)
display.setTextColor(BLACK);
//display.setTextSize(1);
display.setFont();
display.setCursor(6,52);
//display.print("1");//TESTING DIGITS
display.print(soc, DEC);
display.print("%");
bool has_something_gone_wrong = bms.get_protection_status_summary();
// Returns True if any protection status bits are currently active
if (has_something_gone_wrong) {
display.setTextColor(WHITE);
display.setCursor(40,34);
display.print ("ERROR! ");
}
else {
display.setTextColor(WHITE);
display.setCursor(40,34);
display.print ("Status OK ");
display.print(bms.get_discharge_mosfet_status()? "DS" : "! ");
display.print(bms.get_charge_mosfet_status()? "CHG": "! ");
}
bool cell_1_status = bms.get_balance_status(0);
bool cell_2_status = bms.get_balance_status(1);
bool cell_3_status = bms.get_balance_status(2);
bool cell_4_status = bms.get_balance_status(3);
display.fillRoundRect(39, 48, 10, 14, 1, WHITE); //Cell 1 No Balance
display.fillRoundRect(50, 48, 10, 14, 1, WHITE); //Cell 2 No Balance
display.fillRoundRect(61, 48, 10, 14, 1, WHITE); //Cell 3 No Balance
display.fillRoundRect(72, 48, 10, 14, 1, WHITE); //Cell 4 No Balance
display.setTextColor(BLACK);
display.setCursor(42,52);
display.println(cell_1_status? "B" : "1");
display.setCursor(53,52);
display.println(cell_2_status? "B" : "2");
display.setCursor(64,52);
display.println(cell_3_status? "B" : "3");
display.setCursor(75,52);
display.println(cell_4_status? "B" : "4");
display.setTextColor(WHITE);
display.setCursor(85,52);
display.print ("Balance");
float current = bms.get_current();
display.setFont(&FreeSansBold12pt7b);
display.setTextColor(WHITE);
display.setTextSize(1);
display.setCursor(43,22);
//display.print("2"); //TESTING
display.print(current, 1);
display.println(" A");
display.drawFastHLine(40, 29, 87, WHITE);
display.drawFastHLine(40, 46, 87, WHITE);
display.drawFastHLine(40, 63, 87, WHITE);
//display.drawFastVLine(60, 22, 32, WHITE);
///display.drawFastVLine(90, 32, 32, WHITE);
//display.drawRoundRect(40, 48, 80, 16, 3, WHITE);
display.display();
Wire.beginTransmission(0x3c);
Wire.write(0x00);
Wire.write(BRIGHTNESSREG);
Wire.endTransmission();
Wire.beginTransmission(0x3c);
Wire.write(0x00);
Wire.write(BRIGHTNESS);
Wire.endTransmission();
if (millis() - last_soc_check_time > SOC_POLL_RATE) {
if (soc < 30) {
digitalWrite(LED_BUILTIN, HIGH);
}
else {
digitalWrite(LED_BUILTIN, LOW);
}
last_soc_check_time = millis();
}
}