RPM Sensing

Hi all ,
has anyone implemented a tachometer ? i am looking for a way to input a hall effect sensor to measure shaft rotation speed (30,000 rpm+ ) , but without using the timer input capture pin as this is already used .

any code appriciated too

I don’t seem to have my code still lying around, but I am a big fan of hall effect tachometers.

I spent some time making a programmable trip odometer for my car that would count down (rather than up) miles until my next turn, which would make map program directions soooooooo much more useful. I thought I could just listen to the pulses coming from my engine’s built in encoder (it must have one somewhere, since I have a digital odometer) but it turns out people are very wary about even talking about messing with car odometers for legal reasons. To avoid all this I was going to put a couple of magnets on one of the drive shafts and mount a hall effect sensor near it. I was just about ready to mount it to the car, then I got a USB GPS receiver with some map software from my dad for Christmas. Oh well, I learned a lot!

Anyway, the gist of my implementation was to have the hall effect sensor connected to an interrupt pin set to respond to only a rising (or falling, your choice) edge by incrementing (or in my case decrementing) a variable. For slow rotation, it’s more accurate measure the time between ticks, but your target speed is pretty fast, so you’ll probably want to count ticks/time. If you have a free counter, or even one already running doing something else, you can have it trigger code on overflow that does something useful with the number of ticks since the last overflow, and resets the tick count variable!

The biggest hurdle I encountered was selection of the hall effect sensor itself. I was able to scrounge up some spares around my lab, but they were analog (i.e. their output voltage was proportional to local magnetic field direction and intensity) and very noisy. Software denouncing could have dealt with this, but I decided to get better sensors instead. Digital hall effect sensors, sometime referred to as “hall switches” would be good for you. Most have built in hysteresis, so the magnetic field has to change a lot before the digital output will.

I went one step further with “latching” hall effect sensors. These will output high when they have a strong pole of one type passed near the sensor face, and will stay high even in the absence of any field, until a strong pole of the other type passed over them (and the process repeats). My thought was, if the magnet is right by the sensor, and I roll backwards a little before going forwards, like starting up on a hill, I don’t want the sensor to count twice (this would make almost no difference, but I thought it was neat anyway). I was going to put two small magnets on opposite sides of the shaft, so that it would take a complete 360 degree rotation to cause another counter tick. With a small enough shaft, you only really need one magnet, because as it is rotated the sensor will see both poles.

So, have you selected a sensor yet? A digital hall effect sensor with some hysteresis would be good, so long as their rise/fall time is fast enough for you. For example, the latching sensors I have take 1us to change in each direction, so it could track rotations up to 500,000 RPM. I guess the other big trick will be keeping your interrupt code very very small. You could have your tick interrupt do nothing but increment the variable, and your counter overflow interrupt grab a copy of the current count and reset the count variable, leaving any speed math to be done outside the interrupt.

Wow, that was a lot. I guess I really do like magnetic tachometers. Did this help at all?


P.S. If you’re ever looking for a quick way to make a simple display tachometer or odometer in the <300 RPM range, pick up the cheapest “bike computer” you can find (the kind where you put a magnet on a spoke). I got one for $10 that I set up to show a mixing motor’s speed in my wife’s lab. Ones that would directly display RPM (they call it cadence) were $45 and up, but that’s not entirely necessary, since even the really lame ones let you program in your wheel circumference. If you put in 1667mm as the circumference (or 531mm diameter, whichever) then the readout in km/h is actually a readout in tens of RPM (i.e. 10.5 km/h=105 RPM). Or, put in 1000mm as the circumference, and each kilometer traveled will actually be a count of 1000 rotations. Sweet! The best part is, since she switched to a stepper motor for mixing, the bike computer is now actually on my bike!

I’m doing this with an AVR Butterlfy using (oddly enough) a hall effect switch, just like Adam described. The I/O pins that can be used as timer/counter sources are tied up in the Butterfly, so I made-do with a pin change interrupt for PORTB. Since it’s the only thing plugged in to PORTB, the code is pretty dumb. ANY time PCINT1 happens, check the state of PB7 and make sure you’re only transitioning on either a rising or a falling edge (so you only get one tick per rev).

I tried a couple of approaches. Different speed regimes work better with one or the other. For a high speed spindle, if you don’t mind a slow readout time, a 16-bit volatile unsigned int can be used as a counter. Use a watch crystal as an input for an asynchronous timer/counter and set it up to generate one interrupt per second. In the interrupt handler, take your counter value (revs/second), multiply by 60 (revs/minute) and output the value to the LCD.

For low-speed (I also tried using this for an anemometer, which worked out well), you may only be getting a handful of revs per second. For that I set up one of the AVR’s timer/counters as a free-running timer. On a rising edge transition of the hall-effect switch, I read out the free-running counter and zero it. Knowing how fast that counter is running gives a good value for the time between rotations. I still use the 1-second interrupt, but this time I’m keeping a running average on how long it takes the rotor to make one full rotation. At the end of a second I send the average to the LCD and zero out all the counters. It works well, but starts to choke at higher rotational speeds.

In one of the online forums (Portland Area Robotics Society comes to mind, but I could be wrong), someone mentioned a tach program they wrote that would automatically sense which speed regime it was in and adjust accordingly. That sounded like a pretty slick bit of code.