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,335
Magnetic Field Meter range +- 200mT (milliTesla)

Things used in this project

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

Marco Zonca

12 projects • 43 followers
"From an early age I learned to not use pointers"

Comments