Hall sensor

A Hall sensor feels a magnet without touching it: the A3144 switch, latches and linear sensors, wiring to an Arduino, and a steel ball over a magnet.

Hall sensor
Small black Hall sensors with three legs, round silver magnets, steel balls and a red-and-gray bar magnet with thin purple field lines

What is a Hall sensor?

Around every magnet there is a magnetic field. We can’t see it, but we notice it when a magnet pulls a nail or another magnet. The field is strongest next to the magnet’s poles, north (N) and south (S), and the further away we are, the weaker it gets.

A Hall sensor is a small chip that feels a magnetic field. It reports whether a magnet is near, without anything having to touch it. It is named after the American physicist Edwin Hall, who discovered in 1879 that a magnetic field pushes the current in a conductor slightly to one side.

Where we find them:

  • a laptop has a magnet in its lid and a Hall sensor under the keyboard, so it knows when the lid is closed;
  • many cars use Hall sensors to measure how fast the wheels and the engine turn;
  • an electric scooter uses one to know how far you press the throttle;
  • our pinball machine uses them to detect the ball in the lanes.

A Hall sensor does the same job as a reed switch, but it has no moving parts and no glass tube. It doesn’t wear out, doesn’t bounce and doesn’t break. In return it needs power, so it has three legs instead of two.

On the left an A3144 Hall sensor from the front: a small black case marked 3144 with three legs, 1 VCC, 2 GND and 3 OUT. On the right the same sensor from the side, with a magnet next to its marked face, south pole S towards it. Purple field arrows go through the sensor into the magnet's south pole

Our sensor, the A3144, is a small black case with three legs. The front has writing on it, and the legs, seen from the front, are:

  1. VCC: the supply, 5 V,
  2. GND: minus,
  3. OUT: the output, which reports to the Arduino.

The A3144 turns on when the south pole (S) of a magnet comes near its front, the side with the writing. The north pole doesn’t turn it on. If the sensor doesn’t react, turn the magnet round.

The micro:bit can feel a magnet

The micro:bit has a compass sensor, which also feels a magnetic field. The magnetic force (µT) block in the Input category gives the field's strength in microteslas. Show it on the display and bring a magnet near the micro:bit: the number shoots up. The Earth's magnetic field, which turns a compass needle, is only about 50 µT.

Three kinds of Hall sensor

  • A switch (A3144): its output turns on when the field is strong enough, and off when the magnet goes away. We use it for the ball in the pinball machine.
  • A latch (for example the US1881): a south pole turns it on, and it stays on even when the magnet goes away, until a north pole comes. With a ring of alternating poles it counts the turns of a motor or a wheel.
  • A linear sensor (for example the 49E): it doesn’t only say yes or no, but how strong the field is. Without a magnet it gives about 2.5 V, more with one pole and less with the other. The Arduino reads it with analogRead().

Strong magnets

Small neodymium magnets are very strong. Two of them leap at each other and can pinch a finger. Keep them away from phones and cards with a magnetic stripe. Never put magnets in your mouth: two swallowed magnets can pull together through the walls of the gut and cause serious injury.

The Hall sensor at the Arduino workshop

From here on, this page is for the Arduino workshop. We meet the Hall sensor with a magnet and a steel ball in the lesson Detecting the ball.

Wiring

Schematic: inside the sensor, dashed, the Hall element, an amplifier with two switching points and an NPN transistor whose collector is the OUT pin and whose emitter is GND. The sensor's VCC is on 5V. Inside the Arduino, dashed, the built-in pull-up resistor from 5V to D9, turned on by INPUT_PULLUP. The sensor's OUT is connected to D9
Inside the sensor there are three parts: the Hall element, which gives a tiny voltage in proportion to the field, an amplifier that compares this voltage with a limit, and a transistor at the output. When the field is strong enough, the transistor turns on and connects OUT to GND. When it isn’t, the transistor is off and OUT isn’t connected to anything.

So the output needs a pull-up resistor, like a push button. We turn on the built-in one with pinMode(hallSensor, INPUT_PULLUP), and read the sensor like a button: LOW means a magnet or the ball, HIGH means nothing. If the wires to the sensor are long, add an external 10 kΩ pull-up resistor between OUT and 5V too.

  • The A3144 needs at least 4.5 V, so we power it from the Arduino’s 5V. It doesn’t work on the micro:bit’s 3.3 V.
  • A Hall sensor has no contacts, so it doesn’t bounce. The program reads it without debouncing.
  • Its output can only be connected to GND, and the sensor needs power, so a Hall sensor can’t go into a switch matrix like a button. In the pinball machine the Hall sensors are therefore read by a 74HC165 chip.

Two switching points

The sensor turns on at a stronger field than the one at which it turns off. The graph shows an example: the output drops to 0 V when the field rises to 25 mT, and goes back to 5 V only when it falls below 22 mT.

The output voltage against the field from 0 to 40 mT. While the field rises, the output is 5 V up to 25 mT, then drops to 0 V. While the field falls, the output stays at 0 V down to 22 mT, then goes back to 5 V. Arrows show the direction
The field is measured in milliteslas (mT). The Earth’s field is about 0.05 mT, and a small neodymium magnet has a few hundred mT at its surface. Two switching points stop flickering: when the field is right at a limit, the output doesn’t keep turning on and off, but stays as it was. We did the same in the program for the photoresistor.

