Cell voltages fork (SoC)

Dependencies:   CUER_CAN CUER_DS1820 LTC2943 LTC6804 mbed PowerControl

Committer:
maxv008
Date:
Mon Jul 24 15:00:53 2017 +0000
Revision:
48:5c3f42c44036
Parent:
45:c288d7cbdb4a
Child:
53:4277cdcff69b
Added code in interrupt to reset EEPROM whenever the correct ID CAN Message is recieved. Contents of msg determine initital values. Currently it is inside the interrupt which should be fine as it should only happen very rarely.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
lcockerton62 0:0a5f554d2a16 1 // Here are the functions to generate the CAN messages
lcockerton62 0:0a5f554d2a16 2 #include "CANParserBMU.h"
lcockerton62 0:0a5f554d2a16 3 #include "mbed.h"
maxv008 13:7b42af989cd1 4 #include "Data_Types_BMU.h"
maxv008 17:94dd9a0d3870 5 #include "CAN_IDs.h"
lcockerton62 0:0a5f554d2a16 6
lcockerton62 1:51477fe4851b 7
lcockerton62 0:0a5f554d2a16 8 using namespace CAN_IDs;
lcockerton62 0:0a5f554d2a16 9
maxv008 13:7b42af989cd1 10 /**
maxv008 13:7b42af989cd1 11 * This function is rewritten to give readings for individual probes rather than
maxv008 13:7b42af989cd1 12 * for specific CMU. As a consequence, 0x800 onwards is being used for these probes,
maxv008 14:e0e88a009f4c 13 * as everything above about 0x700 is unused by the Tritium standard. The ID value
maxv008 14:e0e88a009f4c 14 * for the probe is based on the ROM field of DS1820, entries 1-6 being the unique
maxv008 14:e0e88a009f4c 15 * serial value.
maxv008 13:7b42af989cd1 16 */
maxv008 14:e0e88a009f4c 17 CANMessage createTemperatureTelemetry(uint8_t offset, char ProbeROM[8], float Temperature)
lcockerton62 0:0a5f554d2a16 18 {
lcockerton62 0:0a5f554d2a16 19 CANMessage msg;
lcockerton62 0:0a5f554d2a16 20 msg.len = 8;
maxv008 13:7b42af989cd1 21 msg.id = TEMPERATURE_BASE_ID + offset; // for temp it is 0x800 onwards
lcockerton62 0:0a5f554d2a16 22 CAN_Data data;
lcockerton62 0:0a5f554d2a16 23
maxv008 14:e0e88a009f4c 24 for(int i = 1; i <= 6; i++) //ID portion of ROM array
maxv008 14:e0e88a009f4c 25 {
maxv008 14:e0e88a009f4c 26 data.set_u8(i - 1, ProbeROM[i]);
maxv008 14:e0e88a009f4c 27 }
maxv008 14:e0e88a009f4c 28 //Conversion of float to a short, requires multiplying by 100 to not lose precision
maxv008 14:e0e88a009f4c 29 float temp100 = Temperature * 100;
maxv008 14:e0e88a009f4c 30 short shortTemp = (short) temp100;
maxv008 14:e0e88a009f4c 31 data.set_16(3, shortTemp);//There seems to be an error in the function definition for set_16, (ushort instead of short)
maxv008 14:e0e88a009f4c 32
lcockerton62 0:0a5f554d2a16 33 for (int i = 0; i<8; i++) {
lcockerton62 0:0a5f554d2a16 34 msg.data[i] = data.get_u8(i);
lcockerton62 0:0a5f554d2a16 35 }
lcockerton62 0:0a5f554d2a16 36
lcockerton62 0:0a5f554d2a16 37 return msg;
lcockerton62 0:0a5f554d2a16 38 }
maxv008 13:7b42af989cd1 39 /**
maxv008 13:7b42af989cd1 40 * Takes a CANMessage with precondition that it stores temperature of an individual
maxv008 13:7b42af989cd1 41 * probe and returns an individual_temperature object containing ID and reading.
maxv008 14:e0e88a009f4c 42 * The ID is stores in ROM array entry 1-6, other entries may be invalid.
maxv008 13:7b42af989cd1 43 */
maxv008 13:7b42af989cd1 44 individual_temperature decodeTemperatureTelemetry(CANMessage msg)
maxv008 13:7b42af989cd1 45 {
maxv008 13:7b42af989cd1 46 individual_temperature probe_reading;
maxv008 13:7b42af989cd1 47 CAN_Data decode;
maxv008 18:521ffdd724f3 48 unsigned long fullID = 0;
maxv008 13:7b42af989cd1 49
maxv008 13:7b42af989cd1 50 decode.importCANData(msg);
maxv008 14:e0e88a009f4c 51 short shortTemp = decode.get_16(3);
maxv008 14:e0e88a009f4c 52 probe_reading.measurement = ((float)shortTemp) / 100;
maxv008 14:e0e88a009f4c 53
maxv008 14:e0e88a009f4c 54 for(int i = 1; i <=6; i++)
maxv008 14:e0e88a009f4c 55 {
maxv008 17:94dd9a0d3870 56 probe_reading.ROMID[i] = decode.get_u8(i-1);
maxv008 17:94dd9a0d3870 57 fullID += (probe_reading.ROMID[i] << (8 * (i-1))); //Bit order not particularly important
maxv008 14:e0e88a009f4c 58 }
maxv008 17:94dd9a0d3870 59 probe_reading.ID = fullID;
maxv008 13:7b42af989cd1 60 return probe_reading;
maxv008 13:7b42af989cd1 61 }
lcockerton62 0:0a5f554d2a16 62
msharma97 9:82ba050a7e13 63 CANMessage createVoltageTelemetry(int offset_id, uint16_t voltage[])
lcockerton62 0:0a5f554d2a16 64 {
lcockerton62 0:0a5f554d2a16 65 CANMessage msg;
lcockerton62 0:0a5f554d2a16 66 msg.len = 8;
msharma97 9:82ba050a7e13 67 msg.id = BMS_BASE_ID + offset_id; // for voltage 0x601 - 0x6EF @TODO
lcockerton62 0:0a5f554d2a16 68 CAN_Data data;
lcockerton62 0:0a5f554d2a16 69
lcockerton62 0:0a5f554d2a16 70 data.set_u16(0, voltage[0]);
lcockerton62 0:0a5f554d2a16 71 data.set_u16(1, voltage[1]);
lcockerton62 0:0a5f554d2a16 72 data.set_u16(2, voltage[2]);
lcockerton62 0:0a5f554d2a16 73 data.set_u16(3, voltage[3]);
lcockerton62 0:0a5f554d2a16 74
lcockerton62 0:0a5f554d2a16 75 for (int i = 0; i<8; i++) {
lcockerton62 0:0a5f554d2a16 76 msg.data[i] = data.get_u8(i);
lcockerton62 0:0a5f554d2a16 77 }
lcockerton62 0:0a5f554d2a16 78
lcockerton62 0:0a5f554d2a16 79 return msg;
lcockerton62 0:0a5f554d2a16 80 }
maxv008 17:94dd9a0d3870 81 /**
maxv008 17:94dd9a0d3870 82 * This function will properly fill the appropriate entry in an array of voltage
maxv008 17:94dd9a0d3870 83 * readings of the form CMU_voltage voltage[NO_CMUS]. Uses the msg ID and the standard
maxv008 17:94dd9a0d3870 84 * meanings of them as decided in the transmit data function (modified Tritium specs).
maxv008 17:94dd9a0d3870 85 * Function must only be called when the msg has a valid ID for voltage!
maxv008 17:94dd9a0d3870 86 */
maxv008 18:521ffdd724f3 87 bool decodeVoltageTelemetry(CANMessage msg, CMU_voltage readings[NO_CMUS])
maxv008 17:94dd9a0d3870 88 {
maxv008 17:94dd9a0d3870 89 CAN_Data voltData;
maxv008 17:94dd9a0d3870 90 voltData.importCANData(msg);
maxv008 17:94dd9a0d3870 91 int repeating_length = NO_READINGS_PER_CMU /4 + 1;
maxv008 17:94dd9a0d3870 92 int offset = msg.id - BMS_BASE_ID;
ItsJustZi 29:44924d2b1293 93 if(offset <= 0 || offset >= 0x10 || offset % 4 == 1)
maxv008 18:521ffdd724f3 94 return false;
maxv008 17:94dd9a0d3870 95
maxv008 17:94dd9a0d3870 96 int cellsubset = ((offset-1) % repeating_length) - 1; //Which set of 4 voltages within the CMU
maxv008 17:94dd9a0d3870 97 int CMU_number = (offset-1) / repeating_length;
maxv008 17:94dd9a0d3870 98 for(int i = 0; i < 4; i++)
maxv008 17:94dd9a0d3870 99 {
maxv008 17:94dd9a0d3870 100 readings[CMU_number].voltages[cellsubset*4 + i] = voltData.get_u16(i);
maxv008 17:94dd9a0d3870 101 }
maxv008 18:521ffdd724f3 102 return true;
maxv008 17:94dd9a0d3870 103 }
lcockerton62 0:0a5f554d2a16 104
lcockerton62 0:0a5f554d2a16 105 CANMessage createPackSOC(float SOC, float percentageCharge)
lcockerton62 0:0a5f554d2a16 106 {
lcockerton62 0:0a5f554d2a16 107 CANMessage msg;
lcockerton62 0:0a5f554d2a16 108 msg.len = 8;
maxv008 23:a1af4439c1fc 109 msg.id = BMS_BASE_ID + BATTERY_SOC_ID; //0x6F4
lcockerton62 0:0a5f554d2a16 110 CAN_Data data;
lcockerton62 0:0a5f554d2a16 111 data.setLowerFloat(SOC);
lcockerton62 0:0a5f554d2a16 112 data.setUpperFloat(percentageCharge);
lcockerton62 1:51477fe4851b 113 for(int i=0; i<8; i++) {
lcockerton62 0:0a5f554d2a16 114 msg.data[i] = data.get_u8(i);
lcockerton62 0:0a5f554d2a16 115 }
lcockerton62 1:51477fe4851b 116
lcockerton62 0:0a5f554d2a16 117 return msg;
lcockerton62 0:0a5f554d2a16 118 }
lcockerton62 0:0a5f554d2a16 119
lcockerton62 0:0a5f554d2a16 120 CANMessage createPackBalanceSOC(float SOC, float percentageCharge)
lcockerton62 0:0a5f554d2a16 121 {
lcockerton62 0:0a5f554d2a16 122 // @TODO - check is this being used?? section 5.4 trituim BMU CAN data sheet
lcockerton62 0:0a5f554d2a16 123 CANMessage msg;
lcockerton62 0:0a5f554d2a16 124 msg.len = 8;
lcockerton62 1:51477fe4851b 125 msg.id = BMS_BASE_ID + BATTERY_SOC_BASE_ID;
lcockerton62 1:51477fe4851b 126
lcockerton62 0:0a5f554d2a16 127 CAN_Data data;
lcockerton62 0:0a5f554d2a16 128 data.setLowerFloat(SOC);
lcockerton62 0:0a5f554d2a16 129 data.setUpperFloat(percentageCharge);
lcockerton62 1:51477fe4851b 130 for(int i=0; i<8; i++) {
lcockerton62 0:0a5f554d2a16 131 msg.data[i] = data.get_u8(i);
lcockerton62 0:0a5f554d2a16 132 }
lcockerton62 1:51477fe4851b 133
lcockerton62 0:0a5f554d2a16 134 return msg;
lcockerton62 0:0a5f554d2a16 135 }
lcockerton62 0:0a5f554d2a16 136
maxv008 23:a1af4439c1fc 137 /**
maxv008 23:a1af4439c1fc 138 * decodePackSOC and decodePackSOCPercentage can be used with both of the SOC msg types
maxv008 23:a1af4439c1fc 139 */
maxv008 23:a1af4439c1fc 140 float decodePackSOC(CANMessage msg)
maxv008 23:a1af4439c1fc 141 {
maxv008 23:a1af4439c1fc 142 CAN_Data data;
maxv008 23:a1af4439c1fc 143 data.importCANData(msg);
maxv008 23:a1af4439c1fc 144 return data.getLowerFloat();
maxv008 23:a1af4439c1fc 145 }
maxv008 23:a1af4439c1fc 146
maxv008 23:a1af4439c1fc 147 float decodePackSOCPercentage(CANMessage msg)
maxv008 23:a1af4439c1fc 148 {
maxv008 23:a1af4439c1fc 149 CAN_Data data;
maxv008 23:a1af4439c1fc 150 data.importCANData(msg);
maxv008 23:a1af4439c1fc 151 return data.getUpperFloat();
maxv008 23:a1af4439c1fc 152 }
maxv008 23:a1af4439c1fc 153
lcockerton62 1:51477fe4851b 154 CANMessage createCellVoltageMAXMIN(pack_voltage_extremes max_voltage, pack_voltage_extremes min_voltage)
lcockerton62 0:0a5f554d2a16 155 {
lcockerton62 0:0a5f554d2a16 156 CANMessage msg;
lcockerton62 0:0a5f554d2a16 157 msg.len = 8;
lcockerton62 1:51477fe4851b 158 msg.id = BMS_BASE_ID + MAX_MIN_VOLTAGE;
lcockerton62 1:51477fe4851b 159
lcockerton62 0:0a5f554d2a16 160 CAN_Data data;
lcockerton62 1:51477fe4851b 161 data.set_u16(0,min_voltage.voltage); //Min voltage
lcockerton62 1:51477fe4851b 162 data.set_u16(1,max_voltage.voltage); //Max voltage
lcockerton62 1:51477fe4851b 163 data.set_u8(4,min_voltage.CMU_number); //CMU number of lowest cell
lcockerton62 1:51477fe4851b 164 data.set_u8(5,min_voltage.cell_number); //Cell number in CMU with lowest voltage
maxv008 31:888b2602aab2 165 data.set_u8(6,max_voltage.CMU_number); //CMU number of maxiumum cell
maxv008 31:888b2602aab2 166 data.set_u8(7,max_voltage.cell_number); //Cell number in CMU with highest voltage
lcockerton62 1:51477fe4851b 167
lcockerton62 1:51477fe4851b 168 for(int i=0; i<8; i++) {
lcockerton62 0:0a5f554d2a16 169 msg.data[i] = data.get_u8(i);
lcockerton62 0:0a5f554d2a16 170 }
lcockerton62 1:51477fe4851b 171
lcockerton62 0:0a5f554d2a16 172 return msg;
lcockerton62 0:0a5f554d2a16 173 }
lcockerton62 0:0a5f554d2a16 174
maxv008 23:a1af4439c1fc 175 void decodeCellVoltageMAXMIN(CANMessage msg, pack_voltage_extremes &min, pack_voltage_extremes &max)
maxv008 23:a1af4439c1fc 176 {
maxv008 23:a1af4439c1fc 177 CAN_Data decode;
maxv008 23:a1af4439c1fc 178 decode.importCANData(msg);
maxv008 23:a1af4439c1fc 179 min.voltage = decode.get_u16(0);
maxv008 23:a1af4439c1fc 180 max.voltage = decode.get_u16(1);
maxv008 23:a1af4439c1fc 181 min.CMU_number = decode.get_u8(4);
maxv008 23:a1af4439c1fc 182 min.cell_number = decode.get_u8(5);
maxv008 23:a1af4439c1fc 183 max.CMU_number = decode.get_u8(6);
maxv008 23:a1af4439c1fc 184 max.cell_number = decode.get_u8(7);
maxv008 23:a1af4439c1fc 185 }
maxv008 23:a1af4439c1fc 186
maxv008 23:a1af4439c1fc 187 //Since each CAN message can only support 1 ID, need to send 2 using this function
maxv008 23:a1af4439c1fc 188 //Use bool isMin to say if its a minimum or maximum
maxv008 23:a1af4439c1fc 189 CANMessage createCellTemperatureMAXMIN(pack_temperature_extremes ex_temperature, bool isMin)
lcockerton62 0:0a5f554d2a16 190 {
lcockerton62 0:0a5f554d2a16 191 CANMessage msg;
lcockerton62 0:0a5f554d2a16 192 msg.len = 8;
maxv008 23:a1af4439c1fc 193 msg.id = BMS_BASE_ID + (isMin ? MIN_TEMPERATURE : MAX_TEMPERATURE) ;
maxv008 23:a1af4439c1fc 194 //TODO, CHANGE CMU NUMBER TO ROMID
lcockerton62 0:0a5f554d2a16 195 CAN_Data data;
maxv008 23:a1af4439c1fc 196 data.set_u16(3,ex_temperature.temperature); //Extreme temperature
maxv008 23:a1af4439c1fc 197
maxv008 23:a1af4439c1fc 198 for(int i = 1; i <= 6; i++) //ID portion of ROM array
maxv008 23:a1af4439c1fc 199 {
maxv008 23:a1af4439c1fc 200 data.set_u8(i - 1, ex_temperature.ROMID[i]);
maxv008 23:a1af4439c1fc 201 }
lcockerton62 1:51477fe4851b 202
lcockerton62 1:51477fe4851b 203 for(int i=0; i<8; i++) {
lcockerton62 0:0a5f554d2a16 204 msg.data[i] = data.get_u8(i);
lcockerton62 0:0a5f554d2a16 205 }
lcockerton62 1:51477fe4851b 206
lcockerton62 0:0a5f554d2a16 207 return msg;
lcockerton62 0:0a5f554d2a16 208 }
lcockerton62 0:0a5f554d2a16 209
maxv008 23:a1af4439c1fc 210 //It is up to function caller to decide by msg.ID if it is minimum or not
maxv008 23:a1af4439c1fc 211 pack_temperature_extremes decodeCellTemperatureMAXMIN(CANMessage msg)
maxv008 23:a1af4439c1fc 212 {
maxv008 23:a1af4439c1fc 213 pack_temperature_extremes result;
maxv008 23:a1af4439c1fc 214 CAN_Data decode;
maxv008 23:a1af4439c1fc 215 unsigned long fullID = 0;
maxv008 23:a1af4439c1fc 216
maxv008 23:a1af4439c1fc 217 decode.importCANData(msg);
maxv008 23:a1af4439c1fc 218 result.temperature = decode.get_16(3);
maxv008 23:a1af4439c1fc 219
maxv008 23:a1af4439c1fc 220 for(int i = 1; i <=6; i++)
maxv008 23:a1af4439c1fc 221 {
maxv008 23:a1af4439c1fc 222 result.ROMID[i] = decode.get_u8(i-1);
maxv008 23:a1af4439c1fc 223 fullID += (result.ROMID[i] << (8 * (i-1))); //Bit order not particularly important
maxv008 23:a1af4439c1fc 224 }
maxv008 23:a1af4439c1fc 225 result.ID = fullID;
maxv008 23:a1af4439c1fc 226 return result;
maxv008 23:a1af4439c1fc 227 }
maxv008 23:a1af4439c1fc 228
maxv008 31:888b2602aab2 229 CANMessage createBatteryVI(uint32_t batteryVoltage, float batteryCurrent)
lcockerton62 0:0a5f554d2a16 230 {
lcockerton62 0:0a5f554d2a16 231 CANMessage msg;
lcockerton62 0:0a5f554d2a16 232 msg.len = 8;
lcockerton62 1:51477fe4851b 233 msg.id = BMS_BASE_ID + BATTERY_VI_ID;
lcockerton62 1:51477fe4851b 234
lcockerton62 0:0a5f554d2a16 235 CAN_Data data;
lcockerton62 3:527790e4965a 236 data.setLower_uLong(batteryVoltage);
maxv008 31:888b2602aab2 237 data.setUpperFloat(batteryCurrent);
lcockerton62 1:51477fe4851b 238
lcockerton62 1:51477fe4851b 239 for(int i=0; i<8; i++) {
lcockerton62 0:0a5f554d2a16 240 msg.data[i] = data.get_u8(i);
lcockerton62 0:0a5f554d2a16 241 }
lcockerton62 0:0a5f554d2a16 242 return msg;
lcockerton62 0:0a5f554d2a16 243 }
lcockerton62 0:0a5f554d2a16 244
maxv008 31:888b2602aab2 245 uint32_t decodeBatteryVoltage(CANMessage msg)
maxv008 31:888b2602aab2 246 {
maxv008 31:888b2602aab2 247 uint32_t result = 0;
maxv008 31:888b2602aab2 248 CAN_Data decode;
maxv008 31:888b2602aab2 249 decode.importCANData(msg);
maxv008 31:888b2602aab2 250 result = decode.getLower_uLong();
maxv008 31:888b2602aab2 251 return result;
maxv008 31:888b2602aab2 252 }
maxv008 31:888b2602aab2 253
maxv008 31:888b2602aab2 254 float decodeBatteryCurrent(CANMessage msg)
maxv008 31:888b2602aab2 255 {
maxv008 48:5c3f42c44036 256 float result = 0;
maxv008 31:888b2602aab2 257 CAN_Data decode;
maxv008 31:888b2602aab2 258 decode.importCANData(msg);
maxv008 31:888b2602aab2 259 result = decode.getUpperFloat();
maxv008 31:888b2602aab2 260 return result;
maxv008 45:c288d7cbdb4a 261 }
maxv008 45:c288d7cbdb4a 262
maxv008 45:c288d7cbdb4a 263 CANMessage createIVTACurrent(int32_t current)
maxv008 45:c288d7cbdb4a 264 {
maxv008 45:c288d7cbdb4a 265 CANMessage msg;
maxv008 45:c288d7cbdb4a 266 msg.len = 8;
maxv008 45:c288d7cbdb4a 267 msg.id = BMS_BASE_ID + IVTA_ID;
maxv008 45:c288d7cbdb4a 268
maxv008 45:c288d7cbdb4a 269 CAN_Data data;
maxv008 45:c288d7cbdb4a 270 data.setLower_Long(current);
maxv008 45:c288d7cbdb4a 271 data.setHigher_Long(0);
maxv008 45:c288d7cbdb4a 272
maxv008 45:c288d7cbdb4a 273 for(int i=0; i<8; i++) {
maxv008 45:c288d7cbdb4a 274 msg.data[i] = data.get_u8(i);
maxv008 45:c288d7cbdb4a 275 }
maxv008 45:c288d7cbdb4a 276 return msg;
maxv008 31:888b2602aab2 277 }
maxv008 31:888b2602aab2 278
maxv008 45:c288d7cbdb4a 279 int32_t decodeIVTACurrent(CANMessage msg)
maxv008 45:c288d7cbdb4a 280 {
maxv008 45:c288d7cbdb4a 281 int32_t result = 0;
maxv008 45:c288d7cbdb4a 282 CAN_Data decode;
maxv008 45:c288d7cbdb4a 283 decode.importCANData(msg);
maxv008 45:c288d7cbdb4a 284 result = decode.getLower_Long();
maxv008 45:c288d7cbdb4a 285 return result;
maxv008 45:c288d7cbdb4a 286 }
maxv008 45:c288d7cbdb4a 287
lcockerton62 0:0a5f554d2a16 288 CANMessage createBatteryPackStatus(uint16_t voltageThreshold[], uint8_t statusFlag,uint8_t BMS_CMU_Count,uint16_t BMS_Firmware_Build)
lcockerton62 0:0a5f554d2a16 289 {
lcockerton62 1:51477fe4851b 290 CANMessage msg;
lcockerton62 1:51477fe4851b 291 msg.len = 8;
lcockerton62 1:51477fe4851b 292 msg.id = BMS_BASE_ID + BATTERY_PACK_STATUS_ID;
lcockerton62 1:51477fe4851b 293
lcockerton62 1:51477fe4851b 294 CAN_Data data;
lcockerton62 1:51477fe4851b 295 data.set_u16(0,voltageThreshold[0]);
lcockerton62 1:51477fe4851b 296 data.set_u16(1,voltageThreshold[1]);
lcockerton62 1:51477fe4851b 297 data.set_16(3,BMS_Firmware_Build);
lcockerton62 1:51477fe4851b 298 data.set_u8(4,statusFlag);
lcockerton62 1:51477fe4851b 299 data.set_u8(5,BMS_CMU_Count);
lcockerton62 1:51477fe4851b 300
lcockerton62 1:51477fe4851b 301 for(int i=0; i<8; i++) {
lcockerton62 1:51477fe4851b 302 msg.data[i] = data.get_u8(i);
lcockerton62 1:51477fe4851b 303 }
lcockerton62 1:51477fe4851b 304 return msg;
lcockerton62 0:0a5f554d2a16 305 }
lcockerton62 0:0a5f554d2a16 306
lcockerton62 0:0a5f554d2a16 307 CANMessage createExtendedBatteryPackStatus(uint32_t status)
lcockerton62 0:0a5f554d2a16 308 {
lcockerton62 1:51477fe4851b 309 CANMessage msg;
lcockerton62 1:51477fe4851b 310 msg.len = 8;
lcockerton62 1:51477fe4851b 311 msg.id = BMS_BASE_ID + BATTERY_STATUS_ID;
lcockerton62 1:51477fe4851b 312
lcockerton62 1:51477fe4851b 313 CAN_Data data;
lcockerton62 1:51477fe4851b 314 data.setLower_uLong(status); //@TODO see the data sheet for this
lcockerton62 1:51477fe4851b 315 data.set_u8(4,0x00);//Hardware version random data @TODO check this
lcockerton62 1:51477fe4851b 316 data.set_u8(5,0x00);//Model ID @TODO check this
lcockerton62 1:51477fe4851b 317 data.set_u16(3,0x00); // Unused
lcockerton62 1:51477fe4851b 318
lcockerton62 1:51477fe4851b 319 for(int i=0; i<8; i++) {
lcockerton62 1:51477fe4851b 320 msg.data[i] = data.get_u8(i);
lcockerton62 1:51477fe4851b 321 }
lcockerton62 1:51477fe4851b 322 return msg;
lcockerton62 0:0a5f554d2a16 323 }
lcockerton62 0:0a5f554d2a16 324
maxv008 23:a1af4439c1fc 325 uint32_t decodeExtendedBatteryPackStatus(CANMessage msg)
maxv008 23:a1af4439c1fc 326 {
maxv008 23:a1af4439c1fc 327 CAN_Data decode;
maxv008 23:a1af4439c1fc 328 decode.importCANData(msg);
maxv008 23:a1af4439c1fc 329 return decode.getLower_uLong();
maxv008 23:a1af4439c1fc 330 }
maxv008 23:a1af4439c1fc 331
maxv008 31:888b2602aab2 332 //Values here don't matter, added just in case.
maxv008 31:888b2602aab2 333 CANMessage createBMSHeartbeat(uint32_t val1, uint32_t val2)
maxv008 31:888b2602aab2 334 {
maxv008 31:888b2602aab2 335 CANMessage msg;
maxv008 31:888b2602aab2 336 msg.len = 8;
maxv008 31:888b2602aab2 337 msg.id = BMS_BASE_ID;
maxv008 31:888b2602aab2 338
maxv008 31:888b2602aab2 339 CAN_Data data;
maxv008 31:888b2602aab2 340 data.setLower_uLong(val1);
maxv008 31:888b2602aab2 341 data.setHigher_uLong(val2);
maxv008 31:888b2602aab2 342
maxv008 31:888b2602aab2 343 for(int i=0; i<8; i++) {
maxv008 31:888b2602aab2 344 msg.data[i] = data.get_u8(i);
maxv008 31:888b2602aab2 345 }
maxv008 31:888b2602aab2 346 return msg;
maxv008 31:888b2602aab2 347 }
maxv008 31:888b2602aab2 348
maxv008 48:5c3f42c44036 349 CANMessage createEEPROMReset(float init_SOC, float init_SOC_Percent) //TODO: Ensure ID doesn't conflict more carefully (It should be fine)
maxv008 48:5c3f42c44036 350 {
maxv008 48:5c3f42c44036 351 CANMessage msg;
maxv008 48:5c3f42c44036 352 msg.len = 8;
maxv008 48:5c3f42c44036 353 msg.id = BMS_BASE_ID + EEPROM_RESET_ID;
maxv008 48:5c3f42c44036 354
maxv008 48:5c3f42c44036 355 CAN_Data data;
maxv008 48:5c3f42c44036 356 data.setLowerFloat(init_SOC);
maxv008 48:5c3f42c44036 357 data.setUpperFloat(init_SOC_Percent);
maxv008 48:5c3f42c44036 358
maxv008 48:5c3f42c44036 359 for(int i=0; i<8; i++) {
maxv008 48:5c3f42c44036 360 msg.data[i] = data.get_u8(i);
maxv008 48:5c3f42c44036 361 }
maxv008 48:5c3f42c44036 362 return msg;
maxv008 48:5c3f42c44036 363 }
maxv008 48:5c3f42c44036 364
maxv008 48:5c3f42c44036 365 float decodeEEPROMSOC(CANMessage msg)
maxv008 48:5c3f42c44036 366 {
maxv008 48:5c3f42c44036 367 float result = 0;
maxv008 48:5c3f42c44036 368 CAN_Data decode;
maxv008 48:5c3f42c44036 369 decode.importCANData(msg);
maxv008 48:5c3f42c44036 370 result = decode.getLowerFloat();
maxv008 48:5c3f42c44036 371 return result;
maxv008 48:5c3f42c44036 372 }
maxv008 48:5c3f42c44036 373
maxv008 48:5c3f42c44036 374 float decodeEEPROMSOCPercentage(CANMessage msg)
maxv008 48:5c3f42c44036 375 {
maxv008 48:5c3f42c44036 376 float result = 0;
maxv008 48:5c3f42c44036 377 CAN_Data decode;
maxv008 48:5c3f42c44036 378 decode.importCANData(msg);
maxv008 48:5c3f42c44036 379 result = decode.getUpperFloat();
maxv008 48:5c3f42c44036 380 return result;
maxv008 48:5c3f42c44036 381 }
maxv008 48:5c3f42c44036 382
lcockerton62 0:0a5f554d2a16 383 void convertFloatFloat(float lower, float upper, CANMessage& msg, bool littleEndian)
lcockerton62 0:0a5f554d2a16 384 {
lcockerton62 0:0a5f554d2a16 385 // Code taken from driver_controls
lcockerton62 0:0a5f554d2a16 386 //two converters for lower and higher float
lcockerton62 0:0a5f554d2a16 387 float2byte convL;
lcockerton62 0:0a5f554d2a16 388 float2byte convH;
lcockerton62 0:0a5f554d2a16 389 convL.f = lower;
lcockerton62 0:0a5f554d2a16 390 convH.f = upper;
lcockerton62 0:0a5f554d2a16 391 if(littleEndian) {
lcockerton62 0:0a5f554d2a16 392 for(int i=0; i<4; i++) {
lcockerton62 0:0a5f554d2a16 393 msg.data[i] = convL.b[i];
lcockerton62 0:0a5f554d2a16 394 //offset for upper float
lcockerton62 0:0a5f554d2a16 395 msg.data[i+4]=convH.b[i];
lcockerton62 0:0a5f554d2a16 396 }
lcockerton62 0:0a5f554d2a16 397 } else {
lcockerton62 0:0a5f554d2a16 398 for(int i=0; i<4; i++) {
lcockerton62 0:0a5f554d2a16 399 /*
lcockerton62 0:0a5f554d2a16 400 * Subtract because output data is Big Endian
lcockerton62 0:0a5f554d2a16 401 * i.e. convL/H is LSB --> MSB
lcockerton62 0:0a5f554d2a16 402 * output is MSB --> LSB
lcockerton62 0:0a5f554d2a16 403 */
lcockerton62 1:51477fe4851b 404
lcockerton62 0:0a5f554d2a16 405 msg.data[4-i] = convL.b[i];
lcockerton62 0:0a5f554d2a16 406 msg.data[7-i] = convH.b[i];
lcockerton62 0:0a5f554d2a16 407 }
lcockerton62 0:0a5f554d2a16 408 }
lcockerton62 0:0a5f554d2a16 409 }
lcockerton62 0:0a5f554d2a16 410