Code to run on the charger board (used to charge the car from the mains).

Dependencies:   mbed CUER_CAN

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?

UserRevisionLine numberNew 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