Has base BMU code but sends dummy temperature and voltage readings to test CAN

Dependencies:   CUER_CAN DS1820 LTC2943 LTC6804 mbed

Fork of BMS_BMUCore_Max by CUER

Committer:
lcockerton62
Date:
Fri Dec 30 16:04:10 2016 +0000
Revision:
2:94716229ecc3
Parent:
1:51477fe4851b
Child:
4:9050c5d6925e
Formatted code

Who changed what in which revision?

UserRevisionLine numberNew contents of line
lcockerton62 1:51477fe4851b 1 /*
lcockerton62 0:0a5f554d2a16 2 Should also consider the different errors that need to be sent
lcockerton62 0:0a5f554d2a16 3 */
lcockerton62 0:0a5f554d2a16 4 #include "mbed.h"
lcockerton62 0:0a5f554d2a16 5 #include "CANParserBMU.h"
lcockerton62 0:0a5f554d2a16 6 #include "Data_Types_BMU.h"
lcockerton62 0:0a5f554d2a16 7 #include "CAN_Data.h"
lcockerton62 0:0a5f554d2a16 8 #include "CAN_IDs.h"
lcockerton62 1:51477fe4851b 9 #include "EEPROM_I2C.h"
lcockerton62 1:51477fe4851b 10 #include "Temperature.h"
lcockerton62 0:0a5f554d2a16 11
lcockerton62 0:0a5f554d2a16 12 using namespace CAN_IDs;
lcockerton62 0:0a5f554d2a16 13
lcockerton62 0:0a5f554d2a16 14 // Function definitions
lcockerton62 1:51477fe4851b 15 void transmit_data(BMU_data measurements,uint32_t status);
lcockerton62 1:51477fe4851b 16 void read_temperature_sensors(BMU_data &measurements);
lcockerton62 0:0a5f554d2a16 17 void update_SOC();
lcockerton62 0:0a5f554d2a16 18 void init();
lcockerton62 1:51477fe4851b 19 void write_SOC_EEPROM(BMU_data &measurements,uint16_t start_address);
lcockerton62 1:51477fe4851b 20 uint16_t read_EEPROM_startup(BMU_data &measurements);
lcockerton62 1:51477fe4851b 21 uint32_t check_measurements(BMU_data &measurements);
lcockerton62 1:51477fe4851b 22 void take_measurements(BMU_data &measurements);
lcockerton62 0:0a5f554d2a16 23
lcockerton62 0:0a5f554d2a16 24 CAN can(CAN_READ_PIN, CAN_WRITE_PIN); //Create a CAN object to handle CAN comms
lcockerton62 0:0a5f554d2a16 25
lcockerton62 1:51477fe4851b 26 Timeout loop_delay;
lcockerton62 1:51477fe4851b 27 bool delay_finished = false;
lcockerton62 2:94716229ecc3 28
lcockerton62 2:94716229ecc3 29 void loop_delay_callback(void)
lcockerton62 2:94716229ecc3 30 {
lcockerton62 1:51477fe4851b 31 delay_finished = true;
lcockerton62 1:51477fe4851b 32 }
lcockerton62 1:51477fe4851b 33
lcockerton62 0:0a5f554d2a16 34 int main()
lcockerton62 0:0a5f554d2a16 35 {
lcockerton62 1:51477fe4851b 36 BMU_data measurements;
lcockerton62 1:51477fe4851b 37 uint16_t current_EEPROM_address;
lcockerton62 1:51477fe4851b 38 uint32_t status;
lcockerton62 0:0a5f554d2a16 39 int c = 0;
lcockerton62 0:0a5f554d2a16 40 init();
lcockerton62 1:51477fe4851b 41 current_EEPROM_address = read_EEPROM_startup(measurements);
lcockerton62 0:0a5f554d2a16 42 // Read from the eeprom at startup to fill in the values
lcockerton62 1:51477fe4851b 43 while (true) {
lcockerton62 2:94716229ecc3 44
lcockerton62 1:51477fe4851b 45 // Take measurements from the sensors
lcockerton62 1:51477fe4851b 46 take_measurements(measurements);
lcockerton62 0:0a5f554d2a16 47 // Dont want to read the temperature sensors during each iteration of the loop
lcockerton62 1:51477fe4851b 48 if (c == 0) {
lcockerton62 1:51477fe4851b 49 read_temperature_sensors(measurements);
lcockerton62 1:51477fe4851b 50 } else if(c >= 4) {
lcockerton62 0:0a5f554d2a16 51 c = -1;
lcockerton62 0:0a5f554d2a16 52 }
lcockerton62 0:0a5f554d2a16 53 c++;
lcockerton62 0:0a5f554d2a16 54
lcockerton62 1:51477fe4851b 55 // Check data for errors
lcockerton62 1:51477fe4851b 56 status = check_measurements(measurements);
lcockerton62 1:51477fe4851b 57
lcockerton62 0:0a5f554d2a16 58 // Update the SOC
lcockerton62 0:0a5f554d2a16 59 update_SOC();
lcockerton62 0:0a5f554d2a16 60
lcockerton62 1:51477fe4851b 61 //Store data in the eeprom
lcockerton62 1:51477fe4851b 62 write_SOC_EEPROM(measurements, current_EEPROM_address);
lcockerton62 0:0a5f554d2a16 63
lcockerton62 0:0a5f554d2a16 64 // CAN bus transactions
lcockerton62 1:51477fe4851b 65 transmit_data(measurements,status);
lcockerton62 0:0a5f554d2a16 66
lcockerton62 0:0a5f554d2a16 67 // Conserve power - enter a low powered mode
lcockerton62 2:94716229ecc3 68 delay_finished = false;
lcockerton62 1:51477fe4851b 69 loop_delay.attach(loop_delay_callback, LOOP_DELAY_S);
lcockerton62 1:51477fe4851b 70 while (!delay_finished) sleep();
lcockerton62 0:0a5f554d2a16 71 }
lcockerton62 0:0a5f554d2a16 72 }
lcockerton62 0:0a5f554d2a16 73
lcockerton62 1:51477fe4851b 74 void transmit_data(BMU_data measurements, uint32_t status)
lcockerton62 0:0a5f554d2a16 75 {
lcockerton62 0:0a5f554d2a16 76 /*
lcockerton62 0:0a5f554d2a16 77 Place all of the collected data onto the CAN bus
lcockerton62 0:0a5f554d2a16 78 */
lcockerton62 1:51477fe4851b 79 // Send cell voltaages voltages
lcockerton62 1:51477fe4851b 80 for(int i= 0; i < NO_CMUS; i++) {
lcockerton62 1:51477fe4851b 81 createVoltageTelemetry(i + 2 , measurements.cell_voltages[i].first_cell_voltages);
lcockerton62 1:51477fe4851b 82 createVoltageTelemetry(i + 3, measurements.cell_voltages[i].last_cell_voltages);
lcockerton62 1:51477fe4851b 83 }
lcockerton62 1:51477fe4851b 84
lcockerton62 1:51477fe4851b 85 // Create SOC CAN message
lcockerton62 1:51477fe4851b 86 createPackSOC(measurements.SOC, measurements.percentage_SOC);
lcockerton62 0:0a5f554d2a16 87
lcockerton62 1:51477fe4851b 88 // Min/max cell voltages
lcockerton62 1:51477fe4851b 89 createCellVoltageMAXMIN(measurements.max_cell_voltage, measurements.min_cell_voltage);
lcockerton62 2:94716229ecc3 90
lcockerton62 1:51477fe4851b 91 // Min/Max cell temperature
lcockerton62 1:51477fe4851b 92 createCellTemperatureMAXMIN(measurements.min_cell_temp,measurements.max_cell_temp);
lcockerton62 2:94716229ecc3 93
lcockerton62 2:94716229ecc3 94 // Battery voltage and current
lcockerton62 2:94716229ecc3 95 // @TODO make add the voltage and current
lcockerton62 1:51477fe4851b 96 createBatteryVI(measurements.battery_voltage,measurements.battery_current);
lcockerton62 2:94716229ecc3 97
lcockerton62 1:51477fe4851b 98 //Extended battery pack status
lcockerton62 1:51477fe4851b 99 createExtendedBatteryPackStatus(status);
lcockerton62 2:94716229ecc3 100
lcockerton62 0:0a5f554d2a16 101 }
lcockerton62 0:0a5f554d2a16 102
lcockerton62 1:51477fe4851b 103 uint16_t read_EEPROM_startup(BMU_data &measurements)
lcockerton62 0:0a5f554d2a16 104 {
lcockerton62 1:51477fe4851b 105 /* The first page of the EEPROM, specifically the first 2 addresses store a
lcockerton62 1:51477fe4851b 106 pointer of the first memory location of measurement data. The EEPROM only has a finite number of
lcockerton62 1:51477fe4851b 107 read/write cycles which is why we aren't writing to the same location throughout
lcockerton62 1:51477fe4851b 108 */
lcockerton62 1:51477fe4851b 109 uint16_t start_address;
lcockerton62 1:51477fe4851b 110 char start_address_array[2];
lcockerton62 1:51477fe4851b 111 char SOC_out[8]; // 4 bytes for the 2 floats one is SOC and the other % charge
lcockerton62 1:51477fe4851b 112 float *fp1,*fp2; // temporary storage for float conversion
lcockerton62 1:51477fe4851b 113
lcockerton62 1:51477fe4851b 114 // Get a pointer to the start address for the data stored in the eeprom
lcockerton62 1:51477fe4851b 115 i2c_page_read(0x0000,2,start_address_array);
lcockerton62 1:51477fe4851b 116
lcockerton62 1:51477fe4851b 117 // Read the data from this address
lcockerton62 1:51477fe4851b 118 start_address = (start_address_array[1]<< 8) | start_address_array[0]; // mbed little endian follow this convention
lcockerton62 1:51477fe4851b 119 i2c_page_read(start_address, 8,SOC_out);
lcockerton62 0:0a5f554d2a16 120
lcockerton62 1:51477fe4851b 121 // Convert the SOC_out values back into floats
lcockerton62 1:51477fe4851b 122 fp1 = (float*)(&SOC_out[0]);
lcockerton62 1:51477fe4851b 123 fp2 = (float*)(&SOC_out[4]);
lcockerton62 1:51477fe4851b 124 measurements.SOC = *fp1;
lcockerton62 1:51477fe4851b 125 measurements.percentage_SOC = *fp2;
lcockerton62 1:51477fe4851b 126
lcockerton62 1:51477fe4851b 127 // Select the next address to write to
lcockerton62 1:51477fe4851b 128 start_address += 0x0040;
lcockerton62 1:51477fe4851b 129 if(start_address > MAX_WRITE_ADDRESS) {
lcockerton62 1:51477fe4851b 130 start_address = START_WRITE_ADDRESS; // Loop round to the start of the eeprom
lcockerton62 1:51477fe4851b 131 }
lcockerton62 1:51477fe4851b 132
lcockerton62 1:51477fe4851b 133 // write the new address to location 0x0000
lcockerton62 1:51477fe4851b 134 start_address_array[0] = start_address | 0x00FF;
lcockerton62 1:51477fe4851b 135 start_address_array[1] = start_address >> 8;
lcockerton62 1:51477fe4851b 136 i2c_page_write(0x0000, 2, start_address_array);
lcockerton62 1:51477fe4851b 137
lcockerton62 1:51477fe4851b 138 return start_address;
lcockerton62 0:0a5f554d2a16 139 }
lcockerton62 0:0a5f554d2a16 140
lcockerton62 1:51477fe4851b 141 void write_SOC_EEPROM(BMU_data &measurements,uint16_t start_address)
lcockerton62 0:0a5f554d2a16 142 {
lcockerton62 1:51477fe4851b 143 char data_out[8];
lcockerton62 1:51477fe4851b 144 float *fp1,*fp2;
lcockerton62 1:51477fe4851b 145
lcockerton62 1:51477fe4851b 146 fp1 = (float*)(&measurements.SOC);
lcockerton62 1:51477fe4851b 147 fp2 = (float*)(&measurements.percentage_SOC);
lcockerton62 0:0a5f554d2a16 148
lcockerton62 1:51477fe4851b 149 for(int i = 0; i < 4; i++ ) {
lcockerton62 1:51477fe4851b 150 data_out[i] = *fp1;
lcockerton62 1:51477fe4851b 151 fp1++;
lcockerton62 1:51477fe4851b 152 }
lcockerton62 1:51477fe4851b 153 for(int j = 4; j < 7; j++ ) {
lcockerton62 1:51477fe4851b 154 data_out[j] = *fp2;
lcockerton62 1:51477fe4851b 155 fp2++;
lcockerton62 1:51477fe4851b 156 }
lcockerton62 1:51477fe4851b 157 i2c_page_write(start_address, 8,data_out);
lcockerton62 0:0a5f554d2a16 158 }
lcockerton62 0:0a5f554d2a16 159
lcockerton62 1:51477fe4851b 160 void read_temperature_sensors(BMU_data &measurements)
lcockerton62 0:0a5f554d2a16 161 {
lcockerton62 1:51477fe4851b 162 float min_temperature;
lcockerton62 1:51477fe4851b 163 float max_temperature;
lcockerton62 1:51477fe4851b 164
lcockerton62 1:51477fe4851b 165 probe[0]->convert_temperature(DS1820::all_devices);
lcockerton62 1:51477fe4851b 166 min_temperature = probe[0]->temperature('C');
lcockerton62 1:51477fe4851b 167 max_temperature = min_temperature; // Initially set the max and min temperature equal
lcockerton62 1:51477fe4851b 168 for (int i=1; i<devices_found; i++) {
lcockerton62 2:94716229ecc3 169
lcockerton62 1:51477fe4851b 170 measurements.temperature_measurements[i].ID = i;
lcockerton62 1:51477fe4851b 171 measurements.temperature_measurements[i].measurement = probe[i] ->temperature('C');
lcockerton62 2:94716229ecc3 172
lcockerton62 1:51477fe4851b 173 if(measurements.temperature_measurements[i].measurement > max_temperature) {
lcockerton62 1:51477fe4851b 174 max_temperature = measurements.temperature_measurements[i].measurement;
lcockerton62 2:94716229ecc3 175 } else if (measurements.temperature_measurements[i].measurement < min_temperature) {
lcockerton62 1:51477fe4851b 176 min_temperature = measurements.temperature_measurements[i].measurement;
lcockerton62 1:51477fe4851b 177 }
lcockerton62 1:51477fe4851b 178 }
lcockerton62 1:51477fe4851b 179 measurements.max_cell_temp.temperature = max_temperature;
lcockerton62 1:51477fe4851b 180 measurements.min_cell_temp.temperature = min_temperature;
lcockerton62 0:0a5f554d2a16 181 }
lcockerton62 0:0a5f554d2a16 182
lcockerton62 0:0a5f554d2a16 183 void update_SOC()
lcockerton62 0:0a5f554d2a16 184 {
lcockerton62 1:51477fe4851b 185 // Update the SOC value
lcockerton62 0:0a5f554d2a16 186 }
lcockerton62 0:0a5f554d2a16 187
lcockerton62 0:0a5f554d2a16 188
lcockerton62 1:51477fe4851b 189 uint32_t check_measurements(BMU_data &measurements)
lcockerton62 1:51477fe4851b 190 {
lcockerton62 1:51477fe4851b 191 uint32_t status;
lcockerton62 2:94716229ecc3 192
lcockerton62 2:94716229ecc3 193 if(measurements.max_cell_voltage.voltage > MAX_CELL_VOLTAGE) {
lcockerton62 2:94716229ecc3 194 status = status | CELL_OVER_VOLTAGE;
lcockerton62 2:94716229ecc3 195 } else if (measurements.min_cell_voltage.voltage < MIN_CELL_VOLTAGE) {
lcockerton62 1:51477fe4851b 196 status = status | CELL_UNDER_VOLTAGE;
lcockerton62 2:94716229ecc3 197 } else if (measurements.max_cell_temp.temperature > MAX_CELL_TEMPERATURE) {
lcockerton62 1:51477fe4851b 198 status = status | CELL_OVER_TEMPERATURE;
lcockerton62 1:51477fe4851b 199 }
lcockerton62 2:94716229ecc3 200
lcockerton62 1:51477fe4851b 201 /*
lcockerton62 1:51477fe4851b 202 @TODO also include errors for:
lcockerton62 1:51477fe4851b 203 *untrusted measurement
lcockerton62 1:51477fe4851b 204 *CMU timeout
lcockerton62 1:51477fe4851b 205 *SOC not valid
lcockerton62 1:51477fe4851b 206 */
lcockerton62 1:51477fe4851b 207 return status;
lcockerton62 1:51477fe4851b 208 }
lcockerton62 1:51477fe4851b 209
lcockerton62 1:51477fe4851b 210 void take_measurements(BMU_data &measurements)
lcockerton62 1:51477fe4851b 211 {
lcockerton62 2:94716229ecc3 212 // Here collect all measured data from the sensors
lcockerton62 1:51477fe4851b 213 /*
lcockerton62 1:51477fe4851b 214 TODO SOC and cell voltages
lcockerton62 1:51477fe4851b 215 */
lcockerton62 1:51477fe4851b 216 }
lcockerton62 1:51477fe4851b 217
lcockerton62 0:0a5f554d2a16 218 void init()
lcockerton62 0:0a5f554d2a16 219 {
lcockerton62 1:51477fe4851b 220 temperature_init(); // Initialise the temperature sensors
lcockerton62 0:0a5f554d2a16 221 }
lcockerton62 0:0a5f554d2a16 222