Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: CUER_CAN CUER_DS1820 LTC2943 LTC6804 mbed PowerControl
main.cpp@28:f1f882bd1653, 2017-07-09 (annotated)
- Committer:
- maxv008
- Date:
- Sun Jul 09 16:58:32 2017 +0000
- Revision:
- 28:f1f882bd1653
- Parent:
- 25:1fe8a42f8a6d
- Child:
- 29:44924d2b1293
SOC working, voltages mysteriously break everything, tune in next week for more.
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| lcockerton62 | 0:0a5f554d2a16 | 1 | #include "mbed.h" |
| lcockerton62 | 0:0a5f554d2a16 | 2 | #include "CANParserBMU.h" |
| lcockerton62 | 0:0a5f554d2a16 | 3 | #include "Data_Types_BMU.h" |
| lcockerton62 | 0:0a5f554d2a16 | 4 | #include "CAN_Data.h" |
| lcockerton62 | 0:0a5f554d2a16 | 5 | #include "CAN_IDs.h" |
| lcockerton62 | 1:51477fe4851b | 6 | #include "EEPROM_I2C.h" |
| lcockerton62 | 1:51477fe4851b | 7 | #include "Temperature.h" |
| DasSidG | 4:9050c5d6925e | 8 | #include "LTC2943_Read.h" |
| maxv008 | 10:1079f8e52d65 | 9 | #include "Cell_Voltage.h" |
| maxv008 | 7:d00f4433cea9 | 10 | #include "SPI_I2C_Parser.h" |
| maxv008 | 25:1fe8a42f8a6d | 11 | #include "LTC2943.h" |
| lcockerton62 | 0:0a5f554d2a16 | 12 | |
| msharma97 | 9:82ba050a7e13 | 13 | |
| lcockerton62 | 0:0a5f554d2a16 | 14 | using namespace CAN_IDs; |
| lcockerton62 | 0:0a5f554d2a16 | 15 | |
| lcockerton62 | 0:0a5f554d2a16 | 16 | // Function definitions |
| lcockerton62 | 1:51477fe4851b | 17 | void transmit_data(BMU_data measurements,uint32_t status); |
| lcockerton62 | 1:51477fe4851b | 18 | void read_temperature_sensors(BMU_data &measurements); |
| lcockerton62 | 0:0a5f554d2a16 | 19 | void update_SOC(); |
| lcockerton62 | 0:0a5f554d2a16 | 20 | void init(); |
| maxv008 | 14:e0e88a009f4c | 21 | void interruptHandler(); |
| maxv008 | 14:e0e88a009f4c | 22 | void CANDataSentCallback(); |
| lcockerton62 | 1:51477fe4851b | 23 | void write_SOC_EEPROM(BMU_data &measurements,uint16_t start_address); |
| lcockerton62 | 1:51477fe4851b | 24 | uint16_t read_EEPROM_startup(BMU_data &measurements); |
| lcockerton62 | 1:51477fe4851b | 25 | uint32_t check_measurements(BMU_data &measurements); |
| maxv008 | 23:a1af4439c1fc | 26 | uint32_t take_measurements(BMU_data &measurements); |
| maxv008 | 14:e0e88a009f4c | 27 | void test_read_CAN_buffer(); |
| DasSidG | 12:fa9b1a459e47 | 28 | bool test_read_voltage_CAN(uint16_t readings[], int can_ids[]); |
| maxv008 | 10:1079f8e52d65 | 29 | void test_CAN_send(); |
| maxv008 | 10:1079f8e52d65 | 30 | void test_CAN_read(); |
| lcockerton62 | 0:0a5f554d2a16 | 31 | |
| lcockerton62 | 0:0a5f554d2a16 | 32 | CAN can(CAN_READ_PIN, CAN_WRITE_PIN); //Create a CAN object to handle CAN comms |
| maxv008 | 14:e0e88a009f4c | 33 | CANMessage buffer[CAN_BUFFER_SIZE]; //CAN receive buffer |
| maxv008 | 14:e0e88a009f4c | 34 | bool safe_to_write[CAN_BUFFER_SIZE]; //Semaphore bit indicating that it's safe to write to the software buffer |
| maxv008 | 14:e0e88a009f4c | 35 | bool CAN_data_sent = false; |
| maxv008 | 14:e0e88a009f4c | 36 | |
| maxv008 | 20:a1a1bfc938da | 37 | //Global array to store most recently obtained voltage and temp measurement: |
| maxv008 | 17:94dd9a0d3870 | 38 | CMU_voltage voltage_readings[NO_CMUS]; |
| maxv008 | 20:a1a1bfc938da | 39 | individual_temperature templist[NO_TEMPERATURE_SENSORS]; |
| maxv008 | 28:f1f882bd1653 | 40 | uint32_t status; |
| maxv008 | 28:f1f882bd1653 | 41 | //LTC2943 ltc2943(i2c_sda, i2c_scl, alcc_pin, &dummyfunction, R_SENSE, BATTERY_CAPACITY); |
| maxv008 | 17:94dd9a0d3870 | 42 | |
| DasSidG | 4:9050c5d6925e | 43 | uint16_t eeprom_start_address; //the initial address where we store/read SoC values |
| lcockerton62 | 0:0a5f554d2a16 | 44 | |
| lcockerton62 | 1:51477fe4851b | 45 | Timeout loop_delay; |
| lcockerton62 | 1:51477fe4851b | 46 | bool delay_finished = false; |
| lcockerton62 | 2:94716229ecc3 | 47 | |
| maxv008 | 28:f1f882bd1653 | 48 | //The following is to initialize reading tests, can be removed when needed |
| maxv008 | 28:f1f882bd1653 | 49 | float packSOC; |
| maxv008 | 28:f1f882bd1653 | 50 | float packSOCPercentage; |
| maxv008 | 28:f1f882bd1653 | 51 | pack_voltage_extremes minVolt; |
| maxv008 | 28:f1f882bd1653 | 52 | pack_voltage_extremes maxVolt; |
| maxv008 | 28:f1f882bd1653 | 53 | pack_temperature_extremes minTemp; |
| maxv008 | 28:f1f882bd1653 | 54 | pack_temperature_extremes maxTemp; |
| maxv008 | 14:e0e88a009f4c | 55 | |
| lcockerton62 | 2:94716229ecc3 | 56 | void loop_delay_callback(void) |
| lcockerton62 | 2:94716229ecc3 | 57 | { |
| lcockerton62 | 1:51477fe4851b | 58 | delay_finished = true; |
| lcockerton62 | 1:51477fe4851b | 59 | } |
| lcockerton62 | 1:51477fe4851b | 60 | |
| lcockerton62 | 0:0a5f554d2a16 | 61 | int main() |
| DasSidG | 11:cf2db05cfa56 | 62 | { |
| lcockerton62 | 1:51477fe4851b | 63 | BMU_data measurements; |
| lcockerton62 | 1:51477fe4851b | 64 | uint16_t current_EEPROM_address; |
| DasSidG | 12:fa9b1a459e47 | 65 | uint16_t volt_readings[36]; |
| DasSidG | 12:fa9b1a459e47 | 66 | int can_ids[9]; |
| maxv008 | 10:1079f8e52d65 | 67 | |
| lcockerton62 | 0:0a5f554d2a16 | 68 | init(); |
| maxv008 | 10:1079f8e52d65 | 69 | |
| DasSidG | 11:cf2db05cfa56 | 70 | //current_EEPROM_address = read_EEPROM_startup(measurements); // Read from the eeprom at startup to fill in the values of SoC |
| DasSidG | 11:cf2db05cfa56 | 71 | //ltc2943.accumulatedCharge(measurements.percentage_SOC); // Initialise the LTC2943 with the current state of charge |
| DasSidG | 4:9050c5d6925e | 72 | |
| lcockerton62 | 1:51477fe4851b | 73 | while (true) { |
| DasSidG | 11:cf2db05cfa56 | 74 | |
| maxv008 | 28:f1f882bd1653 | 75 | //status = take_measurements(measurements); |
| DasSidG | 11:cf2db05cfa56 | 76 | /*// Dont want to read the temperature sensors during each iteration of the loop |
| lcockerton62 | 0:0a5f554d2a16 | 77 | |
| lcockerton62 | 1:51477fe4851b | 78 | //Store data in the eeprom |
| lcockerton62 | 1:51477fe4851b | 79 | write_SOC_EEPROM(measurements, current_EEPROM_address); |
| DasSidG | 11:cf2db05cfa56 | 80 | */ |
| maxv008 | 28:f1f882bd1653 | 81 | printf("Beginning of loop \r\n"); |
| lcockerton62 | 5:793afeef45dc | 82 | // CAN bus |
| maxv008 | 14:e0e88a009f4c | 83 | CAN_data_sent = false;//Currently does nothing, adding this line in more places then using |
| maxv008 | 14:e0e88a009f4c | 84 | //while(!CAN_data_sent); in order to ensure sending completes |
| maxv008 | 28:f1f882bd1653 | 85 | //transmit_data(measurements,status); |
| maxv008 | 28:f1f882bd1653 | 86 | test_read_CAN_buffer(); |
| DasSidG | 11:cf2db05cfa56 | 87 | |
| DasSidG | 11:cf2db05cfa56 | 88 | /* |
| lcockerton62 | 0:0a5f554d2a16 | 89 | // Conserve power - enter a low powered mode |
| lcockerton62 | 2:94716229ecc3 | 90 | delay_finished = false; |
| lcockerton62 | 1:51477fe4851b | 91 | loop_delay.attach(loop_delay_callback, LOOP_DELAY_S); |
| lcockerton62 | 1:51477fe4851b | 92 | while (!delay_finished) sleep(); |
| DasSidG | 11:cf2db05cfa56 | 93 | */ |
| maxv008 | 28:f1f882bd1653 | 94 | printf("BEFORE THE WAIT \r\n"); |
| DasSidG | 11:cf2db05cfa56 | 95 | wait(1); |
| maxv008 | 28:f1f882bd1653 | 96 | printf("AFTER THE WAIT \r\n"); |
| maxv008 | 10:1079f8e52d65 | 97 | } |
| lcockerton62 | 0:0a5f554d2a16 | 98 | } |
| lcockerton62 | 0:0a5f554d2a16 | 99 | |
| lcockerton62 | 1:51477fe4851b | 100 | void transmit_data(BMU_data measurements, uint32_t status) |
| lcockerton62 | 0:0a5f554d2a16 | 101 | { |
| msharma97 | 9:82ba050a7e13 | 102 | CANMessage msg; |
| lcockerton62 | 0:0a5f554d2a16 | 103 | /* |
| lcockerton62 | 0:0a5f554d2a16 | 104 | Place all of the collected data onto the CAN bus |
| lcockerton62 | 0:0a5f554d2a16 | 105 | */ |
| lcockerton62 | 5:793afeef45dc | 106 | // Send cell voltages |
| maxv008 | 13:7b42af989cd1 | 107 | //voltages sent in sets of 4 + one cmu data set |
| msharma97 | 9:82ba050a7e13 | 108 | int repeating_unit_length = NO_READINGS_PER_CMU /4 + 1; |
| maxv008 | 10:1079f8e52d65 | 109 | for(uint16_t i= 0; i < NO_CMUS; i++) { |
| msharma97 | 9:82ba050a7e13 | 110 | //input id is offset, data structure is info, voltage, voltage, ...... |
| maxv008 | 10:1079f8e52d65 | 111 | //This is a slightly modified version of the Tritium BMS datasheet, to add an extra voltage reading set. |
| maxv008 | 10:1079f8e52d65 | 112 | msg = createVoltageTelemetry(repeating_unit_length*i+2, measurements.cell_voltages[i].voltages); |
| msharma97 | 9:82ba050a7e13 | 113 | can.write(msg); |
| maxv008 | 17:94dd9a0d3870 | 114 | printf("Voltage Message id: %d \r\n", msg.id); |
| maxv008 | 17:94dd9a0d3870 | 115 | //+4 - 4 cell voltages sent per measurement, simple pointer arithmetic |
| maxv008 | 10:1079f8e52d65 | 116 | msg = createVoltageTelemetry(repeating_unit_length*i+3, measurements.cell_voltages[i].voltages + 4); |
| msharma97 | 9:82ba050a7e13 | 117 | can.write(msg); |
| maxv008 | 17:94dd9a0d3870 | 118 | printf("Voltage Message id: %d \r\n", msg.id); |
| maxv008 | 10:1079f8e52d65 | 119 | msg = createVoltageTelemetry(repeating_unit_length*i+4, measurements.cell_voltages[i].voltages + 8); |
| msharma97 | 9:82ba050a7e13 | 120 | can.write(msg); |
| maxv008 | 17:94dd9a0d3870 | 121 | printf("Voltage Message id: %d \r\n", msg.id); |
| lcockerton62 | 1:51477fe4851b | 122 | } |
| maxv008 | 13:7b42af989cd1 | 123 | |
| maxv008 | 13:7b42af989cd1 | 124 | //Transmitting all of the individual probes: |
| maxv008 | 17:94dd9a0d3870 | 125 | for(uint8_t i = 0; i < devices_found; i++) |
| maxv008 | 13:7b42af989cd1 | 126 | { |
| maxv008 | 14:e0e88a009f4c | 127 | individual_temperature tempreading = measurements.temperature_measurements[i]; |
| maxv008 | 14:e0e88a009f4c | 128 | msg = createTemperatureTelemetry(i, &tempreading.ROMID[0], tempreading.measurement); |
| maxv008 | 17:94dd9a0d3870 | 129 | individual_temperature testOut = decodeTemperatureTelemetry(msg); |
| maxv008 | 17:94dd9a0d3870 | 130 | printf("Temperature reading sent (CAN ID = %d): (%f,%d) \r\n", msg.id, testOut.measurement, testOut.ID); |
| maxv008 | 20:a1a1bfc938da | 131 | if(can.write(msg)); |
| maxv008 | 20:a1a1bfc938da | 132 | else |
| maxv008 | 20:a1a1bfc938da | 133 | printf("Sending Temperature Failed for some reason"); |
| maxv008 | 13:7b42af989cd1 | 134 | } |
| lcockerton62 | 1:51477fe4851b | 135 | |
| lcockerton62 | 1:51477fe4851b | 136 | // Create SOC CAN message |
| maxv008 | 23:a1af4439c1fc | 137 | msg = createPackSOC(measurements.SOC, measurements.percentage_SOC); |
| maxv008 | 23:a1af4439c1fc | 138 | can.write(msg); |
| maxv008 | 28:f1f882bd1653 | 139 | printf("SOC is %f and percentage SOC is %f and id is %d \r\n", measurements.SOC, measurements.percentage_SOC, msg.id); |
| maxv008 | 23:a1af4439c1fc | 140 | |
| lcockerton62 | 1:51477fe4851b | 141 | // Min/max cell voltages |
| maxv008 | 23:a1af4439c1fc | 142 | msg = createCellVoltageMAXMIN(measurements.max_cell_voltage, measurements.min_cell_voltage); |
| maxv008 | 23:a1af4439c1fc | 143 | can.write(msg); |
| maxv008 | 23:a1af4439c1fc | 144 | |
| maxv008 | 23:a1af4439c1fc | 145 | // Min/Max cell temperatures |
| maxv008 | 23:a1af4439c1fc | 146 | msg = createCellTemperatureMAXMIN(measurements.min_cell_temp, true); |
| maxv008 | 23:a1af4439c1fc | 147 | can.write(msg); |
| maxv008 | 23:a1af4439c1fc | 148 | msg = createCellTemperatureMAXMIN(measurements.max_cell_temp, false); |
| maxv008 | 23:a1af4439c1fc | 149 | can.write(msg); |
| maxv008 | 23:a1af4439c1fc | 150 | |
| lcockerton62 | 2:94716229ecc3 | 151 | // Battery voltage and current |
| lcockerton62 | 5:793afeef45dc | 152 | // @TODO add the voltage |
| maxv008 | 23:a1af4439c1fc | 153 | msg = createBatteryVI(measurements.battery_voltage,measurements.battery_current); |
| maxv008 | 23:a1af4439c1fc | 154 | //can.write(msg); |
| maxv008 | 23:a1af4439c1fc | 155 | |
| lcockerton62 | 1:51477fe4851b | 156 | //Extended battery pack status |
| maxv008 | 23:a1af4439c1fc | 157 | msg = createExtendedBatteryPackStatus(status); |
| maxv008 | 23:a1af4439c1fc | 158 | can.write(msg); |
| lcockerton62 | 0:0a5f554d2a16 | 159 | } |
| lcockerton62 | 0:0a5f554d2a16 | 160 | |
| maxv008 | 10:1079f8e52d65 | 161 | |
| lcockerton62 | 1:51477fe4851b | 162 | uint16_t read_EEPROM_startup(BMU_data &measurements) |
| lcockerton62 | 0:0a5f554d2a16 | 163 | { |
| lcockerton62 | 1:51477fe4851b | 164 | /* The first page of the EEPROM, specifically the first 2 addresses store a |
| lcockerton62 | 1:51477fe4851b | 165 | pointer of the first memory location of measurement data. The EEPROM only has a finite number of |
| lcockerton62 | 1:51477fe4851b | 166 | read/write cycles which is why we aren't writing to the same location throughout |
| lcockerton62 | 1:51477fe4851b | 167 | */ |
| lcockerton62 | 5:793afeef45dc | 168 | |
| lcockerton62 | 1:51477fe4851b | 169 | uint16_t start_address; |
| lcockerton62 | 1:51477fe4851b | 170 | char start_address_array[2]; |
| lcockerton62 | 22:2df45c818786 | 171 | char SOC_out[10]; // 4 bytes for the 2 floats one is SOC and the other % charge |
| lcockerton62 | 1:51477fe4851b | 172 | float *fp1,*fp2; // temporary storage for float conversion |
| lcockerton62 | 22:2df45c818786 | 173 | uint16_t received_pec; |
| lcockerton62 | 22:2df45c818786 | 174 | uint16_t data_pec; |
| lcockerton62 | 22:2df45c818786 | 175 | int8_t pec_error; |
| lcockerton62 | 1:51477fe4851b | 176 | |
| lcockerton62 | 1:51477fe4851b | 177 | // Get a pointer to the start address for the data stored in the eeprom |
| lcockerton62 | 1:51477fe4851b | 178 | i2c_page_read(0x0000,2,start_address_array); |
| lcockerton62 | 1:51477fe4851b | 179 | |
| lcockerton62 | 1:51477fe4851b | 180 | // Read the data from this address |
| lcockerton62 | 1:51477fe4851b | 181 | start_address = (start_address_array[1]<< 8) | start_address_array[0]; // mbed little endian follow this convention |
| lcockerton62 | 22:2df45c818786 | 182 | i2c_page_read(start_address, 10,SOC_out); // Reading will aquire 2 floats and a PEC for the data |
| lcockerton62 | 0:0a5f554d2a16 | 183 | |
| lcockerton62 | 22:2df45c818786 | 184 | // Convert the SOC_out values back into floats and deal with the pec |
| lcockerton62 | 22:2df45c818786 | 185 | received_pec = (uint16_t)(SOC_out[8]<<8) + (uint16_t)SOC_out[9]; |
| lcockerton62 | 22:2df45c818786 | 186 | data_pec = pec15_calc(8, (uint8_t*)SOC_out); |
| lcockerton62 | 22:2df45c818786 | 187 | if(received_pec != data_pec) { |
| lcockerton62 | 22:2df45c818786 | 188 | pec_error = -1; |
| lcockerton62 | 22:2df45c818786 | 189 | cout << "PEC error!!!" << endl; // @TODO An error flag really needs to be raised here |
| lcockerton62 | 22:2df45c818786 | 190 | } |
| lcockerton62 | 22:2df45c818786 | 191 | else{ |
| lcockerton62 | 22:2df45c818786 | 192 | fp1 = (float*)(&SOC_out[0]); |
| lcockerton62 | 22:2df45c818786 | 193 | fp2 = (float*)(&SOC_out[4]); |
| lcockerton62 | 22:2df45c818786 | 194 | measurements.SOC = *fp1; |
| lcockerton62 | 22:2df45c818786 | 195 | measurements.percentage_SOC = *fp2; |
| lcockerton62 | 22:2df45c818786 | 196 | } |
| lcockerton62 | 1:51477fe4851b | 197 | |
| lcockerton62 | 1:51477fe4851b | 198 | // Select the next address to write to |
| lcockerton62 | 1:51477fe4851b | 199 | start_address += 0x0040; |
| lcockerton62 | 1:51477fe4851b | 200 | if(start_address > MAX_WRITE_ADDRESS) { |
| lcockerton62 | 5:793afeef45dc | 201 | start_address = START_WRITE_ADDRESS; // Loop to the start of the eeprom |
| lcockerton62 | 1:51477fe4851b | 202 | } |
| lcockerton62 | 1:51477fe4851b | 203 | |
| lcockerton62 | 5:793afeef45dc | 204 | /*@TODO need to include a CRC check for the address pointer for the scenario |
| lcockerton62 | 5:793afeef45dc | 205 | when power is removed and we are writing to the eeprom*/ |
| lcockerton62 | 1:51477fe4851b | 206 | // write the new address to location 0x0000 |
| lcockerton62 | 1:51477fe4851b | 207 | start_address_array[0] = start_address | 0x00FF; |
| lcockerton62 | 1:51477fe4851b | 208 | start_address_array[1] = start_address >> 8; |
| lcockerton62 | 1:51477fe4851b | 209 | i2c_page_write(0x0000, 2, start_address_array); |
| lcockerton62 | 1:51477fe4851b | 210 | |
| lcockerton62 | 1:51477fe4851b | 211 | return start_address; |
| lcockerton62 | 0:0a5f554d2a16 | 212 | } |
| lcockerton62 | 0:0a5f554d2a16 | 213 | |
| lcockerton62 | 1:51477fe4851b | 214 | void write_SOC_EEPROM(BMU_data &measurements,uint16_t start_address) |
| lcockerton62 | 0:0a5f554d2a16 | 215 | { |
| lcockerton62 | 22:2df45c818786 | 216 | char data_out[10]; |
| lcockerton62 | 1:51477fe4851b | 217 | float *fp1,*fp2; |
| lcockerton62 | 22:2df45c818786 | 218 | uint16_t data_pec; |
| lcockerton62 | 1:51477fe4851b | 219 | |
| lcockerton62 | 1:51477fe4851b | 220 | fp1 = (float*)(&measurements.SOC); |
| lcockerton62 | 1:51477fe4851b | 221 | fp2 = (float*)(&measurements.percentage_SOC); |
| lcockerton62 | 0:0a5f554d2a16 | 222 | |
| lcockerton62 | 1:51477fe4851b | 223 | for(int i = 0; i < 4; i++ ) { |
| lcockerton62 | 1:51477fe4851b | 224 | data_out[i] = *fp1; |
| lcockerton62 | 1:51477fe4851b | 225 | fp1++; |
| lcockerton62 | 1:51477fe4851b | 226 | } |
| lcockerton62 | 1:51477fe4851b | 227 | for(int j = 4; j < 7; j++ ) { |
| lcockerton62 | 1:51477fe4851b | 228 | data_out[j] = *fp2; |
| lcockerton62 | 1:51477fe4851b | 229 | fp2++; |
| lcockerton62 | 1:51477fe4851b | 230 | } |
| lcockerton62 | 22:2df45c818786 | 231 | data_pec = pec15_calc(8, ((uint8_t*)data_out)); // Calculate the pec and then write it to memory |
| lcockerton62 | 22:2df45c818786 | 232 | data_out[8] = (char)(data_pec >> 8); |
| lcockerton62 | 22:2df45c818786 | 233 | data_out[9] = (char)(data_pec); |
| lcockerton62 | 1:51477fe4851b | 234 | i2c_page_write(start_address, 8,data_out); |
| lcockerton62 | 0:0a5f554d2a16 | 235 | } |
| lcockerton62 | 0:0a5f554d2a16 | 236 | |
| lcockerton62 | 1:51477fe4851b | 237 | void read_temperature_sensors(BMU_data &measurements) |
| lcockerton62 | 0:0a5f554d2a16 | 238 | { |
| lcockerton62 | 1:51477fe4851b | 239 | float min_temperature; |
| maxv008 | 23:a1af4439c1fc | 240 | char min_id[8]; |
| lcockerton62 | 1:51477fe4851b | 241 | float max_temperature; |
| maxv008 | 23:a1af4439c1fc | 242 | char max_id[8]; |
| DasSidG | 21:d461d58e70fc | 243 | isotherm_12V_pin = 1; |
| lcockerton62 | 1:51477fe4851b | 244 | probe[0]->convert_temperature(DS1820::all_devices); |
| DasSidG | 21:d461d58e70fc | 245 | |
| lcockerton62 | 1:51477fe4851b | 246 | min_temperature = probe[0]->temperature('C'); |
| maxv008 | 23:a1af4439c1fc | 247 | std::memcpy(min_id, probe[0]->ROM, sizeof(char)*8); //invalid shallow copy: min_id = probe[0]->ROM; |
| lcockerton62 | 1:51477fe4851b | 248 | max_temperature = min_temperature; // Initially set the max and min temperature equal |
| maxv008 | 23:a1af4439c1fc | 249 | std::memcpy(max_id, probe[0]->ROM, sizeof(char)*8); |
| DasSidG | 16:b2ef68c9a4fd | 250 | for (int i=0; i<devices_found; i++) { |
| maxv008 | 14:e0e88a009f4c | 251 | for(int j = 0; j < 7; j++) |
| maxv008 | 14:e0e88a009f4c | 252 | measurements.temperature_measurements[i].ROMID[j] = probe[i]->ROM[j]; |
| lcockerton62 | 1:51477fe4851b | 253 | measurements.temperature_measurements[i].measurement = probe[i] ->temperature('C'); |
| maxv008 | 14:e0e88a009f4c | 254 | |
| lcockerton62 | 1:51477fe4851b | 255 | if(measurements.temperature_measurements[i].measurement > max_temperature) { |
| lcockerton62 | 1:51477fe4851b | 256 | max_temperature = measurements.temperature_measurements[i].measurement; |
| maxv008 | 23:a1af4439c1fc | 257 | std::memcpy(max_id, measurements.temperature_measurements[i].ROMID, sizeof(char)*8); |
| lcockerton62 | 2:94716229ecc3 | 258 | } else if (measurements.temperature_measurements[i].measurement < min_temperature) { |
| lcockerton62 | 1:51477fe4851b | 259 | min_temperature = measurements.temperature_measurements[i].measurement; |
| maxv008 | 23:a1af4439c1fc | 260 | std::memcpy(min_id, measurements.temperature_measurements[i].ROMID, sizeof(char)*8); |
| lcockerton62 | 1:51477fe4851b | 261 | } |
| DasSidG | 12:fa9b1a459e47 | 262 | |
| maxv008 | 18:521ffdd724f3 | 263 | //printf("Device %d temperature is %3.3f degrees Celcius.\r\n",i+1 ,probe[i]->temperature('C')); |
| lcockerton62 | 1:51477fe4851b | 264 | } |
| DasSidG | 21:d461d58e70fc | 265 | isotherm_12V_pin = 0; |
| maxv008 | 13:7b42af989cd1 | 266 | //There is also a CMU # component of this struct, currently unfilled, perhaps not needed at all. |
| lcockerton62 | 1:51477fe4851b | 267 | measurements.max_cell_temp.temperature = max_temperature; |
| maxv008 | 23:a1af4439c1fc | 268 | std::memcpy(measurements.max_cell_temp.ROMID, max_id, sizeof(char)*8); |
| lcockerton62 | 1:51477fe4851b | 269 | measurements.min_cell_temp.temperature = min_temperature; |
| maxv008 | 28:f1f882bd1653 | 270 | std::memcpy(measurements.min_cell_temp.ROMID, min_id, sizeof(char)*8); |
| maxv008 | 28:f1f882bd1653 | 271 | delete max_id; |
| maxv008 | 28:f1f882bd1653 | 272 | delete min_id; |
| lcockerton62 | 0:0a5f554d2a16 | 273 | } |
| lcockerton62 | 0:0a5f554d2a16 | 274 | |
| lcockerton62 | 0:0a5f554d2a16 | 275 | void update_SOC() |
| lcockerton62 | 0:0a5f554d2a16 | 276 | { |
| lcockerton62 | 1:51477fe4851b | 277 | // Update the SOC value |
| maxv008 | 25:1fe8a42f8a6d | 278 | ltc2943.readAll(); |
| lcockerton62 | 0:0a5f554d2a16 | 279 | } |
| lcockerton62 | 0:0a5f554d2a16 | 280 | |
| lcockerton62 | 0:0a5f554d2a16 | 281 | |
| lcockerton62 | 1:51477fe4851b | 282 | uint32_t check_measurements(BMU_data &measurements) |
| lcockerton62 | 1:51477fe4851b | 283 | { |
| lcockerton62 | 1:51477fe4851b | 284 | uint32_t status; |
| lcockerton62 | 2:94716229ecc3 | 285 | |
| lcockerton62 | 2:94716229ecc3 | 286 | if(measurements.max_cell_voltage.voltage > MAX_CELL_VOLTAGE) { |
| lcockerton62 | 2:94716229ecc3 | 287 | status = status | CELL_OVER_VOLTAGE; |
| lcockerton62 | 2:94716229ecc3 | 288 | } else if (measurements.min_cell_voltage.voltage < MIN_CELL_VOLTAGE) { |
| lcockerton62 | 1:51477fe4851b | 289 | status = status | CELL_UNDER_VOLTAGE; |
| lcockerton62 | 2:94716229ecc3 | 290 | } else if (measurements.max_cell_temp.temperature > MAX_CELL_TEMPERATURE) { |
| lcockerton62 | 1:51477fe4851b | 291 | status = status | CELL_OVER_TEMPERATURE; |
| lcockerton62 | 1:51477fe4851b | 292 | } |
| lcockerton62 | 2:94716229ecc3 | 293 | |
| lcockerton62 | 1:51477fe4851b | 294 | /* |
| lcockerton62 | 1:51477fe4851b | 295 | @TODO also include errors for: |
| lcockerton62 | 1:51477fe4851b | 296 | *untrusted measurement |
| lcockerton62 | 1:51477fe4851b | 297 | *CMU timeout |
| lcockerton62 | 1:51477fe4851b | 298 | *SOC not valid |
| lcockerton62 | 1:51477fe4851b | 299 | */ |
| lcockerton62 | 1:51477fe4851b | 300 | return status; |
| lcockerton62 | 1:51477fe4851b | 301 | } |
| lcockerton62 | 1:51477fe4851b | 302 | |
| maxv008 | 23:a1af4439c1fc | 303 | //Returns the status variable |
| maxv008 | 23:a1af4439c1fc | 304 | uint32_t take_measurements(BMU_data &measurements) |
| lcockerton62 | 1:51477fe4851b | 305 | { |
| maxv008 | 6:b567fcb604aa | 306 | uint16_t cellvoltages[NO_CMUS][12]; |
| DasSidG | 16:b2ef68c9a4fd | 307 | //Use LTC6804_acquireVoltage to fill this array, and then properly format |
| maxv008 | 6:b567fcb604aa | 308 | //it to be sent over CAN |
| maxv008 | 6:b567fcb604aa | 309 | |
| DasSidG | 16:b2ef68c9a4fd | 310 | LTC6804_acquireVoltage(cellvoltages); |
| maxv008 | 23:a1af4439c1fc | 311 | pack_voltage_extremes min_voltage; |
| maxv008 | 23:a1af4439c1fc | 312 | pack_voltage_extremes max_voltage; //TODO do minmax voltage stuff |
| maxv008 | 23:a1af4439c1fc | 313 | min_voltage.voltage = 65535; //largest 16 bit unsigned int |
| maxv008 | 23:a1af4439c1fc | 314 | max_voltage.voltage = 0; |
| maxv008 | 23:a1af4439c1fc | 315 | |
| maxv008 | 23:a1af4439c1fc | 316 | //Sets voltage readings as well as max/min voltage values. |
| maxv008 | 10:1079f8e52d65 | 317 | for(int i=0; i<NO_CMUS; i++){ |
| maxv008 | 17:94dd9a0d3870 | 318 | for(int j=0; j < NO_READINGS_PER_CMU; j++){ |
| DasSidG | 16:b2ef68c9a4fd | 319 | measurements.cell_voltages[i].voltages[j] = cellvoltages[i][j]/ 10; //To get units of mV |
| maxv008 | 17:94dd9a0d3870 | 320 | measurements.cell_voltages[i].CMU_number = i; |
| maxv008 | 23:a1af4439c1fc | 321 | if(measurements.cell_voltages[i].voltages[j] < min_voltage.voltage) |
| maxv008 | 23:a1af4439c1fc | 322 | { |
| maxv008 | 23:a1af4439c1fc | 323 | min_voltage.voltage = measurements.cell_voltages[i].voltages[j]; |
| maxv008 | 23:a1af4439c1fc | 324 | min_voltage.CMU_number = i; |
| maxv008 | 23:a1af4439c1fc | 325 | min_voltage.cell_number = j; |
| maxv008 | 23:a1af4439c1fc | 326 | } |
| maxv008 | 23:a1af4439c1fc | 327 | else if(measurements.cell_voltages[i].voltages[j] < max_voltage.voltage) |
| maxv008 | 23:a1af4439c1fc | 328 | { |
| maxv008 | 23:a1af4439c1fc | 329 | max_voltage.voltage = measurements.cell_voltages[i].voltages[j]; |
| maxv008 | 23:a1af4439c1fc | 330 | max_voltage.CMU_number = i; |
| maxv008 | 23:a1af4439c1fc | 331 | max_voltage.cell_number = j; |
| maxv008 | 23:a1af4439c1fc | 332 | } |
| maxv008 | 10:1079f8e52d65 | 333 | } |
| maxv008 | 23:a1af4439c1fc | 334 | } |
| maxv008 | 23:a1af4439c1fc | 335 | measurements.max_cell_voltage = max_voltage; |
| maxv008 | 23:a1af4439c1fc | 336 | measurements.min_cell_voltage = min_voltage; |
| DasSidG | 4:9050c5d6925e | 337 | |
| maxv008 | 13:7b42af989cd1 | 338 | //Add code to take all temperature measurements and add it to measurements struct. |
| maxv008 | 13:7b42af989cd1 | 339 | read_temperature_sensors(measurements); |
| maxv008 | 23:a1af4439c1fc | 340 | |
| maxv008 | 23:a1af4439c1fc | 341 | // Update the SOC and take relevant measurements |
| maxv008 | 23:a1af4439c1fc | 342 | update_SOC(); |
| maxv008 | 28:f1f882bd1653 | 343 | measurements.battery_current = (uint32_t) ltc2943.current() * 1000; //*1000 to convert to mA |
| DasSidG | 4:9050c5d6925e | 344 | measurements.percentage_SOC = ltc2943.accumulatedCharge(); |
| DasSidG | 4:9050c5d6925e | 345 | measurements.SOC = (measurements.percentage_SOC /100) * BATTERY_CAPACITY; |
| maxv008 | 23:a1af4439c1fc | 346 | |
| maxv008 | 23:a1af4439c1fc | 347 | // Check data for errors |
| maxv008 | 23:a1af4439c1fc | 348 | return check_measurements(measurements); |
| lcockerton62 | 1:51477fe4851b | 349 | } |
| lcockerton62 | 1:51477fe4851b | 350 | |
| lcockerton62 | 0:0a5f554d2a16 | 351 | void init() |
| lcockerton62 | 0:0a5f554d2a16 | 352 | { |
| maxv008 | 18:521ffdd724f3 | 353 | //Comment out measurement stuff with BCU testing |
| maxv008 | 28:f1f882bd1653 | 354 | /*temperature_init(); // Initialise the temperature sensors |
| DasSidG | 4:9050c5d6925e | 355 | LTC2943_initialise(); //Initialises the fixed parameters of the LTC2943 |
| DasSidG | 15:e901aff1f5b3 | 356 | LTC6804_init(MD_FAST, DCP_DISABLED, CELL_CH_ALL, AUX_CH_VREF2); //Initialises the LTC6804s |
| maxv008 | 28:f1f882bd1653 | 357 | */ |
| maxv008 | 14:e0e88a009f4c | 358 | for(int i=0; i<CAN_BUFFER_SIZE; i++) |
| maxv008 | 14:e0e88a009f4c | 359 | { |
| maxv008 | 14:e0e88a009f4c | 360 | buffer[i].id = BLANK_ID; |
| maxv008 | 14:e0e88a009f4c | 361 | safe_to_write[i]= true; |
| maxv008 | 14:e0e88a009f4c | 362 | } |
| maxv008 | 14:e0e88a009f4c | 363 | |
| maxv008 | 14:e0e88a009f4c | 364 | //Initialise CAN stuff, attach CAN interrupt handlers |
| maxv008 | 14:e0e88a009f4c | 365 | can.frequency(CAN_BIT_RATE); //set transmission rate to agreed bit rate (ELEC-006) |
| maxv008 | 14:e0e88a009f4c | 366 | can.reset(); // (FUNC-018) |
| maxv008 | 14:e0e88a009f4c | 367 | can.attach(&interruptHandler, CAN::RxIrq); //receive interrupt handler |
| maxv008 | 14:e0e88a009f4c | 368 | can.attach(&CANDataSentCallback, CAN::TxIrq); //send interrupt handler |
| maxv008 | 17:94dd9a0d3870 | 369 | |
| maxv008 | 17:94dd9a0d3870 | 370 | //Initialize voltage array |
| maxv008 | 17:94dd9a0d3870 | 371 | for(int i = 0; i < NO_CMUS; i++) |
| maxv008 | 17:94dd9a0d3870 | 372 | { |
| maxv008 | 17:94dd9a0d3870 | 373 | for(int j = 0; j < NO_READINGS_PER_CMU; j++) |
| maxv008 | 17:94dd9a0d3870 | 374 | { |
| maxv008 | 17:94dd9a0d3870 | 375 | voltage_readings[i].voltages[j] = 0; |
| maxv008 | 17:94dd9a0d3870 | 376 | } |
| maxv008 | 17:94dd9a0d3870 | 377 | } |
| maxv008 | 20:a1a1bfc938da | 378 | //Initialize Temperature Array |
| maxv008 | 20:a1a1bfc938da | 379 | for(int i = 0; i < NO_TEMPERATURE_SENSORS; i++) |
| maxv008 | 20:a1a1bfc938da | 380 | { |
| maxv008 | 28:f1f882bd1653 | 381 | templist[i].measurement = INFINITY; |
| maxv008 | 20:a1a1bfc938da | 382 | templist[i].ID = 0; |
| maxv008 | 20:a1a1bfc938da | 383 | } |
| maxv008 | 28:f1f882bd1653 | 384 | //initialize stuff used in reading test: |
| maxv008 | 28:f1f882bd1653 | 385 | packSOC = INFINITY; |
| maxv008 | 28:f1f882bd1653 | 386 | packSOCPercentage = INFINITY; |
| maxv008 | 28:f1f882bd1653 | 387 | |
| maxv008 | 28:f1f882bd1653 | 388 | minVolt.voltage = 0; |
| maxv008 | 28:f1f882bd1653 | 389 | maxVolt.voltage = 0; |
| maxv008 | 28:f1f882bd1653 | 390 | |
| maxv008 | 28:f1f882bd1653 | 391 | minTemp.temperature = 0; minTemp.ID = 0; |
| maxv008 | 28:f1f882bd1653 | 392 | maxTemp.temperature = 0; maxTemp.ID = 0; |
| maxv008 | 14:e0e88a009f4c | 393 | } |
| maxv008 | 14:e0e88a009f4c | 394 | |
| maxv008 | 14:e0e88a009f4c | 395 | void CANDataSentCallback(void) { |
| maxv008 | 14:e0e88a009f4c | 396 | CAN_data_sent = true; |
| lcockerton62 | 0:0a5f554d2a16 | 397 | } |
| lcockerton62 | 0:0a5f554d2a16 | 398 | |
| maxv008 | 14:e0e88a009f4c | 399 | void interruptHandler() |
| maxv008 | 14:e0e88a009f4c | 400 | { |
| maxv008 | 14:e0e88a009f4c | 401 | CANMessage msg; |
| DasSidG | 16:b2ef68c9a4fd | 402 | can.read(msg); |
| maxv008 | 14:e0e88a009f4c | 403 | for(int i=0; i<CAN_BUFFER_SIZE; i++) { |
| maxv008 | 14:e0e88a009f4c | 404 | if((buffer[i].id == msg.id || buffer[i].id==BLANK_ID) && safe_to_write[i]) { |
| maxv008 | 14:e0e88a009f4c | 405 | //("id %d added to buffer \r\n", msg.id); |
| maxv008 | 14:e0e88a009f4c | 406 | buffer[i] = msg; |
| maxv008 | 14:e0e88a009f4c | 407 | //return required so that only first blank buffer entry is converted to incoming message ID each time new message ID is encountered |
| maxv008 | 14:e0e88a009f4c | 408 | return; |
| maxv008 | 14:e0e88a009f4c | 409 | } |
| maxv008 | 14:e0e88a009f4c | 410 | } |
| maxv008 | 14:e0e88a009f4c | 411 | } |
| maxv008 | 14:e0e88a009f4c | 412 | |
| maxv008 | 14:e0e88a009f4c | 413 | void test_read_CAN_buffer() |
| maxv008 | 14:e0e88a009f4c | 414 | { |
| maxv008 | 14:e0e88a009f4c | 415 | //Import the data from the buffer into a non-volatile, more usable format |
| maxv008 | 14:e0e88a009f4c | 416 | CAN_Data can_data[CAN_BUFFER_SIZE]; //container for all of the raw data |
| maxv008 | 17:94dd9a0d3870 | 417 | CANMessage msgArray[CAN_BUFFER_SIZE]; //Same as above but some functions take message as their parameter |
| maxv008 | 14:e0e88a009f4c | 418 | int received_CAN_IDs[CAN_BUFFER_SIZE]; //needed to keep track of which IDs we've received so far |
| maxv008 | 14:e0e88a009f4c | 419 | for (int i = 0; i<CAN_BUFFER_SIZE; ++i) |
| maxv008 | 14:e0e88a009f4c | 420 | { |
| maxv008 | 14:e0e88a009f4c | 421 | safe_to_write[i] = false; |
| maxv008 | 14:e0e88a009f4c | 422 | can_data[i].importCANData(buffer[i]); |
| maxv008 | 14:e0e88a009f4c | 423 | received_CAN_IDs[i] = buffer[i].id; |
| maxv008 | 17:94dd9a0d3870 | 424 | msgArray[i] = buffer[i]; |
| maxv008 | 14:e0e88a009f4c | 425 | safe_to_write[i] = true; |
| maxv008 | 14:e0e88a009f4c | 426 | } |
| maxv008 | 17:94dd9a0d3870 | 427 | |
| maxv008 | 23:a1af4439c1fc | 428 | //voltage and Temp and SOC readings: |
| maxv008 | 18:521ffdd724f3 | 429 | for(int i = 0; i < CAN_BUFFER_SIZE; i++) |
| maxv008 | 18:521ffdd724f3 | 430 | { |
| maxv008 | 18:521ffdd724f3 | 431 | //voltage |
| maxv008 | 28:f1f882bd1653 | 432 | if(decodeVoltageTelemetry(msgArray[i], voltage_readings)) |
| maxv008 | 28:f1f882bd1653 | 433 | printf("we made it inside the if \r\n");//continue; |
| maxv008 | 28:f1f882bd1653 | 434 | //temperature |
| maxv008 | 28:f1f882bd1653 | 435 | printf("We made it past the if statement \r\n"); |
| maxv008 | 20:a1a1bfc938da | 436 | if(msgArray[i].id >= 0x700) |
| maxv008 | 18:521ffdd724f3 | 437 | { |
| maxv008 | 20:a1a1bfc938da | 438 | individual_temperature dataPoint = decodeTemperatureTelemetry(msgArray[i]); |
| maxv008 | 20:a1a1bfc938da | 439 | for(int j = 0; j < NO_TEMPERATURE_SENSORS; j++) |
| maxv008 | 20:a1a1bfc938da | 440 | { |
| maxv008 | 20:a1a1bfc938da | 441 | if(dataPoint.ID == templist[j].ID) |
| maxv008 | 20:a1a1bfc938da | 442 | { |
| maxv008 | 20:a1a1bfc938da | 443 | templist[j] = dataPoint; |
| maxv008 | 20:a1a1bfc938da | 444 | break; |
| maxv008 | 20:a1a1bfc938da | 445 | } |
| maxv008 | 20:a1a1bfc938da | 446 | else if(templist[j].ID == 0) |
| maxv008 | 20:a1a1bfc938da | 447 | { |
| maxv008 | 20:a1a1bfc938da | 448 | templist[j] = dataPoint; |
| maxv008 | 20:a1a1bfc938da | 449 | break; |
| maxv008 | 20:a1a1bfc938da | 450 | } |
| maxv008 | 20:a1a1bfc938da | 451 | } |
| maxv008 | 20:a1a1bfc938da | 452 | |
| maxv008 | 23:a1af4439c1fc | 453 | } |
| maxv008 | 23:a1af4439c1fc | 454 | //SOC |
| maxv008 | 23:a1af4439c1fc | 455 | if(msgArray[i].id == 0x6F4) |
| maxv008 | 23:a1af4439c1fc | 456 | { |
| maxv008 | 23:a1af4439c1fc | 457 | packSOC = decodePackSOC(msgArray[i]); |
| maxv008 | 23:a1af4439c1fc | 458 | packSOCPercentage = decodePackSOCPercentage(msgArray[i]); |
| maxv008 | 28:f1f882bd1653 | 459 | } |
| maxv008 | 23:a1af4439c1fc | 460 | |
| maxv008 | 23:a1af4439c1fc | 461 | if(msgArray[i].id == BMS_BASE_ID + MIN_TEMPERATURE) |
| maxv008 | 23:a1af4439c1fc | 462 | minTemp = decodeCellTemperatureMAXMIN(msgArray[i]); |
| maxv008 | 23:a1af4439c1fc | 463 | if(msgArray[i].id == BMS_BASE_ID + MAX_TEMPERATURE) |
| maxv008 | 23:a1af4439c1fc | 464 | maxTemp = decodeCellTemperatureMAXMIN(msgArray[i]); |
| maxv008 | 28:f1f882bd1653 | 465 | |
| maxv008 | 23:a1af4439c1fc | 466 | if(msgArray[i].id == BMS_BASE_ID + MAX_MIN_VOLTAGE) |
| maxv008 | 23:a1af4439c1fc | 467 | { |
| maxv008 | 23:a1af4439c1fc | 468 | decodeCellVoltageMAXMIN(msgArray[i], minVolt, maxVolt); |
| maxv008 | 23:a1af4439c1fc | 469 | } |
| maxv008 | 23:a1af4439c1fc | 470 | |
| maxv008 | 23:a1af4439c1fc | 471 | if(msgArray[i].id == BMS_BASE_ID + BATTERY_STATUS_ID) |
| maxv008 | 28:f1f882bd1653 | 472 | status = decodeExtendedBatteryPackStatus(msgArray[i]); |
| maxv008 | 28:f1f882bd1653 | 473 | } |
| maxv008 | 18:521ffdd724f3 | 474 | //Print obtained Readings: |
| maxv008 | 18:521ffdd724f3 | 475 | for(int i = 0; i < NO_CMUS; i++) |
| maxv008 | 18:521ffdd724f3 | 476 | for(int j = 0; j < 12; j++) |
| maxv008 | 18:521ffdd724f3 | 477 | printf("Voltage number %d for CMU %d is %d \r\n", j, i, voltage_readings[i].voltages[j]); |
| maxv008 | 17:94dd9a0d3870 | 478 | |
| maxv008 | 18:521ffdd724f3 | 479 | for(int i = 0; i < NO_TEMPERATURE_SENSORS; i++) |
| maxv008 | 23:a1af4439c1fc | 480 | printf("Temperature of Sensor with ID %d is %f \r\n", templist[i].ID, templist[i].measurement); |
| maxv008 | 23:a1af4439c1fc | 481 | |
| maxv008 | 23:a1af4439c1fc | 482 | printf("SOC is %f and SOC Percentage is %f \r\n", packSOC, packSOCPercentage); |
| maxv008 | 23:a1af4439c1fc | 483 | |
| maxv008 | 23:a1af4439c1fc | 484 | printf("Voltage (Max,Min) = (%d,%d) \r\n", maxVolt.voltage, minVolt.voltage); |
| maxv008 | 23:a1af4439c1fc | 485 | |
| maxv008 | 28:f1f882bd1653 | 486 | printf("(Temperature, ID): Minimum = (%d,%d). Maximum = (%d,%d) \r\n", |
| maxv008 | 23:a1af4439c1fc | 487 | minTemp.temperature,minTemp.ID,maxTemp.temperature,maxTemp.ID); |
| maxv008 | 23:a1af4439c1fc | 488 | |
| maxv008 | 23:a1af4439c1fc | 489 | printf("Status value is: %d \r\n", status); |
| maxv008 | 14:e0e88a009f4c | 490 | } |
| maxv008 | 23:a1af4439c1fc | 491 | |
| DasSidG | 12:fa9b1a459e47 | 492 | bool test_read_voltage_CAN(uint16_t readings[], int can_ids[]) |
| maxv008 | 10:1079f8e52d65 | 493 | { |
| maxv008 | 10:1079f8e52d65 | 494 | CANMessage msg; |
| maxv008 | 10:1079f8e52d65 | 495 | int can_id; |
| maxv008 | 10:1079f8e52d65 | 496 | int offset; |
| maxv008 | 10:1079f8e52d65 | 497 | int first_index; |
| maxv008 | 10:1079f8e52d65 | 498 | int second_index; |
| maxv008 | 10:1079f8e52d65 | 499 | |
| maxv008 | 10:1079f8e52d65 | 500 | if(can.read(msg)) |
| maxv008 | 10:1079f8e52d65 | 501 | { |
| maxv008 | 10:1079f8e52d65 | 502 | for(int i =0; i < 4; i++) |
| maxv008 | 10:1079f8e52d65 | 503 | { |
| maxv008 | 10:1079f8e52d65 | 504 | readings[i] = (msg.data[2 * i]) + (msg.data[2*i+1] << 8); //Since data is 8 8bit ints not 4 16 bit ones |
| maxv008 | 10:1079f8e52d65 | 505 | } |
| DasSidG | 12:fa9b1a459e47 | 506 | can_id = msg.id; |
| DasSidG | 12:fa9b1a459e47 | 507 | can_ids[0] = msg.id; |
| DasSidG | 12:fa9b1a459e47 | 508 | |
| DasSidG | 11:cf2db05cfa56 | 509 | offset = can_id - 1536; //1536 = 0x600 |
| maxv008 | 10:1079f8e52d65 | 510 | first_index = (offset - 1)/4; //offset of 2,3,4 is CMU 1; 6,7,8, is CMU 2; etc. |
| DasSidG | 11:cf2db05cfa56 | 511 | second_index = ((offset - 1) % 4) - 1; //Makes it so 0,1,2 represent each voltage set //SID: subtracted 1 to make it work |
| DasSidG | 12:fa9b1a459e47 | 512 | |
| DasSidG | 12:fa9b1a459e47 | 513 | return true; |
| maxv008 | 10:1079f8e52d65 | 514 | } |
| maxv008 | 10:1079f8e52d65 | 515 | else |
| DasSidG | 12:fa9b1a459e47 | 516 | return false; |
| maxv008 | 10:1079f8e52d65 | 517 | } |
| maxv008 | 10:1079f8e52d65 | 518 | |
| maxv008 | 10:1079f8e52d65 | 519 | void test_CAN_send() |
| maxv008 | 10:1079f8e52d65 | 520 | { |
| maxv008 | 10:1079f8e52d65 | 521 | CANMessage msg; |
| DasSidG | 11:cf2db05cfa56 | 522 | char value = 142; |
| maxv008 | 10:1079f8e52d65 | 523 | msg = CANMessage(1, &value,1); |
| maxv008 | 10:1079f8e52d65 | 524 | if(can.write(msg)) |
| maxv008 | 10:1079f8e52d65 | 525 | printf("Succesfully sent %d \r\n", value); |
| maxv008 | 10:1079f8e52d65 | 526 | else |
| maxv008 | 10:1079f8e52d65 | 527 | printf("Sending Failed \r\n"); |
| maxv008 | 10:1079f8e52d65 | 528 | } |
| maxv008 | 10:1079f8e52d65 | 529 | |
| maxv008 | 10:1079f8e52d65 | 530 | void test_CAN_read() |
| maxv008 | 10:1079f8e52d65 | 531 | { |
| maxv008 | 10:1079f8e52d65 | 532 | CANMessage msg; |
| maxv008 | 10:1079f8e52d65 | 533 | if(can.read(msg)) |
| maxv008 | 10:1079f8e52d65 | 534 | printf("Successfully recieved %d \r\n", msg.data[0]); |
| maxv008 | 10:1079f8e52d65 | 535 | else |
| maxv008 | 10:1079f8e52d65 | 536 | printf("Reading Failed \r\n"); |
| maxv008 | 10:1079f8e52d65 | 537 | } |