Red Light Racing

  • Increase font size
  • Default font size
  • Decrease font size

Engine Position Signals

E-mail Print PDF

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

    }

  }

 

Donate

Help us shake things up!

Powered by easy paypal donation

User Login

Countdown to Bonneville

 
 Auto X-Prize Contender