Engineer's Asylum

How to make an Arduino based Metal Detector?

What are Metal Detectors?

According to wikipedia, a metal detector is an electronic instrument which detects the presence of metal nearby. Metal detectors are useful for finding metal inclusions hidden within objects, or metal objects buried underground. They often consist of a handheld unit with a sensor probe which can be swept over the ground or other objects. If the sensor comes near a piece of metal this is indicated by a changing tone in earphones, or a needle moving on an indicator. Usually, the device gives some indication of distance; the closer the metal is, the higher the tone in the earphone or the higher the needle goes.

Working of a Metal Detector?

The simplest form of any metal detector consists of an oscillator producing an alternating current that passes through a coil producing an alternating magnetic field. If a piece of electrically conductive metal is close to the coil, eddy currents will be induced in the metal, and this produces a magnetic field of its own. If another coil is used to measure the magnetic field (acting as a magnetometer), the change in the magnetic field due to the metallic object can be detected.

tank_circuit

In the above circuit, the series inductor & Capacitor form a tank circuit. In a tank circuit, energy is passed repeatedly between the capacitor and inductor, resulting in oscillation. Current discharged from these capacitor flows through the inductor, when the capacitor is completely discharged the inductor’s decreasing magnetic field maintains the current flow. The capacitor will then charge with the opposite polarity, and when the magnetic field has completely collapsed, the capacitor will discharge, resulting in current flow in the direction opposite to that of the original current. This cycle continues.

The inductor of the above tank circuit forms the detector of the metal detector. When metallic material approaches the inductor ( coil ), it enters the magnetic field created by the inductor. This changes the magnetic permeability of the inductor’s core, causing the inductance of the coil to change. The change in inductance, in turn, changes the frequency at which tank circuit oscillates. This change in oscillation helps us to identify a metallic objects.

Circuit Schematics

The entire circuits operates on three AA batteries.The coils for the inductor is made from 50 wraps of 26 AWG wire around a spool of 5.5 inches in diameter. There is 10k sensitivity pot to adjust the sensitivity of the metal detector. With the lowest sensitivity, the metal detector is able to pick up large items like cans, cell phones, and iron materials within a few inches away from the coil. On the highest sensitivity, the detector able to detect smaller items like steel rings, screws, and coins within the same proximity.The range of the metal detector can be increased by increasing the number of wire wraps in the inductor coil.

Arduino Source Code for Metal Detector

/*
 * Copyright (c) 2016 Evan Kale
 * Media: @EvanKale91
 * Email: [email protected]
 * Website: www.ISeeDeadPixel.com
 *          www.evankale.blogspot.ca
 *          www.youtube.com/EvanKale91
 *
 * This file is part of ArduinoMetalDetector.
 *
 * ArduinoMetalDetector is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

// Number of cycles from external counter needed to generate a signal event
#define CYCLES_PER_SIGNAL 5000

// Base tone frequency (speaker)
#define BASE_TONE_FREQUENCY 280

// Frequency delta threshold for fancy spinner to trigger
#define SPINNER_THRESHOLD 700

// Pin definitions
#define SENSITIVITY_POT_APIN 1
#define SPEAKER_PIN 2
#define SPINNER_PIN 9
#define TRIGGER_BTN_PIN 11
#define RESET_BTN_PIN 12

unsigned long lastSignalTime = 0;
unsigned long signalTimeDelta = 0;

boolean firstSignal = true;
unsigned long storedTimeDelta = 0;

// This signal is called whenever OCR1A reaches 0
// (Note: OCR1A is decremented on every external clock cycle)
SIGNAL(TIMER1_COMPA_vect)
{
  unsigned long currentTime = micros();
  signalTimeDelta =  currentTime - lastSignalTime;
  lastSignalTime = currentTime;

  if (firstSignal)
  {
    firstSignal = false;
  }
  else if (storedTimeDelta == 0)
  {
    storedTimeDelta = signalTimeDelta;
  }

  // Reset OCR1A
  OCR1A += CYCLES_PER_SIGNAL;
}

void setup()
{
  // Set WGM(Waveform Generation Mode) to 0 (Normal)
  TCCR1A = 0b00000000;
  
  // Set CSS(Clock Speed Selection) to 0b111 (External clock source on T0 pin
  // (ie, pin 5 on UNO). Clock on rising edge.)
  TCCR1B = 0b00000111;

  // Enable timer compare interrupt A (ie, SIGNAL(TIMER1_COMPA_VECT))
  TIMSK1 |= (1 << OCIE1A);

  // Set OCR1A (timer A counter) to 1 to trigger interrupt on next cycle
  OCR1A = 1;

  pinMode(SPEAKER_PIN, OUTPUT);
  pinMode(SPINNER_PIN, OUTPUT);
  pinMode(TRIGGER_BTN_PIN, INPUT_PULLUP);
  pinMode(RESET_BTN_PIN, INPUT_PULLUP);
}

void loop()
{
  if (digitalRead(TRIGGER_BTN_PIN) == LOW)
  {
    float sensitivity = mapFloat(analogRead(SENSITIVITY_POT_APIN), 0, 1023, 0.5, 10.0);
    int storedTimeDeltaDifference = (storedTimeDelta - signalTimeDelta) * sensitivity;
    tone(SPEAKER_PIN, BASE_TONE_FREQUENCY + storedTimeDeltaDifference);

    if (storedTimeDeltaDifference > SPINNER_THRESHOLD)
    {
      digitalWrite(SPINNER_PIN, HIGH);
    }
    else
    {
      digitalWrite(SPINNER_PIN, LOW);
    }
  }
  else
  {
    noTone(SPEAKER_PIN);
    digitalWrite(SPINNER_PIN, LOW);
  }

  if (digitalRead(RESET_BTN_PIN) == LOW)
  {
    storedTimeDelta = 0;
  }
}

float mapFloat(int input, int inMin, int inMax, float outMin, float outMax)
{
  float scale = (float)(input - inMin) / (inMax - inMin);
  return ((outMax - outMin) * scale) + outMin;
}

Code Source: https://github.com/evankale/ArduinoMetalDetector

Reference

  1. https://en.wikipedia.org
  2. https://www.allaboutcircuits.com
  3. https://www.khanacademy.org
  4. http://www.electricalbasicprojects.com
4 Likes