Minimal Arduino Metal Detector

14,401

126

30

Introduction: Minimal Arduino Metal Detector

With an Arduino, 10m of wire and a 100 Ohm resistor you can build a metal detector in 10 minutes! It is based on sound physics and works for a large range of coil sizes and shapes. The sensitivity is not enough for treasure-hunting, but it can be made into a small hand-held device that is very useful indoors to check for the presence of metals. It will help you find nails inside wood or heating pipes in the wall, and to check the composition of tools and furniture. The method can also be used as a proximity sensor for metals as part of another project.

Step 1: Make a Coil

You will need a coil of at least 20 windings but it works better with 50 or more windings. The detector is sensitive to items that are larger than about one tenth of the coil diameter, so smaller coils are better. Finally, make sure that the resistance is less than 10 Ohm. Here I describe the coil I made, but anything will go, even a 10m roll of breadboard wire.

I used AWG26 enameled wire, which has a diameter of 0.4mm and a resistance of 0.13 Ohm per meter. The wire was wound 60 turns around a candy can with a diameter of 6.3cm. Leave one turn extra length for connection leads. The wire comes at ~12m and the resistance 1.5 Ohm. I put some electric isolation tape around it and then squeezed it in an oval shape and completed covering it in isolation tape. It protects the coil and keeps it stable. Remove the isolation at the last few centimeters of the wire with sandpaper.

Step 2: Make a Prototype

Upload the attached sketch to an Arduino Uno or Nano. Connect the coil between pin 8 and pin 10 and a 100 Ohm resistor between ground and pin 8. To get sound, connect a passive buzzer in series with a 10microfarad electrolytic capacitor between ground and pin 12. Calibration can be implemented with a dangling jumper cable on ground. Connect it to pin A0 to force a recalibration.

Try it out! The built-in LED on pin 13 should start flashing when a metal object is brought nearby the coil. The buzzer will click at the same frequency.

If it doesn’t work and the LED on pin 13 is flashing with a regular pattern, you can inerpret the error from the flashing pattern:

  • Single flash: No pulse on probe pin - check connections
  • Double flash: Delay too short - try more windings
  • Triple flash: Delay too long - try fewer windings
  • Quadruple flash: No robust pulse on pulse length scan - check coil resistance

To get more detailed feedback, change “debug false” to “debug true” in the code and check the output of the serial monitor. The minimum value of the measured ‘delay’ is 5 clock cycles, but things work better if the coil has more windings, and the value of ‘delay’ is at least 20.

If there are too many false signals, you may need to reduce the sensitivity from 5000 to 2000 or 1000.

Step 3: How Does It Work?

Detailed tech talk here - feel free to skip to the next step to start building!

This metal detector works by sending pulses to a RL low-pass filter, where the ‘L’ is the inductance of the search coil, and 'R' the external 100 Ohm resistor. The Arduino measures the delay between input pulse (pin 10) and the output pulse (pin 8). This delay is proportional to the inductance of the coil. A conductor near the coil will reduce the inductance because the eddy currents oppose the external magnetic field.

The challenge is that this delay is very short: the characteristic time of an RL circuit is tau=L/R, with L in Henry and R in Ohm. The inductance of the coil we use is circa 300 microHenries, so for R=100 Ohm, tau=3microseconds. We are looking for variations in the inductance of 1 in 5000, so the time needs to be measured with a precision of better than 1 nanosecond.

The Arduino has a clock speed of 16 MHz, and the input capture feature of timer1 can provide a timestamp of a pin change with the accuracy of 1 clock cycle. One such measurement is not precise enough, but by combining a large number of measurements the precision can be improved.

Simply repeating the measurement is not enough because the quantisation error is always the same: if the delay changes from say 3.03 to 3.02 microseconds, the delay is always 48 clock cycles. To overcome this, we measure the timing of the falling edge of a short pulse, and scan this pulse length between 3 and 5 times the value of the delay found originally.

The code aims to measure the inductance 100 times per second, so that the response is quick. For a pulse delay of 25 clock cycles, timer one gets set to a repetition every 215 clock cycles, so in 10ms, a full scan of 50 pulse lengths can be repeated 15 times, and the summed delay of 750 pulses provides the measurement, providing a resolution of order 10^-4 on the delay time.

At startup, the first measurement is taken as a reference value. Whenever a measurement differs by more than a predefined threshold, a phase counter starts to increment. When the phase counter goes over maximum, a 1ms light pulse is produced and a tick is produced on the buzzer. For differences right at threshold, the frequency is 1 Hz, for differences of 10x the threshold, the frequency will be 10Hz etc. The threshold value is determined as the reference measurement divided by the value of ‘sensitivity’. So setting ‘sensitivity’ at 1000 means that the detector will react to changes in the inductance of 10^-3. For a soldered battery-operated device, (see next step) the sensitivity can be set to 5000.

Slow drifts are compensated for by incrementing or decrementing the reference value by 1 if the threshold is not exceeded. In case the reference is not good, it can be quickly zero-ed by momentarily connecting the pin A0 to ground.

Step 4: Make a Hand-held Device

To make a practical device, the detector needs to run on batteries and have a suitable housing. A large-size tic-tac box has ample space for a 9V battery, and Arduino Nano, cabling and buttons. It can be put together in an hour or two.

