New user and another Auto Data Idea

HI all, new user here.

I'm conceptualizing my first real project. I've been through most of the exercises in the "Getting Started with Sketches" book, I have a little bit of background with C, commercial race data systems, MATLAB, and some more background with vehicle dynamics in general. Basically, I know where I need to go but I'm hoping to discover the route through discussion here :slight_smile:

The concept:

What I'm trying to do is to create a device that will allow me to output a 0-5V analog signal that represents corrected acceleration to my vehicle's ecu, which has been modified to allow datalogging already. I’d eventually like to be able to grow this into a program and system robust enough to output torque values directly to the ecu. For now I’d like to focus on just an acceleration value, preferably corrected for road grade. The rest of the calculations can be easily handled in Excel since I can already output to .csv files. The idea is to be able to build a “torque map” that correlates to the fuel/spark maps as shown here:

This will allow me to tune the vehicle for peak torque at each breakpoint of the map.

The basic equation of a moving automobile:

M*V’ = Fd – Ff – Fa – Fg

Where
M = mass of the vehicle
V’ = dV/dx = acceleration of the vehicle
Fd = tractive force, i.e. engine power at the wheels
Ff = frictional forces (tires, wheel bearings, losses due to bumps, etc.)
Fa = aero drag
Fg = road grade contributions

The methodology is to go through and solve each of these individually by negating the others. M*V’ is fairly obvious and is what I would like to measure (specifically the V’!). Ff and Fa can be solved for sequentially (and with reasonable, but not excellent accuracy) by performing low speed and then high speed neutral gear coast down tests per SAE standards… something that car magazines and other testers do on a regular basis. Solving the force balance for Fd is what will allow me to derive and map the torque output of the motor.

Fd is the tricky one (for me). I really want the device to correct for road grade. My first thought was to use the z-axis of the accelerometer to calculate the angle based on the arcosine of the g-value. Then I realized that, while this will give me the angle, it will not tell me if that gradient is positive or negative. I can’t use the arcsine of the x-axis unless the vehicle is in steady state. Research has pointed me in the direction of using GPS to calculate the grade. I should be able to output horizontal and vertical velocities to the Arduino and take the arctangent of Vv/Vh. The GPS would only need to be polled at 1Hz max since logging would generally be done on relatively level and smooth roads where the gradient does not change rapidly. Also I’m in Florida, so there aren’t too many hills here anyway :slight_smile:

I’m thinking I might use a Due for 32-bit capability and to allow for future expansion & CAN-bus capability, along with one of the accelerometers available from SparkFun or similar. I have no idea where to start looking at GPS as this is my first time working with it really. I would love some input. Does everything here sound reasonable and doable? Is there a single sensor that I don't know of that will do the acceleration and grade in one shot? Is this noob in over his head?

Thanks for sticking around for the long-ish read.

I'll give ya a bump cause I'm interested as well

I suggest that rather than trying to calculate or measure all the factors and get an absolutely accurate figure for torque, you smooth them all out by averaging over as many dimensions as you want to optimise over. For example, it doesn't really matter what the aerodynamic drag is at a given speed, as long as it's independent of fuel/ignition/manifold pressure; the optimum is still going to be the optimum.

Acceleration is not a brilliant way to measure torque but if you can collect a big enough data set then you might be able to get somewhere. I mean - I can compare data logging results and see a 10% difference although it needs some careful analysis to make it obvious. But if you're using this for tuning then you need much finer resolution than that.

I suppose you've already put a lot of thought into this, but the way I tackle this is to define my target AFR map and then tune to that, calculate the approximate ignition map and then use knock detection to identify areas that need to be addressed by water/fuel/timing. This works for me because my engine is not particularly sensitive to ignition timing so optimising that isn't so important for me and mainly I just want to be a safe distance from the knock limit and at the right AFRs.

I've thought about that and the issue is that the particular motor that I'm working on is not spark limited. That means that I can feasibly be a few degrees past peak torque and still not knock. I'm mostly concerned with part throttle tuning here, full throttle pulls are easy and/or can be done on inertial dynos. Steady state dynos are hard to find and time is expensive, even though they are the definitive answer to the problem.

It's also kind of (well, mostly) more about doing it than having it. It's all a learning experience for me. I read a few research papers this week. In one of them I noticed an approach, which went mostly unexplained until I started picking through the references. That led me to this tech note from Memsic:

