Cell voltages fork (SoC)
Dependencies: CUER_CAN CUER_DS1820 LTC2943 LTC6804 mbed PowerControl
CANParserBMU.cpp@16:b2ef68c9a4fd, 2017-07-02 (annotated)
- Committer:
- DasSidG
- Date:
- Sun Jul 02 11:39:39 2017 +0000
- Revision:
- 16:b2ef68c9a4fd
- Parent:
- 14:e0e88a009f4c
- Child:
- 17:94dd9a0d3870
Cleaned up Dummy data
Who changed what in which revision?
User | Revision | Line number | New 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" |
lcockerton62 | 0:0a5f554d2a16 | 5 | |
lcockerton62 | 1:51477fe4851b | 6 | |
lcockerton62 | 0:0a5f554d2a16 | 7 | using namespace CAN_IDs; |
lcockerton62 | 0:0a5f554d2a16 | 8 | |
maxv008 | 13:7b42af989cd1 | 9 | /** |
maxv008 | 13:7b42af989cd1 | 10 | * This function is rewritten to give readings for individual probes rather than |
maxv008 | 13:7b42af989cd1 | 11 | * for specific CMU. As a consequence, 0x800 onwards is being used for these probes, |
maxv008 | 14:e0e88a009f4c | 12 | * as everything above about 0x700 is unused by the Tritium standard. The ID value |
maxv008 | 14:e0e88a009f4c | 13 | * for the probe is based on the ROM field of DS1820, entries 1-6 being the unique |
maxv008 | 14:e0e88a009f4c | 14 | * serial value. |
maxv008 | 13:7b42af989cd1 | 15 | */ |
maxv008 | 14:e0e88a009f4c | 16 | CANMessage createTemperatureTelemetry(uint8_t offset, char ProbeROM[8], float Temperature) |
lcockerton62 | 0:0a5f554d2a16 | 17 | { |
lcockerton62 | 0:0a5f554d2a16 | 18 | CANMessage msg; |
lcockerton62 | 0:0a5f554d2a16 | 19 | msg.len = 8; |
maxv008 | 13:7b42af989cd1 | 20 | msg.id = TEMPERATURE_BASE_ID + offset; // for temp it is 0x800 onwards |
lcockerton62 | 0:0a5f554d2a16 | 21 | CAN_Data data; |
lcockerton62 | 0:0a5f554d2a16 | 22 | |
maxv008 | 14:e0e88a009f4c | 23 | for(int i = 1; i <= 6; i++) //ID portion of ROM array |
maxv008 | 14:e0e88a009f4c | 24 | { |
maxv008 | 14:e0e88a009f4c | 25 | data.set_u8(i - 1, ProbeROM[i]); |
maxv008 | 14:e0e88a009f4c | 26 | } |
maxv008 | 14:e0e88a009f4c | 27 | //Conversion of float to a short, requires multiplying by 100 to not lose precision |
maxv008 | 14:e0e88a009f4c | 28 | float temp100 = Temperature * 100; |
maxv008 | 14:e0e88a009f4c | 29 | short shortTemp = (short) temp100; |
maxv008 | 14:e0e88a009f4c | 30 | 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 | 31 | |
lcockerton62 | 0:0a5f554d2a16 | 32 | for (int i = 0; i<8; i++) { |
lcockerton62 | 0:0a5f554d2a16 | 33 | msg.data[i] = data.get_u8(i); |
lcockerton62 | 0:0a5f554d2a16 | 34 | } |
lcockerton62 | 0:0a5f554d2a16 | 35 | |
lcockerton62 | 0:0a5f554d2a16 | 36 | return msg; |
lcockerton62 | 0:0a5f554d2a16 | 37 | } |
maxv008 | 13:7b42af989cd1 | 38 | /** |
maxv008 | 13:7b42af989cd1 | 39 | * Takes a CANMessage with precondition that it stores temperature of an individual |
maxv008 | 13:7b42af989cd1 | 40 | * probe and returns an individual_temperature object containing ID and reading. |
maxv008 | 14:e0e88a009f4c | 41 | * The ID is stores in ROM array entry 1-6, other entries may be invalid. |
maxv008 | 13:7b42af989cd1 | 42 | */ |
maxv008 | 13:7b42af989cd1 | 43 | individual_temperature decodeTemperatureTelemetry(CANMessage msg) |
maxv008 | 13:7b42af989cd1 | 44 | { |
maxv008 | 13:7b42af989cd1 | 45 | individual_temperature probe_reading; |
maxv008 | 13:7b42af989cd1 | 46 | CAN_Data decode; |
maxv008 | 13:7b42af989cd1 | 47 | |
maxv008 | 13:7b42af989cd1 | 48 | decode.importCANData(msg); |
maxv008 | 14:e0e88a009f4c | 49 | short shortTemp = decode.get_16(3); |
maxv008 | 14:e0e88a009f4c | 50 | probe_reading.measurement = ((float)shortTemp) / 100; |
maxv008 | 14:e0e88a009f4c | 51 | |
maxv008 | 14:e0e88a009f4c | 52 | for(int i = 1; i <=6; i++) |
maxv008 | 14:e0e88a009f4c | 53 | { |
maxv008 | 14:e0e88a009f4c | 54 | probe_reading.ROMID[i] = decode.get_u8(i-1); |
maxv008 | 14:e0e88a009f4c | 55 | } |
maxv008 | 13:7b42af989cd1 | 56 | |
maxv008 | 13:7b42af989cd1 | 57 | return probe_reading; |
maxv008 | 13:7b42af989cd1 | 58 | } |
lcockerton62 | 0:0a5f554d2a16 | 59 | |
msharma97 | 9:82ba050a7e13 | 60 | CANMessage createVoltageTelemetry(int offset_id, uint16_t voltage[]) |
lcockerton62 | 0:0a5f554d2a16 | 61 | { |
lcockerton62 | 0:0a5f554d2a16 | 62 | CANMessage msg; |
lcockerton62 | 0:0a5f554d2a16 | 63 | msg.len = 8; |
msharma97 | 9:82ba050a7e13 | 64 | msg.id = BMS_BASE_ID + offset_id; // for voltage 0x601 - 0x6EF @TODO |
lcockerton62 | 0:0a5f554d2a16 | 65 | CAN_Data data; |
lcockerton62 | 0:0a5f554d2a16 | 66 | |
lcockerton62 | 0:0a5f554d2a16 | 67 | data.set_u16(0, voltage[0]); |
lcockerton62 | 0:0a5f554d2a16 | 68 | data.set_u16(1, voltage[1]); |
lcockerton62 | 0:0a5f554d2a16 | 69 | data.set_u16(2, voltage[2]); |
lcockerton62 | 0:0a5f554d2a16 | 70 | data.set_u16(3, voltage[3]); |
lcockerton62 | 0:0a5f554d2a16 | 71 | |
lcockerton62 | 0:0a5f554d2a16 | 72 | for (int i = 0; i<8; i++) { |
lcockerton62 | 0:0a5f554d2a16 | 73 | msg.data[i] = data.get_u8(i); |
lcockerton62 | 0:0a5f554d2a16 | 74 | } |
lcockerton62 | 0:0a5f554d2a16 | 75 | |
lcockerton62 | 0:0a5f554d2a16 | 76 | return msg; |
lcockerton62 | 0:0a5f554d2a16 | 77 | } |
lcockerton62 | 0:0a5f554d2a16 | 78 | |
lcockerton62 | 0:0a5f554d2a16 | 79 | CANMessage createPackSOC(float SOC, float percentageCharge) |
lcockerton62 | 0:0a5f554d2a16 | 80 | { |
lcockerton62 | 0:0a5f554d2a16 | 81 | CANMessage msg; |
lcockerton62 | 0:0a5f554d2a16 | 82 | msg.len = 8; |
lcockerton62 | 0:0a5f554d2a16 | 83 | msg.id = BMS_BASE_ID + BATTERY_SOC_ID; |
lcockerton62 | 0:0a5f554d2a16 | 84 | CAN_Data data; |
lcockerton62 | 0:0a5f554d2a16 | 85 | data.setLowerFloat(SOC); |
lcockerton62 | 0:0a5f554d2a16 | 86 | data.setUpperFloat(percentageCharge); |
lcockerton62 | 1:51477fe4851b | 87 | for(int i=0; i<8; i++) { |
lcockerton62 | 0:0a5f554d2a16 | 88 | msg.data[i] = data.get_u8(i); |
lcockerton62 | 0:0a5f554d2a16 | 89 | } |
lcockerton62 | 1:51477fe4851b | 90 | |
lcockerton62 | 0:0a5f554d2a16 | 91 | return msg; |
lcockerton62 | 0:0a5f554d2a16 | 92 | } |
lcockerton62 | 0:0a5f554d2a16 | 93 | |
lcockerton62 | 0:0a5f554d2a16 | 94 | CANMessage createPackBalanceSOC(float SOC, float percentageCharge) |
lcockerton62 | 0:0a5f554d2a16 | 95 | { |
lcockerton62 | 0:0a5f554d2a16 | 96 | // @TODO - check is this being used?? section 5.4 trituim BMU CAN data sheet |
lcockerton62 | 0:0a5f554d2a16 | 97 | CANMessage msg; |
lcockerton62 | 0:0a5f554d2a16 | 98 | msg.len = 8; |
lcockerton62 | 1:51477fe4851b | 99 | msg.id = BMS_BASE_ID + BATTERY_SOC_BASE_ID; |
lcockerton62 | 1:51477fe4851b | 100 | |
lcockerton62 | 0:0a5f554d2a16 | 101 | CAN_Data data; |
lcockerton62 | 0:0a5f554d2a16 | 102 | data.setLowerFloat(SOC); |
lcockerton62 | 0:0a5f554d2a16 | 103 | data.setUpperFloat(percentageCharge); |
lcockerton62 | 1:51477fe4851b | 104 | for(int i=0; i<8; i++) { |
lcockerton62 | 0:0a5f554d2a16 | 105 | msg.data[i] = data.get_u8(i); |
lcockerton62 | 0:0a5f554d2a16 | 106 | } |
lcockerton62 | 1:51477fe4851b | 107 | |
lcockerton62 | 0:0a5f554d2a16 | 108 | return msg; |
lcockerton62 | 0:0a5f554d2a16 | 109 | } |
lcockerton62 | 0:0a5f554d2a16 | 110 | |
lcockerton62 | 1:51477fe4851b | 111 | CANMessage createCellVoltageMAXMIN(pack_voltage_extremes max_voltage, pack_voltage_extremes min_voltage) |
lcockerton62 | 0:0a5f554d2a16 | 112 | { |
lcockerton62 | 0:0a5f554d2a16 | 113 | CANMessage msg; |
lcockerton62 | 0:0a5f554d2a16 | 114 | msg.len = 8; |
lcockerton62 | 1:51477fe4851b | 115 | msg.id = BMS_BASE_ID + MAX_MIN_VOLTAGE; |
lcockerton62 | 1:51477fe4851b | 116 | |
lcockerton62 | 0:0a5f554d2a16 | 117 | CAN_Data data; |
lcockerton62 | 1:51477fe4851b | 118 | data.set_u16(0,min_voltage.voltage); //Min voltage |
lcockerton62 | 1:51477fe4851b | 119 | data.set_u16(1,max_voltage.voltage); //Max voltage |
lcockerton62 | 1:51477fe4851b | 120 | data.set_u8(4,min_voltage.CMU_number); //CMU number of lowest cell |
lcockerton62 | 1:51477fe4851b | 121 | data.set_u8(5,min_voltage.cell_number); //Cell number in CMU with lowest voltage |
lcockerton62 | 1:51477fe4851b | 122 | data.set_u8(6,min_voltage.CMU_number); //CMU number of maxiumum cell |
lcockerton62 | 1:51477fe4851b | 123 | data.set_u8(7,min_voltage.cell_number); //Cell number in CMU with highest voltage |
lcockerton62 | 1:51477fe4851b | 124 | |
lcockerton62 | 1:51477fe4851b | 125 | for(int i=0; i<8; i++) { |
lcockerton62 | 0:0a5f554d2a16 | 126 | msg.data[i] = data.get_u8(i); |
lcockerton62 | 0:0a5f554d2a16 | 127 | } |
lcockerton62 | 1:51477fe4851b | 128 | |
lcockerton62 | 0:0a5f554d2a16 | 129 | return msg; |
lcockerton62 | 0:0a5f554d2a16 | 130 | } |
lcockerton62 | 0:0a5f554d2a16 | 131 | |
lcockerton62 | 1:51477fe4851b | 132 | CANMessage createCellTemperatureMAXMIN(pack_temperature_extremes min_temperature, pack_temperature_extremes max_temperature) |
lcockerton62 | 0:0a5f554d2a16 | 133 | { |
lcockerton62 | 0:0a5f554d2a16 | 134 | CANMessage msg; |
lcockerton62 | 0:0a5f554d2a16 | 135 | msg.len = 8; |
lcockerton62 | 1:51477fe4851b | 136 | msg.id = BMS_BASE_ID + MAX_MIN_TEMPERATURE; |
lcockerton62 | 1:51477fe4851b | 137 | |
lcockerton62 | 0:0a5f554d2a16 | 138 | CAN_Data data; |
lcockerton62 | 1:51477fe4851b | 139 | data.set_u16(0,min_temperature.temperature); //Min temperature |
lcockerton62 | 1:51477fe4851b | 140 | data.set_u16(1,max_temperature.temperature); //Max temperature |
lcockerton62 | 1:51477fe4851b | 141 | data.set_u8(4,min_temperature.CMU_number); //CMU number of lowest temperature cell |
lcockerton62 | 0:0a5f554d2a16 | 142 | data.set_u8(5,BLANK_DATA); //Dummy data |
lcockerton62 | 1:51477fe4851b | 143 | data.set_u8(6,max_temperature.CMU_number); //CMU number of maxiumum temperature cell |
lcockerton62 | 1:51477fe4851b | 144 | data.set_u8(7,BLANK_DATA); //Dummy data |
lcockerton62 | 1:51477fe4851b | 145 | |
lcockerton62 | 1:51477fe4851b | 146 | for(int i=0; i<8; i++) { |
lcockerton62 | 0:0a5f554d2a16 | 147 | msg.data[i] = data.get_u8(i); |
lcockerton62 | 0:0a5f554d2a16 | 148 | } |
lcockerton62 | 1:51477fe4851b | 149 | |
lcockerton62 | 0:0a5f554d2a16 | 150 | return msg; |
lcockerton62 | 0:0a5f554d2a16 | 151 | } |
lcockerton62 | 0:0a5f554d2a16 | 152 | |
lcockerton62 | 0:0a5f554d2a16 | 153 | CANMessage createBatteryVI(uint32_t batteryVoltage,uint32_t batteryCurrent) |
lcockerton62 | 0:0a5f554d2a16 | 154 | { |
lcockerton62 | 0:0a5f554d2a16 | 155 | CANMessage msg; |
lcockerton62 | 0:0a5f554d2a16 | 156 | msg.len = 8; |
lcockerton62 | 1:51477fe4851b | 157 | msg.id = BMS_BASE_ID + BATTERY_VI_ID; |
lcockerton62 | 1:51477fe4851b | 158 | |
lcockerton62 | 0:0a5f554d2a16 | 159 | CAN_Data data; |
lcockerton62 | 3:527790e4965a | 160 | data.setLower_uLong(batteryVoltage); |
lcockerton62 | 3:527790e4965a | 161 | data.setHigher_uLong(batteryCurrent); |
lcockerton62 | 1:51477fe4851b | 162 | |
lcockerton62 | 1:51477fe4851b | 163 | for(int i=0; i<8; i++) { |
lcockerton62 | 0:0a5f554d2a16 | 164 | msg.data[i] = data.get_u8(i); |
lcockerton62 | 0:0a5f554d2a16 | 165 | } |
lcockerton62 | 0:0a5f554d2a16 | 166 | return msg; |
lcockerton62 | 0:0a5f554d2a16 | 167 | } |
lcockerton62 | 0:0a5f554d2a16 | 168 | |
lcockerton62 | 0:0a5f554d2a16 | 169 | CANMessage createBatteryPackStatus(uint16_t voltageThreshold[], uint8_t statusFlag,uint8_t BMS_CMU_Count,uint16_t BMS_Firmware_Build) |
lcockerton62 | 0:0a5f554d2a16 | 170 | { |
lcockerton62 | 1:51477fe4851b | 171 | CANMessage msg; |
lcockerton62 | 1:51477fe4851b | 172 | msg.len = 8; |
lcockerton62 | 1:51477fe4851b | 173 | msg.id = BMS_BASE_ID + BATTERY_PACK_STATUS_ID; |
lcockerton62 | 1:51477fe4851b | 174 | |
lcockerton62 | 1:51477fe4851b | 175 | CAN_Data data; |
lcockerton62 | 1:51477fe4851b | 176 | data.set_u16(0,voltageThreshold[0]); |
lcockerton62 | 1:51477fe4851b | 177 | data.set_u16(1,voltageThreshold[1]); |
lcockerton62 | 1:51477fe4851b | 178 | data.set_16(3,BMS_Firmware_Build); |
lcockerton62 | 1:51477fe4851b | 179 | data.set_u8(4,statusFlag); |
lcockerton62 | 1:51477fe4851b | 180 | data.set_u8(5,BMS_CMU_Count); |
lcockerton62 | 1:51477fe4851b | 181 | |
lcockerton62 | 1:51477fe4851b | 182 | for(int i=0; i<8; i++) { |
lcockerton62 | 1:51477fe4851b | 183 | msg.data[i] = data.get_u8(i); |
lcockerton62 | 1:51477fe4851b | 184 | } |
lcockerton62 | 1:51477fe4851b | 185 | return msg; |
lcockerton62 | 0:0a5f554d2a16 | 186 | } |
lcockerton62 | 0:0a5f554d2a16 | 187 | |
lcockerton62 | 0:0a5f554d2a16 | 188 | CANMessage createExtendedBatteryPackStatus(uint32_t status) |
lcockerton62 | 0:0a5f554d2a16 | 189 | { |
lcockerton62 | 1:51477fe4851b | 190 | CANMessage msg; |
lcockerton62 | 1:51477fe4851b | 191 | msg.len = 8; |
lcockerton62 | 1:51477fe4851b | 192 | msg.id = BMS_BASE_ID + BATTERY_STATUS_ID; |
lcockerton62 | 1:51477fe4851b | 193 | |
lcockerton62 | 1:51477fe4851b | 194 | CAN_Data data; |
lcockerton62 | 1:51477fe4851b | 195 | data.setLower_uLong(status); //@TODO see the data sheet for this |
lcockerton62 | 1:51477fe4851b | 196 | data.set_u8(4,0x00);//Hardware version random data @TODO check this |
lcockerton62 | 1:51477fe4851b | 197 | data.set_u8(5,0x00);//Model ID @TODO check this |
lcockerton62 | 1:51477fe4851b | 198 | data.set_u16(3,0x00); // Unused |
lcockerton62 | 1:51477fe4851b | 199 | |
lcockerton62 | 1:51477fe4851b | 200 | for(int i=0; i<8; i++) { |
lcockerton62 | 1:51477fe4851b | 201 | msg.data[i] = data.get_u8(i); |
lcockerton62 | 1:51477fe4851b | 202 | } |
lcockerton62 | 1:51477fe4851b | 203 | return msg; |
lcockerton62 | 0:0a5f554d2a16 | 204 | } |
lcockerton62 | 0:0a5f554d2a16 | 205 | |
lcockerton62 | 0:0a5f554d2a16 | 206 | void convertFloatFloat(float lower, float upper, CANMessage& msg, bool littleEndian) |
lcockerton62 | 0:0a5f554d2a16 | 207 | { |
lcockerton62 | 0:0a5f554d2a16 | 208 | // Code taken from driver_controls |
lcockerton62 | 0:0a5f554d2a16 | 209 | //two converters for lower and higher float |
lcockerton62 | 0:0a5f554d2a16 | 210 | float2byte convL; |
lcockerton62 | 0:0a5f554d2a16 | 211 | float2byte convH; |
lcockerton62 | 0:0a5f554d2a16 | 212 | convL.f = lower; |
lcockerton62 | 0:0a5f554d2a16 | 213 | convH.f = upper; |
lcockerton62 | 0:0a5f554d2a16 | 214 | if(littleEndian) { |
lcockerton62 | 0:0a5f554d2a16 | 215 | for(int i=0; i<4; i++) { |
lcockerton62 | 0:0a5f554d2a16 | 216 | msg.data[i] = convL.b[i]; |
lcockerton62 | 0:0a5f554d2a16 | 217 | //offset for upper float |
lcockerton62 | 0:0a5f554d2a16 | 218 | msg.data[i+4]=convH.b[i]; |
lcockerton62 | 0:0a5f554d2a16 | 219 | } |
lcockerton62 | 0:0a5f554d2a16 | 220 | } else { |
lcockerton62 | 0:0a5f554d2a16 | 221 | for(int i=0; i<4; i++) { |
lcockerton62 | 0:0a5f554d2a16 | 222 | /* |
lcockerton62 | 0:0a5f554d2a16 | 223 | * Subtract because output data is Big Endian |
lcockerton62 | 0:0a5f554d2a16 | 224 | * i.e. convL/H is LSB --> MSB |
lcockerton62 | 0:0a5f554d2a16 | 225 | * output is MSB --> LSB |
lcockerton62 | 0:0a5f554d2a16 | 226 | */ |
lcockerton62 | 1:51477fe4851b | 227 | |
lcockerton62 | 0:0a5f554d2a16 | 228 | msg.data[4-i] = convL.b[i]; |
lcockerton62 | 0:0a5f554d2a16 | 229 | msg.data[7-i] = convH.b[i]; |
lcockerton62 | 0:0a5f554d2a16 | 230 | } |
lcockerton62 | 0:0a5f554d2a16 | 231 | } |
lcockerton62 | 1:51477fe4851b | 232 | |
lcockerton62 | 0:0a5f554d2a16 | 233 | } |
lcockerton62 | 0:0a5f554d2a16 | 234 |