MCU
Loading...
Searching...
No Matches
AMSInterface.cpp
Go to the documentation of this file.
1#include "AMSInterface.h"
2#include "SysClock.h"
3
4/* Send inverter CAN messages with new CAN library */
5template<typename U>
6void AMSInterface::enqueue_new_CAN(U* structure, uint32_t (* pack_function)(U*, uint8_t*, uint8_t*, uint8_t*)) {
7 CAN_message_t can_msg;
8 can_msg.id = pack_function(structure, can_msg.buf, &can_msg.len, (uint8_t*) &can_msg.flags.extended);
9 uint8_t buf[sizeof(CAN_message_t)] = {};
10 memmove(buf, &can_msg, sizeof(CAN_message_t));
11 msg_queue_->push_back(buf, sizeof(CAN_message_t));
12}
13
14void AMSInterface::init(SysTick_s &initial_tick) {
15
16 // Set pin mode
17 pinMode(pin_software_ok_, OUTPUT);
18
19 set_heartbeat(initial_tick.millis);
20
21 last_tick_ = initial_tick;
22
23 timestamp_start_ = -1; //starts at -1
24
25 // Initializes the bms_voltages_ member variable to an invalid state. This will
26 // get overridden once retrieve_voltage_CAN() has been called at least once.
27 bms_voltages_.low_voltage_ro = 0xFFFFU;
28 bms_voltages_.high_voltage_ro = 0x1111U;
29
30}
31
33
34 digitalWrite(pin_software_ok_, HIGH);
35
36}
37
38//SETTERS//
40 if (ok_high)
41 digitalWrite(pin_software_ok_, HIGH);
42 else
43 digitalWrite(pin_software_ok_, LOW);
44}
45
46void AMSInterface::set_heartbeat(unsigned long curr_millis) {
47 last_heartbeat_time_ = curr_millis;
48}
49
50bool AMSInterface::heartbeat_received(unsigned long curr_millis) {
51 return ((curr_millis - last_heartbeat_time_) < HEARTBEAT_INTERVAL);
52}
53
55 return (HYTECH_low_voltage_ro_fromS(bms_voltages_.low_voltage_ro) < PACK_CHARGE_CRIT_LOWEST_CELL_THRESHOLD);
56}
57
59 return (HYTECH_total_voltage_ro_fromS(bms_voltages_.total_voltage_ro) < PACK_CHARGE_CRIT_TOTAL_THRESHOLD);
60}
61
64}
65
66//GETTERS//
68 bms_high_temp = bms_temperatures_.get_high_temperature() / 100.0;
71}
72
74 bms_low_voltage = HYTECH_low_voltage_ro_fromS(bms_voltages_.low_voltage_ro);
77}
78
80 int i = 0;
81 float lowest_voltage = HYTECH_low_voltage_ro_fromS(bms_voltages_.low_voltage_ro);
82
83 while (lowest_voltage - VOLTAGE_LOOKUP_TABLE[i] < 0) {
84 i++;
85 }
86 charge_ = ( (100 - i) / 100.0) * MAX_PACK_CHARGE;
87 SoC_ = (charge_ / MAX_PACK_CHARGE) * 100;
88
89 return charge_;
90}
91
92void AMSInterface::calculate_SoC_em(const SysTick_s &tick) {
93 unsigned long delta_time_micros = tick.micros - last_tick_.micros;
94
95 float current = HYTECH_em_current_ro_fromS(em_measurements_.em_current_ro); // Current in amps
96
97 // coulombs = amps * microseconds * (1sec / 1000000 microsec)
98 charge_ -= (current * delta_time_micros) / 1000000;
99
100 SoC_ = (charge_ / MAX_PACK_CHARGE) * 100;
101}
102
103void AMSInterface::calculate_SoC_acu(const SysTick_s &tick) {
104 unsigned long delta_time_micros = tick.micros - last_tick_.micros;
105
106 // Converts analog read (from 0 to 4095) into some value (0.0 to 3.3)
107 // float current = HYTECH_current_shunt_read_ro_fromS(acu_shunt_measurements_.current_shunt_read_ro);
108
109 // shunt_voltage ranges from -3.33 to 2.635
110 // float shunt_voltage = (current * (9.22 / 5.1)) - 3.3 - 0.03;
111
112 // calc_current ranges from -666 to 527.176
113 // float calc_current = (shunt_voltage / 0.005);
114 charge_ -= (HYTECH_current_shunt_read_ro_fromS(acu_shunt_measurements_.current_shunt_read_ro) * delta_time_micros) / 1000000;
115
116 SoC_ = (charge_ / MAX_PACK_CHARGE) * 100;
117}
118
119void AMSInterface::tick(const SysTick_s &tick) {
120
121 // Only calculate the updated SoC if charge has been properly initialized.
123 // Do not edit this block! If both calculate_SoC_em AND calculate_SoC_acu are run,
124 // then the charge will be subtracted from the SoC member variable twice.
125 if (use_em_for_soc_) {
127 } else {
129 }
130 }
131
132 // If AMSInterface has a valid reading in bms_voltages_ and enough time has passed since init(), then initialize charge
134
137
138 }
139
140 // Send CAN message
141 // enqueue_state_of_charge_CAN();
142 STATE_OF_CHARGE_t soc_struct;
143 soc_struct.charge_percentage_ro = HYTECH_charge_percentage_ro_toS(SoC_);
144 soc_struct.charge_coulombs_ro = HYTECH_charge_coulombs_ro_toS(charge_);
145 soc_struct.min_cell_voltage_est_ro = HYTECH_min_cell_voltage_est_ro_toS(VOLTAGE_LOOKUP_TABLE[100 - (int) SoC_]);
146 enqueue_new_CAN<STATE_OF_CHARGE_t>(&soc_struct, Pack_STATE_OF_CHARGE_hytech);
147
149}
150
151//RETRIEVE CAN MESSAGES//
152void AMSInterface::retrieve_status_CAN(unsigned long curr_millis, CAN_message_t &recvd_msg) {
153 bms_status_.load(recvd_msg.buf);
154 set_heartbeat(curr_millis);
155}
156
157void AMSInterface::retrieve_temp_CAN(CAN_message_t &recvd_msg) {
158 bms_temperatures_.load(recvd_msg.buf);
159}
160
161void AMSInterface::retrieve_voltage_CAN(CAN_message_t &can_msg) {
162 Unpack_BMS_VOLTAGES_hytech(&bms_voltages_, can_msg.buf, can_msg.len);
163
165 {
168 }
169
170}
171
172void AMSInterface::retrieve_em_measurement_CAN(CAN_message_t &can_msg) {
173 Unpack_EM_MEASUREMENT_hytech(&em_measurements_, can_msg.buf, can_msg.len);
174}
175
176void AMSInterface::retrieve_current_shunt_CAN(const CAN_message_t &can_msg) {
177 Unpack_ACU_SHUNT_MEASUREMENTS_hytech(&acu_shunt_measurements_, can_msg.buf, can_msg.len);
178}
179
181 float voltage_lim_factor = 1.0;
182 float startDerateVoltage = 3.5;
183 float endDerateVoltage = 3.2;
184 float voltage_lim_max = 1;
185 float voltage_lim_min = 0.2;
186
187 float temp_lim_factor = 1.0;
188 float startDerateTemp = 50;
189 float stopDerateTemp = 58;
190 float temp_lim_max = 1;
191 float temp_lim_min = 0.2;
192
194 //float_map equivalient because new code is bad
195 voltage_lim_factor = (filtered_min_cell_voltage - startDerateVoltage) * (voltage_lim_min - voltage_lim_max) / (endDerateVoltage - startDerateVoltage) + voltage_lim_max;
196 voltage_lim_factor = max(min(voltage_lim_max, voltage_lim_factor), voltage_lim_min);
197
198 temp_lim_factor = (filtered_max_cell_temp - startDerateTemp) * (temp_lim_min - temp_lim_max) / (stopDerateTemp - startDerateTemp) + temp_lim_max;
199 temp_lim_factor = max(min(temp_lim_factor, temp_lim_max), temp_lim_min);
200
201 acc_derate_factor = min(temp_lim_factor,voltage_lim_factor);
202}
203
206 return acc_derate_factor;
207}
208
209
float get_acc_derate_factor()
bool has_initialized_charge_
Definition: AMSInterface.h:250
float cell_voltage_alpha
Definition: AMSInterface.h:218
void tick(const SysTick_s &tick)
BMS_VOLTAGES_t bms_voltages_
Definition: AMSInterface.h:207
float acc_derate_factor
Definition: AMSInterface.h:220
float filtered_min_cell_voltage
Definition: AMSInterface.h:216
void retrieve_current_shunt_CAN(const CAN_message_t &can_msg)
void set_heartbeat(unsigned long curr_millis)
SysTick_s last_tick_
Definition: AMSInterface.h:245
BMS_temperatures bms_temperatures_
Definition: AMSInterface.h:204
float get_filtered_min_cell_voltage()
float bms_low_voltage
Definition: AMSInterface.h:214
ACU_SHUNT_MEASUREMENTS_t acu_shunt_measurements_
Definition: AMSInterface.h:205
bool is_below_pack_charge_critical_total_thresh()
void init(SysTick_s &initial_tick)
void retrieve_status_CAN(unsigned long curr_millis, CAN_message_t &recvd_msg)
void retrieve_temp_CAN(CAN_message_t &recvd_msg)
float bms_high_temp
Definition: AMSInterface.h:213
void enqueue_new_CAN(U *structure, uint32_t(*pack_function)(U *, uint8_t *, uint8_t *, uint8_t *))
Definition: AMSInterface.cpp:6
unsigned long last_heartbeat_time_
Definition: AMSInterface.h:210
bool heartbeat_received(unsigned long curr_millis)
void calculate_SoC_acu(const SysTick_s &tick)
bool use_em_for_soc_
Definition: AMSInterface.h:227
float cell_temp_alpha
Definition: AMSInterface.h:217
float get_filtered_max_cell_temp()
unsigned long timestamp_start_
Definition: AMSInterface.h:261
int pin_software_ok_
Definition: AMSInterface.h:200
void set_state_ok_high(bool ok_high)
bool has_received_bms_voltage_
Definition: AMSInterface.h:256
BMS_status bms_status_
Definition: AMSInterface.h:203
bool is_below_pack_charge_critical_low_thresh()
void retrieve_voltage_CAN(CAN_message_t &recvd_msg)
EM_MEASUREMENT_t em_measurements_
Definition: AMSInterface.h:206
CANBufferType * msg_queue_
Definition: AMSInterface.h:197
float initialize_charge()
void set_start_state()
float filtered_max_cell_temp
Definition: AMSInterface.h:215
void retrieve_em_measurement_CAN(CAN_message_t &can_msg)
const float VOLTAGE_LOOKUP_TABLE[101]
Definition: AMSInterface.h:187
bool pack_charge_is_critical()
void calculate_acc_derate_factor()
void calculate_SoC_em(const SysTick_s &tick)
const unsigned short MAX_PACK_CHARGE
Definition: AMSInterface.h:22
const unsigned long PACK_CHARGE_CRIT_LOWEST_CELL_THRESHOLD
Definition: AMSInterface.h:16
const unsigned long PACK_CHARGE_CRIT_TOTAL_THRESHOLD
Definition: AMSInterface.h:15
const unsigned long DEFAULT_INITIALIZATION_WAIT_INTERVAL
Definition: AMSInterface.h:23
const unsigned long HEARTBEAT_INTERVAL
Definition: AMSInterface.h:14