Skip to Content

Build Arduino Tachometer Using A3144 Hall Effect Sensor

Build Arduino Tachometer Using A3144 Hall Effect Sensor

In this tutorial you will learn how to use the A3144 Hall Effect Sensor and an Arduino to build a Tachometer. A tachometer is a device to measure the speed of a rotating object. For instance, it is common in automotive applications to monitor the RPM (revolutions per minute) of an engine.

The Hall Effect sensor detects the presence of a magnetic field. By attaching a small magnet to a rotating object, we can use this to count revolutions. With an Arduino we then can measure the time it took for a given number of revolutions and calculate the RPM.

In the next sections, I will list the required parts for this project, explain the basics of Hall Effect sensors, and introduce the A3144 Hall Effect sensor, which we will be using for our tachometer. I will also provide examples of different tachometer implementations using the A3144 sensor, including a simple tachometer and a more advanced one using interrupts.

So let’s get started!

Required Parts

Below you will find the parts required for this project. If you just want to explore and learn about Hall Effect Sensors buy the Sensor Module. It will be a bit easier to use but is too big for practical applications. For those rather buy the Hall Effect Sensor itself, which is much smaller and cheaper as well.

Arduino Uno

USB Data Sync cable Arduino

USB Cable for Arduino UNO

Dupont wire set

Dupont Wire Set

Resistor & LED kit

A3144 Hall Effect Sensor Module

A3144 Hall Effect Sensor

Magnets

Makerguides.com is a participant in the Amazon Services LLC Associates Program, an affiliate advertising program designed to provide a means for sites to earn advertising fees by advertising and linking to products on Amazon.com. As an Amazon Associate we earn from qualifying purchases.

Basics of Hall Effect Sensors

Hall Effect sensors are electronic devices that can detect the presence of a magnetic field. They work based on the Hall Effect, which is the creation of a voltage difference across a conductor when it is placed in a magnetic field while current flows through it.

How do they work?

Hall Effect sensors consist of three main components: a voltage source, a current-carrying conductor, and a magnetic field. When a magnetic field is applied perpendicular to the current flow in the conductor, it creates a Lorentz force that pushes the electrons to one side of the conductor. This creates a voltage difference across the conductor, which can be measured.

Hall Effect (source)

Typical applications

Typical application for Hall Effect sensors are:

  • Proximity sensing: Hall Effect sensors can detect the presence or absence of a magnetic field, making them suitable for proximity sensing applications.
  • Speed measurement: By attaching a magnet to a rotating object and using a Hall Effect sensor to detect the magnetic field changes, the speed of the object can be measured.
  • Current sensing: Hall Effect sensors can measure the current flowing through a conductor by detecting the magnetic field generated by the current.
  • Position sensing: By placing magnets at specific positions and using Hall Effect sensors, the position of an object can be determined.

Latching vs non-latching

Hall Effect sensors can be categorized as latching or non-latching. Latching sensors have a built-in magnetic field that keeps them in the on or off state until another magnetic field of opposite polarity is applied. Non-latching sensors, on the other hand, only detect the presence of a magnetic field and do not retain their state. We will be using a non-latching sensor.

Bipolar vs unipolar

Hall Effect sensors can also be classified as bipolar or unipolar. Bipolar sensors can detect both positive and negative magnetic fields, while unipolar sensors only respond to one polarity. The A3144 Hall Effect Sensor is a unipolar sensor and will react only to one pole of a magnet.

Switching vs linear

Hall Effect sensors can operate in either switching or linear mode. Switching sensors provide a digital output, toggling between on and off states based on the presence or absence of a magnetic field. Linear sensors, on the other hand, provide an analog output that varies linearly with the strength of the magnetic field. We will be using the A3144 Hall Effect Sensor, which is of the switching type.

Hall Effect Sensors vs Reed Relays

Apart from the Hall Effect Sensor another common type of magnetic switch is the Reed Relay. Let’s quickly discuss the differences between them.

Hall Effect Sensors offer advantages such as non-contact sensing, solid-state technology, faster response time, wide operating temperature range, and digital output. However, they have a limited sensing range, higher cost, and are sensitive to stray magnetic fields.

Reed relays, on the other had, have a wide sensing range, lower cost, and are insensitive to stray magnetic fields. However, they suffer from mechanical wear and tear, slower response time, and limited operating temperature range. For more detailed information have a look at our tutorial on Interfacing Magnetic Switch To The Arduino.

In the next section, we will have a look at the A3144 Hall Effect sensor and its features.