The switching points differ from sensor to sensor. For the A3144 the maker only guarantees that it turns on by the time the field rises to 35 mT, and turns off by the time it falls to 5 mT. That is why each module for the pinball machine is set up on its own.

A steel ball over a magnet

A steel ball isn’t a magnet, so a Hall sensor wouldn’t notice it on its own. That is why there is a magnet under the sensor, whose field is a little too weak for the sensor. When the ball comes over the sensor, the steel pulls the field lines towards itself and the field through the sensor gets stronger:

Left: a magnet under the sensor, with field lines spreading upwards. A bar shows that the field through the sensor is weaker than the dashed limit, so the light is off. Right: a ball over the sensor gathers the field lines towards itself, the field through the sensor is stronger than the limit and the light is on
In the lesson’s module the magnet gives 20 mT, and a 15 mm ball right over the sensor raises that to 32.5 mT. The graph shows a calculation for the ball rolling over the sensor at 0.5 m/s, with switching points of 25 and 22 mT:
Top: the field through the sensor over 80 ms. While the ball is far away the field is 20 mT, and as it passes over the sensor it rises to 32.5 mT and falls again. Dashed lines are the limits of 25 and 22 mT. Bottom: the OUT pin is at 5 V, and at 0 V from 30 to 56.5 ms
The output is at 0 V for 26.5 ms: from the moment the ball is 5 mm before the sensor to the moment it is 8 mm past it. It turns off later than it turned on, because the lower limit waits for the field to fall further. That is long enough for the Arduino to be sure to see the pass. The program counts only the moment the output becomes LOW, so it counts each pass once:

// C++
int hall = digitalRead(hallSensor);
if (hall == LOW && lastHall == HIGH) {     // the ball has just arrived over the sensor
  passes = passes + 1;
}
lastHall = hall;                           // remember it for the next time round loop()

The board between the ball and the sensor must be thin. In the pinball machine it may be at most 2 mm thick, so we thin it from below there.

A linear sensor: how strong is the field?

The 49E linear sensor has the same three legs, but its output gives a voltage. Without a magnet that is about 2.5 V, half the supply, so analogRead() gives a number around 512. So the program first measures what the sensor gives without a magnet, and then prints the difference:

// C++
const int sensor = A0;                 // the output of a linear Hall sensor (49E)
const int THRESHOLD = 30;              // how much the number must change to turn the LED on

int resting = 0;                       // what the sensor gives without a magnet

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  Serial.begin(9600);
  long sum = 0;
  for (int i = 0; i < 16; i++) {       // the average of 16 readings, while no magnet is near
    sum = sum + analogRead(sensor);
    delay(10);
  }
  resting = sum / 16;
}

void loop() {
  int field = analogRead(sensor) - resting;   // one pole gives positive numbers, the other negative
  Serial.println(field);

  if (abs(field) > THRESHOLD) {
    digitalWrite(LED_BUILTIN, HIGH);   // a magnet is near, whichever pole
  } else {
    digitalWrite(LED_BUILTIN, LOW);
  }
  delay(50);
}

Connect VCC to 5V, GND to GND, and the output to A0. Upload the program and open the Serial Plotter, as described on the Arduino IDE page. Bring a magnet near with one pole, then the other: the line goes up or down, and the closer the magnet, the further it goes. The abs() function takes the number without its sign, so the LED lights for both poles. The average in setup() is taken while no magnet is near, so bring the magnet close only once the program is running.

What did we learn?

  • A Hall sensor feels a magnetic field without touching. It has no contacts, so it doesn’t wear out or bounce.
  • The A3144 has the legs VCC, GND and OUT. A magnet’s south pole facing the side with the writing turns it on.
  • The output is connected to GND when the field is strong enough, so we read it with INPUT_PULLUP, like a button: LOW means a magnet.
  • The sensor turns on at a stronger field than the one at which it turns off, so it doesn’t flicker.
  • A steel ball over a magnet strengthens the field through the sensor. A linear sensor also reports how strong the field is.

Quick quiz

1. In what way is a Hall sensor better than a reed switch, and in what way not?
It has no moving parts and no glass, so it doesn’t wear out, bounce or break. In return it needs power and has three legs instead of two.
2. You bring a magnet near an A3144 and nothing happens. What do you try first?
Turn the magnet round. Only a south pole facing the side with the writing turns the A3144 on.
3. Why do we use INPUT_PULLUP for the pin with a Hall sensor?
The sensor can only connect its output to GND. Without a magnet the output isn’t connected to anything, so the pull-up resistor holds it HIGH.
4. Why don't we debounce a Hall sensor like a button?
It has no metal contacts that could bounce. Besides, it turns on at a stronger field than the one at which it turns off, so it doesn’t flicker even at the edge.
5. A steel ball isn't a magnet. How does a Hall sensor notice it, then?
There is a magnet under the sensor, whose field is a little too weak for the sensor. The ball over the sensor gathers the field lines towards itself, so the field through the sensor gets strong enough.
6. A linear sensor gives about 512 without a magnet. What do 600 and 420 mean?
The field of one pole (600) and the field of the other pole (420), roughly equally strong. The further the number is from 512, the stronger the field.