@@ -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.
54104void  try_to_receive_data ();
55105void  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
179282void  generate_payload (uint16_t  pid, uint8_t  *payload) {
0 commit comments