A tachometer (REV counter) using a ugly signal coming from the ignition coil

sjirafje:
Quick question, does using "RISING" instead of "FALLING" for the interrupt make any difference in my case?

I don't think so. You would get the same count of falling edges in 500ms as you would get rising edges wouldn't you?

PaulRB:
I don't think so. You would get the same count of falling edges in 500ms as you would get rising edges wouldn't you?

My recent experience with a Nano and a reed switch showed me the rising was a lot more susceptible to noise impulse than falling was. Maybe just my system.

Paul

@OP
Yes, You have got it. The plus - minus 1 error gives some 6 - 7% error at those low RPM.
Thinking about measuring the time between pulses, or the time between every 4 pulses, would give an error a lot less. Use microseconds.

Paul_KD7HB:
Nano and a reed switch.... rising was a lot more susceptible to noise impulse than falling was.

Was the reed connected between the Arduino pin and ground? To put the question another way, was the reed "bouncier" on make or break? In my mind I picture make suffering from bouncing more than break.

PaulRB:
Was the reed connected between the Arduino pin and ground? To put the question another way, was the reed "bouncier" on make or break? In my mind I picture make suffering from bouncing more than break.

Was a long struggle. The anemometer has a bar magnet spinning directly over the center of a reed switch, so the magnetic field switched the reed sw twice per rotation. A very thin, about 40 ft, shielded cable connects to the Arduino display in the house. Worked great for several years.

The program counts the interrupts for one second and then computes the MPH based on the factory formula for the rotating head. The display shows the latest maximum wind speed and the average over the last 15 seconds.

Over time, the maximum would show unrealistic values. MY ham radio on VHF would effect the maximum, but recently the value would creep up as I watched it. Something had to be done. I changed from the internal pullup resistor to an external pullup and still got the bogus maximum. I added a low pass filter to the input and still got the bad interrupt count on occasion. I changed the interrupt from falling to rising. Still errors.
Oh, I also changed to Arduino power to a 5 volt cell phone charger and added a ground wire to the mains wiring ground.

Last possible problem had to be the rotating sensor part. I took it down and removed the reed switch circuit board. I have a bunch of reed switches from the 1960's. Some were removed from circuit boards that used reed relays and some are new in the original packages.

The Anemometer reed switch is not like any others I have ever seen or read about. I has a SINGLE moving leaf, not two as we all believe reed switches to have. That lets the physical size be much smaller. So, the leaf contacted the metal rod on the opposite end to make electrical contact. Such an arrangement does not allow the magnetic field to pull the two leaves together or apart.

I happened to have a true reed switch in the drawer that was small enough to replace the factory switch and put the device back together and got all reconnected.

I still saw the maximum wind speed creep up, but nowhere as much or as rapid as before.

I changed the interrupt from rising to falling and all began to work as it used to do.

And that is why I suspect the rising is more susceptible to noise input than the falling.

I am sure the initial problem was the aging of the leaf in the factory reed switch which caused bouncing of the contacts on make. The anemometer I got is likely a factory research project to find a cheaper version of their commercial unit. The commercial also has aluminum cups where mine are plastic. I got the thing at a ham radio swap meet, so who know how old it is or what it was subject to.

Paul

Paul_KD7HB:
I changed from the internal pullup resistor to an external pullup...
...I suspect the rising is more susceptible to noise input than the falling.
...bouncing of the contacts on make.

But wouldn't make be the falling edge?

PaulRB:
Yes, but why not forget time and oldtime and simply write

rpm=rev*60000*2/updateInterval/c;

I now realise that, in the current version of the code, the arduino is only counting pulses during the delay, so there should not be any need to calculate the measurement duration. I'm going to try this.

Railroader:
@OP
Yes, You have got it. The plus - minus 1 error gives some 6 - 7% error at those low RPM.
Thinking about measuring the time between pulses, or the time between every 4 pulses, would give an error a lot less. Use microseconds.

Something like this?

int rpm;
int oldtime=0;
int time;
int re;
int updateInterval = 500;
int pulses=0;
int rev=1;

void setup() {
	re=rev*4;
}

void isr(){ 
  pulses++;
}

void loop() {
	if (pulses==re){
		detachInterrupt(0);
		time=micros()-oldtime;
		rpm=60000000/rev/time;
		pulses=0;
	if (rpm<0){
		display.setSegments(SEG_ERR);
	}
	if (rpm==0){
		display.setSegments(SEG_OFF);
	}  
	if (rpm>9999){
		display.setSegments(SEG_ERR);
	}
	if (rpm>0){
		display.showNumberDec(rpm, false);
	}
	delay(updateInterval);
	oldtime=micros();
	attachInterrupt(0,isr,FALLING);
}

I would like the ISR to read microSeconds and subtract the previous reading delivering the pulse to pulse time for reading by the normal code.

void isr(){
  newTime = microSeconds();//get the time now
  duration = newTime - previousTime;// Time elapsed since previous pulse.
  previousTime = newTime;//Book keeping the time of this reading
}

Interrupts must be inhibited just when "duration" is copied in the code below.

I like that idea. I'm going to test it as soon as possible.

Maybe the ISR should also set a flag "new data" and when You read the data You nock down that flag. Then You will not read the same data twice.

I can't imagine a situation where the calculation would read the same data twice as I need to include a delay for the display. Otherwise it would update to fast to be readable. Or am I missing something?

Perhaps in the future I'll experiment with a servo to try and make an "analog" display but then the servo will probably be the limiting factor preventing using the same date twice.

Don't use delay for that!
Use millis. Set a time, from millis. when You want to updste the display. When millis gets gretaer than that time, do the display update and(!) set the time for the next update. Some 200 - 500 milliseconds later.

something like this?

if (millis()>displayTime){
 //insert update display code here
 displayTime=millis()+updateInterval;
}

Also what is the advantage over using delay in my case?

Exactly! Declaring the variable displayTime (insigned long) "early" in the code will set it to zero causing one imiediate disply update and then the process is running.

You can replace //insert update display code here with a call to a function "updateDisply" if You like.

unsigned long....

Railroader:
[...]

You can replace

//insert update display code here

with a call to a function "updateDisply" if You like.

Will it make any difference on how fast the code is running? Or is it mainly for readability of the code?

It's just for being more readable and more easily maintained in the future.

sjirafje:
something like this?

if (millis()>displayTime){

//insert update display code here
displayTime=millis()+updateInterval;
}

Not quite, While it won't matter for your application, that code will cause an error after ~50 days. (when millis() rolls over)

better to learn the proper way using subtraction so that you won't have this issue in future projects.

if (millis() - displayTime >= updateInterval){
 //insert update display code here
displayTime = millis();
}

Hutkikz:
Not quite, While it won't matter for your application, that code will cause an error after ~50 days.

better to learn the proper way using subtraction so that you won't have this issue in future projects.

if (millis() - displayTime >= updateInterval){

//insert update display code here
displayTime = millis();
}

Thanks! You are right. I just hastily copied a piece from a sleepy brain.

Sorry to bother your post.
I am really interested in your project, I would like to adapt it for my paramotor.

I don't understand how you connect to the ignition coil.

Can I adapt it to this 2 stroke coil ?

Thanks