Hall Sensor and Timers

Hello I am trying to re-create an example/tutorial of a sketch I found online with my own modifications.
The sketch uses the UNO timer with an IR Sensor to determine RPM (revolutions per minute).


  1. Using MEGA instead of UNO
  2. I am substituting the the IR Sensor with a Hall Sensor.
  3. Instead of having an LCD screen to display the RPM. I would like to use the serial monitor on the computer.

When I run the sketch the only RPM readings I receive are either "0" or "14448"


Since I am using a MEGA I changed the Hall Sensor to use pin 21 with interrupt 2. Does anyone know which one of my "modifications" is not making the code work?

NOTE: I did not delete any original code. Just made them "comments" instead.

#include <Arduino.h>
//#include <U8x8lib.h>
#include <SPI.h>
#include <Wire.h>
//U8X8_SSD1306_128X64_NONAME_HW_I2C u8x8(/* reset=*/ U8X8_PIN_NONE);
unsigned long rpmtime;
float rpmfloat;
unsigned int rpm;
bool tooslow = 1;

void setup() {


  TCCR1A = 0;
  TCCR1B = 0;
  TCCR1B |= (1 << CS12); //Prescaler 256
  TIMSK1 |= (1 << TOIE1); //enable timer overflow
  pinMode(21, INPUT);
  //pinMode(2, INPUT); (ORIGINAL CODE)
  attachInterrupt(2, RPM, FALLING);
  //attachInterrupt(0, RPM, FALLING); (ORIGINAL CODE)

ISR(TIMER1_OVF_vect) {
  tooslow = 1;

void loop() {
  if (tooslow == 1) {
    //u8x8.drawString(1, 0, "SLOW!");
  else {
    rpmfloat = 120 / (rpmtime / 31250.00);
    rpm = round(rpmfloat);
    Serial.print("RPM = ");

void RPM () {
  rpmtime = TCNT1;
  TCNT1 = 0;
  tooslow = 0;

File Attached.

Thank you.

tachometer_uKW8AK4IGy.ino (1.17 KB)

Finding something online does not mean it is any good. However, this project is by GreatScott! so it is okay :smiley:

How do you know that your Hall sensor gives a good signal ?
You could test it with: FreqMeasure Library, for Measuring Frequencies in the 0.1 to 1000 Hz range, or RPM Tachometer Applications

The reference of the attachInterrup() function shows how it should be used.

Have you read this:

attachInterrupt(digitalPinToInterrupt(pin), ISR, mode) (recommended)
attachInterrupt(interrupt, ISR, mode) (not recommended)

The Arduino Mega can use both pin 2 and 21.
You have 21, then you should use this:

attachInterrupt(digitalPinToInterrupt(21), RPM, FALLING);

Hey Koepel,

Yes GreatScott seems to know what he is talking about. Unfortunately that is not the case for me.
I tried updating that line of code you recommended but I still get the same results. Reading 0 and 14448.

If I isolate the formula to solve for rpmtime.

rpmfloat = 14448
rpmfloat = 120 / (rpmtime / 31250.00);

rpmtime = approx. 259.551

Any other ideas?

Did you see the signal with a oscilloscope ?
Can you try that FreqMeasure library ?

These variables should be made volatile:

volatile unsigned long rpmtime;
volatile bool tooslow = 1;

You can try your sketch with another Arduino board that generates a signal with tone() (note that the minimum frequency for tone() is 31 Hz).

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.