PulseIn returning frustrating glitch

Hi guys, I'm reading off a signal from an ignition coil primary winding. I don't have a scope so i can tell you the correct voltage it produces but my MM says 4.5-5.8v see attached.

This is the code:

int pulsePin = 10;
unsigned long RPS;
unsigned long total;
unsigned long average;

void setup() {
  Serial.begin(9600);  
}

void loop() {
  total = 0;
  for (int i = 0; i <10; i++){
  unsigned long interval = pulseIn(pulsePin, HIGH) + pulseIn(pulsePin, LOW); // Pulse interval in microseconds
  RPS = (1000000UL / interval);
  Serial.print("RPS: ");Serial.println(RPS);
  total = total + RPS;
  delay(1000);
  
  }
  average = total / 10;
  Serial.print(average); Serial.println("RPS");
  delay(2000);
}

it seems to work well except for (usually) a single stray reading tha'ts way way off what it should be, sometimes i get all ten readings the same but usually its just a single stray reading upsetting the average.
So one cycle i usually get:

RPS: 72
RPS: 72
RPS: 686
RPS: 72
RPS: 72
RPS: 72
RPS: 72
RPS: 72
RPS: 72
RPS: 72
133RPS

Could it be that the pulse is being read mid point of the signal and hence calculating a greater RPS. But as i understand it PulseIn waits for a rising edge before it reads??

Another anomaly is the count of 72, this implies that its counting at 4320 RPM - could this be the rise and fall time of the opto? which is stated as 18uS Max (3-4Typical) which seems negligible.

Any comments about the circuit welcome too

thanks

Ignition sensor.GIF

Maybe you should try reading in the HIGH pulse and the LOW pulse into separate variables so you can see what is giving you the errand value.

thank you blh64,

i included some variables:

int pulsePin = 10;
unsigned long RPS;
unsigned long total;
unsigned long average;
unsigned long pHigh;
unsigned long pLow;

void setup() {
Serial.begin(9600);
}

void loop() {
total = 0;
for (int i = 0; i <10; i++){
pHigh = pulseIn(pulsePin, HIGH);
pLow = pulseIn(pulsePin, LOW);
unsigned long interval = pulseIn(pulsePin, HIGH) + pulseIn(pulsePin, LOW);
Serial.print(pHigh);Serial.print(" : ");Serial.print(pLow);
RPS = (1000000UL / interval);
Serial.print("RPS: ");Serial.println(RPS);
total = total + RPS;
delay(100);

}
average = total / 10;
Serial.print(average); Serial.println("RPS");
delay(2000);
}

and the output:

1265 : 12953RPS: 288
1259 : 12929RPS: 287
1265 : 12892RPS: 71
1265 : 12949RPS: 288
1260 : 13007RPS: 287
1266 : 12934RPS: 72
1264 : 12912RPS: 71
1265 : 12890RPS: 71
1267 : 13044RPS: 288
1264 : 12893RPS: 71
179RPS
1265 : 168RPS: 70
1267 : 12865RPS: 288
1260 : 12778RPS: 290
1259 : 12803RPS: 289
1267 : 12778RPS: 290
1261 : 12855RPS: 288
1268 : 12866RPS: 288
1266 : 60RPS: 70
1267 : 87RPS: 70
1265 : 12863RPS: 288
223RPS
1265 : 12889RPS: 289

so the high signal appears to be solid, and looks to me that the Low is probably getting interrupted by noise or erratic spikes, even so looking at the results even the correct readings are being interpreted incorrectly.

I'll move the circuit off the breadboard onto a proto board to see if it helps.

just a quick note i've gone thru the readings and on the high side there is only a difference of 13uS in the print out 1258 lowest and 1271 highest,
disregarding the spurious readings on the low side its just 328uS so the program works.

can anyone help with the circuit design too

Please use code tags, it looks horrible without. You are reading the "same" values twice and the printouts are not separated by a line break..

pHigh = pulseIn(pulsePin, HIGH); //High first
pLow = pulseIn(pulsePin, LOW); //Low first
unsigned long interval = pulseIn(pulsePin, HIGH) + pulseIn(pulsePin, LOW); //High & Low second
Serial.print(pHigh);Serial.print("     :      ");Serial.print(pLow); //No line ending

Danois90:
Please use code tags, it looks horrible without. You are reading the "same" values twice and the printouts are not separated by a line break..

pHigh = pulseIn(pulsePin, HIGH); //High first

pLow = pulseIn(pulsePin, LOW); //Low first
unsigned long interval = pulseIn(pulsePin, HIGH) + pulseIn(pulsePin, LOW); //High & Low second
Serial.print(pHigh);Serial.print("    :      ");Serial.print(pLow); //No line ending

noted

You don't need to use pulseIn() 4 times. After reading in the high pulse and the low pulse, just add those two values together and store in interval. If you look at your data, you will notice that they don't "add up" if you add pHigh and pLow and then convert to RPS.

pHigh = pulseIn(pulsePin, HIGH);
pLow = pulseIn(pulsePin, LOW);
unsigned long interval = pHigh + pLow;
Serial.print(pHigh);Serial.print("     :      ");Serial.println(pLow);

72 RPS = 4,320 RPM = 13.888 millisecond cycle time
686 RPS = 41,160 RPM = 1.458 millisecond cycle time

Does your engine ever go 41,000 RPM?!?