Introducing the A3144 Hall Effect Sensor

The A3144 Hall Effect Sensor is a fantastic, very small magnetic sensor packed with electronics.

It can operate with unregulated voltages from 4.5 up to 24 Volts due to a built-in voltage regulator. In addition it has reverse polarity protection, which means if you wire it wrongly it will survive. The power consumption with 3.5mA (at 5V) is minimal, making it a suitable for battery-powered applications.

The image below shows you the pinout. If you look at the sensor from the front where you can read the label, the positive pin (+) will be to the left. Ground (-) is in the middle and the signal output (s) is the right pin.

Pinout of the A3144 Hall Effect Sensor
Pinout of the A3144 Sensor

Note that the A3144 is unipolar. So it will react to only one pole of a magnet but not the other. Remember this when testing it!

The sensor has an open-collector output, which means it can be directly interfaced with microcontrollers and can drive up to 25mA. We will take advantage of that and directly connect an LED to test its function.

Finally, the A3144 sensor has a high sensitivity (2.5mV/Gauss), a high operating frequency of 2kHz and a wide operating temperature range of -40°C to +150°C. In short, it is a great sensor for almost any application that requires frequent, contactless, fast switching.

Testing the A3144 Hall Effect Sensor

As mentioned under required parts, you can buy the sensor as a module or the plain sensor itself. The module has an integrated LED and pullup resistor (R1) and is therefore very easy to test. Just connect 5V (up 24V) to the module and bring the magnet close to the sensor. The LED should light up. But remember that the sensor is unipolar. Try both poles of the magnet. One side will work the other will not.

Testing the A3144 Module
Testing the A3144 Module

If you want to test the plain sensor, you will need to wire up an LED and a pullup resistor yourself. The schematic below shows you how to do this.

Testing the A3144 Hall Effect Sensor
Testing the A3144 Hall Effect Sensor

Note that the logic is inverted. The LED will glow weakly (due to the 10 KΩ resistor) and will switch off when the magnet gets near the sensor. Remember this behaviour for later. In short, the output of the A3144 will go low when the a magnetic field is detected and is otherwise high.

By the way: If you want to test this on a breadboard using the Arduino power supply; here is the wiring. Don’t forget the 10 KΩ pullup resistor.

Testing the A3144 on a breadboard
Testing the A3144 on a breadboard

In the next section, I show you how to connect the A3144 Sensor properly to the Arduino.

Connecting the A3144 Hall Effect Sensor

Most of the necessary wiring you have seen already above. The only difference will be that we will connect the output of the A3144 Sensor to Pin 2 of the Arduino.

Connecting the A3144 Sensor to the Arduino
Connecting the A3144 Sensor to the Arduino

To summarize, we connect power from the Arduino to the breadboard and from there to the A3144 Sensor. Then we add the 10 KΩ pullup resistor and connect the output of the A3144 to Pin 2 of the Arduino. If you have any issues; below is the complete wiring table.

FromPinWire colorToPin
Arduino5VRedBreadboardPositive rail
ArduinoGNDBlueBreadboardNegative rail
A3144GNDBlueBreadboardNegative rail
A3144VCCRedBreadboardPositive rail
A3144 Out/SignalYellowArduino2
A3144 Out/SignalResistor1
Resistor2RedBreadboardPositive rail

In the next section I will show you, how to use the A3144 as a simple magnetic switch.

Example 1: A Magnetic Switch

Have a quick look at the very simple code below. Every 10ms we read the sensor value and if its value is LOW we switch the built-in LED of the Arduino on. If you bring a magnet close to the sensor, the LED should light up.

const int hallPin = 2;
const int ledPin = 13;  // built-in

void setup() {
  pinMode(hallPin, INPUT);
  pinMode(ledPin, OUTPUT);
}

void loop() {
  int val = digitalRead(hallPin);
  digitalWrite(ledPin, val ? LOW : HIGH);
  delay(10);
}

Here a detailed explanation of the code.

Constants and Variables

The code begins by defining two constants: hallPin and ledPin. The hallPin constant specifies the pin to which the Hall Effect sensor is connected, and the ledPin constant the pin for the built-in LED on the Arduino board.

const int hallPin = 2;
const int ledPin = 13;  // built-in

Setup function

In the setup() function, we set the mode of hallPin to INPUT and the mode of ledPin to OUTPUT. This is done using the pinMode() function.

void setup() {
  pinMode(hallPin, INPUT);
  pinMode(ledPin, OUTPUT);
}

Loop function

