Skip to content

Commit 2616947

Browse files
committed
Handle TPMS pressure / temperature requests
1 parent 9823a11 commit 2616947

File tree

1 file changed

+103
-0
lines changed

1 file changed

+103
-0
lines changed

examples/FakeSubaruBRZ/FakeSubaruBRZ.ino

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,56 @@ void setup() {
5050
Serial.println("CAN controller connected");
5151
}
5252

53+
class FakeTpmsEcu {
54+
public:
55+
FakeTpmsEcu() {
56+
has_continuation_frame = false;
57+
original_frame_acked = false;
58+
}
59+
60+
void scheduleNextFrame(uint16_t pid, uint8_t *data, uint8_t len) {
61+
has_continuation_frame = true;
62+
original_frame_acked = false;
63+
next_frame_pid = pid;
64+
memcpy(next_frame_data, data, len);
65+
next_frame_length = len;
66+
}
67+
68+
void handleFrameAck(uint8_t separation_time_millis = 0) {
69+
if (!has_continuation_frame) {
70+
return;
71+
}
72+
73+
original_frame_acked = true;
74+
next_frame_timestamp_millis = millis() + separation_time_millis;
75+
}
76+
77+
void sendNextFrameIfNeeded() {
78+
if (!has_continuation_frame || !original_frame_acked) {
79+
return;
80+
}
81+
82+
// Unsigned math magic to check if "time_diff" is "negative":
83+
unsigned long time_diff = millis() - next_frame_timestamp_millis;
84+
if (time_diff >> (8 * sizeof(time_diff) - 1)) {
85+
return;
86+
}
87+
88+
send_data(next_frame_pid, next_frame_data, next_frame_length);
89+
has_continuation_frame = false;
90+
original_frame_acked = false;
91+
}
92+
93+
private:
94+
bool has_continuation_frame;
95+
uint16_t next_frame_pid;
96+
uint8_t next_frame_data[8];
97+
uint8_t next_frame_length;
98+
99+
bool original_frame_acked;
100+
unsigned long next_frame_timestamp_millis;
101+
} fake_tpms_ecu;
102+
53103
// Forward declaration for a helper.
54104
void try_to_receive_data();
55105
void generate_payload(uint16_t pid, uint8_t *payload);
@@ -99,6 +149,7 @@ void loop() {
99149
+ (num_messages_sent * 1000000) / num_messages_per_second;
100150
if ((long)(micros() - next_message_time_micros) < 0) {
101151
try_to_receive_data();
152+
fake_tpms_ecu.sendNextFrameIfNeeded();
102153
delayMicroseconds(10);
103154
}
104155
}
@@ -174,6 +225,58 @@ void try_to_receive_data() {
174225
send_data(0x7E8, response, 8);
175226
return;
176227
}
228+
229+
if (id == 0x750 && data[0] == 0x2a) {
230+
if (data[1] == 0x02 && data[2] == 0x21) {
231+
if (data[3] == 0x30) {
232+
// TPMS pressures request.
233+
uint8_t response[8] = {0};
234+
response[0] = 0x2a;
235+
response[1] = 0x10; // "1" means "first frame in a sequence"
236+
response[2] = 0x07;
237+
response[3] = 0x61;
238+
response[4] = 0x30;
239+
response[5] = 0xAB; // ~34 psi
240+
response[6] = 0xAC; // ~34 psi
241+
response[7] = 0xAD; // ~34 psi
242+
send_data(0x758, response, 8);
243+
244+
response[0] = 0x2a;
245+
response[1] = 0x21; // "2" means "continuation frame", "1" means "first continuation frame".
246+
response[2] = 0xAE; // ~34 psi
247+
response[3] = 0x00;
248+
response[4] = 0x00;
249+
response[5] = 0x00;
250+
response[6] = 0x00;
251+
response[7] = 0x00;
252+
fake_tpms_ecu.scheduleNextFrame(0x758, response, 8);
253+
} else if (data[3] == 0x16) {
254+
// TPMS temperatures request.
255+
uint8_t response[8] = {0};
256+
response[0] = 0x2a;
257+
response[1] = 0x10; // "1" means "first frame in a sequence"
258+
response[2] = 0x07;
259+
response[3] = 0x61;
260+
response[4] = 0x16;
261+
response[5] = 40 + 21; // 21ºC
262+
response[6] = 40 + 22; // 22ºC
263+
response[7] = 40 + 23; // 23ºC
264+
send_data(0x758, response, 8);
265+
266+
response[0] = 0x2a;
267+
response[1] = 0x21; // "2" means "continuation frame", "1" means "first continuation frame".
268+
response[2] = 40 + 24; // 24ºC
269+
response[3] = 0x00;
270+
response[4] = 0x00;
271+
response[5] = 0x00;
272+
response[6] = 0x00;
273+
response[7] = 0x00;
274+
fake_tpms_ecu.scheduleNextFrame(0x758, response, 8);
275+
}
276+
} else if (data[1] == 0x30 && data[2] == 0x00) {
277+
fake_tpms_ecu.handleFrameAck(data[3]);
278+
}
279+
}
177280
}
178281

179282
void generate_payload(uint16_t pid, uint8_t *payload) {

0 commit comments

Comments
 (0)