Memsic app note #AN-00MX-012

I also read up on a thread here regarding using Kalman Filtering to get control of the road grade estimation.

I have more to talk about, but have to run.

I think I'm gong to move toward using this thread as a place to catalog my progress, so expect some hyptohesizing, pics, links, and occasional rambling from here on out. I look forward to other's input as I figure this all out.

After doing some more research, I've decided to break the project down into smaller, more newb friendly stages.

The first step will be to try and get the Arduino to talk to my vehicle's ecu through its serial connection. It's been done before for the purposes of adding LCD displays, etc. so the code, protocol, and necessary addresses are all readily available. The data will come in handy for a few reasons:

-I can log it to to and SD card that way and have far more storage than I already have onboard (4Mb)
-I can output to .csv and manipulate the data in Excel/Mathcad/MATLAB
-I can work toward my end goal of creating a "real time dyno" type of algorithm
-I can implement some sort of LCD or add an mpguino type of display to the car.
-etc.....

Here are some links for what has already been done:

https://code.google.com/p/rzdash/wiki/HowCommunicationWorks

Normally the ecu's CN2 data port is used as described in the last link. On my ecu I have installed an emulator/logging board that occupies that spot for its own purposes, but I discovered that I can add an output header to the board as shown below:

The trick is going to be to figure out the data addresses and baud rate of the emulator board, as they are not the same as the oem ones. I'm confident that the information is out there, I just haven't stumbled on it quite yet.

I've also already added a header to the ADC inputs (H7 at the lower right of the board in the picture), so I will also be able to feed data back to it for logging, or add extra sensors here and there. Should be fun.

Long time since I've worked on this really.

I've spent the last month or so educating myself on serial communication, baud rates, monitoring ports, etc etc.

I'm able to talk to my board through Realterm and retrieve the packets of data that it sends back. I have to figure out how to parse them and decode them now. Here is what they look like:

4F 54 54 ... 54 4F

(Edited due to IP)

where this is the hardware's data protocol:

''O'+R(1,1)+….+R(x,nx)+'O'+CS

So the packet always opens and closes with a 4F and the very last digit is the checksum, in this case another 4F.

Next step is to figure out how to parse the data and then to turn it into something useful.

I haven't been able to communicate with the secondary port yet. Looks like I accidentally got a cable that only works with 3.3V logic, I need to pick one up that runs at 5V logic. Hopefully that solves that problem, and I can start trying to talk to the board with an Arduino once I confirm that I can talk to it through Realterm.

Also, my communication is at 921k6 baud. Looking around on the internet, I'm getting mixed messages as to whether or not the Uno R3 will support this rate. I will probably be moving to a Mega or Due down the road, but I'd like to see if I can get the lcd display working on the Uno first since I already have it. Can anyone confirm whether that rate will work? I understand that I will have to use an external software to monitor it since the Arduino serial monitor apparently only runs up to 115k2.

Baby steps :slight_smile:

So way back from the dead on my own project. It went dormant for a while while I built an engine simulator so that I can run my ecu at my desk and isolate the variables. I've been able to decode most of the data packets to get the info that I need.

Next step is talking to the car's ecu via the Arduino. I'm hoping someone here might be able to help me out with my initial code. On a Mega now, I'm trying to send the demon a byte, receive my packet, and then dump it on the serial monitor.

I can pass a byte from Realterm to the Mega and out to the serial monitor and I can talk straight to the Demon via Realterm & an FTDI cable, so I know I'm not too far off... But I'm having trouble talking to the Demon and passing it to the serial monitor. Any help is appreciated.

/*
Demon Communication
First Attempt

Adam Jones 
07/20/14
*/

int delayTime = 1000;
byte demonOut = 0x64;
byte demonIn = 0;
int dataVal = 0;

void setup()
{
  //Initialize Ports
  Serial.begin(115200);
  Serial2.begin(921600);
}

void loop()
{
  //Ping Demon for data packet and pause for reply
  Serial2.write(demonOut);
  Serial.write(demonOut); //copy to serial monitor
  Serial.write('\n');    //Carriage return
  delay(delayTime);
  
  //Read data to Serial Monitor
  if (Serial2.available())
  {
    int demonIn = Serial2.read();
    Serial.write(demonIn);
    Serial.write('\n');
  }
  delay(delayTime);  
}