Skip to content

Commit

Permalink
Merge pull request #170 from dalathegreat/feature/event-log
Browse files Browse the repository at this point in the history
Event handling! Unit tests!
  • Loading branch information
Cabooman authored Feb 12, 2024
2 parents 5157e51 + 09db151 commit 8f61883
Show file tree
Hide file tree
Showing 50 changed files with 1,066 additions and 311 deletions.
30 changes: 30 additions & 0 deletions .github/workflows/unit-tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: Run Unit Tests


on: [push, pull_request]

jobs:
build:
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Configure and build with CMake
run: |
mkdir build
cd build
cmake ..
cmake --build .
- name: Run unit tests
run: |
set -e # Exit immediately on non-zero exit code
cd build/test
dir -s
for test_executable in *; do
if [ -f "$test_executable" ] && [ -x "$test_executable" ]; then
./"$test_executable"
fi
done
7 changes: 5 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# Ignore any .vscode folder
*.vscode/

# Ignore any files in the build folder
Software/build/
# Ignore any files in any build folder
*build/

# Ignore .exe (unit tests)
*.exe
10 changes: 10 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
cmake_minimum_required(VERSION 3.10)

# Set the C++ standard to C++20
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

project(BatteryEmulator)

# add_subdirectory(Software/src/devboard/utils)
add_subdirectory(test)
62 changes: 36 additions & 26 deletions Software/Software.ino
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ static uint8_t brightness = 0;
static bool rampUp = true;
const uint8_t maxBrightness = 100;
uint8_t LEDcolor = GREEN;
bool test_all_colors = false;

// Contactor parameters
#ifdef CONTACTOR_CONTROL
Expand Down Expand Up @@ -149,6 +150,9 @@ void setup() {
#ifdef BATTERY_HAS_INIT
init_battery();
#endif

// BOOT button at runtime is used as an input for various things
pinMode(0, INPUT_PULLUP);
}

// Perform main program functions
Expand Down Expand Up @@ -187,7 +191,7 @@ void loop() {
previousMillisUpdateVal = millis();
update_values(); // Update values heading towards inverter. Prepare for sending on CAN, or write directly to Modbus.
if (DUMMY_EVENT_ENABLED) {
set_event(EVENT_DUMMY, (uint8_t)millis());
set_event(EVENT_DUMMY_ERROR, (uint8_t)millis());
}
}

Expand All @@ -196,7 +200,13 @@ void loop() {
#ifdef DUAL_CAN
send_can2();
#endif
update_event_timestamps();
run_event_handling();

if (digitalRead(0) == HIGH) {
test_all_colors = false;
} else {
test_all_colors = true;
}
}

// Initialization functions
Expand Down Expand Up @@ -557,30 +567,30 @@ void handle_LED_state() {
} else if (!rampUp && brightness == 0) {
rampUp = true;
}
switch (LEDcolor) {
case GREEN:
pixels.setPixelColor(0, pixels.Color(0, brightness, 0)); // Green pulsing LED
break;
case YELLOW:
pixels.setPixelColor(0, pixels.Color(brightness, brightness, 0)); // Yellow pulsing LED
break;
case BLUE:
pixels.setPixelColor(0, pixels.Color(0, 0, brightness)); // Blue pulsing LED
break;
case RED:
pixels.setPixelColor(0, pixels.Color(150, 0, 0)); // Red LED full brightness
break;
case TEST_ALL_COLORS:
pixels.setPixelColor(0, pixels.Color(brightness, abs((100 - brightness)), abs((50 - brightness)))); // RGB
break;
default:
break;
}

