diff --git a/Software/src/battery/FORD-MACH-E-BATTERY.cpp b/Software/src/battery/FORD-MACH-E-BATTERY.cpp index e44325f4..c040c6c2 100644 --- a/Software/src/battery/FORD-MACH-E-BATTERY.cpp +++ b/Software/src/battery/FORD-MACH-E-BATTERY.cpp @@ -21,16 +21,12 @@ void FordMachEBattery::update_values() { datalayer.battery.status.max_charge_power_W; - datalayer.battery.status.cell_max_voltage_mV; - - datalayer.battery.status.cell_min_voltage_mV; - maximum_cellvoltage_mV = datalayer.battery.status.cell_voltages_mV[0]; minimum_cellvoltage_mV = datalayer.battery.status.cell_voltages_mV[0]; // Loop through the array to find min and max cellvoltages, ignoring 0 values for (uint8_t i = 0; i < MAX_AMOUNT_CELLS; i++) { - if (datalayer.battery.status.cell_voltages_mV[i] != 0) { // Ignore unavailable values + if (datalayer.battery.status.cell_voltages_mV[i] > 1000) { // Ignore unavailable values if (datalayer.battery.status.cell_voltages_mV[i] < minimum_cellvoltage_mV) { minimum_cellvoltage_mV = datalayer.battery.status.cell_voltages_mV[i]; } @@ -40,6 +36,10 @@ void FordMachEBattery::update_values() { } } + datalayer.battery.status.cell_max_voltage_mV = maximum_cellvoltage_mV; + + datalayer.battery.status.cell_min_voltage_mV = minimum_cellvoltage_mV; + // Initialize highest and lowest to the first element maximum_temperature = cell_temperature[0]; minimum_temperature = cell_temperature[0]; @@ -119,28 +119,31 @@ void FordMachEBattery::handle_incoming_can_frame(CAN_frame rx_frame) { case 0x4a2: { datalayer.battery.status.CAN_battery_still_alive = CAN_STILL_ALIVE; - // Calculate starting cell index: (CAN_ID - 0x490) * 5 (Ends at 0x4A2) const uint8_t start_index = (rx_frame.ID - 0x490) * 5; - // Each CAN message contains 5 cellvoltages + // Process 5 cells per message for (uint8_t i = 0; i < 5; i++) { - const uint8_t byte_offset = i * 3; + uint16_t voltage = 0; - if (i % 2 == 0) { - // Even indices: bytes 0,1 | 3,4 | 6,7 - datalayer.battery.status.cell_voltages_mV[start_index + i] = - (((rx_frame.data.u8[byte_offset] << 4) | (rx_frame.data.u8[byte_offset + 1] >> 4)) + 1000); - } else { - // Odd indices: bytes 1,2 | 4,5 - datalayer.battery.status.cell_voltages_mV[start_index + i] = - ((((rx_frame.data.u8[byte_offset] & 0x0F) << 8) | rx_frame.data.u8[byte_offset + 1]) + 1000); + if (i == 0) { + voltage = (rx_frame.data.u8[0] << 4) | (rx_frame.data.u8[1] >> 4); + } else if (i == 1) { + voltage = ((rx_frame.data.u8[1] & 0x0F) << 8) | rx_frame.data.u8[2]; + } else if (i == 2) { + voltage = (rx_frame.data.u8[3] << 4) | (rx_frame.data.u8[4] >> 4); + } else if (i == 3) { + voltage = ((rx_frame.data.u8[4] & 0x0F) << 8) | rx_frame.data.u8[5]; + } else if (i == 4) { + voltage = (rx_frame.data.u8[6] << 4) | (rx_frame.data.u8[7] >> 4); } + + datalayer.battery.status.cell_voltages_mV[start_index + i] = voltage + 1000; } break; } case 0x4a3: //1s datalayer.battery.status.CAN_battery_still_alive = CAN_STILL_ALIVE; - datalayer.battery.status.cell_voltages_mV[95] = (rx_frame.data.u8[0] << 4) | (rx_frame.data.u8[1] >> 4); + datalayer.battery.status.cell_voltages_mV[95] = ((rx_frame.data.u8[0] << 4) | (rx_frame.data.u8[1] >> 4)) + 1000; //Celltemperatures cell_temperature[0] = ((rx_frame.data.u8[2] - 40) / 2); cell_temperature[1] = ((rx_frame.data.u8[2] - 40) / 2); @@ -171,8 +174,8 @@ void FordMachEBattery::transmit_can(unsigned long currentMillis) { if (currentMillis - previousMillis10 >= INTERVAL_10_MS) { previousMillis10 = currentMillis; - transmit_can_frame(&FORD_217); - transmit_can_frame(&FORD_442); + //transmit_can_frame(&FORD_217); Not needed for contactor closing + //transmit_can_frame(&FORD_442); Not needed for contactor closing } // Send 30ms CAN Message @@ -203,19 +206,29 @@ void FordMachEBattery::transmit_can(unsigned long currentMillis) { //TODO: handle FORD_4C properly very odd looping - transmit_can_frame(&FORD_77); - transmit_can_frame(&FORD_7D); - transmit_can_frame(&FORD_167); - transmit_can_frame(&FORD_48F); //Only sent in AC charging logs! - transmit_can_frame(&FORD_204); - transmit_can_frame(&FORD_4B0); - transmit_can_frame(&FORD_47); - transmit_can_frame(&FORD_230); - transmit_can_frame(&FORD_415); - transmit_can_frame(&FORD_4C); + counter_8_30ms = (counter_8_30ms + 1) % 8; // cycles 0-7 (8 values before wrap) + + // Byte 6: counts up by 2 each step (0, 2, 4, 6, 8, 10, 12, 14) + FORD_200.data.u8[6] = counter_8_30ms * 2; + + // Byte 7: counts down by 2 each step, maintaining byte6 + byte7 = 0x7F + FORD_200.data.u8[7] = 0x7F - (counter_8_30ms * 2); + + //transmit_can_frame(&FORD_77); Not needed for contactor closing + //transmit_can_frame(&FORD_7D); Not needed for contactor closing + //transmit_can_frame(&FORD_167); Not needed for contactor closing + //transmit_can_frame(&FORD_48F); //Only sent in AC charging logs! Not needed for contactor closing + //transmit_can_frame(&FORD_204); Not needed for contactor closing + //transmit_can_frame(&FORD_4B0); Not needed for contactor closing + //transmit_can_frame(&FORD_47); Not needed for contactor closing + //transmit_can_frame(&FORD_230); Not needed for contactor closing + //transmit_can_frame(&FORD_415); Not needed for contactor closing + //transmit_can_frame(&FORD_4C); Not needed for contactor closing transmit_can_frame(&FORD_7E); transmit_can_frame(&FORD_48); transmit_can_frame(&FORD_165); + transmit_can_frame(&FORD_7F); + transmit_can_frame(&FORD_200); } // Send 50ms CAN Message if (currentMillis - previousMillis50 >= INTERVAL_50_MS) { @@ -240,6 +253,11 @@ void FordMachEBattery::transmit_can(unsigned long currentMillis) { &FORD_5A); //This message actually has checksum/counter, but it seems to close contactors without those transmit_can_frame(&FORD_166); transmit_can_frame(&FORD_175); + transmit_can_frame(&FORD_178); + transmit_can_frame(&FORD_203); + transmit_can_frame( + &FORD_176); //This message actually has checksum/counter, but it seems to close contactors without those + transmit_can_frame(&FORD_185); } // Send 1s CAN Message if (currentMillis - previousMillis1000 >= INTERVAL_1_S) { diff --git a/Software/src/battery/FORD-MACH-E-BATTERY.h b/Software/src/battery/FORD-MACH-E-BATTERY.h index 540afe98..67e4dc36 100644 --- a/Software/src/battery/FORD-MACH-E-BATTERY.h +++ b/Software/src/battery/FORD-MACH-E-BATTERY.h @@ -34,6 +34,7 @@ class FordMachEBattery : public CanBattery { uint16_t minimum_cellvoltage_mV = 3700; uint8_t counter_30ms = 0; + uint8_t counter_8_30ms = 0; CAN_frame FORD_47 = {.FD = false, .ext_ID = false, @@ -70,6 +71,11 @@ class FordMachEBattery : public CanBattery { .DLC = 8, .ID = 0x07E, .data = {0x00, 0x00, 0x3E, 0x80, 0x00, 0x04, 0x00, 0x00}}; + CAN_frame FORD_7F = {.FD = false, + .ext_ID = false, + .DLC = 8, + .ID = 0x07F, + .data = {0x00, 0x00, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00}}; CAN_frame FORD_156 = {.FD = false, .ext_ID = false, .DLC = 8, @@ -95,11 +101,36 @@ class FordMachEBattery : public CanBattery { .DLC = 8, .ID = 0x175, .data = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}; + CAN_frame FORD_176 = {.FD = false, + .ext_ID = false, + .DLC = 8, + .ID = 0x176, + .data = {0x00, 0x0E, 0xF0, 0x10, 0x00, 0x00, 0x00, 0x00}}; + CAN_frame FORD_178 = {.FD = false, //Static content + .ext_ID = false, + .DLC = 8, + .ID = 0x175, + .data = {0x01, 0xB6, 0x02, 0x00, 0x4E, 0x46, 0xC6, 0x17}}; CAN_frame FORD_12F = {.FD = false, .ext_ID = false, .DLC = 8, .ID = 0x12F, .data = {0x0A, 0xF8, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}}; + CAN_frame FORD_185 = {.FD = false, + .ext_ID = false, + .DLC = 8, + .ID = 0x185, + .data = {0x03, 0x4E, 0x75, 0x32, 0x00, 0x00, 0x00, 0x00}}; + CAN_frame FORD_200 = {.FD = false, + .ext_ID = false, + .DLC = 8, + .ID = 0x200, + .data = {0x00, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x70}}; + CAN_frame FORD_203 = {.FD = false, + .ext_ID = false, + .DLC = 8, + .ID = 0x203, + .data = {0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}; CAN_frame FORD_204 = {.FD = false, .ext_ID = false, .DLC = 8,