Commit ec62f567 authored by Thomas Plaz's avatar Thomas Plaz
Browse files

initial commit

parent 60879b47
# Libre Solar BMS software
Firmware for [5s](https://github.com/LibreSolar/BMS-5s) and [48V](https://github.com/LibreSolar/BMS48V) BMS boards using bq769x0 IC from Texas Instruments.
Firmware for https://github.com/LibreSolar/bms-15s80-sc/tree/rev2 BMS boards using bq769x0 IC from Texas Instruments.
Former: [5s](https://github.com/LibreSolar/BMS-5s) and [48V](https://github.com/LibreSolar/BMS48V)
Please find a description about system integration of the BMS in the [Open Source Ecology Wiki](https://wiki.opensourceecology.de/24-48V_BMS) (in German).
## Selection of board type
......@@ -16,6 +19,11 @@ For 10s/15s (48V) version:
#define BMS_PCB_48V
```
## In the available code following adjustments are made:
06/29/2021: code adapted for bq76940 (15 cells, 3 temp sensors), with standard assignment of UEXT and activated OLED (but initially only for 10 cells due to lack of space).
07/01/2021: Shunt changed to 0.75 mOhm and UEXT output changed to fit to the arduino code under https://gitlab.opensourceecology.de/soldorado-open-solar-system/solar-storage-controller-software
## Firmware development and flashing
See [here](http://libre.solar/docs/flashing/) for an explanation how to flash the software to your board.
......@@ -21,7 +21,7 @@
env_default = nucleo
[env:nucleo]
platform = ststm32
platform = ststm32@4.6.0
framework = mbed
board = nucleo_f072rb
upload_protocol = stlink
......@@ -41,7 +41,7 @@ build_flags =
#monitor_port = /dev/ttyUSB1
; Custom Serial Monitor baud rate
monitor_baud = 115200
monitor_speed = 115200
lib_deps =
https://github.com/LibreSolar/bq769x0_mbed_lib.git#master
......
......@@ -20,8 +20,8 @@
#include "bq769x0.h"
// select BMS board
#define BMS_PCB_5S
//#define BMS_PCB_48V
//#define BMS_PCB_5S
#define BMS_PCB_48V
#define ADC_AVG_SAMPLES 8 // number of ADC values to read for averaging
......@@ -44,7 +44,7 @@
// 48V BMS with bq76930 or bq76940
// https://github.com/LibreSolar/BMS48V
#ifdef BMS_PCB_48V
#define BMS_BQ_TYPE bq76930
#define BMS_BQ_TYPE bq76940
#include "config_48v.h"
#endif // BMS_PCB_48V
......
......@@ -17,7 +17,7 @@
#ifndef CONFIG_48V_H
#define CONFIG_48V_H
#define SHUNT_RESISTOR 1.5 // mOhm
#define SHUNT_RESISTOR 0.75 // mOhm
#define PIN_UEXT_TX PA_2
#define PIN_UEXT_RX PA_3
......
......@@ -85,7 +85,8 @@ int main()
can_process_inbox();
BMS.update();
update_measurements();
// called once per second
if (time(NULL) - last_second >= 1) {
last_second = time(NULL);
......@@ -101,7 +102,7 @@ int main()
btnTimer.reset();
}
fflush(stdout);
//fflush(stdout);
/*
// test communication
......@@ -112,11 +113,14 @@ int main()
serial.printf("buf: 0x%x\n", buf[0]);
*/
update_measurements();
fflush(stdout);
//BMS.printRegisters();
output_oled();
//output_doglcd();
output_serial();
output_serial_uext();
led_green = !led_green;
}
......@@ -133,11 +137,13 @@ void setup()
serial.printf("\nSerial interface started. Time: %d\n", time(NULL));
freopen("/serial", "w", stdout); // retarget stdout to serial
init_serial_uext();
can.attach(&can_receive);
can.mode(CAN::Normal);
// not needed if doglcd not used. remove if other device connected to UEXT SPI port
init_doglcd();
// init_doglcd();
// TXFP: Transmit FIFO priority driven by request order (chronologically)
// NART: No automatic retransmission
......@@ -147,18 +153,18 @@ void setup()
BMS.setTemperatureLimits(-20, 45, 0, 45);
BMS.setShuntResistorValue(SHUNT_RESISTOR);
BMS.setShortCircuitProtection(35000, 200); // delay in us
BMS.setOvercurrentChargeProtection(25000, 200); // delay in ms
BMS.setOvercurrentDischargeProtection(20000, 320); // delay in ms
BMS.setOvercurrentChargeProtection(30000, 200); // delay in ms
BMS.setOvercurrentDischargeProtection(30000, 320); // delay in ms
BMS.setCellUndervoltageProtection(2800, 2); // delay in s
BMS.setCellOvervoltageProtection(3650, 2); // delay in s
BMS.setOCV(OCV);
BMS.setBatteryCapacity(45000); // mAh
BMS.setBatteryCapacity(72000); // mAh
BMS.update(); // get voltage and temperature measurements before switching on
BMS.setBalancingThresholds(10, 3200, 10); // minIdleTime_min, minCellV_mV, maxVoltageDiff_mV
BMS.setIdleCurrentThreshold(100);
BMS.setBalancingThresholds(5, 3350, 5); // minIdleTime_min, minCellV_mV, maxVoltageDiff_mV
BMS.setIdleCurrentThreshold(6000);
BMS.enableAutoBalancing();
// TODO: watch voltage rise before stopping pre-charge
......@@ -199,7 +205,7 @@ void update_measurements(void)
for (int i = 0; i < ADC_AVG_SAMPLES; i++) {
sum_adc_readings += v_load.read_u16();
}
load_voltage = (sum_adc_readings / ADC_AVG_SAMPLES) * 110 / 10 * vcc / 0xFFFF;
load_voltage = (sum_adc_readings / ADC_AVG_SAMPLES) * 105.6 / 5.6 * vcc / 0xFFFF;
battery_voltage = BMS.getBatteryVoltage();
battery_current = BMS.getBatteryCurrent();
......
......@@ -30,7 +30,7 @@ I2C i2c(PIN_UEXT_SDA, PIN_UEXT_SCL);
Adafruit_SSD1306_I2c oled(i2c, PB_2, 0x78, 64, 128);
SPI spi(PIN_UEXT_MOSI, NC, PIN_UEXT_SCK);
DogLCD lcd(spi, PIN_UEXT_SSEL, PIN_UEXT_RX, PIN_UEXT_TX); // spi, cs, a0, reset
// DogLCD lcd(spi, PIN_UEXT_SSEL, PIN_UEXT_RX, PIN_UEXT_TX); // spi, cs, a0, reset
extern bool blinkOn;
......@@ -46,23 +46,50 @@ extern float SOC;
void output_serial()
{
int balancingStatus = BMS.getBalancingStatus();
serial.printf("|");
for (int i = 1; i <= 5; i++) {
for (int i = 1; i <= 15; i++) {
serial.printf("%i|", BMS.getCellVoltage(i));
}
serial.printf("%i|", BMS.getBatteryVoltage());
serial.printf("%i|", BMS.getBatteryCurrent());
serial.printf("%.2f|", BMS.getSOC());
serial.printf("%.1f|", BMS.getTemperatureDegC(1));
//serial.printf("%.1f|", BMS.getTemperatureDegC(2));
//serial.printf("%.1f|", BMS.getTemperatureDegC(3));
serial.printf("%.1f|", BMS.getTemperatureDegC(2));
serial.printf("%.1f|", BMS.getTemperatureDegC(3));
serial.printf("%i|", load_voltage);
serial.printf("%i|", BMS.getBalancingStatus());
for (int i = 0; i < BMS.getNumberOfCells(); i++) {
serial.printf((balancingStatus & (1 << i)) ? "1" : "0");
}
//serial.printf("|%i|", BMS.getStatus() & 0b00111111);
serial.printf("\n");
}
serial.printf(" \n");
void init_serial_uext()
{
serial_uext.baud(115200);
}
void init_doglcd()
void output_serial_uext()
{
serial_uext.printf("!");
for (int i = 1; i <= 15; i++) {
serial_uext.printf("%i|", BMS.getCellVoltage(i));
}
serial_uext.printf("%i|", BMS.getBatteryVoltage());
serial_uext.printf("%i|", BMS.getBatteryCurrent());
serial_uext.printf("%.2f|", BMS.getSOC());
serial_uext.printf("%.1f|", BMS.getTemperatureDegC(1));
serial_uext.printf("%.1f|", BMS.getTemperatureDegC(2));
serial_uext.printf("%.1f|", BMS.getTemperatureDegC(3));
serial_uext.printf("%i|", load_voltage);
serial_uext.printf("%i|", BMS.getBalancingStatus());
serial_uext.printf("\n");
}
/* void init_doglcd()
{
lcd.init();
lcd.view(VIEW_TOP);
......@@ -98,7 +125,7 @@ void output_doglcd() // EA DOG
}
}
}
*/
void output_oled() // OLED SSD1306
{
int balancingStatus = BMS.getBalancingStatus();
......@@ -119,7 +146,7 @@ void output_oled() // OLED SSD1306
oled.setTextCursor(0, 16);
oled.printf("Load: %.2fV", load_voltage/1000.0);
for (int i = 0; i < BMS.getNumberOfCells(); i++) {
for (int i = 0; i < 10; i++) {
if (blinkOn || !(balancingStatus & (1 << i))) {
oled.setTextCursor((i % 2 == 0) ? 0 : 64, 24 + (i / 2) * 8);
oled.printf("%d:%.3f V", i+1, BMS.getCellVoltage(i+1)/1000.0);
......
......@@ -19,6 +19,10 @@
#define OUTPUT_H
void output_serial();
void init_serial_uext();
void output_serial_uext();
void output_oled();
void init_doglcd();
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment