CUER
/
charger_code
Code to run on the charger board (used to charge the car from the mains).
charger.cpp@7:70cf5bff23f9, 2017-09-10 (annotated)
- Committer:
- DasSidG
- Date:
- Sun Sep 10 11:10:54 2017 +0000
- Revision:
- 7:70cf5bff23f9
- Parent:
- 5:756fae795d37
- Child:
- 8:e5c07b9b8593
Changed charging algorithm; Refactored code to move stuff out of charger.cpp and into other files
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
drajan | 0:6d930d0d13a1 | 1 | #include "charger.h" |
DasSidG | 1:0c77e20b4d4c | 2 | #include "mbed.h" |
DasSidG | 1:0c77e20b4d4c | 3 | #include "CAN_Data.h" |
DasSidG | 1:0c77e20b4d4c | 4 | #include "CAN_IDs.h" |
DasSidG | 1:0c77e20b4d4c | 5 | #include "Data_types.h" |
DasSidG | 1:0c77e20b4d4c | 6 | #include "CANParserCharger.h" |
DasSidG | 1:0c77e20b4d4c | 7 | |
DasSidG | 1:0c77e20b4d4c | 8 | using namespace CAN_IDs; |
DasSidG | 1:0c77e20b4d4c | 9 | |
DasSidG | 1:0c77e20b4d4c | 10 | |
DasSidG | 7:70cf5bff23f9 | 11 | |
DasSidG | 1:0c77e20b4d4c | 12 | |
DasSidG | 1:0c77e20b4d4c | 13 | void init(); |
DasSidG | 7:70cf5bff23f9 | 14 | |
DasSidG | 1:0c77e20b4d4c | 15 | |
DasSidG | 7:70cf5bff23f9 | 16 | float calculate_desired_current(float charger_current, float min_cell_voltage); |
DasSidG | 1:0c77e20b4d4c | 17 | void check_timeouts(); |
DasSidG | 1:0c77e20b4d4c | 18 | void update_LEDS(); |
DasSidG | 7:70cf5bff23f9 | 19 | |
DasSidG | 1:0c77e20b4d4c | 20 | |
DasSidG | 5:756fae795d37 | 21 | DigitalOut green_led(p21); //charging LED |
DasSidG | 5:756fae795d37 | 22 | DigitalOut yellow_led(p22); //timeout LED |
DasSidG | 5:756fae795d37 | 23 | DigitalOut red_led(p23); //error LED |
DasSidG | 5:756fae795d37 | 24 | DigitalIn charge_switch(p8); //switch to enable charging |
drajan | 0:6d930d0d13a1 | 25 | |
DasSidG | 5:756fae795d37 | 26 | uint8_t charger_status; //status packet given by charger, see Elcon CAN Specification in google drive |
DasSidG | 5:756fae795d37 | 27 | bool precharge_status; |
DasSidG | 5:756fae795d37 | 28 | bool comms_timeout; |
DasSidG | 5:756fae795d37 | 29 | bool charger_failure; |
DasSidG | 5:756fae795d37 | 30 | bool charge_finished; |
DasSidG | 5:756fae795d37 | 31 | bool bms_error; |
DasSidG | 7:70cf5bff23f9 | 32 | bool charging; |
DasSidG | 5:756fae795d37 | 33 | |
DasSidG | 5:756fae795d37 | 34 | float min_cell_voltage = 3600; //mV |
DasSidG | 5:756fae795d37 | 35 | float max_cell_voltage = 3600;//mV |
DasSidG | 5:756fae795d37 | 36 | |
DasSidG | 5:756fae795d37 | 37 | float charger_current; //mA |
DasSidG | 5:756fae795d37 | 38 | float charger_voltage; //mV |
DasSidG | 5:756fae795d37 | 39 | |
DasSidG | 5:756fae795d37 | 40 | float desired_current = 0; //mA |
DasSidG | 7:70cf5bff23f9 | 41 | float desired_voltage = MAX_PACK_VOLTAGE; //mV |
DasSidG | 5:756fae795d37 | 42 | |
DasSidG | 5:756fae795d37 | 43 | float voltage_error = 1000; //mV //This = RISING_BALANCE_THRESHOLD - max_cell_voltage |
DasSidG | 5:756fae795d37 | 44 | |
DasSidG | 5:756fae795d37 | 45 | uint8_t charger_control = STOP_CHARGING; |
drajan | 0:6d930d0d13a1 | 46 | |
DasSidG | 1:0c77e20b4d4c | 47 | timeouts_t timeouts; |
DasSidG | 1:0c77e20b4d4c | 48 | |
DasSidG | 1:0c77e20b4d4c | 49 | int main() { |
drajan | 0:6d930d0d13a1 | 50 | |
DasSidG | 1:0c77e20b4d4c | 51 | init(); |
drajan | 0:6d930d0d13a1 | 52 | |
DasSidG | 1:0c77e20b4d4c | 53 | while(1) { |
DasSidG | 7:70cf5bff23f9 | 54 | |
DasSidG | 1:0c77e20b4d4c | 55 | //get the various data from the CAN packets |
DasSidG | 1:0c77e20b4d4c | 56 | get_CAN_data(); |
DasSidG | 1:0c77e20b4d4c | 57 | |
DasSidG | 1:0c77e20b4d4c | 58 | check_timeouts(); |
DasSidG | 1:0c77e20b4d4c | 59 | update_LEDS(); |
DasSidG | 1:0c77e20b4d4c | 60 | |
DasSidG | 5:756fae795d37 | 61 | charger_control = STOP_CHARGING; |
DasSidG | 5:756fae795d37 | 62 | |
DasSidG | 7:70cf5bff23f9 | 63 | //if (min_cell_voltage > RISING_BALANCE_THRESHOLD || charge_finished) { //Note: if balancing is implemented, use this version instead |
DasSidG | 7:70cf5bff23f9 | 64 | if ((max_cell_voltage > CHARGING_FINISHED_THRESHOLD_VOLTAGE && charger_current < CHARGING_FINISHED_THRESHOLD_CURRENT) |
DasSidG | 7:70cf5bff23f9 | 65 | || charge_finished |
DasSidG | 7:70cf5bff23f9 | 66 | || max_cell_voltage > MAX_CELL_VOLTAGE) { |
DasSidG | 3:a7626dffb64a | 67 | charge_finished = true; |
DasSidG | 7:70cf5bff23f9 | 68 | charging = false; |
DasSidG | 5:756fae795d37 | 69 | if (DEBUG) printf("Charge Finished\r\n"); |
DasSidG | 3:a7626dffb64a | 70 | car_can.write(generate_charging_finished_msg()); |
DasSidG | 5:756fae795d37 | 71 | charger_control = STOP_CHARGING; //set charger control bit to stop charging |
DasSidG | 3:a7626dffb64a | 72 | } |
DasSidG | 7:70cf5bff23f9 | 73 | else if (precharge_status && !bms_error && !comms_timeout && !charger_failure && charge_switch.read()) { |
DasSidG | 7:70cf5bff23f9 | 74 | charging = true; |
DasSidG | 7:70cf5bff23f9 | 75 | desired_current = calculate_desired_current(charger_current, min_cell_voltage); |
DasSidG | 7:70cf5bff23f9 | 76 | desired_voltage = MAX_PACK_VOLTAGE; |
DasSidG | 3:a7626dffb64a | 77 | charge_finished = false; |
DasSidG | 5:756fae795d37 | 78 | charger_control = START_CHARGING; //set charger control bit to start charging |
DasSidG | 3:a7626dffb64a | 79 | } |
DasSidG | 1:0c77e20b4d4c | 80 | |
DasSidG | 1:0c77e20b4d4c | 81 | //send CAN data |
DasSidG | 4:f6459580c312 | 82 | |
DasSidG | 4:f6459580c312 | 83 | Timer t; |
DasSidG | 4:f6459580c312 | 84 | t.start(); |
DasSidG | 4:f6459580c312 | 85 | charger_CAN_data_sent = false; |
DasSidG | 1:0c77e20b4d4c | 86 | charger_can.write(generate_charger_control_msg(desired_voltage, desired_current, charger_control)); //control message to charger |
DasSidG | 4:f6459580c312 | 87 | while(!charger_CAN_data_sent && t.read_ms() < CAN_TIMEOUT_MS); |
DasSidG | 4:f6459580c312 | 88 | |
DasSidG | 4:f6459580c312 | 89 | t.reset(); |
DasSidG | 4:f6459580c312 | 90 | car_CAN_data_sent = false; |
DasSidG | 1:0c77e20b4d4c | 91 | car_can.write(generate_charger_info_msg(charger_voltage, charger_current, charger_status)); //charger info message for rest of car |
DasSidG | 4:f6459580c312 | 92 | while(!car_CAN_data_sent && t.read_ms() < CAN_TIMEOUT_MS); |
DasSidG | 1:0c77e20b4d4c | 93 | |
DasSidG | 5:756fae795d37 | 94 | if (DEBUG) { |
DasSidG | 5:756fae795d37 | 95 | printf("Desired Voltage = %f \r\n", desired_voltage); |
DasSidG | 5:756fae795d37 | 96 | printf("Desired Current = %f \r\n", desired_current); |
DasSidG | 5:756fae795d37 | 97 | printf("Charger voltage = %f \r\n", charger_voltage); |
DasSidG | 5:756fae795d37 | 98 | printf("Charger current = %f \r\n", charger_current); |
DasSidG | 5:756fae795d37 | 99 | printf("Min cell voltage = %f \r\n", min_cell_voltage); |
DasSidG | 5:756fae795d37 | 100 | printf("Max cell voltage = %f \r\n", max_cell_voltage); |
DasSidG | 5:756fae795d37 | 101 | printf("Precharge status is %d \r\n", precharge_status); |
DasSidG | 7:70cf5bff23f9 | 102 | printf("Voltage error is %f \r\n", voltage_error); |
DasSidG | 7:70cf5bff23f9 | 103 | printf("\r\n"); |
DasSidG | 5:756fae795d37 | 104 | } |
DasSidG | 5:756fae795d37 | 105 | |
DasSidG | 7:70cf5bff23f9 | 106 | wait_ms(500); |
DasSidG | 1:0c77e20b4d4c | 107 | |
drajan | 0:6d930d0d13a1 | 108 | } |
DasSidG | 1:0c77e20b4d4c | 109 | } |
drajan | 0:6d930d0d13a1 | 110 | |
DasSidG | 7:70cf5bff23f9 | 111 | float calculate_desired_current(float _charger_current, float _min_cell_voltage){ |
DasSidG | 7:70cf5bff23f9 | 112 | float _desired_current; |
DasSidG | 7:70cf5bff23f9 | 113 | _desired_current += 500; //gradually ramp up current when charging starts |
DasSidG | 5:756fae795d37 | 114 | |
DasSidG | 7:70cf5bff23f9 | 115 | if (_min_cell_voltage < DEEP_DISCHARGE_THRESHOLD_VOLTAGE) { |
DasSidG | 7:70cf5bff23f9 | 116 | if(_desired_current > DEEP_DISCHARGE_MAX_CURRENT) { |
DasSidG | 7:70cf5bff23f9 | 117 | _desired_current = DEEP_DISCHARGE_MAX_CURRENT; |
DasSidG | 7:70cf5bff23f9 | 118 | } |
DasSidG | 7:70cf5bff23f9 | 119 | } |
DasSidG | 7:70cf5bff23f9 | 120 | |
DasSidG | 7:70cf5bff23f9 | 121 | else if(_desired_current > MAX_CURRENT) { |
DasSidG | 7:70cf5bff23f9 | 122 | _desired_current = MAX_CURRENT; |
DasSidG | 7:70cf5bff23f9 | 123 | } |
DasSidG | 7:70cf5bff23f9 | 124 | if(_desired_current < 0) { |
DasSidG | 7:70cf5bff23f9 | 125 | _desired_current = 0; |
DasSidG | 3:a7626dffb64a | 126 | } |
DasSidG | 5:756fae795d37 | 127 | |
DasSidG | 7:70cf5bff23f9 | 128 | return _desired_current; |
drajan | 0:6d930d0d13a1 | 129 | } |
drajan | 0:6d930d0d13a1 | 130 | |
DasSidG | 1:0c77e20b4d4c | 131 | void init() |
DasSidG | 1:0c77e20b4d4c | 132 | { |
DasSidG | 1:0c77e20b4d4c | 133 | //Start comms timeout timers |
DasSidG | 1:0c77e20b4d4c | 134 | timeouts.BMS_timeout.start(); |
DasSidG | 1:0c77e20b4d4c | 135 | timeouts.charger_timeout.start(); |
DasSidG | 5:756fae795d37 | 136 | precharge_status = false; |
DasSidG | 7:70cf5bff23f9 | 137 | //Reset error indicators |
DasSidG | 7:70cf5bff23f9 | 138 | comms_timeout = false; |
DasSidG | 7:70cf5bff23f9 | 139 | charger_failure = false; |
DasSidG | 7:70cf5bff23f9 | 140 | bms_error = false; |
DasSidG | 7:70cf5bff23f9 | 141 | charging = false; |
DasSidG | 1:0c77e20b4d4c | 142 | } |
DasSidG | 1:0c77e20b4d4c | 143 | |
DasSidG | 1:0c77e20b4d4c | 144 | void check_timeouts() //Check if it's been too long since any of the other devices in the car have communicated |
DasSidG | 1:0c77e20b4d4c | 145 | { |
DasSidG | 1:0c77e20b4d4c | 146 | |
DasSidG | 1:0c77e20b4d4c | 147 | if (timeouts.BMS_timeout.read_ms() > BMS_MSG_TIMEOUT_MS) |
DasSidG | 1:0c77e20b4d4c | 148 | { |
DasSidG | 5:756fae795d37 | 149 | if (DEBUG) printf("Error: BMS comms timeout"); |
DasSidG | 1:0c77e20b4d4c | 150 | comms_timeout = true; |
DasSidG | 1:0c77e20b4d4c | 151 | } |
DasSidG | 1:0c77e20b4d4c | 152 | |
DasSidG | 1:0c77e20b4d4c | 153 | if (timeouts.charger_timeout.read_ms() > CHARGER_MSG_TIMEOUT_MS) |
DasSidG | 1:0c77e20b4d4c | 154 | { |
DasSidG | 5:756fae795d37 | 155 | if (DEBUG) printf("Error: Charger comms timeout"); |
DasSidG | 1:0c77e20b4d4c | 156 | comms_timeout = true; |
DasSidG | 1:0c77e20b4d4c | 157 | } |
DasSidG | 1:0c77e20b4d4c | 158 | } |
DasSidG | 1:0c77e20b4d4c | 159 | |
DasSidG | 1:0c77e20b4d4c | 160 | void update_LEDS() { |
DasSidG | 1:0c77e20b4d4c | 161 | if (charger_failure || bms_error) { |
DasSidG | 1:0c77e20b4d4c | 162 | desired_current = 0; |
DasSidG | 1:0c77e20b4d4c | 163 | red_led = 1; |
DasSidG | 1:0c77e20b4d4c | 164 | } |
drajan | 0:6d930d0d13a1 | 165 | |
DasSidG | 1:0c77e20b4d4c | 166 | else if (comms_timeout) { |
DasSidG | 1:0c77e20b4d4c | 167 | desired_current = 0; |
DasSidG | 1:0c77e20b4d4c | 168 | yellow_led = 1; |
DasSidG | 1:0c77e20b4d4c | 169 | } |
DasSidG | 1:0c77e20b4d4c | 170 | |
DasSidG | 1:0c77e20b4d4c | 171 | else if (!charge_finished) { |
DasSidG | 1:0c77e20b4d4c | 172 | green_led = 1; |
DasSidG | 1:0c77e20b4d4c | 173 | } |
DasSidG | 1:0c77e20b4d4c | 174 | |
DasSidG | 1:0c77e20b4d4c | 175 | else { |
DasSidG | 1:0c77e20b4d4c | 176 | red_led = 0; |
DasSidG | 1:0c77e20b4d4c | 177 | yellow_led = 0; |
DasSidG | 1:0c77e20b4d4c | 178 | green_led = 0; |
DasSidG | 4:f6459580c312 | 179 | } |
DasSidG | 3:a7626dffb64a | 180 | |
DasSidG | 1:0c77e20b4d4c | 181 | } |
DasSidG | 1:0c77e20b4d4c | 182 |