• Sign Up! To view all forums and unlock additional cool features

    Welcome to the #1 Fiesta ST Forum and Fiesta ST community dedicated to Fiesta ST owners and enthusiasts. Register for an account, it's free and it's easy, so don't hesitate to join the Fiesta ST Forum today!


FiST Instrumentation/Electronics Build:

Messages
9
Likes
13
Location
Minneapolis, MN, USA
#1
Got a 2016 ST a couple months ago, and have been driving it back and forth to work. The only thing I have done so far is put it on snow tires. It’s a very fun car, but the interior does leave something to be desired. Maybe it’s just my paranoia from driving Subarus, but I can’t stand not having things like water temp on my dash. So I think I will tackle things like that first. From there I might try to do some autocross/rallycross, but that would be a new form of racing to me. So I’m sure I’ll need to address other aspects of the car eventually.

My first thought and probably yours too was just use one of those ELM OBD dongles and an Android app. I have used that in the past but I’ve never seen anything I can’t build myself. Also, I don’t want to be locked into their code and limitations. For example I don’t think you can code up something like gear position in those apps or really go crazy with the theming. Gonna need some help once I get to the theming part. I’m going to be sharing my code in the hopes that people will work along with me and contribute.

Here are the parameters I’m interested in right now:
  • Oil temp/Pressure (standard PID)
  • Water temp (standard PID)
  • Battery voltage (standard PID)
  • Boost (calculated)
  • Gear position (found in CAN) - See post below
  • Fuel usage (calculated) - I have seen this done a few ways
  • I would also like to better display how much traction control is kicking in

That’s all I can think of right now before actually getting any track time and finding out what else I’m forgetting. Let me know if you have been looking for anything. It would be fun to do some reverse engineering on non standard IDs.

To start I’m gonna put all of this on a tablet or phone, then I hope to eventually integrate it a bit more permanently with dedicated screens and gauges.

First I’m gonna get my code working using a computer, USB to Macchina M2. Then I will port everything to a phone/webapp and smaller dongle or maybe tap the lines directly to leave the obd port open.

m2savvycan.jpg


Luckily I’m not on my own. There is plenty of code laying around I can use.

I started with this code:

C++:
#include <due_can.h>

uint8_t codes[4] = {5, 0xB, 0xC, 0xD};
int idx = 0;
uint32_t tick = 0;

void sendPIDRequest(uint32_t id, uint8_t PID)
{
   CAN_FRAME frame;
   frame.id = id;
   frame.length = 8;
   for (int i = 0; i < 8; i++) frame.data.bytes[i] = 0xAA;
   frame.data.bytes[0] = 2; //2 more bytes to follow
   frame.data.bytes[1] = 1;
   frame.data.bytes[2] = PID;
   Can0.sendFrame(frame);
}

void processPID(CAN_FRAME &frame)
{
   int temperature;
   float psi;
   int RPM;
   int MPH;
 
   if (frame.data.bytes[1] != 0x41) return; //not anything we're interested in then
   switch (frame.data.bytes[2])
   {
   case 5:
      temperature = frame.data.bytes[3] - 40;
      SerialUSB.print("Coolant temperature (C): ");
      SerialUSB.println(temperature);
      break;
   case 0xB:
      psi = frame.data.bytes[3] * 0.145038; //kPA to PSI
      SerialUSB.print("Manifold abs pressure (psi): ");
      SerialUSB.println(psi);    
      break;
   case 0xC:
      RPM = ((frame.data.bytes[3] * 256) + frame.data.bytes[4])/4;
      SerialUSB.print("Engine RPM: ");
      SerialUSB.println(RPM);          
      break;
   case 0xD:
      MPH = frame.data.bytes[3] * 0.621371;
      SerialUSB.print("Vehicle Speed (MPH): ");
      SerialUSB.println(MPH);
      break;
   }
}

void setup() {
  Can0.begin(CAN_BPS_500K);
  int filter;
  //extended
  for (filter = 0; filter < 3; filter++) {
  Can0.setRXFilter(filter, 0, 0, false);
  Can1.setRXFilter(filter, 0, 0, false);
  }
}