Required components:

  • Arduino Nano
  • 60-turn search coil
  • 9V battery and battery clip
  • 100 Ohm resistor
  • An on/off switch
  • A push-button
  • A passive buzzer
  • A 10 muF capacitor
  • 2 skewer sticks
  • 7 pieces of 8-cm stranded wire
  • Heat-shrink tube in various diameters

Tools:

  • Soldering iron
  • Wire clipper
  • Sharp tweezer
  • Hot glue gun

With the tweezers, punch holes in the lid of the tic-tac box for the leads of the on/off button, the push-button, the buzzer and the coil leads feedthrough. Apply little solder blobs on all leads. Prepare 7 pieces of stranded wire, 8cm each, strip the ends en pre-tin them.

Solder all the connections according to the provided schematic. Best is to start with the wires of the components on the lid of the box, since space is confined there. Once all is connected, the Nano and battery can be squeezed in the box.

To fix the coil, I hot-glued skewer sticks to the tic-tac box, making sure that the lid can come off to replace the battery or reprogram the Nano. Then the search coil is fixed to the skewers with ordinary scotch.

Upload the code and you are ready to go. I noticed that once soldered and powered from a battery, the stability was much better and I could change the value of the sensitivity in the code from 1000 to 5000.

The calibration button is now handily accessible: whenever the detector starts ticking without metal present, just push it and it will use the present measurement as a new reference value.

1000th Contest

Participated in the
1000th Contest

3 People Made This Project!

Recommendations

  • Reclaimed Materials Contest

    Reclaimed Materials Contest
  • Micro:bit Contest

    Micro:bit Contest
  • Robots Contest

    Robots Contest

30 Comments

0
sguidi
sguidi

5 weeks ago

Great project
Is the only one that I managed to make work as a pointer combined with my metal detector
Thanks

0
ghpille
ghpille

Question 3 months ago

Would you expect this instructable to work on a atmega2560 too? Thanks!

0
rgco
rgco

Answer 3 months ago

Yes, but the code will need many small changes, since the registers and pin numbering differ.

0
ghpille
ghpille

Reply 3 months ago

Would the fact that on the mega2560 the timer1 input capture pin isn't broken out, involve a small change in the code too? :-(

0
ghpille
ghpille

Reply 3 months ago

Switching to timer4 seems to be all what was needed. Pulsepin 7 and probepin 49 (ICP4) as those belong to timer4. Oh, almost forgot Sound (0B01000000) and Vision (0B10000000) for pins 12 and 13 on PORTB.

0
nathancasadei1806
nathancasadei1806

Question 8 months ago

Ciao, non mi fa aprire lo sketch del codice con arduino ide, non è che potete mendarmelo tramite formate di testo perfavore? Sono quasi alla fine del progetto presto vi mostrerò il risultato finale.
Grazie in anticipo

0
mm.bonora
mm.bonora

Question 8 months ago

Hi! Thanks for this awesome project!
Do you mind letting me know how to improve the detection?
I want to install it in my garage edge so when I go out with my car I can make a sound and people can know I'm pulling out with my car and prevent accidents.
But it seems like I need a powerful detector...
Could you help me?
Thanks!

0
rgco
rgco

Answer 8 months ago

You could try make the coil bigger. The maximum detection distance is circa the coil diameter. A car is a huge metal object, so even with a large coil it should be detectable. Just like those induction loops under the asphalt, they are big too. Think ~1m loop. It does not need to be circular. Reduce the number of turns, to keep the inductance similar. I would try 1m diameter, 10 loops. Good luck!

0
mm.bonora
mm.bonora

Reply 8 months ago

Thanks a lot!!! I'm gonna try and let you know!!!

0
rgco
rgco

Reply 8 months ago

OK, It's a good idea. If it works you should write it up and submit it to the microcontroller contest!

0
DocWhoK9
DocWhoK9

9 months ago

Thanks a lot. After a lot of tinkering I seem to have it working to pulse once on the LED upon detection. I used some dodgy code/thinking and some even more suspect maths. However, its working. I basically take a standard deviation (SD) then look at old versus new means for marked differences. Right now the SD is hard coded but if I find time I may try to effectively 'train' the detector then have it detect (i.e. compute the SD)...I like the simplicity of the circuit (if you discount the Arduino). I actually made an Arduino too so I may try it all together one day! Cheers :)

0
oum456
oum456

Reply 9 months ago

Hello, can you please share your thinkercad link in here?

0
DocWhoK9
DocWhoK9

Reply 9 months ago

So sorry but I don't have one. I just followed the article. 🙂

0
oum456
oum456

Reply 9 months ago

First of all, thank you for answering :)
Yes it would be really helpful if you could share the updated code. Thank you for suggesting it I really appreciate it.

0
DocWhoK9
DocWhoK9

Reply 9 months ago

Ok, please allow me a little time & somehow I'll publish it either here or elsewhere then let you know... Cheers.

0
oum456
oum456

Reply 9 months ago

Thank you so much for your help :)

0
DocWhoK9
DocWhoK9

Reply 9 months ago

I think what you'd really need to update this along the lines I mentioned in my first comment would be the updated software? I could put that on my GitHub & provide the link. It's just hacked together so there's lots of room for improvement but it seems to work as stated. Let me know & I can try to find time. Cheers.

0
luketaiwan2019
luketaiwan2019

Question 9 months ago

Can I use it as a capacitor?(100uf)

螢幕擷取畫面 2021-01-02 101809.png