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