linear Hall sensor/Reading it/06. The first reading
Reading it · 06 of 9

The first reading

Three wires, no library, and a sketch that measures SIGNAL with no magnet near, keeps that as zero, and from then on prints the field in gauss with its sign and the pole's name. SIGNAL goes to the analog pin the NTC and ambient light books use: A0 on an Uno, GPIO 34 on an ESP32, GPIO 4 on an ESP32-S3, GP26 on a Pico.

Three wires

Three wires
Your board
VCC to
3V3
SIGNAL to
GPIO 4
Reads at rest
about 2180
GND to GND, VCC to 3V3, SIGNAL to GPIO 4, which is on ADC1, the converter that keeps working with Wi-Fi on. Not the 5V pin: from 5 V a strong field takes SIGNAL to about 4 V, and the ESP32-S3's pins run at 3.3 V. At rest it reads about 2180 of 4095.

GND to GND. VCC to your board's logic voltage: 3V3 on an ESP32, an ESP32-S3 or a Pico, 5V on an Uno. SIGNAL to an analog pin. NC stays unconnected.

The analog pin is the same in every sketch in this book, and the same as in the NTC thermistor and ambient light books: A0 on an Uno, GPIO 34 on an ESP32, GPIO 4 on an ESP32-S3, GP26 on a Pico. The two ESP32 pins are on ADC1, the converter that keeps working while Wi-Fi is on.

Zero first

The resting level differs from chip to chip and moves with the supply, so the sketch does not assume one. It measures it.

Measure the zero, then subtract it
At start
Serial Monitor
Zero
not yet
Magnet
-
Prints
-
Press run. The sketch starts, and the first thing it does is measure SIGNAL with the magnet where you left it.

setup() waits half a second, then reads SIGNAL 64 times and keeps the average as zeroMv. Every pass of loop() averages 16 readings, subtracts the zero and divides by MV_PER_GAUSS, which is 3.25 on an Uno and 2.1 on the 3.3 V boards. The result is the field in gauss, positive for the pole that raises the output.

Readings go through readMilliVolts(). On an ESP32 that is analogReadMilliVolts, which the chip corrects with its own calibration; on an Uno or a Pico it is the count scaled to the ADC's full scale.

What you should see

At 115200 the serial monitor prints the zero once, something near zero: 2500 mV on an Uno or zero: 1650 mV on a 3.3 V board. Then four lines a second: 0 G or a few gauss either side with nothing near. Bring a magnet's face to the front of the board over the chip, and the number climbs, with north or south after it once it passes 5 G. Past 460 G it adds (past the linear range).

The sketch compiles for an ESP32-S3 and an Uno. Here is the block on the owner's own boards, a magnet brought to the chip:

The TK70 on a LEGO baseplate, cabled to an Uno-format TinkerBlock board. A hand brings a small round magnet to the front of the block, over the chip, and takes it away.
The TK70 wired to a Raspberry Pi Pico on a LEGO baseplate with three jumper wires. A small round magnet is held to the front of the block and taken away.

The code

No library. setup() averages 64 readings with no magnet near and keeps them as zero; loop() averages 16, subtracts the zero and divides by the chip's millivolts per gauss. The #if picks 3.25 mV per gauss on an Uno and 2.1 on a 3.3 V board. Change HALL_PIN to the pin you wired SIGNAL to.

hall_first_reading.ino
/*
  Linear Hall Effect Sensor - first reading             TK70 / /p/tk70

  Wiring. Count from the square pad on the TinkerBlock board, parts
  up, header at the bottom:

    GND    -> GND
    VCC    -> 3V3 on an ESP32, ESP32-S3 or Pico; 5V on an Uno.
              Your board's logic voltage: a strong field takes
              SIGNAL up to about 0.8 x VCC.
    NC     -> nothing   (unconnected on the board)
    SIGNAL -> A0 on an Uno, GPIO 34 on an ESP32, GPIO 4 on an
              ESP32-S3, GP26 on a Raspberry Pi Pico

  Keep magnets away while it starts: it measures its zero then.

  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 analog pin SIGNAL is wired to.
// Uno: A0. ESP32: 34. ESP32-S3: 4. Pico: 26.
const int HALL_PIN = 4;

#if defined(ARDUINO_ARCH_AVR)
// Uno, VCC on 5V: 3.25 mV per gauss, typical; ADC full scale 5 V.
const float MV_PER_GAUSS = 3.25;
const float FULL_SCALE_MV = 5000.0;
#else
// VCC on 3V3: about 2.1 mV per gauss; Pico's ADC full scale 3.3 V.
const float MV_PER_GAUSS = 2.1;
const float FULL_SCALE_MV = 3300.0;
#endif

// Which pole, held to the front, raises the output. The data
// sheet's SOT-23 drawing says north. If a compass says otherwise,
// make this false.
const bool NORTH_RAISES = true;

float zeroMv;   // SIGNAL with no magnet near: about half of VCC

float readMilliVolts() {
#if defined(ARDUINO_ARCH_ESP32)
  return analogReadMilliVolts(HALL_PIN);   // calibrated in the chip
#else
  return analogRead(HALL_PIN) * FULL_SCALE_MV / 1023.0;
#endif
}

// The average of n readings: steadier than one.
float averageMv(int n) {
  float sum = 0;
  for (int i = 0; i < n; i++) sum += readMilliVolts();
  return sum / n;
}

void setup() {
  Serial.begin(115200);
  delay(500);

  zeroMv = averageMv(64);   // no magnet near, please
  Serial.print("zero: ");
  Serial.print(zeroMv, 0);
  Serial.println(" mV");
}

void loop() {
  float gauss = (averageMv(16) - zeroMv) / MV_PER_GAUSS;

  Serial.print(gauss, 0);
  Serial.print(" G");
  if (fabs(gauss) >= 5) {
    bool raised = gauss > 0;
    Serial.print(raised == NORTH_RAISES ? "  north" : "  south");
  }
  if (fabs(gauss) > 460) {
    Serial.print("  (past the linear range)");
  }
  Serial.println();
  delay(250);
}

Keep magnets away while it starts or resets. Positive is the pole that raises the output, north by the data sheet's drawing; flip NORTH_RAISES if a compass says otherwise. The sketch compiles for an ESP32-S3 and an Uno.

View on GitHub · blocks/tk70-linear-hall-sensor/arduino/hall_first_reading/hall_first_reading.ino @ v1.5

When it does not work

It prints a field with no magnet near.

The zero was measured with something magnetic nearby: the magnet in your hand, a steel screw, a speaker. Move them away and press reset, and the sketch measures its zero again. A few gauss either way is jitter and the Earth's field; tens is something near the board.

It prints zero: 0 mV, or about 0 G whatever I do.

The chip has no power, or SIGNAL is not on HALL_PIN. With power and no field it would print a zero near half of VCC, about 1650 mV on a 3.3 V board. Count from the square pad: GND, VCC, NC, SIGNAL.

The serial monitor stays empty on my ESP32-S3.

Set Tools > USB CDC On Boot to Enabled and upload again. Without it the S3's USB port does not bring up a serial port at boot, so the sketch runs with nowhere to print.

The MicroPython version prints a huge field on my ESP32 with nothing near.

Check the atten line is there. Without it an ESP32's ADC tops out near 1 V, the resting 1.65 V reads as full scale, and every number after is wrong. The sketch sets 11 dB, the range to about 3.1 V.

Where this goes next

What one step of your board's ADC is worth, and how far away a magnet still counts.

How much field a count is →

Edit this page — content/books/linear-hall-sensor/the-first-reading.mdx

Community

Questions about this product

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

Ask a question ↗

Linear 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 →