Go Down

Topic: Rev counter problem (Read 989 times) previous topic - next topic

BigusDickus

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?

Cheers

flyboy

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.

pylon

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
}

BigusDickus

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

I feel a big 'learn' coming on!

Cheers

BigusDickus

hmmmm..... haven't tried this yet, but I'm not sure the suggestion will work. I found this on the reference page for attacheInterupt()...
Quote
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!

Thanks

pylon

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 :-) ).

BigusDickus

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