Wow, thanks for the great feedback. I feel stupid that I assumed the reed switch wouldn't bounce.
Duane, I like your idea of using an IR emitter/detector and using reflectance (instead of beam braking). Maybe I'll use this technique if the reed switch and magnet give me more headache.
I will also try hall effect sensors when I get one. I've noticed that most people use hall effect sensors (instead of reed switches) when making a magnet based wheel encoder.
Anyway, since all I have are reed switches to play with right now, I'm going to try to debounce them. I am trying a software based technique to debounce before trying hardware based techniques.
The code I came up with is:
volatile int counter = 0; //For counting number of times the magnet passes the reed switch
volatile long lastRiseTime = 0; //Time at which pin2 (interrupt 0) goes from LOW to HIGH
attachInterrupt(0, rising, RISING);
attachInterrupt(0, falling, FALLING);
digitalWrite(2, HIGH); //Enable pullup
//If more than 50 ms has elapsed since the last time pin 2 went high
if ((millis() - lastRiseTime) > 50)
lastRiseTime = millis();
I don't have an oscilloscope to see how the reed switch actually bounces, but I'm guessing it's something like this:
So, whenever pin 2 goes from High to Low (i.e. a magnet passes the reed switch), it checks how much time has elapsed since the last time pin 2 went from Low to High. If the elapsed time is greater than 50 ms, increase the counter. If the pin goes from High to Low very quickly (< 50 ms) because of bouncing, the counter will not be incremented.
The algorithm seemed very straightforward, but it did not work.
I think it's because the millis() function doesn't work in an ISR? Is that correct?
Another approach I used was to simply set a flag in the ISR (whenever pin 2 goes from high to low). Then, I check the flag in the main loop. If it is '1', I increase the pulse counter variable. I don't measure time at all. This surprisingly seems to work! I think it's because by the time the program returns to the main loop to check the flag variable, the reed switch is already done bouncing. Seems like a very cheap technique though.
Any more ideas for a better software debouncing algorithm I could use?