CUER
/
charger_code
Code to run on the charger board (used to charge the car from the mains).
charger.cpp@5:756fae795d37, 2017-07-30 (annotated)
- Committer:
- DasSidG
- Date:
- Sun Jul 30 22:59:37 2017 +0000
- Revision:
- 5:756fae795d37
- Parent:
- 4:f6459580c312
- Child:
- 7:70cf5bff23f9
Made it calculate the voltage error itself.; Made it reset the relevant part of the CAN buffer each time it reads it so that it uses fresh data each time; ; Ready for testing.
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 | void car_interruptHandler(); |
DasSidG | 1:0c77e20b4d4c | 11 | void car_CANDataSentCallback(); |
DasSidG | 1:0c77e20b4d4c | 12 | |
DasSidG | 1:0c77e20b4d4c | 13 | void charger_interruptHandler(); |
DasSidG | 1:0c77e20b4d4c | 14 | void charger_CANDataSentCallback(); |
DasSidG | 1:0c77e20b4d4c | 15 | |
DasSidG | 1:0c77e20b4d4c | 16 | void init(); |
DasSidG | 1:0c77e20b4d4c | 17 | void get_CAN_data(); |
DasSidG | 1:0c77e20b4d4c | 18 | |
DasSidG | 5:756fae795d37 | 19 | void calculate_current(float ¤t); |
DasSidG | 1:0c77e20b4d4c | 20 | void check_timeouts(); |
DasSidG | 1:0c77e20b4d4c | 21 | void update_LEDS(); |
DasSidG | 1:0c77e20b4d4c | 22 | bool idAccepted(int id); |
DasSidG | 1:0c77e20b4d4c | 23 | |
DasSidG | 5:756fae795d37 | 24 | DigitalOut green_led(p21); //charging LED |
DasSidG | 5:756fae795d37 | 25 | DigitalOut yellow_led(p22); //timeout LED |
DasSidG | 5:756fae795d37 | 26 | DigitalOut red_led(p23); //error LED |
DasSidG | 5:756fae795d37 | 27 | DigitalIn charge_switch(p8); //switch to enable charging |
DasSidG | 5:756fae795d37 | 28 | void calculate_current(float voltage_error, float temp_margin, float *current, float *voltage); |
drajan | 0:6d930d0d13a1 | 29 | |
DasSidG | 5:756fae795d37 | 30 | uint8_t charger_status; //status packet given by charger, see Elcon CAN Specification in google drive |
DasSidG | 5:756fae795d37 | 31 | bool precharge_status; |
DasSidG | 5:756fae795d37 | 32 | bool comms_timeout; |
DasSidG | 5:756fae795d37 | 33 | bool charger_failure; |
DasSidG | 5:756fae795d37 | 34 | bool charge_finished; |
DasSidG | 5:756fae795d37 | 35 | bool bms_error; |
DasSidG | 5:756fae795d37 | 36 | |
DasSidG | 5:756fae795d37 | 37 | |
DasSidG | 5:756fae795d37 | 38 | //float temp_margin = 0; //degrees C, this is the max cell temperature minus max cell temperature limit, need to avoid this hitting 0 |
DasSidG | 5:756fae795d37 | 39 | |
DasSidG | 5:756fae795d37 | 40 | float min_cell_voltage = 3600; //mV |
DasSidG | 5:756fae795d37 | 41 | float max_cell_voltage = 3600;//mV |
DasSidG | 5:756fae795d37 | 42 | |
DasSidG | 5:756fae795d37 | 43 | float charger_current; //mA |
DasSidG | 5:756fae795d37 | 44 | float charger_voltage; //mV |
DasSidG | 5:756fae795d37 | 45 | |
DasSidG | 5:756fae795d37 | 46 | float desired_current = 0; //mA |
DasSidG | 5:756fae795d37 | 47 | float desired_voltage = MAX_VOLTAGE; //mV |
DasSidG | 5:756fae795d37 | 48 | |
DasSidG | 5:756fae795d37 | 49 | float voltage_error = 1000; //mV //This = RISING_BALANCE_THRESHOLD - max_cell_voltage |
DasSidG | 5:756fae795d37 | 50 | |
DasSidG | 5:756fae795d37 | 51 | uint8_t charger_control = STOP_CHARGING; |
drajan | 0:6d930d0d13a1 | 52 | |
DasSidG | 1:0c77e20b4d4c | 53 | timeouts_t timeouts; |
DasSidG | 1:0c77e20b4d4c | 54 | |
DasSidG | 1:0c77e20b4d4c | 55 | //CAN stuff. Not that there are two sets because there are two separate CAN buses here; one to communicate with the charger, and one to communicate with the rest of the car (importantly the BMS). |
DasSidG | 1:0c77e20b4d4c | 56 | //The reason that there are two separate CAN buses is because the charger uses the extended CAN frame format, with a 29 bit ID, whereas the car uses the default 11 bit ID. |
DasSidG | 1:0c77e20b4d4c | 57 | CAN car_can(CAR_CAN_READ_PIN, CAR_CAN_WRITE_PIN); //Create a CAN object to handle CAN comms |
DasSidG | 1:0c77e20b4d4c | 58 | CANMessage car_buffer[CAN_BUFFER_SIZE]; //CAN receive buffer |
DasSidG | 1:0c77e20b4d4c | 59 | bool car_safe_to_write[CAN_BUFFER_SIZE]; //Semaphore bit indicating that it's safe to write to the software buffer |
DasSidG | 1:0c77e20b4d4c | 60 | bool car_CAN_data_sent = false; |
DasSidG | 1:0c77e20b4d4c | 61 | |
DasSidG | 1:0c77e20b4d4c | 62 | CAN charger_can(CHARGER_CAN_READ_PIN, CHARGER_CAN_WRITE_PIN); //Create a CAN object to handle CAN comms |
DasSidG | 1:0c77e20b4d4c | 63 | CANMessage charger_buffer[CAN_BUFFER_SIZE]; //CAN receive buffer |
DasSidG | 1:0c77e20b4d4c | 64 | bool charger_safe_to_write[CAN_BUFFER_SIZE]; //Semaphore bit indicating that it's safe to write to the software buffer |
DasSidG | 1:0c77e20b4d4c | 65 | bool charger_CAN_data_sent = false; |
DasSidG | 1:0c77e20b4d4c | 66 | |
DasSidG | 1:0c77e20b4d4c | 67 | int main() { |
drajan | 0:6d930d0d13a1 | 68 | |
DasSidG | 1:0c77e20b4d4c | 69 | init(); |
drajan | 0:6d930d0d13a1 | 70 | |
DasSidG | 1:0c77e20b4d4c | 71 | while(1) { |
DasSidG | 1:0c77e20b4d4c | 72 | |
DasSidG | 1:0c77e20b4d4c | 73 | //Reset error indicators |
DasSidG | 1:0c77e20b4d4c | 74 | comms_timeout = false; |
DasSidG | 1:0c77e20b4d4c | 75 | charger_failure = false; |
DasSidG | 1:0c77e20b4d4c | 76 | bms_error = false; |
DasSidG | 1:0c77e20b4d4c | 77 | |
DasSidG | 1:0c77e20b4d4c | 78 | //get the various data from the CAN packets |
DasSidG | 1:0c77e20b4d4c | 79 | get_CAN_data(); |
DasSidG | 1:0c77e20b4d4c | 80 | |
DasSidG | 1:0c77e20b4d4c | 81 | check_timeouts(); |
DasSidG | 1:0c77e20b4d4c | 82 | update_LEDS(); |
DasSidG | 1:0c77e20b4d4c | 83 | |
DasSidG | 5:756fae795d37 | 84 | charger_control = STOP_CHARGING; |
DasSidG | 5:756fae795d37 | 85 | |
DasSidG | 3:a7626dffb64a | 86 | if (min_cell_voltage > RISING_BALANCE_THRESHOLD || charge_finished) { |
DasSidG | 3:a7626dffb64a | 87 | charge_finished = true; |
DasSidG | 5:756fae795d37 | 88 | if (DEBUG) printf("Charge Finished\r\n"); |
DasSidG | 3:a7626dffb64a | 89 | car_can.write(generate_charging_finished_msg()); |
DasSidG | 5:756fae795d37 | 90 | charger_control = STOP_CHARGING; //set charger control bit to stop charging |
DasSidG | 3:a7626dffb64a | 91 | } |
DasSidG | 5:756fae795d37 | 92 | else if (precharge_status && charge_switch.read()) { |
DasSidG | 5:756fae795d37 | 93 | calculate_current(desired_current); |
DasSidG | 3:a7626dffb64a | 94 | desired_voltage = MAX_VOLTAGE; |
DasSidG | 3:a7626dffb64a | 95 | charge_finished = false; |
DasSidG | 5:756fae795d37 | 96 | charger_control = START_CHARGING; //set charger control bit to start charging |
DasSidG | 3:a7626dffb64a | 97 | } |
DasSidG | 1:0c77e20b4d4c | 98 | |
DasSidG | 1:0c77e20b4d4c | 99 | //send CAN data |
DasSidG | 4:f6459580c312 | 100 | |
DasSidG | 4:f6459580c312 | 101 | Timer t; |
DasSidG | 4:f6459580c312 | 102 | t.start(); |
DasSidG | 4:f6459580c312 | 103 | charger_CAN_data_sent = false; |
DasSidG | 1:0c77e20b4d4c | 104 | charger_can.write(generate_charger_control_msg(desired_voltage, desired_current, charger_control)); //control message to charger |
DasSidG | 4:f6459580c312 | 105 | while(!charger_CAN_data_sent && t.read_ms() < CAN_TIMEOUT_MS); |
DasSidG | 4:f6459580c312 | 106 | |
DasSidG | 4:f6459580c312 | 107 | t.reset(); |
DasSidG | 4:f6459580c312 | 108 | car_CAN_data_sent = false; |
DasSidG | 1:0c77e20b4d4c | 109 | car_can.write(generate_charger_info_msg(charger_voltage, charger_current, charger_status)); //charger info message for rest of car |
DasSidG | 4:f6459580c312 | 110 | while(!car_CAN_data_sent && t.read_ms() < CAN_TIMEOUT_MS); |
DasSidG | 1:0c77e20b4d4c | 111 | |
DasSidG | 5:756fae795d37 | 112 | if (DEBUG) { |
DasSidG | 5:756fae795d37 | 113 | printf("Desired Voltage = %f \r\n", desired_voltage); |
DasSidG | 5:756fae795d37 | 114 | printf("Desired Current = %f \r\n", desired_current); |
DasSidG | 5:756fae795d37 | 115 | printf("Charger voltage = %f \r\n", charger_voltage); |
DasSidG | 5:756fae795d37 | 116 | printf("Charger current = %f \r\n", charger_current); |
DasSidG | 5:756fae795d37 | 117 | printf("Min cell voltage = %f \r\n", min_cell_voltage); |
DasSidG | 5:756fae795d37 | 118 | printf("Max cell voltage = %f \r\n", max_cell_voltage); |
DasSidG | 5:756fae795d37 | 119 | printf("Precharge status is %d \r\n", precharge_status); |
DasSidG | 5:756fae795d37 | 120 | } |
DasSidG | 5:756fae795d37 | 121 | |
DasSidG | 5:756fae795d37 | 122 | wait(TIME_STEP); |
DasSidG | 1:0c77e20b4d4c | 123 | |
drajan | 0:6d930d0d13a1 | 124 | } |
DasSidG | 1:0c77e20b4d4c | 125 | } |
drajan | 0:6d930d0d13a1 | 126 | |
DasSidG | 5:756fae795d37 | 127 | void calculate_current(float ¤t){ |
drajan | 0:6d930d0d13a1 | 128 | |
DasSidG | 5:756fae795d37 | 129 | float Idot; |
DasSidG | 5:756fae795d37 | 130 | |
DasSidG | 3:a7626dffb64a | 131 | static bool balancing = false; |
DasSidG | 5:756fae795d37 | 132 | if (current < 800 && voltage_error < 100 || balancing) { |
DasSidG | 3:a7626dffb64a | 133 | balancing = true; |
DasSidG | 5:756fae795d37 | 134 | if (DEBUG) printf("balancing\r\n"); |
DasSidG | 5:756fae795d37 | 135 | Idot = voltage_error *KI_BALANCE; |
DasSidG | 5:756fae795d37 | 136 | } |
DasSidG | 3:a7626dffb64a | 137 | else { |
DasSidG | 3:a7626dffb64a | 138 | Idot = voltage_error*KI_CHARGE; |
DasSidG | 3:a7626dffb64a | 139 | } |
DasSidG | 5:756fae795d37 | 140 | |
DasSidG | 5:756fae795d37 | 141 | current += Idot*TIME_STEP/1000.0; |
drajan | 0:6d930d0d13a1 | 142 | |
DasSidG | 5:756fae795d37 | 143 | if(current > MAX_CURRENT) { |
DasSidG | 5:756fae795d37 | 144 | current = MAX_CURRENT; |
drajan | 0:6d930d0d13a1 | 145 | } |
DasSidG | 5:756fae795d37 | 146 | if(current < 0) { |
DasSidG | 5:756fae795d37 | 147 | current = 0; |
drajan | 0:6d930d0d13a1 | 148 | } |
DasSidG | 3:a7626dffb64a | 149 | /* |
drajan | 0:6d930d0d13a1 | 150 | //Reduce current if temperature is too high |
drajan | 0:6d930d0d13a1 | 151 | if (temp_margin > TEMP_RAMP_START) { |
drajan | 0:6d930d0d13a1 | 152 | I = 1 - ((temp_margin - TEMP_RAMP_START) / (TEMP_RAMP_FINISH - TEMP_RAMP_START)); |
drajan | 0:6d930d0d13a1 | 153 | } |
drajan | 0:6d930d0d13a1 | 154 | if (temp_margin > TEMP_RAMP_FINISH) { |
drajan | 0:6d930d0d13a1 | 155 | I *= 0; |
drajan | 0:6d930d0d13a1 | 156 | } |
DasSidG | 3:a7626dffb64a | 157 | */ |
drajan | 0:6d930d0d13a1 | 158 | } |
drajan | 0:6d930d0d13a1 | 159 | |
DasSidG | 1:0c77e20b4d4c | 160 | void init() |
DasSidG | 1:0c77e20b4d4c | 161 | { |
DasSidG | 1:0c77e20b4d4c | 162 | for(int i=0; i<CAN_BUFFER_SIZE; i++) |
DasSidG | 1:0c77e20b4d4c | 163 | { |
DasSidG | 1:0c77e20b4d4c | 164 | car_buffer[i].id = BLANK_ID; |
DasSidG | 1:0c77e20b4d4c | 165 | //("%d",buffer[i].id); |
DasSidG | 1:0c77e20b4d4c | 166 | car_safe_to_write[i]= true; |
drajan | 0:6d930d0d13a1 | 167 | |
DasSidG | 1:0c77e20b4d4c | 168 | charger_buffer[i].id = BLANK_ID; |
DasSidG | 1:0c77e20b4d4c | 169 | //("%d",buffer[i].id); |
DasSidG | 1:0c77e20b4d4c | 170 | charger_safe_to_write[i]= true; |
DasSidG | 1:0c77e20b4d4c | 171 | } |
DasSidG | 1:0c77e20b4d4c | 172 | |
DasSidG | 1:0c77e20b4d4c | 173 | //Initialise CAN stuff, attach CAN interrupt handlers |
DasSidG | 1:0c77e20b4d4c | 174 | car_can.frequency(CAN_BIT_RATE); //set transmission rate to agreed bit rate |
DasSidG | 1:0c77e20b4d4c | 175 | car_can.reset(); |
DasSidG | 1:0c77e20b4d4c | 176 | car_can.attach(&car_interruptHandler, CAN::RxIrq); //receive interrupt handler |
DasSidG | 1:0c77e20b4d4c | 177 | car_can.attach(&car_CANDataSentCallback, CAN::TxIrq); //send interrupt handler |
DasSidG | 1:0c77e20b4d4c | 178 | |
DasSidG | 1:0c77e20b4d4c | 179 | charger_can.frequency(CHARGER_CAN_BIT_RATE); //set transmission rate to agreed bit rate |
DasSidG | 1:0c77e20b4d4c | 180 | charger_can.reset(); |
DasSidG | 1:0c77e20b4d4c | 181 | charger_can.attach(&charger_interruptHandler, CAN::RxIrq); //receive interrupt handler |
DasSidG | 1:0c77e20b4d4c | 182 | charger_can.attach(&charger_CANDataSentCallback, CAN::TxIrq); //send interrupt handler |
DasSidG | 1:0c77e20b4d4c | 183 | |
DasSidG | 1:0c77e20b4d4c | 184 | //Start comms timeout timers |
DasSidG | 1:0c77e20b4d4c | 185 | |
DasSidG | 1:0c77e20b4d4c | 186 | timeouts.BMS_timeout.start(); |
DasSidG | 1:0c77e20b4d4c | 187 | timeouts.charger_timeout.start(); |
DasSidG | 5:756fae795d37 | 188 | |
DasSidG | 5:756fae795d37 | 189 | precharge_status = false; |
DasSidG | 1:0c77e20b4d4c | 190 | } |
DasSidG | 1:0c77e20b4d4c | 191 | |
DasSidG | 1:0c77e20b4d4c | 192 | void car_CANDataSentCallback(void) { |
DasSidG | 1:0c77e20b4d4c | 193 | car_CAN_data_sent = true; |
DasSidG | 1:0c77e20b4d4c | 194 | } |
DasSidG | 1:0c77e20b4d4c | 195 | |
DasSidG | 1:0c77e20b4d4c | 196 | void charger_CANDataSentCallback(void) { |
DasSidG | 1:0c77e20b4d4c | 197 | charger_CAN_data_sent = true; |
DasSidG | 1:0c77e20b4d4c | 198 | } |
DasSidG | 1:0c77e20b4d4c | 199 | |
DasSidG | 1:0c77e20b4d4c | 200 | void car_interruptHandler() |
DasSidG | 1:0c77e20b4d4c | 201 | { |
DasSidG | 1:0c77e20b4d4c | 202 | CANMessage msg; |
DasSidG | 1:0c77e20b4d4c | 203 | car_can.read(msg); |
DasSidG | 1:0c77e20b4d4c | 204 | //if(DEBUG) printf("id %d incoming \r\n", msg.id); |
DasSidG | 1:0c77e20b4d4c | 205 | if(idAccepted(msg.id)) { |
DasSidG | 1:0c77e20b4d4c | 206 | for(int i=0; i<CAN_BUFFER_SIZE; i++) { |
DasSidG | 1:0c77e20b4d4c | 207 | if((car_buffer[i].id == msg.id || car_buffer[i].id==BLANK_ID) && car_safe_to_write[i]) { |
DasSidG | 1:0c77e20b4d4c | 208 | //("id %d added to buffer \r\n", msg.id); |
DasSidG | 1:0c77e20b4d4c | 209 | car_buffer[i] = msg; |
DasSidG | 1:0c77e20b4d4c | 210 | //return required so that only first blank buffer entry is converted to incoming message ID each time new message ID is encountered |
DasSidG | 1:0c77e20b4d4c | 211 | return; |
DasSidG | 1:0c77e20b4d4c | 212 | } |
DasSidG | 1:0c77e20b4d4c | 213 | } |
DasSidG | 1:0c77e20b4d4c | 214 | } |
DasSidG | 1:0c77e20b4d4c | 215 | } |
DasSidG | 1:0c77e20b4d4c | 216 | |
DasSidG | 1:0c77e20b4d4c | 217 | void charger_interruptHandler() |
DasSidG | 1:0c77e20b4d4c | 218 | { |
DasSidG | 1:0c77e20b4d4c | 219 | CANMessage msg; |
DasSidG | 1:0c77e20b4d4c | 220 | charger_can.read(msg); |
DasSidG | 1:0c77e20b4d4c | 221 | //if(DEBUG) printf("id %d incoming \r\n", msg.id); |
DasSidG | 1:0c77e20b4d4c | 222 | if(idAccepted(msg.id)) { |
DasSidG | 1:0c77e20b4d4c | 223 | for(int i=0; i<CAN_BUFFER_SIZE; i++) { |
DasSidG | 1:0c77e20b4d4c | 224 | if((charger_buffer[i].id == msg.id || charger_buffer[i].id==BLANK_ID) && charger_safe_to_write[i]) { |
DasSidG | 1:0c77e20b4d4c | 225 | //("id %d added to buffer \r\n", msg.id); |
DasSidG | 1:0c77e20b4d4c | 226 | charger_buffer[i] = msg; |
DasSidG | 1:0c77e20b4d4c | 227 | //return required so that only first blank buffer entry is converted to incoming message ID each time new message ID is encountered |
DasSidG | 1:0c77e20b4d4c | 228 | return; |
DasSidG | 1:0c77e20b4d4c | 229 | } |
DasSidG | 1:0c77e20b4d4c | 230 | } |
DasSidG | 1:0c77e20b4d4c | 231 | } |
DasSidG | 1:0c77e20b4d4c | 232 | } |
DasSidG | 1:0c77e20b4d4c | 233 | |
DasSidG | 1:0c77e20b4d4c | 234 | bool idAccepted(int id) |
DasSidG | 1:0c77e20b4d4c | 235 | { |
DasSidG | 1:0c77e20b4d4c | 236 | switch(id) { |
DasSidG | 1:0c77e20b4d4c | 237 | case BMS_BASE_ID: |
DasSidG | 1:0c77e20b4d4c | 238 | timeouts.BMS_timeout.reset(); |
DasSidG | 1:0c77e20b4d4c | 239 | return true; |
DasSidG | 1:0c77e20b4d4c | 240 | |
DasSidG | 1:0c77e20b4d4c | 241 | case BMS_BASE_ID + MAX_MIN_VOLTAGE: |
DasSidG | 5:756fae795d37 | 242 | case BMS_BASE_ID + BATTERY_STATUS_ID: |
DasSidG | 5:756fae795d37 | 243 | case BMS_BASE_ID + BATTERY_PRECHARGE_ID: |
DasSidG | 1:0c77e20b4d4c | 244 | return true; |
DasSidG | 1:0c77e20b4d4c | 245 | case CHARGER_VI_INFO_ID: |
DasSidG | 1:0c77e20b4d4c | 246 | timeouts.charger_timeout.reset(); |
DasSidG | 1:0c77e20b4d4c | 247 | return true; |
DasSidG | 1:0c77e20b4d4c | 248 | default: |
DasSidG | 1:0c77e20b4d4c | 249 | return false; |
DasSidG | 1:0c77e20b4d4c | 250 | } |
DasSidG | 1:0c77e20b4d4c | 251 | } |
drajan | 0:6d930d0d13a1 | 252 | |
drajan | 0:6d930d0d13a1 | 253 | |
DasSidG | 1:0c77e20b4d4c | 254 | void check_timeouts() //Check if it's been too long since any of the other devices in the car have communicated |
DasSidG | 1:0c77e20b4d4c | 255 | { |
DasSidG | 1:0c77e20b4d4c | 256 | |
DasSidG | 1:0c77e20b4d4c | 257 | if (timeouts.BMS_timeout.read_ms() > BMS_MSG_TIMEOUT_MS) |
DasSidG | 1:0c77e20b4d4c | 258 | { |
DasSidG | 5:756fae795d37 | 259 | if (DEBUG) printf("Error: BMS comms timeout"); |
DasSidG | 1:0c77e20b4d4c | 260 | comms_timeout = true; |
DasSidG | 1:0c77e20b4d4c | 261 | } |
DasSidG | 1:0c77e20b4d4c | 262 | |
DasSidG | 1:0c77e20b4d4c | 263 | if (timeouts.charger_timeout.read_ms() > CHARGER_MSG_TIMEOUT_MS) |
DasSidG | 1:0c77e20b4d4c | 264 | { |
DasSidG | 5:756fae795d37 | 265 | if (DEBUG) printf("Error: Charger comms timeout"); |
DasSidG | 1:0c77e20b4d4c | 266 | comms_timeout = true; |
DasSidG | 1:0c77e20b4d4c | 267 | } |
DasSidG | 1:0c77e20b4d4c | 268 | } |
DasSidG | 1:0c77e20b4d4c | 269 | |
DasSidG | 1:0c77e20b4d4c | 270 | void update_LEDS() { |
DasSidG | 1:0c77e20b4d4c | 271 | if (charger_failure || bms_error) { |
DasSidG | 1:0c77e20b4d4c | 272 | desired_current = 0; |
DasSidG | 1:0c77e20b4d4c | 273 | red_led = 1; |
DasSidG | 1:0c77e20b4d4c | 274 | } |
drajan | 0:6d930d0d13a1 | 275 | |
DasSidG | 1:0c77e20b4d4c | 276 | else if (comms_timeout) { |
DasSidG | 1:0c77e20b4d4c | 277 | desired_current = 0; |
DasSidG | 1:0c77e20b4d4c | 278 | yellow_led = 1; |
DasSidG | 1:0c77e20b4d4c | 279 | } |
DasSidG | 1:0c77e20b4d4c | 280 | |
DasSidG | 1:0c77e20b4d4c | 281 | else if (!charge_finished) { |
DasSidG | 1:0c77e20b4d4c | 282 | green_led = 1; |
DasSidG | 1:0c77e20b4d4c | 283 | } |
DasSidG | 1:0c77e20b4d4c | 284 | |
DasSidG | 1:0c77e20b4d4c | 285 | else { |
DasSidG | 1:0c77e20b4d4c | 286 | red_led = 0; |
DasSidG | 1:0c77e20b4d4c | 287 | yellow_led = 0; |
DasSidG | 1:0c77e20b4d4c | 288 | green_led = 0; |
DasSidG | 4:f6459580c312 | 289 | } |
DasSidG | 3:a7626dffb64a | 290 | |
DasSidG | 1:0c77e20b4d4c | 291 | } |
DasSidG | 1:0c77e20b4d4c | 292 | |
DasSidG | 1:0c77e20b4d4c | 293 | void get_CAN_data() { |
drajan | 0:6d930d0d13a1 | 294 | |
DasSidG | 1:0c77e20b4d4c | 295 | //Import the data from the buffer into a non-volatile, more usable format |
DasSidG | 1:0c77e20b4d4c | 296 | CANMessage car_msgArray[CAN_BUFFER_SIZE]; //Same as above but some functions take message as their parameter |
DasSidG | 1:0c77e20b4d4c | 297 | int car_received_CAN_IDs[CAN_BUFFER_SIZE]; //needed to keep track of which IDs we've received so far |
DasSidG | 1:0c77e20b4d4c | 298 | for (int i = 0; i<CAN_BUFFER_SIZE; ++i) |
DasSidG | 1:0c77e20b4d4c | 299 | { |
DasSidG | 1:0c77e20b4d4c | 300 | car_safe_to_write[i] = false; |
DasSidG | 1:0c77e20b4d4c | 301 | car_received_CAN_IDs[i] = car_buffer[i].id; |
DasSidG | 1:0c77e20b4d4c | 302 | car_msgArray[i] = car_buffer[i]; |
DasSidG | 5:756fae795d37 | 303 | car_buffer[i].id = BLANK_ID; //this effectively clears the buffer, so that we never reuse old values |
DasSidG | 1:0c77e20b4d4c | 304 | car_safe_to_write[i] = true; |
DasSidG | 1:0c77e20b4d4c | 305 | |
DasSidG | 1:0c77e20b4d4c | 306 | //Now actually import the data from the CAN packets into the global variables |
DasSidG | 1:0c77e20b4d4c | 307 | switch (car_received_CAN_IDs[i]) { |
drajan | 0:6d930d0d13a1 | 308 | |
DasSidG | 1:0c77e20b4d4c | 309 | case BMS_BASE_ID: |
DasSidG | 1:0c77e20b4d4c | 310 | break; |
DasSidG | 1:0c77e20b4d4c | 311 | |
DasSidG | 1:0c77e20b4d4c | 312 | case BMS_BASE_ID + MAX_MIN_VOLTAGE: |
DasSidG | 1:0c77e20b4d4c | 313 | get_max_min_voltage(car_msgArray[i], min_cell_voltage, max_cell_voltage); |
DasSidG | 5:756fae795d37 | 314 | voltage_error = RISING_BALANCE_THRESHOLD - max_cell_voltage; |
DasSidG | 1:0c77e20b4d4c | 315 | break; |
DasSidG | 1:0c77e20b4d4c | 316 | |
DasSidG | 1:0c77e20b4d4c | 317 | case BMS_BASE_ID + BATTERY_STATUS_ID: |
DasSidG | 1:0c77e20b4d4c | 318 | get_battery_status(car_msgArray[i], bms_error); |
DasSidG | 1:0c77e20b4d4c | 319 | break; |
DasSidG | 5:756fae795d37 | 320 | |
DasSidG | 5:756fae795d37 | 321 | case BMS_BASE_ID + BATTERY_PRECHARGE_ID: |
DasSidG | 5:756fae795d37 | 322 | check_precharge_status(car_msgArray[i], precharge_status); |
DasSidG | 5:756fae795d37 | 323 | break; |
DasSidG | 5:756fae795d37 | 324 | |
DasSidG | 1:0c77e20b4d4c | 325 | case BLANK_ID: //This means we haven't received this type of message yet, so do nothing |
DasSidG | 1:0c77e20b4d4c | 326 | break; |
DasSidG | 1:0c77e20b4d4c | 327 | default: |
DasSidG | 1:0c77e20b4d4c | 328 | break; |
DasSidG | 1:0c77e20b4d4c | 329 | } |
DasSidG | 1:0c77e20b4d4c | 330 | } |
drajan | 0:6d930d0d13a1 | 331 | |
DasSidG | 1:0c77e20b4d4c | 332 | //Import the data from the buffer into a non-volatile, more usable format |
DasSidG | 1:0c77e20b4d4c | 333 | CANMessage charger_msgArray[CAN_BUFFER_SIZE]; //Same as above but some functions take message as their parameter |
DasSidG | 1:0c77e20b4d4c | 334 | int charger_received_CAN_IDs[CAN_BUFFER_SIZE]; //needed to keep track of which IDs we've received so far |
DasSidG | 1:0c77e20b4d4c | 335 | for (int i = 0; i<CAN_BUFFER_SIZE; ++i) |
DasSidG | 1:0c77e20b4d4c | 336 | { |
DasSidG | 1:0c77e20b4d4c | 337 | charger_safe_to_write[i] = false; |
DasSidG | 1:0c77e20b4d4c | 338 | charger_received_CAN_IDs[i] = charger_buffer[i].id; |
DasSidG | 1:0c77e20b4d4c | 339 | charger_msgArray[i] = charger_buffer[i]; |
DasSidG | 5:756fae795d37 | 340 | charger_buffer[i].id = BLANK_ID; |
DasSidG | 1:0c77e20b4d4c | 341 | charger_safe_to_write[i] = true; |
DasSidG | 1:0c77e20b4d4c | 342 | |
DasSidG | 1:0c77e20b4d4c | 343 | //Now actually import the data from the CAN packets into the global variables |
DasSidG | 1:0c77e20b4d4c | 344 | switch (charger_received_CAN_IDs[i]) { |
DasSidG | 1:0c77e20b4d4c | 345 | |
DasSidG | 1:0c77e20b4d4c | 346 | case CHARGER_VI_INFO_ID: |
DasSidG | 1:0c77e20b4d4c | 347 | get_charger_VI_info(charger_msgArray[i], charger_voltage, charger_current, charger_status); |
DasSidG | 1:0c77e20b4d4c | 348 | if(charger_status bitand 1 == 1) { |
DasSidG | 5:756fae795d37 | 349 | if (DEBUG) printf("Charger status: Hardware Failure\r\n"); |
DasSidG | 1:0c77e20b4d4c | 350 | charger_failure = true; |
DasSidG | 1:0c77e20b4d4c | 351 | } |
DasSidG | 1:0c77e20b4d4c | 352 | |
DasSidG | 1:0c77e20b4d4c | 353 | if(charger_status bitand 2 == 2) { |
DasSidG | 5:756fae795d37 | 354 | if (DEBUG) printf("Charger status: Over Temperature\r\n"); |
DasSidG | 1:0c77e20b4d4c | 355 | charger_failure = true; |
DasSidG | 1:0c77e20b4d4c | 356 | } |
DasSidG | 1:0c77e20b4d4c | 357 | |
DasSidG | 1:0c77e20b4d4c | 358 | if(charger_status bitand 4 == 4) { |
DasSidG | 5:756fae795d37 | 359 | if (DEBUG) printf("Charger status: Input Voltage Wrong\r\n"); |
DasSidG | 1:0c77e20b4d4c | 360 | charger_failure = true; |
DasSidG | 1:0c77e20b4d4c | 361 | } |
DasSidG | 1:0c77e20b4d4c | 362 | |
DasSidG | 1:0c77e20b4d4c | 363 | if(charger_status bitand 8 == 8) { |
DasSidG | 5:756fae795d37 | 364 | if (DEBUG) printf("Charger status: Reverse Polarity\r\n"); |
DasSidG | 1:0c77e20b4d4c | 365 | charger_failure = true; |
DasSidG | 1:0c77e20b4d4c | 366 | } |
DasSidG | 1:0c77e20b4d4c | 367 | |
DasSidG | 1:0c77e20b4d4c | 368 | if(charger_status bitand 16 == 16) { |
DasSidG | 5:756fae795d37 | 369 | if (DEBUG) printf("Charger status: communication timeout\r\n"); |
DasSidG | 1:0c77e20b4d4c | 370 | charger_failure = true; |
DasSidG | 1:0c77e20b4d4c | 371 | } |
DasSidG | 1:0c77e20b4d4c | 372 | break; |
DasSidG | 1:0c77e20b4d4c | 373 | case BLANK_ID: //This means we haven't received this type of message yet, so do nothing |
DasSidG | 1:0c77e20b4d4c | 374 | break; |
DasSidG | 1:0c77e20b4d4c | 375 | default: |
DasSidG | 1:0c77e20b4d4c | 376 | break; |
DasSidG | 1:0c77e20b4d4c | 377 | } |
drajan | 0:6d930d0d13a1 | 378 | } |
drajan | 0:6d930d0d13a1 | 379 | } |