EFI - Hall Effect sensor interrupt counter

im using a effect sensor to count pulses from a trigger wheel mounted to the crankshaft of an engine, fed into an UNO to control fuel and ignition, im using an external interrupt to increment a counter each time the sensor is triggered low. everything seems to work perfectly fine if I turn the engine at a low speed by hand. but cant seem to keep up with at anything close to operating RPM. my trigger wheel has 75 teeth, after removing 2 to create a gap to reset the count each rotation. the sensor is rated for 15k Hz, and at 600 RPM should only be 750 Hz. which I also believe the UNO can handle much for. looking at the data sheet for the sensor the only spec my trigger wheel does not meet is the distance between teeth, being almost half. my meter seems to pick up a frequency of around 900 Hz (using a drill), no problem from the sensor while spinning the engine faster. i do have the recommended 1kohm pull up resistor across VCC and pin 2. I cant seem to find what is causing my interrupt to miss counts.

byte IGN1 = 15;
byte IGN2 = 53;

//INPUTS//
const byte CKS = 2;
byte SIG = A0;
//OUTPUTS//
const byte COIL1 = 7;
const byte COIL2 = 8;

//MEMORY//
byte Counter = 0;
unsigned long Time;
unsigned long lastTime;
unsigned long Gap;
unsigned long lastGap;

void setup() {
  Serial.begin(9600);
  pinMode(CKS, INPUT);
  pinMode(COIL1,OUTPUT);
  pinMode(COIL2,OUTPUT);
  attachInterrupt(digitalPinToInterrupt(CKS), Crank, FALLING);
}

void loop() {
  int X = analogRead(SIG);
  Serial.println(X);
}


void Crank(){
  Counter++;
  if (Counter == IGN1)
    {digitalWrite(COIL1, HIGH);}
    else{digitalWrite(COIL1, LOW);}
  if (Counter == IGN2)
    {digitalWrite(COIL2, HIGH);}
    else{digitalWrite(COIL2, LOW);}
  Time = millis();
  Gap = Time - lastTime;
  lastTime = Time;
  if (Gap >= lastGap + lastGap / 2){ Counter = 1;}
  lastGap = Gap;
}

the outputs on pins 7 and 8, are 2 ignition coils that fire when given a 5v signal, and int X was just used for some testing.

the sensor im using
GS1005-GS1007 Series Datasheet by ZF Electronics | Digi-Key Electronics

Trigger Wheel
teeth - 75
tooth width - 2.5mm
tooth gap - 5mm
reset gap - 21mm
.
hope maybe someone can spot something, thanks !

It would help if you posted a schematic, not a frizzy thing. Include all your ground and power connections. Your sensor has a 5V minimum and if you are powering via USB you do not have it.

i was using a wall adapter and it didnt make a difference, also, the ignition is powered from a 12v battery, and only needs a logic ground and 5v signals (pins 7-8) from the arduino, so i could make a diagram but its only those few connections with a pull up resistor across pin2 and VCC

LVEFI - Imgur
A simple view of whats going on

Try using micros() instead of millis(). Over 800 RPM, gap will be less than 1 milli.
Try:

if(gap > lastGap <<1) { Counter = 1;} // gap is greater than lastGap times 2

And you better not connect those coils directly to the UNOs output pins, you need driver transistors and diodes across the coils.

The diagram does not really show everything going on. The coils I'm using have a driver circuit built in, and only need a ground and a 5 v signal to fire. The high voltage should be isolated from the uno.

Also I don't not understand the bitshift..

JCA34F:
Try using micros() instead of millis(). Over 800 RPM, gap will be less than 1 milli.
Try:

if(gap > lastGap <<1) { Counter = 1;} // gap is greater than lastGap times 2

And you better not connect those coils directly to the UNOs output pins, you need driver transistors and diodes across the coils.

Also, I don’t understand the bitshift?

Also, I don't understand the bitshift?

If your conditional test indeed finds the missing tooth gap, then use what you were doing but use micros() instead of millis() for your timing.

if (Gap >= lastGap + lastGap / 2){ Counter = 1;}
  lastGap = Gap;

At only 600 RPM (sensor at 750 Hz), hopefully this condition triggers at better than 3Hz (no more than about 333ms)
if (Gap >= lastGap + lastGap / 2){ Counter = 1;}or your byte counter overflows. You may need a volatile unsigned int for your counter.

Let me rephrase that:

if(gap > lastGap * 2) { Counter = 1;} // gap is greater than lastGap times 2

<<1 is shorthand for * 2 with binary numbers, like:
num = B00000100 = 4, num <<1 = B00001000 = 8.
Study the diagram below, still might have problem if engine is accelerating or decelerating rapidly.

  • 1333 micros per tooth @ 600 RPM
    | + 2666
    | |
    /_/_/_____/_/_/_
    | | | | + 1333
    | | | + 3999
    | | +1333
    | + 1333
  • 1333

I think printing at 9600 baud is too slow. If your analog read of SIG is 3 characters (bytes), and you need to keep up with 750 x 3 = 2,250 bytes/sec … 9600 baud is only 960 bytes/sec. I guess the serial buffer is saturating and you’re not able to see (print) the signal correctly. Try 115200 baud?

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.