edge lab LIVE! starts Tuesday in Munich. Grab a workshop seat and take home the board you build on. Code FRIEND-HACKSTER saves 20%. () Learn more!
Marco Zonca
Published © GPL3+

Magnetic Field Meter range +- 200mT (milliTesla)

A stable instrument with display, LED and buzzer to feel the Magnetic Field live.

IntermediateFull instructions provided3,730
Magnetic Field Meter range +- 200mT (milliTesla)

Things used in this project

Hardware components

Arduino Nano R3
Arduino Nano R3
×1

Story

Read more

Schematics

PCB OVERVIEW

PCB top solder face

PCB bottom solder face

PCB top components

PCB bottom components

Fritzing proto board schematic

Code

Arduino Sketch

Arduino
/*
 This sketch acts as a Magnetic Field Meter, by Marco Zonca, 3/2021
 Arduino Nano as 5V MPU, UGN3503UA magnetic sensor, i2c Oled 128x32 display, a LED,
 one button, an active buzzer and a few resistors;

 Magnetic Field Meter, output in milliTesla (mT)
  
 from sensor +- 1.3 mV = +- 1 Gauss = +- 0.1 mT
 from sensor 2.5V = 0 (0-2.5V = -2500 to 0 mV, 2.5-5V = 0 to 2500mV)  
*/

#include <Wire.h>
#include <Adafruit_SSD1306.h>

Adafruit_SSD1306 display = Adafruit_SSD1306 (128, 32, &Wire, -1);

float aVal=0;
float aZero=0;
float aRead=0;
float VL=0;
float Gauss=0;
float mTesla=0;
float fTot=0;
float fNr=0;
float fMax=0;
float fMin=0;
float fAvr=0;

unsigned long fprevMillis=0;

const unsigned long fMillis=500;  // update display and average calc every 0.5 seconds
const int aValPin=14;
const int aLedPin=10;
const int aBuzPin=9;
const int aButton=15;

String mT = "  -0.0 mT";

void setup() {
  //Serial.begin(9600);
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // Display Address 0x3C for 128x32 pixels
  mT.reserve(20);
}  //setup()

void loop() {
  aRead=analogRead(aValPin);
  if (aZero==0) aZero=aRead;  // initial auto zero
  if (digitalRead(aButton)==LOW) aZero=aRead;  // forced zero with button
  aVal=(map(aRead,0,1023,0,5000)-map(aZero,0,1023,0,5000)) / 1.3;  // to milliVolt, to Gauss
  if (aVal != 0) {
    fTot=fTot+aVal;
    fNr=fNr+1;
  }
  if (aVal>fMax) fMax=aVal;  // mem max
  if (aVal<fMin) fMin=aVal;  // mem min
  if (millis() > (fMillis+fprevMillis)) showVal(); 
}  //loop()

void showVal() {
  if (fMax != 0) {
    fTot=fTot-fMax;  // average without max
    fNr=fNr-1;    
  }
  if (fMin != 0) {
    fTot=fTot-fMin;  // average without min
    fNr=fNr-1;    
  }
  if (fNr > 0) {
    aVal=fTot/fNr;  // average value
  } else {
    aVal=0;
  }
  if (aVal != aZero) {
    Gauss=aVal;
    mTesla=Gauss/10;  // to milliTesla
    VL=abs((aVal) / 10);
    if (VL>255) VL=255;
    analogWrite(aLedPin,VL);  // lights led
    analogWrite(aBuzPin,VL);  // beeps buz
    //Serial.print(roundOneDec(mTesla));
    //Serial.println("mT");
  } else {
    Gauss=0;
    mTesla=0;
    analogWrite(aLedPin,0);  // off led
    analogWrite(aBuzPin,0);  // off buz
  }
  display.clearDisplay();  // output to display
  display.setTextColor(SSD1306_WHITE);
  display.setTextSize(1);
  display.setCursor(1,1);
  display.print("Magnetic Field Meter");
  display.setTextSize(2);
  display.setCursor(8,16);
  mT="      "+String(roundOneDec(mTesla),1)+" mT";
  display.print(mT.substring(mT.length()-9));  // right alignment
  display.display();  
  
  fprevMillis=millis();
  fTot=0;
  fNr=0;
  fMin=0;
  fMax=0;
}  //showVal()

float roundOneDec(float f) {
  float y, d;
  y = f*10;
  d = y - (int)y;
  y = (float)(int)(f*10)/10;
  if (d >= 0.5) {
    y += 0.1;
   } else {
    if (d < -0.5) {
    y -= 0.1;
  }
  }
  return y;
}  //roundOneDec()

Credits

Marco Zonca
21 projects • 62 followers
"From an early age I learned to not use pointers"

Comments