Go Down

Topic: Rev counter problem (Read 1 time) previous topic - next topic


I've just added a rev counter to a project. It's pretty simple, I've stuck a magnet on the rim of the wheel I'm monitoring and I've put a magnetic reed switch just next to where the magnet passes. Each time the wheel spins the magnet passes the switch and momentarily closes it. The switch is connected to an arduino input pin whose state I monitor as the arduino continuously loops, whenever the magnet passes the pin is pulled low by the closing switch, by timing these events I can work out the speed of the wheel.

The rev counter works fine on it's own, but when incorporated into a larger project it becomes less accurate, I've worked out that what's happening is that the momentary blip on the input pin is being missed because it only last for a few milliseconds (if the wheel is moving fast) and if the arduino is busy doing something else (processing a gps signal, writing data to an SD card etc etc) then the value on the pin will change back again without being noticed.

Is there a programming way to fix this? I guess I could add some form of set/reset flip-flop mechanism, but this would be a hardware change, I'd prefer some form of software fix. Any ideas?



I would suggest looking into using interrupts.  Unfortunately, I don't have any experience in using interrupts so, hopefully, someone who can provide some good knowledge will step in and add some details.


Connect your reed switch to pin 2, then use the following code:

Code: [Select]
volatile uint32_t counter = 0;
volatile uint32_t last = 0;

void getspeed() {
  counter++; // increase a counter (if that's desired)
  uint32_t timediff = micros() - last; // from the timediff you can calculate the RPM
  last = micros();

void setup() {
  attachInterrupt(0, getspeed, RISING); // pin 2 is INT0

void loop() {
  // do what you wanna do


Thanks for that, I've not come across attachInterrupt() before.

I feel a big 'learn' coming on!



hmmmm..... haven't tried this yet, but I'm not sure the suggestion will work. I found this on the reference page for attacheInterupt()...
Inside the attached function, delay() won't work and the value returned by millis() will not increment.

So unless micros() is entirely different from millis() I think this may be a non-starter.

Still, I'll probably try it anyway!



The information you found is correct but I just get the current value of micros() and do not expect it to increase during the interrupt handler. You can access the micros() (and millis()) value in an interrupt service routine but because interrupts are disabled during the service routine the values are not increased. This is one of the reasons you should keep your interrupt service routines as short as possible (I think mine is :-) ).


ahhh - so millis() will be incremented inbetween succesvive interupts, but not whilst the interrupt routine is being run?

I think I get it, cheers

Go Up