void loop() {
   CAN_FRAME incoming;

   if (Can0.available() > 0) {
      Can0.read(incoming);
      if (incoming.id > 0x7DF && incoming.id < 0x7F0)
      {
         processPID(incoming);
      }  
   }

   //every second rotate to a new code and send it. Hopefully something replies
   if (millis() > (tick + 1000) )
   {
       tick = millis();
       sendPIDRequest(0x7DF, codes[idx]);
       idx = (idx + 1) % 4;
       SerialUSB.println(".");
   }
}
It seemed to be working for other people but not the Fiesta. So I took SavvyCAN and the M2 again and spied on a diagnostic dongle that I did know was working.

savvycansnap.png

Here was my general reverse eingeering process:

1 start logging CAN data with SavvyCAN​
2 start the car​
3 wait for new IDs to stop showing up​
4 filter out those IDs​
5 Plug in other dongle (using a splitter cable)​
6 See what new IDs were added​
I also made logs of each device, mine and the working example.

Turns out it was just the length of the message the Fiesta was expecting. A friend who understands CAN better than me spotted this difference in the logs. With a quick change from 29 to 11 bit messages and I was finally getting data.

I added this: frame.extended = 0;

Now this code should work for the fiesta to print out whatever PIDs you request:

C++:
#include <due_can.h>

uint8_t codes[4] = {5, 0xB, 0xC, 0xD};
int idx = 0;
uint32_t tick = 0;

void sendPIDRequest(uint32_t id, uint8_t PID)
{
   CAN_FRAME frame;
   frame.id = id;
   frame.extended = 0;
   frame.length = 8;
   for (int i = 0; i < 8; i++) frame.data.bytes[i] = 0xAA;
   frame.data.bytes[0] = 2; //2 more bytes to follow
   frame.data.bytes[1] = 1;
   frame.data.bytes[2] = PID;
   Can0.sendFrame(frame);
}

void processPID(CAN_FRAME &frame)
{
   int temperature;
   float psi;
   int RPM;
   int MPH;
 
   if (frame.data.bytes[1] != 0x41) return; //not anything we're interested in then
   switch (frame.data.bytes[2])
   {
   case 5:
      temperature = frame.data.bytes[3] - 40;
      SerialUSB.print("Coolant temperature (C): ");
      SerialUSB.println(temperature);
      break;
   case 0xB:
      psi = frame.data.bytes[3] * 0.145038; //kPA to PSI
      SerialUSB.print("Manifold abs pressure (psi): ");
      SerialUSB.println(psi);    
      break;
   case 0xC:
      RPM = ((frame.data.bytes[3] * 256) + frame.data.bytes[4])/4;
      SerialUSB.print("Engine RPM: ");
      SerialUSB.println(RPM);          
      break;
   case 0xD:
      MPH = frame.data.bytes[3] * 0.621371;
      SerialUSB.print("Vehicle Speed (MPH): ");
      SerialUSB.println(MPH);
      break;
   }
}

void setup() {
  Can0.begin(CAN_BPS_500K);
  int filter;
  //extended
  for (filter = 0; filter < 3; filter++) {
  Can0.setRXFilter(filter, 0, 0, false);
  Can1.setRXFilter(filter, 0, 0, false);
  }
}

void loop() {
   CAN_FRAME incoming;

   if (Can0.available() > 0) {
      Can0.read(incoming);
      if (incoming.id > 0x7DF && incoming.id < 0x7F0)
      {
         processPID(incoming);
      }  
   }

   //every second rotate to a new code and send it. Hopefully something replies
   if (millis() > (tick + 1000) )
   {
       tick = millis();
       sendPIDRequest(0x7DF, codes[idx]);
       idx = (idx + 1) % 4;
       SerialUSB.println(".");
   }
}
OBDtermianl.jpg

Project build Files Summary:

I will add further updates in future posts, but I will try to keep this section updated with my latest files and links for anyone looking to recreate this project or work along with me.

2/7/2020:
Macchina M2 - (engineering tool that I will eventually replace with something less expensive)
SavvyCAN - (great tool with a bit of a learning curve, Getting M2 set up with savvycan doc here, SavvyCAN feature documentation here)
OBD2 code (directly above)
due_can.h (referenced in OBD2 code)​


Next:
I'm going to try calculating Boost, I also have an idea for a quick way to display this data on an old cell phone over wifi.
 


Last edited:
Messages
161
Likes
160
Location
Charlotte, NC
#2
This is sick! Good on you for creating a killer second post on the forum. I work in IT so anything like this I will definitely follow along
 


Messages
55
Likes
54
Location
Pittsburgh
#3
Very impressive! I just got an Accessport and called it a day lol. Definitetly interested in what you come up with.
 


