Counting turns
Fix a magnet to a wheel, put the block beside it, and count each time SIGNAL goes LOW. It needs no debouncing, because nothing bounces. It does need the wheel slow enough that every pass lasts longer than the chip's 22 ms between looks: a few hundred turns a minute, not thousands.
Count the arrival
A pass is not "SIGNAL is LOW". SIGNAL is LOW for as long as the magnet is in
range, and loop() comes round thousands of times in that time. A pass is
the moment SIGNAL changes to LOW. So the sketch keeps the last reading,
and counts only when the magnet is there now and was not last time.
The push button's counter does the same thing and has to add a debounce window, because metal contacts bounce. This one does not: there are no contacts, and the chip's hysteresis stops a magnet at the edge of range from flickering. One arrival, one change.
How fast is too fast
The chip looks at the field about every 22 ms. For a pass to be counted for certain, a look has to land while the magnet is in range, and another while it is out of range, before the next pass. So both stretches have to last at least one scan period.
How long the magnet is in range depends on the magnet, the gap and how far it is from the hub. Call it the dwell: the share of each turn it spends in range. Pick one in the figure and slide the speed up:
- 10 % of a turn, a small magnet near the rim: safe to about 270 rpm.
- 25 %: safe to about 680 rpm.
- 50 %, half the turn in range and half out: about 1360 rpm, around 22 passes a second. No magnet arrangement does better with one look every 22 ms.
Those are at the typical scan period, and the datasheet gives no maximum, so keep well under them. Past the line, turns go missing without any sign in the output. That makes this block right for a slowly turning wheel, a turntable or a hand crank, and wrong for a fan or a motor shaft.
What the sketch prints
turns: 1
turns: 2 rpm: 62
turns: 3 rpm: 60
turns: 4 rpm: 61Each speed is timed from one pass to the next. The chip can report each arrival up to about 22 ms late, so a single reading at speed is only approximate; average several turns for a steadier figure.
The code
Counts each pass of a magnet by watching for SIGNAL to change to LOW, and prints the count and the speed worked out from the time since the last pass. No library, no delay(), no debouncing.
/*
Hall Effect Sensor - counting turns TK18 / /p/tk18
Wiring. Count from the square pad on the TinkerBlock board, parts
up, header at the bottom:
GND -> GND
VCC -> 5V on an Uno; 3V3 on an ESP32, ESP32-S3 or Pico
(with no magnet, SIGNAL sits at whatever VCC is)
NC -> nothing (unconnected on the board)
SIGNAL -> D2 on an Uno, GPIO 25 on an ESP32, GPIO 4 on an
ESP32-S3, GP15 on a Raspberry Pi Pico
One magnet on the wheel, a flat face passing the small chip at
the top left of the block.
Arduino IDE
Tools > Board your board, e.g. ESP32S3 Dev Module
Tools > Port the one that appears when you plug in
Tools > USB CDC On Boot Enabled (ESP32-S3 only)
No library needed.
*/
// The GPIO number SIGNAL is wired to.
// Uno: 2. ESP32: 25. ESP32-S3: 4. Pico: 15.
const int HALL_PIN = 4;
bool lastMagnet = false; // was the magnet there last time round?
unsigned long turns = 0;
unsigned long lastPass = 0; // millis() at the last pass
void setup() {
Serial.begin(115200);
pinMode(HALL_PIN, INPUT); // the chip drives SIGNAL both ways
}
void loop() {
bool magnet = digitalRead(HALL_PIN) == LOW; // active low
if (magnet && !lastMagnet) { // the magnet has just arrived
unsigned long now = millis();
turns++;
Serial.print("turns: ");
Serial.print(turns);
if (lastPass != 0) {
Serial.print(" rpm: ");
Serial.print(60000.0 / (now - lastPass), 0);
}
Serial.println();
lastPass = now;
}
lastMagnet = magnet;
}No debounce window: a Hall switch has no contacts to bounce, and the chip's hysteresis keeps a magnet at the edge from flickering. What limits it is the chip's 22 ms between looks: every pass must be in range longer than that, and out of range longer than that too.
The same counter in MicroPython: watch for the pin to change to 0, count it, and work out the speed from the time since the last pass.
"""
Hall Effect Sensor - counting turns, MicroPython TK18 / /p/tk18
Wiring. Count from the square pad on the TinkerBlock board, parts
up, header at the bottom:
GND -> GND
VCC -> 3V3 (never 5V: with no magnet, SIGNAL sits at VCC)
NC -> nothing (unconnected on the board)
SIGNAL -> GPIO 25 on an ESP32, GPIO 4 on an ESP32-S3,
GP15 on a Raspberry Pi Pico
One magnet on the wheel, a flat face passing the small chip at
the top left of the block.
Thonny
Run > Configure interpreter MicroPython (ESP32) or
MicroPython (Raspberry Pi Pico)
Save it to the board as main.py to run it on every power-up.
Nothing to install: machine and time are built in.
"""
from machine import Pin
import time
# The GPIO number SIGNAL is wired to. ESP32: 25. ESP32-S3: 4. Pico: 15.
HALL_PIN = 4
hall = Pin(HALL_PIN, Pin.IN) # the chip drives SIGNAL both ways
last_magnet = False
turns = 0
last_pass = None
while True:
magnet = hall.value() == 0 # active low
if magnet and not last_magnet: # the magnet has just arrived
now = time.ticks_ms()
turns += 1
if last_pass is None:
print("turns:", turns)
else:
gap = time.ticks_diff(now, last_pass)
print("turns:", turns, " rpm:", round(60000 / gap))
last_pass = now
last_magnet = magnetMicroPython's loop is slower than compiled Arduino code, but it still reads the pin hundreds of times for every look the chip takes, so it misses nothing the chip saw. Stop it with Ctrl-C in Thonny's shell.
When it does not work
The magnet is passing the chip in less time than the chip takes between looks, about 22 ms, and some passes fall between two of them. Slow the wheel, or make each pass last longer: a bigger magnet, a closer gap, or the magnet nearer the hub, where it moves more slowly.
Two magnets, or one magnet close enough to switch the chip on two parts of its path, such as a bar magnet whose two ends both pass the chip. Use one small disc magnet with a flat face towards the chip. The chip itself does not bounce.
Each reading is timed from one pass to the next, and SIGNAL can change up to about 22 ms after the magnet arrives. At 300 rpm a turn takes 200 ms, so that alone moves one reading by about a tenth. Average several turns for a steadier number.
You can, on D2 on an Uno, but it gains nothing here. SIGNAL changes at most about 45 times a second, because that is how often the chip looks, and a loop that does nothing else reads the pin far faster than that.
A magnet on the door, the block on the frame, and a sketch that times how long it has been open.
A door alarm →Edit this page — content/books/hall-effect-sensor/counting-turns.mdx
Questions about this product
See what other owners have asked, and read their solutions.
Hall Effect Sensor
Loading discussions…
Discuss this article
Ask about this page. The answer stays here, on the page it belongs to, for whoever hits the same wall next.