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.
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
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.
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.
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.
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?