I suspect the short interval is catching a contact bounce. Perhaps you could just throw away any value under 6000 microseconds (roughly 10,000 RPM).

revised code:

int pulsePin = 10;
unsigned long RPS;
unsigned long total;
unsigned long average;
unsigned long pHigh;
unsigned long pLow;

void setup() {
  Serial.begin(9600);  
}

void loop() {
  total = 0;
  for (int i = 0; i <10; i++){
  pHigh = pulseIn(pulsePin, HIGH);
  pLow = pulseIn(pulsePin, LOW);
  Serial.print(pHigh);Serial.print("\t:\t");Serial.print(pLow);
  unsigned long interval = pHigh + pLow;
  RPS = (1000000UL / interval);
  Serial.print("\tRPS: ");Serial.println(RPS);
  total = total + RPS;
  delay(100);
  
  }
  average = total / 10;
  Serial.print("Average RPS: "); Serial.println(average);
  delay(2000);
}

and output sample:

1282	:	13744	RPS: 66
1282	:	13611	RPS: 67
1283	:	13780	RPS: 66
1282	:	13631	RPS: 67
1282	:	13706	RPS: 66
1282	:	13591	RPS: 67
1282	:	13722	RPS: 66
1283	:	141	RPS: 702
1282	:	13604	RPS: 67
1275	:	13622	RPS: 67
Average RPS: 130
1283	:	13744	RPS: 66
1282	:	98	RPS: 724
1284	:	13579	RPS: 67
1283	:	13723	RPS: 66
1283	:	13562	RPS: 67
1282	:	13779	RPS: 66
1283	:	13530	RPS: 67
1281	:	13709	RPS: 66
1282	:	13600	RPS: 67
1283	:	13751	RPS: 66
Average RPS: 132
1275	:	13716	RPS: 66
1276	:	13579	RPS: 67
1282	:	13707	RPS: 66
1277	:	27	RPS: 766
1282	:	142	RPS: 702
1282	:	13700	RPS: 66
1277	:	13775	RPS: 66
1276	:	13620	RPS: 67
1283	:	13779	RPS: 66
1283	:	89	RPS: 728
Average RPS: 266
1284	:	13849	RPS: 66
1284	:	13625	RPS: 67
1283	:	13760	RPS: 66
1283	:	253	RPS: 651
1283	:	78	RPS: 734
1282	:	201	RPS: 674
1282	:	142	RPS: 702
1282	:	13599	RPS: 67
1282	:	13670	RPS: 66
1283	:	161	RPS: 692
Average RPS: 378

i turned down the idle speed slightly and it makes sense from the last readings, so it looks definitely like a bounce or noise, being that its a very (mostly) short period after the high time i suspect a bounce even more. (or is a 161 uS bounce a bit long after the high drops out?)

johnwasser i think you misunderstood the readings (probably bit clearer now), but on the left is the magnet passing over the coil (the HIGH period) and on the right the low period and then the calculated RPS. Any chance you could advise me on how to disregard the readings, as you said?

Sure:

void loop()
{
  total = 0;
  for (int i = 0; i < 10; )
  {
    pHigh = pulseIn(pulsePin, HIGH);
    pLow = pulseIn(pulsePin, LOW);
    Serial.print(pHigh); 
    Serial.print("\t:\t"); 
    Serial.print(pLow);
    unsigned long interval = pHigh + pLow;


    if (interval > 6000)
    {
      RPS = (1000000UL / interval);
      Serial.print("\tRPS: "); 
      Serial.println(RPS);
      total = total + RPS;
      i++;
    }
  }
  
  average = total / 10;
  Serial.print("Average RPS: "); 
  Serial.println(average);
  delay(2000);
}

Success

thanks you johnwasser, Danois90, blh64

1321	:	15319	RPS: 60
1311	:	15055	RPS: 61
1321	:	15343	RPS: 60
1116	:	15064	RPS: 61
1319	:	15456	RPS: 59
1175	:	15148	RPS: 61
1313	:	15430	RPS: 59
1322	:	15310	RPS: 60
1231	:	14953	RPS: 61
1312	:	15432	RPS: 59
Average RPS: 60
1265	:	15175	RPS: 60
1318	:	15465	RPS: 59
1229	:	15075	RPS: 61
1317	:	15385	RPS: 59
1343	:	15025	RPS: 61
1311	:	15470	RPS: 59
1391	:	15105	RPS: 60
1316	:	15316	RPS: 60
1204	:	15036	RPS: 61
1309	:	15416	RPS: 59
Average RPS: 59
1313	:	15182	RPS: 60
1371	:	15056	RPS: 60
1308	:	15232	RPS: 60
1221	:	14990	RPS: 61
1314	:	15274	RPS: 60
1283	:	15039	RPS: 61
1307	:	15280	RPS: 60
1302	:	14950	RPS: 61
1307	:	15223	RPS: 60
1380	:	14965	RPS: 61
Average RPS: 60
1314	:	15253	RPS: 60
1409	:	14984	RPS: 61
1310	:	15416	RPS: 59
1363	:	15181	RPS: 60
1314	:	15260	RPS: 60
1081	:	15009	RPS: 62
1310	:	15305	RPS: 60
1342	:	15097	RPS: 60
1310	:	15271	RPS: 60
1278	:	15106	RPS: 61
Average RPS: 60

Averaging 60 RPS this is what i was after, although the readings have lost accuracy its giving a clear average and perfectly usable.