// BMS in fault state overrides everything
if (bms_status == FAULT) {
LEDcolor = RED;
pixels.setPixelColor(0, pixels.Color(255, 0, 0)); // Red LED full brightness
if (test_all_colors == false) {
switch (get_event_level()) {
case EVENT_LEVEL_INFO:
LEDcolor = GREEN;
pixels.setPixelColor(0, pixels.Color(0, brightness, 0)); // Green pulsing LED
break;
case EVENT_LEVEL_WARNING:
LEDcolor = YELLOW;
pixels.setPixelColor(0, pixels.Color(brightness, brightness, 0)); // Yellow pulsing LED
break;
case EVENT_LEVEL_DEBUG:
case EVENT_LEVEL_UPDATE:
LEDcolor = BLUE;
pixels.setPixelColor(0, pixels.Color(0, 0, brightness)); // Blue pulsing LED
break;
case EVENT_LEVEL_ERROR:
LEDcolor = RED;
pixels.setPixelColor(0, pixels.Color(150, 0, 0)); // Red LED full brightness
break;
default:
break;
}
} else {
pixels.setPixelColor(0, pixels.Color(brightness, abs((100 - brightness)), abs((50 - brightness)))); // RGB
}

pixels.show(); // This sends the updated pixel color to the hardware.
Expand Down
8 changes: 4 additions & 4 deletions Software/USER_SETTINGS.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
//#define CHADEMO_BATTERY
//#define IMIEV_CZERO_ION_BATTERY
//#define KIA_HYUNDAI_64_BATTERY
//#define NISSAN_LEAF_BATTERY
// #define NISSAN_LEAF_BATTERY
//#define RENAULT_KANGOO_BATTERY
//#define RENAULT_ZOE_BATTERY
//#define SANTA_FE_PHEV_BATTERY
Expand All @@ -21,7 +21,7 @@

/* Select inverter communication protocol. See Wiki for which to use with your inverter: https://github.com/dalathegreat/BYD-Battery-Emulator-For-Gen24/wiki */
//#define BYD_CAN //Enable this line to emulate a "BYD Battery-Box Premium HVS" over CAN Bus
//#define BYD_MODBUS //Enable this line to emulate a "BYD 11kWh HVM battery" over Modbus RTU
// #define BYD_MODBUS //Enable this line to emulate a "BYD 11kWh HVM battery" over Modbus RTU
//#define LUNA2000_MODBUS //Enable this line to emulate a "Luna2000 battery" over Modbus RTU
//#define PYLON_CAN //Enable this line to emulate a "Pylontech battery" over CAN bus
//#define SMA_CAN //Enable this line to emulate a "BYD Battery-Box H 8.9kWh, 7 mod" over CAN bus
Expand All @@ -37,10 +37,10 @@
//#define SERIAL_LINK_RECEIVER //Enable this line to receive battery data over RS485 pins from another Lilygo (This LilyGo interfaces with inverter)
//#define SERIAL_LINK_TRANSMITTER //Enable this line to send battery data over RS485 pins to another Lilygo (This LilyGo interfaces with battery)
#define WEBSERVER //Enable this line to enable WiFi, and to run the webserver. See USER_SETTINGS.cpp for the Wifi settings.
#define LOAD_SAVED_SETTINGS_ON_BOOT //Enable this line to read settings stored via the webserver on boot
// #define LOAD_SAVED_SETTINGS_ON_BOOT //Enable this line to read settings stored via the webserver on boot

/* MQTT options */
//#define MQTT // Enable this line to enable MQTT
// #define MQTT // Enable this line to enable MQTT
#define MQTT_SUBSCRIPTIONS \
{ "my/topic/abc", "my/other/topic" }
#define MQTT_SERVER "192.168.xxx.yyy"
Expand Down
6 changes: 1 addition & 5 deletions Software/src/battery/BMW-I3-BATTERY.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,6 @@ static uint16_t DC_link = 0;
static int16_t Battery_Power = 0;

void update_values_i3_battery() { //This function maps all the values fetched via CAN to the correct parameters used for modbus
bms_status = ACTIVE; //Startout in active mode

//Calculate the SOC% value to send to inverter
Calculated_SOC = (Display_SOC * 10); //Increase decimal amount
Calculated_SOC =
Expand Down Expand Up @@ -102,9 +100,7 @@ void update_values_i3_battery() { //This function maps all the values fetched v

/* Check if the BMS is still sending CAN messages. If we go 60s without messages we raise an error*/
if (!CANstillAlive) {
bms_status = FAULT;
Serial.println("No CAN communication detected for 60s. Shutting down battery control.");
set_event(EVENT_CAN_FAILURE, 0);
set_event(EVENT_CAN_RX_FAILURE, 0);
} else {
CANstillAlive--;
}
Expand Down
1 change: 0 additions & 1 deletion Software/src/battery/BMW-I3-BATTERY.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ extern uint16_t capacity_Wh;
extern uint16_t remaining_capacity_Wh;
extern uint16_t max_target_discharge_power;
extern uint16_t max_target_charge_power;
extern uint8_t bms_status;
extern uint8_t bms_char_dis_status;
extern uint16_t stat_batt_power;
extern uint16_t temperature_min;
Expand Down
5 changes: 1 addition & 4 deletions Software/src/battery/CHADEMO-BATTERY.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,6 @@ uint8_t HighCurrentControlStatus = 0;
uint8_t HighVoltageControlStatus = 0;

void update_values_chademo_battery() { //This function maps all the values fetched via CAN to the correct parameters used for the inverter
bms_status = ACTIVE; //Startout in active mode

SOC = ChargingRate;

Expand All @@ -105,10 +104,8 @@ void update_values_chademo_battery() { //This function maps all the values fetc

/* Check if the Vehicle is still sending CAN messages. If we go 60s without messages we raise an error*/
if (!CANstillAlive) {
bms_status = FAULT;
errorCode = 7;
Serial.println("No CAN communication detected for 60s. Shutting down battery control.");
set_event(EVENT_CAN_FAILURE, 0);
set_event(EVENT_CAN_RX_FAILURE, 0);
} else {
CANstillAlive--;
}
Expand Down
6 changes: 1 addition & 5 deletions Software/src/battery/IMIEV-CZERO-ION-BATTERY.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,6 @@ static double max_temp_cel = 20.00;
static double min_temp_cel = 19.00;

void update_values_imiev_battery() { //This function maps all the values fetched via CAN to the correct parameters used for modbus
bms_status = ACTIVE; //Startout in active mode

SOC = (uint16_t)(BMU_SOC * 100); //increase BMU_SOC range from 0-100 -> 100.00

battery_voltage = (uint16_t)(BMU_PackVoltage * 10); // Multiply by 10 and cast to uint16_t
Expand Down Expand Up @@ -108,9 +106,7 @@ void update_values_imiev_battery() { //This function maps all the values fetche

/* Check if the BMS is still sending CAN messages. If we go 60s without messages we raise an error*/
if (!CANstillAlive) {
bms_status = FAULT;
Serial.println("No CAN communication detected for 60s. Shutting down battery control.");
set_event(EVENT_CAN_FAILURE, 0);
set_event(EVENT_CAN_RX_FAILURE, 0);
} else {
CANstillAlive--;
}
Expand Down
2 changes: 0 additions & 2 deletions Software/src/battery/IMIEV-CZERO-ION-BATTERY.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ extern uint16_t capacity_Wh;
extern uint16_t remaining_capacity_Wh;
extern uint16_t max_target_discharge_power;
extern uint16_t max_target_charge_power;
extern uint8_t bms_status;
extern uint8_t bms_char_dis_status;
extern uint16_t stat_batt_power;
extern uint16_t temperature_min;
Expand All @@ -28,7 +27,6 @@ extern uint16_t cell_max_voltage;
extern uint16_t cell_min_voltage;
extern bool batteryAllowsContactorClosing; //Bool, 1=true, 0=false
extern bool inverterAllowsContactorClosing; //Bool, 1=true, 0=false
extern uint8_t LEDcolor;

void update_values_imiev_battery();
void receive_can_imiev_battery(CAN_frame_t rx_frame);
Expand Down
16 changes: 1 addition & 15 deletions Software/src/battery/KIA-HYUNDAI-64-BATTERY.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -195,45 +195,31 @@ void update_values_kiaHyundai_64_battery() { //This function maps all the value

cell_min_voltage = CellVoltMin_mV;

bms_status = ACTIVE; //Startout in active mode. Then check safeties

/* Check if the BMS is still sending CAN messages. If we go 60s without messages we raise an error*/
if (!CANstillAlive) {
bms_status = FAULT;
Serial.println("No CAN communication detected for 60s. Shutting down battery control.");
set_event(EVENT_CAN_FAILURE, 0);
set_event(EVENT_CAN_RX_FAILURE, 0);
} else {
CANstillAlive--;
}

if (waterleakageSensor == 0) {
Serial.println("Water leakage inside battery detected. Operation halted. Inspect battery!");
bms_status = FAULT;
set_event(EVENT_WATER_INGRESS, 0);
}

if (leadAcidBatteryVoltage < 110) {
Serial.println("12V battery source below required voltage to safely close contactors. Inspect the supply/battery!");
LEDcolor = YELLOW;
set_event(EVENT_12V_LOW, leadAcidBatteryVoltage);
}

// Check if cell voltages are within allowed range
cell_deviation_mV = (cell_max_voltage - cell_min_voltage);

if (cell_max_voltage >= MAX_CELL_VOLTAGE) {
bms_status = FAULT;
Serial.println("ERROR: CELL OVERVOLTAGE!!! Stopping battery charging and discharging. Inspect battery!");
set_event(EVENT_CELL_OVER_VOLTAGE, 0);
}
if (cell_min_voltage <= MIN_CELL_VOLTAGE) {
bms_status = FAULT;
Serial.println("ERROR: CELL UNDERVOLTAGE!!! Stopping battery charging and discharging. Inspect battery!");
set_event(EVENT_CELL_UNDER_VOLTAGE, 0);
}
if (cell_deviation_mV > MAX_CELL_DEVIATION) {
LEDcolor = YELLOW;
Serial.println("ERROR: HIGH CELL DEVIATION!!! Inspect battery!");
set_event(EVENT_CELL_DEVIATION_HIGH, 0);
}

Expand Down
2 changes: 0 additions & 2 deletions Software/src/battery/KIA-HYUNDAI-64-BATTERY.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ extern uint16_t capacity_Wh; //Wh, 0-60000
extern uint16_t remaining_capacity_Wh; //Wh, 0-60000
extern uint16_t max_target_discharge_power; //W, 0-60000
extern uint16_t max_target_charge_power; //W, 0-60000
extern uint8_t bms_status; //Enum, 0-5
extern uint8_t bms_char_dis_status; //Enum, 0-2
extern uint16_t stat_batt_power; //W, Goes thru convert2unsignedint16 function (5W = 5, -5W = 65530)
extern uint16_t temperature_min; //C+1, Goes thru convert2unsignedint16 function (15.0C = 150, -15.0C = 65385)
Expand All @@ -29,7 +28,6 @@ extern uint16_t cell_max_voltage; //mV, 0-4350
extern uint16_t cell_min_voltage; //mV, 0-4350
extern uint16_t cellvoltages[120]; //mV 0-4350 per cell
extern uint8_t nof_cellvoltages; // Total number of cell voltages, set by each battery.
extern uint8_t LEDcolor; //Enum, 0-10
extern bool batteryAllowsContactorClosing; //Bool, 1=true, 0=false
extern bool inverterAllowsContactorClosing; //Bool, 1=true, 0=false

Expand Down
Loading

0 comments on commit 8f61883

Please sign in to comment.