Hey, I've got an interesting set up which should be pretty simple for someone who has a little know-how in this area. I'm just reaching out for help at this point because I don't know why I'm getting the results I'm getting. There's a short version at the bottom if you want to skip most of the reading.
The situation is that a friend of mine has a 97 BMW 328i we put a turbo on. There's no easy way to tune these cars, and piggy-back ECUs and FICs are in the $300-400 range... they don't do anything that this arduino I've had laying around can't do in one form or another so I figured I'd give this a shot before wasting a bunch of money.
We need to increase the voltage coming from the MAF by a percentage. Rough is fine till we can get it working, then we'll improve it. The MAF puts out 0-5 volts depending on how much air is flowing through it.
I want to intercept this 0-5v signal using the arduino, increase it, and send the modified voltage along it's intended path.
I know the arduino can't output anything but PWM, so I did some looking and started to get in above my head. I used a diagram to build a low pass filter, and it works! If I set the arduino to 100% duty cycle I get ~4.85 volts, and I get regular analog voltage across the entire range (even down to ~1 volt). I can't post a link to the guide I was using as I don't have enough posts yet. It suggested for the default PWM frequency of the arduino that 6.9k ohms of resistance and a 47 uF capacitor was ideal.
So I'm using a total of 6.85k ohms (measured) resistance, and a 47 uF capacitor for my low pass filter. The resistors are connected in-line on the signal, and the capacitor is connected between signal and ground, after the resistors. The low-pass filter seems to work - but it's output isn't linear.
I have the arduino read the analog voltage coming from the MAF (which it does fine), multiply it by 1.2, then divide by four, and send back out. The only issue is that when there's ~1.6 volts coming into the arduino, even after a 1.2x multiplication, ~1.3 volts comes out.
The response time of this filter seems to be fast enough. To be honest anything under a 100-150 ms time to reach new voltage is acceptable. Is there a way to build a filter that responds more quickly if that becomes an issue later on down the line? Ripple isn't a huge issue. This setup was supposed to have 34 mV of ripple which is totally ok. Ripple up to ~200 mV is acceptable.
So, I'll probably add more as I can think of it but that should be the jist of it...
What follows is my (messy) code that runs on the arduino.
/*Jason LaGuidice
8/29/10
Program to read MAF voltage and export pulse width voltages.
This is meant to take place of a MAF translator and allow manual
adjustment of AFRs without replacing any other tuning software.
Future revisions will check TPS voltage and only apply modification at WOT.
*/
int sensorPin = 14; //select analog pin 0 for MAF voltage input
int ecuPin = 3; //select pin to output voltage via PWM
int sensorValue = 0; //variable to store value coming from sensor
int modifiedValue = 0; //variable for the modified MAF voltage
void setup() {
//declaration of the ecu pin as an analog output is NOT NECESSARY
pinMode(sensorPin, OUTPUT);
//use MAF reference voltage as reference voltage, just as the ECU does, connect to AREF
//temporarily not used until a stable 5v reference can be found, once found
//set to EXTERNAL
analogReference(DEFAULT);
}
void loop() {
//read MAF voltage
sensorValue = analogRead(sensorPin);
//if voltage is too (aka car not running) fake a singal for easy starting
if(modifiedValue < 120)
{
modifiedValue = 125;
}
//if below 3v, increase voltage for driveability. this section may be replaced
//and omitted once WOT detection is added
else if(modifiedValue > 615)
{
modifiedValue = sensorValue + 100;
modifiedValue = int(sensorValue * 1.8);
}
//at high loads. The reason the multiplication factor is smaller here is because
//the low pass filter output based on duty cycle doesn't seem to be linear :( More
//resolution of values will be necessary. Does the Arduino support log curves?
//if not, can a reference table like in an actual ECU be used to determine multiplication
//factor?
else
{
modifiedValue = sensorValue + 100;
modifiedValue = int(sensorValue * 1.4);
}
//output to ECU - analogRead values go from 0-1023 while analogWrite values go from 0-254
analogWrite(ecuPin, modifiedValue / 4);
}
SHORT VERSION:
I want to read a variable 0-5v DC signal (which will never actually reach 5v in use), multiply it by a number, and send it back along - and there's a ~100ms time constraint. Help?
Edit: As a small update. I noticed that no matter what I did, I was getting the same results when multiplying values to be written out to the low pass filter. I did test the filter with a demo program that just stepped up the PWM duty cycle over time, it worked great.
I looked over my program again and noticed I had an error (pinMode(sensorPin, OUTPUT);)... so I set that to INPUT, and now my Arduino won't put out any voltage on any of the out pins, either via PWM or digital. The only one that works is the on-board LED. So it seems as if I've killed it somehow even though I was working with low voltages. Ugh.
Anyway, still, does anyone have any suggestions?