Inside the loop() function, we first read the value of the hallPin using the digitalRead() function. The value read from the pin will be LOW when a magnetic field is detected and HIGH otherwise. Watch out for this inverted logic.

int val = digitalRead(hallPin);

Next, we use the digitalWrite() function to control the state of the ledPin based on the value read from the Hall Effect sensor. If the value is HIGH, it means there is no magnetic field detected and we set the ledPin to LOW, turning off the LED. Otherwise we set the ledPin to HIGH, which turns on the LED.

digitalWrite(ledPin, val ? LOW : HIGH);

Finally, we introduce a small delay of 10 milliseconds using the delay() function. This delay allows for stable readings and prevents rapid fluctuations in the LED state.

delay(10);

And that’s it. Now you have a simple magnetic switch that reliably and quickly detects magnetic fields.

You could use the code above to build a start or end switch for a DC or Stepper Motor. Let’s say you want to rotate a motor to a certain position – for instance, a defined start position of a stepper motor that drives a clock after a power outage. Or the end position of a stepper motor for a 3D printer.

For this you simply attach a magnet on the motor to mark the desired position and attach the Hall sensor nearby. If the sensor detects the magnet it stops the motor. To actually implement this you would need to switch a relay instead of an LED, since motors generally cannot be controlled directly from an Arduino output. Have a look at our tutorial on How To Use A Relay With Arduino, if you aim to do this.

In the next section, we use the same principle to measure the rotational speed of a motor.

Example 2: A Simple Tachometer

In the first example we wrote the code to detect when the magnet is near the sensor. If we count how often that happens within a certain timeframe, we can measure the speed of a rotating object. We build this tachometer by attaching the magnet somewhere on the rotating object and whenever it passes the Hall Effect sensor we count it as one rotation.

const int hallPin = 2;
const int maxCnt = 100;

void setup() {
  Serial.begin(9600);
  pinMode(hallPin, INPUT);
}

void loop() {
  unsigned long start = micros();
  int old = 1;
  int cnt = 0;
  while (cnt < maxCnt) {
    int val = digitalRead(hallPin);
    if (!val && val != old) cnt++;
    old = val;
  }
  float seconds = (micros() - start) / 1000000.0;
  float rpm = cnt / seconds * 60.0;
  Serial.print("rpm: ");
  Serial.println(rpm);
}

This is what the above code does. Let’s take a closer look and understand how it works in detail.

Constants and Variables

The code starts by defining two constants: hallPin and maxCnt. The hallPin constant specifies the pin to which the Hall Effect sensor is connected, and the maxCnt constant sets the maximum count value. We will be counting max counts and then measure the elapsed time to calculate the speed.

const int hallPin = 2;
const int maxCnt = 100;

Setup function

In the setup() function, we initialize the serial communication with a baud rate of 9600 using Serial.begin(9600). We also set the hallPin as an input pin using pinMode(hallPin, INPUT).

void setup() {
  Serial.begin(9600);
  pinMode(hallPin, INPUT);
}

Loop function

The loop() function is where the main functionality of the tachometer is implemented. We start by getting the current time using micros() and storing it in the start variable. We also initialize the old sensor reading variable to 1 and the cnt variable to 0.

void loop() {
  unsigned long start = micros();
  int old = 1;
  int cnt = 0;

Inside the while loop, the code reads the value of the hallPin using digitalRead(hallPin) and stores it in the val variable. If the value is 0 (magnetic field detected) and different from the previous value (val != old), it increments the cnt variable.

  while (cnt < maxCnt) {
    int val = digitalRead(hallPin);
    if (!val && val != old) cnt++;
    old = val;
  }

Now this is important. We cannot simply count every time we detect a 0 (magnet detected) because we would count multiple times while the magnet is near. We must only count when there is a change in state. Either from 1 to 0 (Falling Edge) or 0 to 1 (Raising Edge). Have a look at the picture below that shows the Serial Plotter output with two detections of the magnet with different durations.

Falling and raising flanks in detection signal
Falling and raising flanks in detection signal

In the code above we only count when the sensor transitions from 0 (!val) to 1 (val !=old). In short, we detect the raising edge of the signal.

After the while loop, we calculate the time elapsed in seconds by subtracting the start time from the current time using micros() and dividing it by 1000000.0. From that we calculate the RPM (rotations per minute) by dividing the cnt by the elapsed time in seconds and multiplying it by 60 (a minute).

  float seconds = (micros() - start) / 1000000.0;
  float rpm = cnt / seconds * 60.0;

Finally, the code prints the calculated RPM value to the serial monitor using Serial.print() and Serial.println().

  Serial.print("rpm: ");
  Serial.println(rpm);
}

