Cell voltages fork (SoC)
Dependencies: CUER_CAN CUER_DS1820 LTC2943 LTC6804 mbed PowerControl
CANParserBMU.cpp
- Committer:
- DasSidG
- Date:
- 2017-07-02
- Revision:
- 16:b2ef68c9a4fd
- Parent:
- 14:e0e88a009f4c
- Child:
- 17:94dd9a0d3870
File content as of revision 16:b2ef68c9a4fd:
// Here are the functions to generate the CAN messages #include "CANParserBMU.h" #include "mbed.h" #include "Data_Types_BMU.h" using namespace CAN_IDs; /** * This function is rewritten to give readings for individual probes rather than * for specific CMU. As a consequence, 0x800 onwards is being used for these probes, * as everything above about 0x700 is unused by the Tritium standard. The ID value * for the probe is based on the ROM field of DS1820, entries 1-6 being the unique * serial value. */ CANMessage createTemperatureTelemetry(uint8_t offset, char ProbeROM[8], float Temperature) { CANMessage msg; msg.len = 8; msg.id = TEMPERATURE_BASE_ID + offset; // for temp it is 0x800 onwards CAN_Data data; for(int i = 1; i <= 6; i++) //ID portion of ROM array { data.set_u8(i - 1, ProbeROM[i]); } //Conversion of float to a short, requires multiplying by 100 to not lose precision float temp100 = Temperature * 100; short shortTemp = (short) temp100; data.set_16(3, shortTemp);//There seems to be an error in the function definition for set_16, (ushort instead of short) for (int i = 0; i<8; i++) { msg.data[i] = data.get_u8(i); } return msg; } /** * Takes a CANMessage with precondition that it stores temperature of an individual * probe and returns an individual_temperature object containing ID and reading. * The ID is stores in ROM array entry 1-6, other entries may be invalid. */ individual_temperature decodeTemperatureTelemetry(CANMessage msg) { individual_temperature probe_reading; CAN_Data decode; decode.importCANData(msg); short shortTemp = decode.get_16(3); probe_reading.measurement = ((float)shortTemp) / 100; for(int i = 1; i <=6; i++) { probe_reading.ROMID[i] = decode.get_u8(i-1); } return probe_reading; } CANMessage createVoltageTelemetry(int offset_id, uint16_t voltage[]) { CANMessage msg; msg.len = 8; msg.id = BMS_BASE_ID + offset_id; // for voltage 0x601 - 0x6EF @TODO CAN_Data data; data.set_u16(0, voltage[0]); data.set_u16(1, voltage[1]); data.set_u16(2, voltage[2]); data.set_u16(3, voltage[3]); for (int i = 0; i<8; i++) { msg.data[i] = data.get_u8(i); } return msg; } CANMessage createPackSOC(float SOC, float percentageCharge) { CANMessage msg; msg.len = 8; msg.id = BMS_BASE_ID + BATTERY_SOC_ID; CAN_Data data; data.setLowerFloat(SOC); data.setUpperFloat(percentageCharge); for(int i=0; i<8; i++) { msg.data[i] = data.get_u8(i); } return msg; } CANMessage createPackBalanceSOC(float SOC, float percentageCharge) { // @TODO - check is this being used?? section 5.4 trituim BMU CAN data sheet CANMessage msg; msg.len = 8; msg.id = BMS_BASE_ID + BATTERY_SOC_BASE_ID; CAN_Data data; data.setLowerFloat(SOC); data.setUpperFloat(percentageCharge); for(int i=0; i<8; i++) { msg.data[i] = data.get_u8(i); } return msg; } CANMessage createCellVoltageMAXMIN(pack_voltage_extremes max_voltage, pack_voltage_extremes min_voltage) { CANMessage msg; msg.len = 8; msg.id = BMS_BASE_ID + MAX_MIN_VOLTAGE; CAN_Data data; data.set_u16(0,min_voltage.voltage); //Min voltage data.set_u16(1,max_voltage.voltage); //Max voltage data.set_u8(4,min_voltage.CMU_number); //CMU number of lowest cell data.set_u8(5,min_voltage.cell_number); //Cell number in CMU with lowest voltage data.set_u8(6,min_voltage.CMU_number); //CMU number of maxiumum cell data.set_u8(7,min_voltage.cell_number); //Cell number in CMU with highest voltage for(int i=0; i<8; i++) { msg.data[i] = data.get_u8(i); } return msg; } CANMessage createCellTemperatureMAXMIN(pack_temperature_extremes min_temperature, pack_temperature_extremes max_temperature) { CANMessage msg; msg.len = 8; msg.id = BMS_BASE_ID + MAX_MIN_TEMPERATURE; CAN_Data data; data.set_u16(0,min_temperature.temperature); //Min temperature data.set_u16(1,max_temperature.temperature); //Max temperature data.set_u8(4,min_temperature.CMU_number); //CMU number of lowest temperature cell data.set_u8(5,BLANK_DATA); //Dummy data data.set_u8(6,max_temperature.CMU_number); //CMU number of maxiumum temperature cell data.set_u8(7,BLANK_DATA); //Dummy data for(int i=0; i<8; i++) { msg.data[i] = data.get_u8(i); } return msg; } CANMessage createBatteryVI(uint32_t batteryVoltage,uint32_t batteryCurrent) { CANMessage msg; msg.len = 8; msg.id = BMS_BASE_ID + BATTERY_VI_ID; CAN_Data data; data.setLower_uLong(batteryVoltage); data.setHigher_uLong(batteryCurrent); for(int i=0; i<8; i++) { msg.data[i] = data.get_u8(i); } return msg; } CANMessage createBatteryPackStatus(uint16_t voltageThreshold[], uint8_t statusFlag,uint8_t BMS_CMU_Count,uint16_t BMS_Firmware_Build) { CANMessage msg; msg.len = 8; msg.id = BMS_BASE_ID + BATTERY_PACK_STATUS_ID; CAN_Data data; data.set_u16(0,voltageThreshold[0]); data.set_u16(1,voltageThreshold[1]); data.set_16(3,BMS_Firmware_Build); data.set_u8(4,statusFlag); data.set_u8(5,BMS_CMU_Count); for(int i=0; i<8; i++) { msg.data[i] = data.get_u8(i); } return msg; } CANMessage createExtendedBatteryPackStatus(uint32_t status) { CANMessage msg; msg.len = 8; msg.id = BMS_BASE_ID + BATTERY_STATUS_ID; CAN_Data data; data.setLower_uLong(status); //@TODO see the data sheet for this data.set_u8(4,0x00);//Hardware version random data @TODO check this data.set_u8(5,0x00);//Model ID @TODO check this data.set_u16(3,0x00); // Unused for(int i=0; i<8; i++) { msg.data[i] = data.get_u8(i); } return msg; } void convertFloatFloat(float lower, float upper, CANMessage& msg, bool littleEndian) { // Code taken from driver_controls //two converters for lower and higher float float2byte convL; float2byte convH; convL.f = lower; convH.f = upper; if(littleEndian) { for(int i=0; i<4; i++) { msg.data[i] = convL.b[i]; //offset for upper float msg.data[i+4]=convH.b[i]; } } else { for(int i=0; i<4; i++) { /* * Subtract because output data is Big Endian * i.e. convL/H is LSB --> MSB * output is MSB --> LSB */ msg.data[4-i] = convL.b[i]; msg.data[7-i] = convH.b[i]; } } }