Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bms/pdb #415

Draft
wants to merge 6 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ endfunction()
## Include Rover Apps
add_subdirectory(${ROVER_APPS_DIR}/common)
add_app_subdirectory(${ROVER_APPS_DIR}/arm_2021)
add_app_subdirectory(${ROVER_APPS_DIR}/bms_2022)
add_app_subdirectory(${ROVER_APPS_DIR}/gamepad_2021)
add_app_subdirectory(${ROVER_APPS_DIR}/gimbal_2021)
add_app_subdirectory(${ROVER_APPS_DIR}/pdb_2021)
Expand Down
25 changes: 25 additions & 0 deletions rover-apps/bms_2022/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
add_library(BMS_Monitoring STATIC)
target_sources(BMS_Monitoring PRIVATE src/BMSMonitoring.cpp)
target_include_directories(BMS_Monitoring PUBLIC
include
${ROVER_APPS_DIR}/common/include
)
target_link_libraries(BMS_Monitoring
PRIVATE
Logger
mbed-os
)

add_executable(bms_2022)
target_sources(bms_2022 PRIVATE ${ROVER_APPS_DIR}/common/src/main.cpp)
target_include_directories(bms_2022 PUBLIC include ${ROVER_APPS_DIR}/common/include)
target_link_libraries(bms_2022
PRIVATE
CANBus
CANMsg
Logger
uwrt-mars-rover-hw-bridge
#Modules
BMS_Monitoring
)
mbed_set_post_build(bms_2022)
12 changes: 12 additions & 0 deletions rover-apps/bms_2022/include/AppConfig.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#pragma once

#include <vector>

#include "BMSMonitoring.h"
#include "Module.h"

BMSMonitoring BMS_Monitoring;

std::vector<Module*> gModules = {
&BMS_Monitoring,
};
32 changes: 32 additions & 0 deletions rover-apps/bms_2022/include/BMSMonitoring.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#pragma once

#include "Module.h"
#include "mbed.h"

/*This PDB module is for load, rail and temperature monitoring.*/

class BMSMonitoring final : public Module {
public:
/* Sets the Load DIAG_EN pins */
BMSMonitoring();
void periodic_1s(void) override;
void periodic_10s(void) override {}
void periodic_100ms(void) override {}
void periodic_10ms(void) override {}
void periodic_1ms(void) override;

private:
void current_monitoring();
void cell_monitoring();
void update_voltage_percent();
void low_battery_warning();
void send_can_data();

int cell_voltages[12];
bool is_cell_balancing = false;
int coloumb_count = 0;
const int battery_capacity = 22000; // mAh
int battery_percent_couloumb;
int battery_percent_voltage;
int battery_voltage;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Our convention is to prefix private member variables with m_, eg. m_battery_voltage

};
130 changes: 130 additions & 0 deletions rover-apps/bms_2022/src/BMSMonitoring.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
#include "BMSMonitoring.h"

#include <cmath>
#include <map>

#include "Logger.h"
#include "mbed.h"

SPI spi(SDI, SDO, CLK); // mosi, miso, sclk
AnalogIn currentADC(CURR_ANLG_IN);
DigitalOut buzzer_en(BUZZER_EN);
DigitalOut chip_select(SAMPL);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These should be private member variables


BMSMonitoring::BMSMonitoring() {
buzzer_en.write(0);
chip_select.write(1);
spi.format(24, 3);
spi.frequency(1000000);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make this a constant (no magic numbers)

}

void BMSMonitoring::cell_monitoring() {
chip_select.write(0);

// TODO: recieve data from can
// is_cell_balancing = getRXSignal
// can.getRXSignalValue(HWBRIDGE::CANID::BMS, HWBRIDGE::CANSIGNAL::BMS_STATE, is_cell_balancing);

// if voltage is too low on one cell, enable balancing on that cell
// only way to balance is to keep all fets on so cells always have same voltage
int spi_message = 0b000000000000000000000000;
if (is_cell_balancing) {
spi_message = 0b111111111111111100000000;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: can make this a ternary expression:
int spi_message = (is_cell_balancing ? 0b111111111111111100000000 : 0b000000000000000000000000);

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also using hex here instead of binary might make it more readable


battery_voltage = 0;
for (int i = 0; i < 16; i++) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why 16? The size of your cell_voltages array is 12 so this will seg fault

cell_voltages[i] = spi.write(spi_message);
battery_voltage += cell_voltages[i];
spi_message += 0b10000;
}
chip_select.write(1);

update_voltage_percent();
}