To try the code, attach a magnet in the right orientation to a rotating object let’s say a cooling fan. Then bring the sensor close enough and ensure that the magnet passes the sensor in each rotation. If you now run the code, you should be able to measure the RPM of the fan.

Measuring the speed of a fan using the A3144 sensor
Measuring the speed of a fan using the A3144 sensor

The code above should will work fine. But for faster rotating objects and more accurate measurements we can do even better by using interrupts. How that works, I’ll show you in the next section.

Example 3: A Faster Tachometer using Interrupts

The code example above uses a loop to poll the state of the Hall Effect sensor and if we detect a change in state from 0 to 1 we count this as one rotation. However, the speed of the Arduino is limited. If the object rotates faster then we can poll, we will miss changes in state and undercount.

Interrupts provide a solution for this problem. Instead of polling and looking for state changes we attach an interrupt to the sensor pin and whenever the state changes an ISR (interrupt service routine) is called. This will be a lot faster and the code is even simpler. Have a look:

const int hallPin = 2;
const int maxCnt = 100;

volatile int cnt = 0;

void count() {
  cnt++;
}

void setup() {
  Serial.begin(9600);
  pinMode(hallPin, INPUT);
  attachInterrupt(digitalPinToInterrupt(hallPin), count, FALLING);
}

void loop() {
  unsigned long start = micros();
  while (cnt < maxCnt) ;
  float seconds = (micros() - start) / 1000000.0;
  float rpm = cnt / seconds * 60.0;
  Serial.print("rpm: ");
  Serial.println(rpm);
  cnt = 0;
}

Let’s dive in and understand how this works in detail.

Constants and Variables

The code starts by defining the constants and variables.

const int hallPin = 2;
const int maxCnt = 100;

volatile int cnt = 0;

As before the hallPin constant specifies the pin to which the Hall Effect sensor is connected and the maxCnt constant sets the maximum count. The cnt variable is used to keep track of the number of rotations. Note that it is declared as “volatile“. That is necessary because we are going to use it inside of an interrupt service routine. More about this in the next section.

Count Function

The count() function is the interrupt service routine (ISR) that is called whenever the Hall Effect sensor detects a falling edge on the hallPin. ISRs should be as short as possible. In our case the function just increments the cnt variable by one, which is great for an ISR.

void count() {
  cnt++;
}

Setup Function

In the setup() function, we initialize the serial communication and set the hallPin as an input. Most importantly, we attach an interrupt to the hallPin that triggers the count() function on a falling edge.

Note that not all pins can be used for interrupts! It will depend on the microcontroller. In case of the Arduino Uno only pins 2 and 3 can be used for interrupts.

void setup() {
  Serial.begin(9600);
  pinMode(hallPin, INPUT);
  attachInterrupt(digitalPinToInterrupt(hallPin), count, FALLING);
}

Loop Function

In the loop() function we get the current time using the micros() function. Then, we enters a while loop that simply waits until the cnt variable reaches the maxCnt value. This ensures that we have counted enough rotations to calculate the speed accurately. Note that the counter is incremented outside the loop within the interrupt service routine count(). In short the Arduino is waiting in the while loop, while in parallel reacting to interrupts by calling the count() function.

If we have received enough counts the while loop exists. We then calculate the RPM (rotations per minute) as before and after resetting the cnt variable to zero, the main loop starts again.

void loop() {
  unsigned long start = micros();
  while (cnt < maxCnt) ;
  float seconds = (micros() - start) / 1000000.0;
  float rpm = cnt / seconds * 60.0;
  Serial.print("rpm: ");
  Serial.println(rpm);
  cnt = 0;
}

For more accurate but slower measurements of the rotational speed increase the value of the maxCnt constant. You will be averaging over more rotations, which will give you more stable readings but it will take longer. A lower maxCnt value, will give you faster RPM readings but they will fluctuate more.
That’s it! With this code, you can build a tachometer using an Arduino and a Hall Effect sensor to measure the speed of a rotating object.

Conclusion

In this tutorial, we have learned how to build a tachometer using a Hall Effect sensor and an Arduino. We started by understanding the basics of Hall Effect sensors and then introduced the A3144 Hall Effect sensor, which is commonly used in speed measurement applications.

Then we tested the A3144 sensor to ensure its functionality and proceeded to connect it to the Arduino. We explored three different examples to demonstrate the versatility of the sensor.

