Metal detector using Arduino

I made a metal detector using Arduino for my college project. Our metal detector is detecting the metal. Our professor told us to implement a counter to count every time the metal is detected.We implemented the count. But the problem is every time our led flickers the count goes up.
I do not know how to rectify it.
Here's the code:

const byte npulse = 12; // number of pulses to charge the capacitor before each measurement
 
const byte pin_pulse = A0; // sends pulses to charge the capacitor (can be a digital pin)
const byte pin_cap  = A1; // measures the capacitor charge
const byte pin_LED = 12; // LED that turns on when metal is detected
#define Interval  5000
int numberOfTurnOn = 0;

unsigned long msecLst = 0;

void setup() {
  Serial.begin(9600);
  pinMode(pin_pulse, OUTPUT);
  digitalWrite(pin_pulse, LOW);
  pinMode(pin_cap, INPUT);
  pinMode(pin_LED, OUTPUT);
  digitalWrite(pin_LED, LOW);
}
 
const int nmeas = 256; //measurements to take
long int sumsum = 0; //running sum of 64 sums
long int skip = 0; //number of skipped sums
long int diff = 0;      //difference between sum and avgsum
long int flash_period = 0; //period (in ms)
long unsigned int prev_flash = 0; //time stamp of previous flash
 
void loop() {
 
  int minval = 2000;
  int maxval = 0;
 
  //perform measurement
  unsigned long msec = millis ();

  long unsigned int sum = 0;
  for (int imeas = 0; imeas < nmeas + 2; imeas++) {
    //reset the capacitor
    pinMode(pin_cap, OUTPUT);
    digitalWrite(pin_cap, LOW);
    delayMicroseconds(40);
    pinMode(pin_cap, INPUT);
    //apply pulses
    for (int ipulse = 0; ipulse < npulse; ipulse++) {
      digitalWrite(pin_pulse, HIGH); //takes 3.5 microseconds
      delayMicroseconds(3);
      digitalWrite(pin_pulse, LOW); //takes 3.5 microseconds
      delayMicroseconds(3);
    }
    //read the charge on the capacitor
    int val = analogRead(pin_cap); //takes 13x8=104 microseconds
    minval = min(val, minval);
    maxval = max(val, maxval);
    sum += val;
 
    //determine if LEDs should be on or off
    long unsigned int timestamp = millis();
    byte ledstat = 0;
    if (timestamp < prev_flash +12) {
      if (diff > 0)ledstat = 1;
      if (diff < 0)ledstat = 2;
    }
    if (timestamp > prev_flash + flash_period) {
      if (diff > 0)ledstat = 1;
      if (diff < 0)ledstat = 2;
      prev_flash = timestamp;
    }
    if (flash_period > 1000)ledstat = 0;
 
    //switch the LEDs to this setting
    if (ledstat == 0) {
      digitalWrite(pin_LED, LOW);
    }
    if (ledstat == 1) {
      digitalWrite(pin_LED, LOW);
    }
    if (ledstat == 2) {
      digitalWrite(pin_LED, HIGH);
    }
    if(ledstat == 2) {
            if ((msec - msecLst) > Interval)  {
                msecLst = msec;
                numberOfTurnOn++;
                Serial.println (numberOfTurnOn);
            }
        }
 
 
  }
 
  //subtract minimum and maximum value to remove spikes
  sum -= minval; sum -= maxval;
 
  //process
  if (sumsum == 0) sumsum = sum << 6; //set sumsum to expected value
  long int avgsum = (sumsum + 32) >> 6;
  diff = sum - avgsum;
  if (abs(diff)<avgsum >> 100) {   //adjust for small changes
    sumsum = sumsum + sum - avgsum;
    skip = 0;
  } else {
    skip++;
  }
  if (skip > 64) {  // break off in case of prolonged skipping
    sumsum = sum << 6;
    skip = 0;
  }
 
  // one permille change = 2 ticks/s
  if (diff == 0) flash_period = 1000000;
  else flash_period = avgsum / (2* abs(diff));
}

1 Like

What is the LED telling you when it blinks?

What makes the LED flicker?

How long does the LED have to be lit for there to be metal detected? Just use the length of time the led is on to determine metal detection.

1 Like

I tried that, the metal has to be held for 5 seconds for the count to go up.

But my problem arises when the led is flickering for 5 seconds, the count goes up

I recommend that you implement (in software) a jitter filter - see "debouncing".

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.