void BMSMonitoring::update_voltage_percent() {
if (battery_voltage >= 50.40) {
battery_percent_voltage = 100;
} else if (battery_voltage >= 49.80) {
battery_percent_voltage = 95;
} else if (battery_voltage >= 49.32) {
battery_percent_voltage = 90;
} else if (battery_voltage >= 48.96) {
battery_percent_voltage = 85;
} else if (battery_voltage >= 48.24) {
battery_percent_voltage = 80;
} else if (battery_voltage >= 47.76) {
battery_percent_voltage = 75;
} else if (battery_voltage >= 47.40) {
battery_percent_voltage = 70;
} else if (battery_voltage >= 46.92) {
battery_percent_voltage = 65;
} else if (battery_voltage >= 46.44) {
battery_percent_voltage = 60;
} else if (battery_voltage >= 46.20) {
battery_percent_voltage = 55;
} else if (battery_voltage >= 46.08) {
battery_percent_voltage = 50;
} else if (battery_voltage >= 45.84) {
battery_percent_voltage = 45;
} else if (battery_voltage >= 45.60) {
battery_percent_voltage = 40;
} else if (battery_voltage >= 45.48) {
battery_percent_voltage = 35;
} else if (battery_voltage >= 45.24) {
battery_percent_voltage = 30;
} else if (battery_voltage >= 45.00) {
battery_percent_voltage = 25;
} else if (battery_voltage >= 44.76) {
battery_percent_voltage = 20;
} else if (battery_voltage >= 44.52) {
battery_percent_voltage = 15;
} else if (battery_voltage >= 44.28) {
battery_percent_voltage = 10;
} else if (battery_voltage >= 43.32) {
battery_percent_voltage = 5;
} else {
battery_percent_voltage = 0;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like there should be a better way of doing this, what about mapping 0-100% to 43.32-50.4V? Like battery_percent_voltage = (battery_voltage - 43.32) / (50.4 - 43.32); and just do a catch for the corner cases of V > 50.4 and V < 43.32.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lipo battery voltages are not linear and they aren't the most accurate for state of charge estimation. I'm following this battery voltage chart.

}

void BMSMonitoring::current_monitoring() {
float current = (currentADC.read() * 20) - 33;
if (current < 0) {
current = 0;
} else if (current > 29) {
current = 29.1;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

current = current * 1000; // converts Amps to MilliAmps
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: current *= 1000;

coloumb_count += current * 0.001; // converts to MilliAmp Seconds
int battery_capacity_seconds = battery_capacity * 3600; // converts to MilliAmp Seconds
battery_percent_couloumb = (1 - (coloumb_count / battery_capacity_seconds)) * 100;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Integer division will truncate, is this intended?

}

void BMSMonitoring::low_battery_warning() {
if (battery_percent_couloumb <= 15 || battery_percent_voltage <= 15) {
buzzer_en.write(1);
} else {
buzzer_en.write(0);
}
}

void BMSMonitoring::send_can_data() {
// TODO: Send data over CAN
// Things to send over CAN
// - cell voltages for 12 cells: cell_voltages
// - percent battery: battery_percent_couloumb and battery_percent_couloumb
// - current: current
// setTXSignalValue(HWBRIDGE::CANID msgID, HWBRIDGE::CANSIGNAL signalName, HWBRIDGE::CANSignalValue_t signalValue);
}

void BMSMonitoring::periodic_1s() {
low_battery_warning();
send_can_data();
}

void BMSMonitoring::periodic_1ms() {
current_monitoring();
cell_monitoring();
}
15 changes: 5 additions & 10 deletions rover-apps/pdb_2021/include/PDBMonitoring.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,12 @@ class PDBMonitoring final : public Module {
void load_monitoring();
void rail_monitoring();
void temperature_monitoring();
void LED_matrix();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like there were unintended changes to pdb_2021, can you revert these?


static const float PDB_VBAT_RAIL_NOMINAL_VOLTAGE;
static const float PDB_VBAT_RAIL_MIN_THRESHOLD;
static const float PDB_VBAT_RAIL_MAX_THRESHOLD;

static const float PDB_24V_RAIL_NOMINAL_VOLTAGE;
static const float PDB_24V_RAIL_MIN_THRESHOLD;
static const float PDB_24V_RAIL_MAX_THRESHOLD;

static const float PDB_17V_RAIL_NOMINAL_VOLTAGE;
static const float PDB_17V_RAIL_MIN_THRESHOLD;
static const float PDB_17V_RAIL_MAX_THRESHOLD;
Expand All @@ -44,7 +41,6 @@ class PDBMonitoring final : public Module {
static const bool PDB_5V_LOAD2_DIAG_EN;
static const bool PDB_5V_LOAD3_DIAG_EN;
static const bool PDB_5V_LOAD4_DIAG_EN;
static const bool PDB_5V_LOAD5_DIAG_EN;
static const bool PDB_17V_LOAD_DIAG_EN;

/* Pins configuration for Load Monitoring */
Expand All @@ -60,18 +56,17 @@ class PDBMonitoring final : public Module {
DigitalOut load4_5V_diag_en;
DigitalIn load4_5V_fault_n;

DigitalOut load5_5V_diag_en;
DigitalIn load5_5V_fault_n;

DigitalOut load_17V_diag_en;
DigitalIn load_17V_fault_n;

DigitalOut LED_matrix_red;
PwmOut LED_matrix_green;
DigitalOut LED_matrix_blue;

/* Pins configuration for Rail Monitoring */
AnalogIn railBattery;
AnalogIn rail5V;
AnalogIn rail17V;
AnalogIn rail24V;
DigitalIn rail24V_pgood_n;

/* Pins configuration for Temperature Monitoring */
AnalogIn temperatureADC;
Expand Down
Loading