Once every 22 ms · 08 of 10

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

Counting turns
The magnet is in range for
Wheel speed300 rpm
Turns in 3 s
15
Counted
15
Safe below
about 682 rpm
300 rpm, the magnet in range for 50 ms of every 200 ms turn. Both the time in range and the time out of it are longer than 22 ms, so a look lands in each and every pass is counted. Below about 682 rpm this wheel is safe, at the typical scan period.

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: 61

Each 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_count_turns.ino
/*
  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.

When it does not work

It counts correctly when slow and too few when fast.

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.

It counts two for one turn.

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.

The rpm jumps about from line to line.

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.

Can I use an interrupt instead of polling?

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.

Where this goes next

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

Community

Questions about this product

See what other owners have asked, and read their solutions.

Ask a question ↗

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.

Browse Modules and blocks on the forum