In example 1, we used the A3144 sensor as a magnetic switch, detecting the presence or absence of a magnetic field. This can be useful in various applications such as door/window sensors or proximity detection.

In example 2, we built a simple tachometer using the A3144 sensor. By attaching the sensor to a rotating object, we were able to measure its speed in revolutions per minute (RPM). This can be handy in applications like monitoring the speed of a motor or a fan.

In example 3, we improved upon the simple tachometer by utilizing interrupts. By configuring the Arduino to trigger an interrupt whenever the A3144 sensor detects a magnet, we achieved more accurate and reliable RPM measurements.

By following this tutorial, you should now have a good understanding of how to use the A3144 Hall Effect sensor with an Arduino to build a tachometer. If you have any questions or need further assistance, feel free to check out the frequently asked questions section.

Happy tinkering!

Frequently Asked Questions

Here are some commonly asked questions about building a tachometer using a Hall Effect sensor with an Arduino:

Q: What is a tachometer?

A: A tachometer is a device used to measure the speed of a rotating object. It provides information about the rotational speed in revolutions per minute (RPM).

Q: What is a Hall Effect sensor?

A: A Hall Effect sensor is a transducer that detects the presence of a magnetic field. It works on the principle of the Hall Effect, which states that when a conductor with current flowing through it is placed in a magnetic field, a voltage is generated perpendicular to both the current and the magnetic field.

Q: What are the advantages of Hall Effect sensors?

Hall effect sensors are generally immune to noise, light, or temperature. Since they have no mechanical parts they react fast and last pretty much forever. In addition, they are very small and therefore can fit in tight space.

Q: Why use a Hall Effect sensor for a tachometer?

A: Hall Effect sensors are commonly used in tachometers because they can accurately measure the speed of rotating objects without physical contact. This makes them ideal for applications where non-intrusive speed measurement is required.

Q: Why is the Hall Effect sensor not reacting?

A: Make sure that everything is correctly wired up. The A3144 is a unipolar Hall Effect Sensor and will react only to one pole of the magnet. Check that your magnet is strong enough.

Q: Can I use the A3144 to measure the strength of a magnetic field

The A3144 is a switching Hall Effect sensor and not suitable for that. You would need a linear Hall Effect sensor

Q: Can I use the A3144 with an ESP32

Not directly. The A3144 operates with 5V while the ESP operates with 3.3V. You would need a voltage level shifter.

Neil

Friday 22nd of November 2024

Hi

Great article!

it looks like the yellow wire on both your 2 breadboard diagrams are connect at the wrong end of the resistor..

Also as the output is open collector, this device can be used with an ESP32, you just need to connect the resistor to 3.3 volts rather than 5 volts - of course the '+' pin still needs to be connected to 5 volts.

Stefan Maetschke

Saturday 23rd of November 2024

Hi Neil, you are right on both accounts! Thank you for pointing this error out. Much appreciated! The wiring diagrams have been corrected. Thanks

Mike

Thursday 31st of October 2024

This is an excellent tutorial. I really appreciate how you walk through the code step by step.

Stefan Maetschke

Friday 1st of November 2024

Thanks, much appreciated.

Michael

Monday 3rd of June 2024

Hi, I have a problem and I want to measure the rpm of a 6V DC motor, how can I do it, do I have to put a small magnet on the shaft or directly to the motor housing?

Michael

Monday 3rd of June 2024

@Stefan Maetschke, I understand and to connect it to the ESP32 the output signal, I had that doubt since you mentioned it at the end.

Stefan Maetschke

Monday 3rd of June 2024

Hi, for measuring rpm you have to attach a magnet to a moving part of the motor. Could be the shaft, or a cog. Placing it on the housing doesn't work, since it doesn't move.

Michael Sailor

Wednesday 14th of February 2024

Hi, I have a sixslotted wheel that I am using in pace of the hall sensor. I am using an Arduino Nana ESP32 board and the reading I am getting are times the value that I read with my digital tach. What could be the problem?

Stefan Maetschke

Monday 19th of February 2024

Hi, without seeing the code and the hardware setup it is difficult to tell. You are mentioning a "six slotted wheel". Are you using six magnets and one Hall sensor? Or is your digital tachometer reading six times higher speed due to the six slotted wheel?

Art

Sunday 26th of November 2023

Thnks, code (for old arduino nano) needs pinMode(hallPin,INPUT); instead of pinMode(hallPin)

Stefan Maetschke

Monday 27th of November 2023

Indeed, Thanks! Code has been fixed.