The program below, written by Eric Smith, takes VW 1.2L TDI engine position signals, digests them, then kicks out the proper outputs to trigger an RS-232 integrated circuit that pumps simulated engine position signals to the Honda Insight ECU. The Honda ECU doesn't know the difference and as a result thinks there's a Honda engine pumping away under the hood. Load this in to an Arduino micro controller, hook up an RS-232 chip and you've got a VW to Honda translator for about $40.
/*
*/
int VWcrank_pin=5;
int crank_pin =2;
int camA_pin =3;
int camB_pin =4;
int phase_pot_pin = 0;
unsigned long last;
signed long closed_loop_angle=0;
unsigned long last_period;
unsigned long periods = 10000;
unsigned long time_trigger=0;
unsigned long triggered_angle=0;
signed int angle_error=0;
signed int error_delta=0;
void set_outputs(long deg){
int pwidth = 60; //cam signals high for 60deg
deg=deg % 720; //cam signal repeats every 2 engine rotations
digitalWrite(crank_pin,(deg%30)>15); //crank square wave every 30deg
digitalWrite(camA_pin,((deg>000)&&(deg<(000+pwidth)))||((deg>480)&&(deg<(480+pwidth)))); //camA pulse at 0deg and 480deg
digitalWrite(camB_pin,((deg>240)&&(deg<(240+pwidth)))||((deg>480)&&(deg<(480+pwidth)))); //camB pulse at 240deg and 480deg
}
boolean rising(){
static boolean prev;
boolean cur;
cur=digitalRead(VWcrank_pin);
if (cur&&(!prev)){
prev=cur;
return true;}
else{
prev=cur;
return false;}
}
unsigned int measure_period(){
unsigned long time;
unsigned long ans;
time=micros();
ans =time-last;
last=time;
return ans;
}
void setup(){
pinMode(VWcrank_pin, INPUT);
pinMode(crank_pin, OUTPUT);
pinMode(camA_pin, OUTPUT);
pinMode(camB_pin, OUTPUT);
Serial.begin(9600); // set up Serial library at 9600 bps
time_trigger=micros();
}
void loop(){
if (rising()){
last_period = measure_period();
if ((last_period>200)&&(last_period<2000)){ // valid range (500 rpm -> 5000 rpm)
if (last_period < (periods+(periods>>1))){ // periods more than 50% longer than expected are gaps, don't count
periods=((periods<<3)-periods+last_period)>>3; //digital low pass
//periods=last_period; //unfiltered version
}
else{ //we just saw a gap
angle_error=closed_loop_angle % 120;
if (angle_error>60){
angle_error-=120;} //angle errors are in range +/- 60 deg
periods+=angle_error*4; //speed up if late, slow down if early
}
}
}
if (micros()>(last+10000)){ //time out (engine stopped)
periods=10000;
last=micros();
}
if (micros()>time_trigger){
if ((time_trigger>periods)||(micros()<(2*time_trigger))){ //if (timer not wrapped) or (time is less than twice trigger aka not false trigger due to wrap around)
closed_loop_angle+=6; //advance estimated angle by 6 degrees
set_outputs(closed_loop_angle); //update output
time_trigger+=periods; //set time at which next VW pulse is expected
}
}
}