Messages
145
Likes
46
Location
Lenexa, KS, USA
#9
Yeah I have herd of Autopi. What do they have like SavvyCAN or are you just using CAN-utils?
There’s a python-obd library that they’ve added canbus to.

They’ve built a little web GUI over it too that makes ITTT type logic and building gauge, graph and button dashboards pretty point and click.
 


Messages
55
Likes
54
Location
Pittsburgh
#10
That is pretty darn slick! Accessport can, um, access and log pretty much any sensor or data point, the list is a long one. You can choose up to 6 to display at a time. For example, I've got boost, fuel level % for E30 mixing, estimated HP and torque, OAR and knock count currently dispayed on mine. But what you're doing is way cooler!
 


OP
B
Messages
9
Likes
13
Location
Minneapolis, MN, USA
Thread Starter #13
I'm not 100% sure on how to make an update to this that is easy to follow.

In short, I have found the active gear in the CAN data. So I don't need to calculate it as I talked about above.

I don't have it on the display yet, but see if you can see it changing in the filtered CAN data as I shift. It's not lagging much which is pretty cool as I was using WiFi to connect to the OBD2.


ShiftCANview.gif
 


Attachments

M-Sport fan

9000 Post Club
Messages
14,101
Likes
6,755
Location
Princeton, N.J.
#14
I also could not stand to not have a constant, ACTUAL coolant temp display either, but definitely NOT being an IT maestro/engineer like yourself (NO snark, that IS a direct compliment with much envy! [thumb] [wink]), and all of the others on here, I took the NON-techies', IT illiterate route, and just got myself an OBD plug-in Ultragauge, and mounted it with 3M tape up on the head unit panel. [wink]

It also will display all of the other factory reported PIDs, at least three at a time, on it's re-configurable screen, and only costs about $70.00. [:)]
 


LilPartyBox

1000 Post Club
Premium Account
Messages
1,488
Likes
769
Location
NYC
#16
I stopped using my ultragauge. I blame it for shutting off my car two times while driving. Maybe I have a bum unit as it's pretty old.

OP, hats off to you. I'm in IT and have coded in my day. What your pulling off isn't easy!
 


Last edited:

Intuit

3000 Post Club
Messages
3,650
Likes
2,254
Location
South West Ohio
#17
I stopped using my ultragauge. I blame it for shutting off my car two times while driving. Maybe I have him unit as it's pretty old.
Using a different PC-based OBD II tool to query data from a Buick Park Avenue, (been many years) there was some particular query I ran that nearly caused it to shutoff. Ran a little different after that too. (probably just had to relearn) But I suppose it's possible. Needless to say I disconnected and quit using the tool after that.
 


M-Sport fan

9000 Post Club
Messages
14,101
Likes
6,755
Location
Princeton, N.J.
#18
I stopped using my ultragauge. I blame it for shutting off my car two times while driving. Maybe I have a bum unit as it's pretty old.
The ONLY time mine has done this is if I plugged it into the OBD port once/after the engine was already running.
It has NEVER done this if plugged in when the engine/ignition was totally off, and then started. [wink]
 


Intuit

3000 Post Club
Messages
3,650
Likes
2,254
Location
South West Ohio
#19
@M-Sport fan - Possible it may have been dis/reconnecting while driving? That could be a safety issue. So much for gifting any of these devices. 🙂 Do you have v1.4?

Sounds like manufacturers may need a little more safety testing to determine what commands should be banned while the speedometer is >zero. (forward or reverse)

With some additional testing, @BearMetal might be able to provide some insight.
 


M-Sport fan

9000 Post Club
Messages
14,101
Likes
6,755
Location
Princeton, N.J.
#20
@M-Sport fan - Possible it may have been dis/reconnecting while driving? That could be a safety issue. So much for gifting any of these devices. 🙂 Do you have v1.4?

Sounds like manufacturers may need a little more safety testing to determine what commands should be banned while the speedometer is >zero. (forward or reverse)

With some additional testing, @BearMetal might be able to provide some insight.
Yes, version 1.4.

I did not disconnect and re-connect the OBD plug while driving. [nono]

I started the car at my home parking spot, THEN plugged in the Ultra Gauge while still parked, and it cut everything to a dead stop about 100 yards later, once moving, while still in my 15 MPH development. [wink]

It was a one-off incident, only due to the above circumstances, and it has not 'misbehaved' since, in almost three years of continuous use. [:)]
 


Similar threads



Top