mirror of
https://github.com/dalathegreat/Battery-Emulator.git
synced 2025-10-03 01:39:30 +02:00
Compare commits
3 commits
668a225e7f
...
ff71cadcb2
Author | SHA1 | Date | |
---|---|---|---|
![]() |
ff71cadcb2 | ||
![]() |
657656b1f5 | ||
![]() |
5cbfe92de9 |
3 changed files with 236 additions and 9 deletions
|
@ -68,6 +68,8 @@ const char* name_for_battery_type(BatteryType type) {
|
|||
return ChademoBattery::Name;
|
||||
case BatteryType::CmfaEv:
|
||||
return CmfaEvBattery::Name;
|
||||
case BatteryType::FordMachE:
|
||||
return FordMachEBattery::Name;
|
||||
case BatteryType::Foxess:
|
||||
return FoxessBattery::Name;
|
||||
case BatteryType::GeelyGeometryC:
|
||||
|
|
|
@ -167,10 +167,85 @@ void FordMachEBattery::handle_incoming_can_frame(CAN_frame rx_frame) {
|
|||
}
|
||||
|
||||
void FordMachEBattery::transmit_can(unsigned long currentMillis) {
|
||||
// Send 10ms CAN Message
|
||||
if (currentMillis - previousMillis10 >= INTERVAL_10_MS) {
|
||||
previousMillis10 = currentMillis;
|
||||
|
||||
transmit_can_frame(&FORD_217);
|
||||
transmit_can_frame(&FORD_442);
|
||||
}
|
||||
|
||||
// Send 30ms CAN Message
|
||||
if (currentMillis - previousMillis30 >= INTERVAL_30_MS) {
|
||||
previousMillis30 = currentMillis;
|
||||
|
||||
counter_30ms = (counter_30ms + 1) % 16; // cycles 0-15
|
||||
|
||||
// Byte 2: upper nibble = 0xF, lower nibble = (0xF - counter_10ms) % 16
|
||||
FORD_7D.data.u8[2] = 0xF0 | ((0xF - counter_30ms) & 0x0F);
|
||||
// Byte 3: upper nibble = counter_10ms, lower nibble = 0x0
|
||||
FORD_7D.data.u8[3] = (counter_30ms << 4) & 0xF0;
|
||||
|
||||
// Byte 0: starts at 0xC0 and increments by 4 each step, wraps every 16 steps
|
||||
FORD_204.data.u8[0] = 0xC0 + (counter_30ms * 4);
|
||||
// Byte 5: starts at 0xFC and decrements by 1 each step, wraps every 16 steps
|
||||
FORD_204.data.u8[5] = 0xFC - counter_30ms;
|
||||
|
||||
// Byte 4: upper nibble = counter_10ms, lower nibble = 0x0
|
||||
FORD_4B0.data.u8[4] = (counter_30ms << 4) & 0xF0;
|
||||
// Byte 7: upper nibble = 0xF, lower nibble = (0xF - counter_10ms) % 16
|
||||
FORD_4B0.data.u8[7] = 0xF0 | ((0xF - counter_30ms) & 0x0F);
|
||||
|
||||
// Byte 2: starts at 0xC0 and increments by 4 each step, wraps every 16 steps
|
||||
FORD_415.data.u8[2] = 0xC0 + (counter_30ms * 4);
|
||||
// Byte 3: starts at 0xFC and decrements by 1 each step, wraps every 16 steps
|
||||
FORD_415.data.u8[3] = 0xFC - counter_30ms;
|
||||
|
||||
//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);
|
||||
transmit_can_frame(&FORD_7E);
|
||||
transmit_can_frame(&FORD_48);
|
||||
transmit_can_frame(&FORD_165);
|
||||
}
|
||||
// Send 50ms CAN Message
|
||||
if (currentMillis - previousMillis50 >= INTERVAL_50_MS) {
|
||||
previousMillis50 = currentMillis;
|
||||
transmit_can_frame(&FORD_42C);
|
||||
transmit_can_frame(&FORD_42F);
|
||||
transmit_can_frame(&FORD_43D);
|
||||
}
|
||||
|
||||
// Send 100ms CAN Message
|
||||
if (currentMillis - previousMillis100 >= INTERVAL_100_MS) {
|
||||
previousMillis100 = currentMillis;
|
||||
//transmit_can_frame(&TEST);
|
||||
|
||||
transmit_can_frame(
|
||||
&FORD_12F); //This message actually has checksum/counter, but it seems to close contactors without those
|
||||
transmit_can_frame(&FORD_332);
|
||||
transmit_can_frame(&FORD_333);
|
||||
transmit_can_frame(&FORD_42B);
|
||||
transmit_can_frame(&FORD_2EC);
|
||||
transmit_can_frame(&FORD_156);
|
||||
transmit_can_frame(
|
||||
&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);
|
||||
}
|
||||
// Send 1s CAN Message
|
||||
if (currentMillis - previousMillis1000 >= INTERVAL_1_S) {
|
||||
previousMillis1000 = currentMillis;
|
||||
transmit_can_frame(&FORD_3C3);
|
||||
transmit_can_frame(&FORD_581);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -18,9 +18,12 @@ class FordMachEBattery : public CanBattery {
|
|||
static const int MAX_CELL_VOLTAGE_MV = 4250;
|
||||
static const int MIN_CELL_VOLTAGE_MV = 2900;
|
||||
|
||||
unsigned long previousMillis10 = 0; // will store last time a 10ms CAN Message was send
|
||||
unsigned long previousMillis100 = 0; // will store last time a 100ms CAN Message was send
|
||||
unsigned long previousMillis10s = 0; // will store last time a 1s CAN Message was send
|
||||
unsigned long previousMillis10 = 0; // will store last time a 10ms CAN Message was send
|
||||
unsigned long previousMillis30 = 0; // will store last time a 10ms CAN Message was send
|
||||
unsigned long previousMillis50 = 0; // will store last time a 100ms CAN Message was send
|
||||
unsigned long previousMillis100 = 0; // will store last time a 100ms CAN Message was send
|
||||
unsigned long previousMillis1000 = 0; // will store last time a 1s CAN Message was send
|
||||
unsigned long previousMillis10s = 0; // will store last time a 10s CAN Message was send
|
||||
|
||||
int16_t cell_temperature[6] = {0};
|
||||
int16_t maximum_temperature = 0;
|
||||
|
@ -30,11 +33,158 @@ class FordMachEBattery : public CanBattery {
|
|||
uint16_t maximum_cellvoltage_mV = 3700;
|
||||
uint16_t minimum_cellvoltage_mV = 3700;
|
||||
|
||||
CAN_frame TEST = {.FD = false,
|
||||
.ext_ID = false,
|
||||
.DLC = 8,
|
||||
.ID = 0x123,
|
||||
.data = {0x10, 0x64, 0x00, 0xB0, 0x00, 0x1E, 0x00, 0x8F}};
|
||||
uint8_t counter_30ms = 0;
|
||||
|
||||
CAN_frame FORD_47 = {.FD = false,
|
||||
.ext_ID = false,
|
||||
.DLC = 8,
|
||||
.ID = 0x047,
|
||||
.data = {0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
CAN_frame FORD_48 = {.FD = false,
|
||||
.ext_ID = false,
|
||||
.DLC = 8,
|
||||
.ID = 0x048,
|
||||
.data = {0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
CAN_frame FORD_4C = {.FD = false,
|
||||
.ext_ID = false,
|
||||
.DLC = 8,
|
||||
.ID = 0x04C,
|
||||
.data = {0x70, 0xAA, 0xBF, 0xDE, 0xCC, 0xEC, 0x00, 0x00}};
|
||||
CAN_frame FORD_5A = {.FD = false,
|
||||
.ext_ID = false,
|
||||
.DLC = 8,
|
||||
.ID = 0x05A,
|
||||
.data = {0x00, 0x00, 0x00, 0x0B, 0xF2, 0x90, 0x10, 0x00}};
|
||||
CAN_frame FORD_77 = {.FD = false,
|
||||
.ext_ID = false,
|
||||
.DLC = 8,
|
||||
.ID = 0x077,
|
||||
.data = {0x00, 0x00, 0x0F, 0xFE, 0xFF, 0xFF, 0xFB, 0xFE}};
|
||||
CAN_frame FORD_7D = {.FD = false,
|
||||
.ext_ID = false,
|
||||
.DLC = 8,
|
||||
.ID = 0x07D,
|
||||
.data = {0x00, 0x00, 0xF0, 0xF0, 0x00, 0x3F, 0xEF, 0xFE}};
|
||||
CAN_frame FORD_7E = {.FD = false,
|
||||
.ext_ID = false,
|
||||
.DLC = 8,
|
||||
.ID = 0x07E,
|
||||
.data = {0x00, 0x00, 0x3E, 0x80, 0x00, 0x04, 0x00, 0x00}};
|
||||
CAN_frame FORD_156 = {.FD = false,
|
||||
.ext_ID = false,
|
||||
.DLC = 8,
|
||||
.ID = 0x156,
|
||||
.data = {0x4B, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00}};
|
||||
CAN_frame FORD_165 = {.FD = false,
|
||||
.ext_ID = false,
|
||||
.DLC = 8,
|
||||
.ID = 0x165,
|
||||
.data = {0x10, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
CAN_frame FORD_166 = {.FD = false,
|
||||
.ext_ID = false,
|
||||
.DLC = 8,
|
||||
.ID = 0x166,
|
||||
.data = {0x00, 0x00, 0x00, 0x01, 0x5C, 0x89, 0x00, 0x00}};
|
||||
CAN_frame FORD_167 = {.FD = false,
|
||||
.ext_ID = false,
|
||||
.DLC = 8,
|
||||
.ID = 0x167,
|
||||
.data = {0x00, 0x80, 0x00, 0x11, 0xFF, 0xE0, 0x00, 0x00}};
|
||||
CAN_frame FORD_175 = {.FD = false,
|
||||
.ext_ID = false,
|
||||
.DLC = 8,
|
||||
.ID = 0x175,
|
||||
.data = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
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_204 = {.FD = false,
|
||||
.ext_ID = false,
|
||||
.DLC = 8,
|
||||
.ID = 0x204,
|
||||
.data = {0xD4, 0x00, 0x7D, 0x00, 0x00, 0xF7, 0x00, 0x00}};
|
||||
CAN_frame FORD_217 = {.FD = false,
|
||||
.ext_ID = false,
|
||||
.DLC = 8,
|
||||
.ID = 0x217,
|
||||
.data = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
CAN_frame FORD_230 = {.FD = false,
|
||||
.ext_ID = false,
|
||||
.DLC = 8,
|
||||
.ID = 0x230,
|
||||
.data = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03}};
|
||||
CAN_frame FORD_25B = {.FD = false,
|
||||
.ext_ID = false,
|
||||
.DLC = 8,
|
||||
.ID = 0x25B,
|
||||
.data = {0x01, 0xF4, 0x09, 0xF4, 0xE0, 0x00, 0x80, 0x00}};
|
||||
CAN_frame FORD_2EC = {.FD = false,
|
||||
.ext_ID = false,
|
||||
.DLC = 8,
|
||||
.ID = 0x2EC,
|
||||
.data = {0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00}};
|
||||
CAN_frame FORD_332 = {.FD = false,
|
||||
.ext_ID = false,
|
||||
.DLC = 8,
|
||||
.ID = 0x332,
|
||||
.data = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
CAN_frame FORD_333 = {.FD = false,
|
||||
.ext_ID = false,
|
||||
.DLC = 8,
|
||||
.ID = 0x333,
|
||||
.data = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
CAN_frame FORD_3C3 = {.FD = false,
|
||||
.ext_ID = false,
|
||||
.DLC = 8,
|
||||
.ID = 0x3C3,
|
||||
.data = {0x5C, 0xC8, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00}};
|
||||
CAN_frame FORD_415 = {.FD = false,
|
||||
.ext_ID = false,
|
||||
.DLC = 8,
|
||||
.ID = 0x415,
|
||||
.data = {0x00, 0x00, 0xC0, 0xFC, 0x0F, 0xFE, 0xEF, 0xFE}};
|
||||
CAN_frame FORD_42B = {.FD = false,
|
||||
.ext_ID = false,
|
||||
.DLC = 8,
|
||||
.ID = 0x42B,
|
||||
.data = {0xCB, 0xBE, 0x00, 0x02, 0x00, 0x00, 0xCE, 0x00}};
|
||||
CAN_frame FORD_42C = {.FD = false,
|
||||
.ext_ID = false,
|
||||
.DLC = 8,
|
||||
.ID = 0x42C,
|
||||
.data = {0x80, 0x02, 0x00, 0x00, 0x19, 0xA0, 0x00, 0x00}};
|
||||
CAN_frame FORD_42F = {.FD = false,
|
||||
.ext_ID = false,
|
||||
.DLC = 8,
|
||||
.ID = 0x42F,
|
||||
.data = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
CAN_frame FORD_43D = {.FD = false,
|
||||
.ext_ID = false,
|
||||
.DLC = 8,
|
||||
.ID = 0x43D,
|
||||
.data = {0x00, 0x00, 0xDC, 0x00, 0x00, 0x77, 0x00, 0x00}};
|
||||
CAN_frame FORD_442 = {.FD = false,
|
||||
.ext_ID = false,
|
||||
.DLC = 8,
|
||||
.ID = 0x442,
|
||||
.data = {0x4E, 0x20, 0x78, 0x7E, 0x7C, 0x00, 0x00, 0x40}};
|
||||
CAN_frame FORD_48F = {.FD = false, //Only sent in active charging logs (OBC?)
|
||||
.ext_ID = false,
|
||||
.DLC = 8,
|
||||
.ID = 0x48F,
|
||||
.data = {0x30, 0x4E, 0x20, 0x80, 0x00, 0x00, 0x80, 0x00}};
|
||||
CAN_frame FORD_4B0 = {.FD = false,
|
||||
.ext_ID = false,
|
||||
.DLC = 8,
|
||||
.ID = 0x4B0,
|
||||
.data = {0x01, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0xF0}};
|
||||
CAN_frame FORD_581 = {.FD = false,
|
||||
.ext_ID = false,
|
||||
.DLC = 8,
|
||||
.ID = 0x4B0,
|
||||
.data = {0x81, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}};
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue