Pocket gaussmeter on an Arduino Uno
A 49E linear Hall sensor on A0 and a 16x2 I2C LCD: the field in gauss, which pole it is, and the strongest seen since power on. The whole build, an Arduino Uno and 2 more parts, runs here in your browser on the firmware below; open it in the editor to change the wiring or the code and run it again.
BeginnerRuns in your browser. Free, and no account needed.
The code
The firmware exactly as the editor opens it. Change a line there and press Run: it compiles in the browser.
// Pocket gaussmeter: a 49E linear Hall sensor on A0, and the field on a 16x2
// I2C LCD.
//
// A0 the 49E's OUT (its VCC on 5 V, GND on GND, printed face out)
// LCD SDA -> A4 SCL -> A5 VCC -> 5 V GND -> GND
//
// The 49E puts out half its supply with no field, and moves 1.4 mV a gauss:
// up for a south pole at its printed face, down for a north pole. So
//
// gauss = (mV - zero mV) / 1.4
//
// One ADC count on 5 V is 4.89 mV, about 3.5 G: that is the meter's
// resolution. Its range ends where the output does, 0.95 V from either rail,
// about 1100 G each way; a neodymium magnet held against the face reads
// "over".
//
// # Zeroing
//
// The null is 2.50 V typical, but anything from 2.25 to 2.75 V on the sheet.
// So the meter zeroes itself at power on, with no magnet near, from the
// average of 64 readings, as a real one does when you press its zero button.
//
// Everything is whole numbers: this board has no floating point to spare.
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
const int HALL = A0;
// mV per count x 1000, on 5 V: 5000 / 1023.
const long UV_PER_COUNT = 4888;
// Sensitivity in microvolts per gauss.
const long UV_PER_GAUSS = 1400;
// Where the output stops: 0.95 V from either rail, as counts.
const int LOW_END = 195;
const int HIGH_END = 828;
LiquidCrystal_I2C lcd(0x27, 16, 2);
long zero4 = 0; // the null, in quarter counts
long peak = 0;
long readQuarters(int n) {
long sum = 0;
for (int i = 0; i < n; i++) sum += analogRead(HALL);
return sum * 4 / n;
}
void setup() {
Serial.begin(115200);
Serial.println("Mokxi Arduino Uno: pocket gaussmeter");
lcd.init();
lcd.backlight();
lcd.print("Zeroing...");
zero4 = readQuarters(64);
Serial.print("zero at count ");
Serial.println(zero4 / 4);
lcd.clear();
}
void loop() {
long raw4 = readQuarters(8);
int raw = (int)(raw4 / 4);
bool over = raw <= LOW_END || raw >= HIGH_END;
long gauss = (raw4 - zero4) * UV_PER_COUNT / 4 / UV_PER_GAUSS;
long size = gauss < 0 ? -gauss : gauss;
if (size > peak) peak = size;
lcd.setCursor(0, 0);
if (over) {
lcd.print("over range ");
} else {
lcd.print(size);
lcd.print(" G ");
if (size < 5) {
lcd.print("no field ");
} else {
lcd.print(gauss > 0 ? "SOUTH " : "NORTH ");
}
}
lcd.setCursor(0, 1);
lcd.print("peak ");
lcd.print(peak);
lcd.print(" G ");
Serial.print("field ");
Serial.print(gauss);
Serial.println(over ? " G (over)" : " G");
delay(250);
}
Parts list
4 parts, plus the jumper wires. Every one is in the editor's parts bin.
How it is wired
5 connections, pin by pin, read from the circuit itself. Each line is one set of pins joined together, by a jumper wire or a breadboard strip.
- Arduino Uno R3 pin 5V; Hall sensor, 49E linear pin VCC; Character LCD with I2C backpack pin VCC
- Ground: Arduino Uno R3 pin GND; Hall sensor, 49E linear pin GND; Character LCD with I2C backpack pin GND
- Arduino Uno R3 pin A0; Hall sensor, 49E linear pin OUT
- Arduino Uno R3 pin A4; Character LCD with I2C backpack pin SDA
- Arduino Uno R3 pin A5; Character LCD with I2C backpack pin SCL
Change it and keep it
Open it in the editor, change the circuit or the code, and keep your version in a free account.