Arduino金属探测器
Arduino Metal Detector Project with Code and Circuit Diagram
Metal Detector using Arduino
Metal Detector is a security device which is used for detecting metals which can be harmful, at various places like Airports, shopping malls, cinemas, etc. Previously we have made a very simple Metal detector without a microcontroller, now we are building the Metal Detector using Arduino. In this project, we are going to use a coil and capacitor which will be responsible for the detection of metals. Here we have used an Arduino Nano to build this metal detector project. This is very interesting project for all electronics lovers. Wherever this detector detects any metal near it, the buzzer starts beeping very rapidly.
金属探测器是一种安全设备,用于在机场、商场、电影院等不同场所检测可能有害的金属。 之前我们在没有微控制器的情况下制作了一个非常简单的金属探测器,现在我们使用 Arduino 制作金属探测器。 在这个项目中,我们将使用一个线圈和电容器来检测金属。 在这里,我们使用 Arduino Nano 来制作这个金属探测器项目。 对于所有电子爱好者来说,这是一个非常有趣的项目。 只要探测器探测到附近有金属,蜂鸣器就会发出急促的蜂鸣声。
Required Components:
The following are the components that you would need to build a simple DIY metal detector using Arduino. All these components should be easily available in your local hardware shop.
- Arduino (any)
- Coil
- 10nF capacitor
- Buzzer
- The 1k resistor
- 330-ohm resistor
- LED
- 1N4148 diode
- Breadboard or PCB
- Connecting jumper wire
- 9v Battery
How does a metal detector work?
Whenever some current passes through the coil, it generates a magnetic field around it. And the change in the magnetic field generates an electric field. Now according to Faraday’s law, because of this Electric field, a voltage develops across the coil which opposes the change in magnetic field and that’s how Coil develops the Inductance, means the generated voltage opposes the increase in the current. The unit of Inductance is Henry and formula to measure the Inductance is:
每当有电流通过线圈时,线圈周围就会产生磁场。 磁场的变化会产生电场。 根据法拉第定律,由于电场的存在,线圈上会产生一个电压,与磁场的变化相抵消,这就是线圈产生电感的原因,即产生的电压与电流的增加相抵消。 电感的单位是亨利,测量电感的公式是
L
=
(
μ
ο
∗
N
2
∗
A
)
l
L = \frac{(μ_ο * N^2 * A)}{l}
L=l(μο∗N2∗A)
Where,
L- Inductance in Henries电感(亨利
μο- Permeability, its 4π10-7 for Air 空气的渗透率为
4
π
∗
1
0
−
7
4π*10^{-7}
4π∗10−7
N- Number of turns 转数
A- Inner Core Area
π
r
2
πr^2
πr2 in
m
2
m^2
m2内核面积(
π
r
2
πr^2
πr2),单位:平方米
l- Length of the Coil in meters 线圈长度(米)
When any metal comes near to the coil then coil changes its inductance. This change in inductance depends upon the metal type. It’s decreases for non-magnetic metal and increases for ferromagnetic materials like iron.
Depending on the core of the coil, inductance value changes drastically. In the figure below you can see the air-cored inductors, in these inductors, there will be no solid core. They are basically coils left in the air. The medium of flow of magnetic field generated by the inductor is nothing or air. These inductors have inductances of very less value.
当任何金属靠近线圈时,线圈的电感都会发生变化。 电感值的变化取决于金属类型。 根据线圈磁芯的不同,电感值也会发生很大变化。 在下图中,您可以看到空芯电感器。 它们基本上是留在空气中的线圈。 由电感器产生的磁场流动介质是空无一物或空气。 这些电感器的电感值非常小。
These inductors are used when the need for values of few microHenry. For values greater than few milliHenry these are not a suitable one. In below figure you can see an inductor with ferrite core. These Ferrite Core inductor has very large inductance value.
这些电感器用于需要几微亨利值的场合。 如果数值超过几毫亨利,则不适合使用这些电感器。在下图中,您可以看到一个铁氧体磁芯电感器。 这些铁氧体磁芯电感器的电感值非常大。
Remember the coil wound here is a air-cored one, so when a metal piece is brought near the coil, the metal piece acts as a core for the air cored inductor. By this metal acting as a core, the inductance of the coil changes or increases considerably. With this sudden increase in inductance of coil the overall reactance or impedance of the LC circuit changes by a considerable amount when compared without the metal piece.
So here in this Arduino Metal Detector Project, we have to find the inductance of the coil to detect metals. So to do this we have used LR circuit (Resistor-Inductor Circuit) that we already mentioned. Here in this circuit, we have used a coil having around 20 turns or winding with a 10cm diameter. We have used an empty tape roll and wind the wire around it to make the coil.
请记住,这里绕制的是空芯线圈,因此当金属片靠近线圈时,金属片就会充当空芯电感器的磁芯。 由于金属片起到了磁芯的作用,线圈的电感发生了很大的变化或增加。 随着线圈电感的突然增加,与没有金属片的情况相比,LC 电路的整体电抗或阻抗会发生相当大的变化。因此,在这个 Arduino 金属探测器项目中,我们必须找到线圈的电感值来检测金属。 为此,我们使用了前面提到的 LR 电路(电阻电感电路)。 在这个电路中,我们使用了一个直径为 10 厘米、绕 20 圈左右的线圈。 我们使用了一个空的胶带卷,将导线绕在上面制成线圈。
Circuit Diagram:
We have used an Arduino Nano for controlling whole this Metal Detector Project. A LED and Buzzer are used as metal detection indicator. A Coil and capacitor is used for the detection of metals. A signal diode is also used for reducing the voltage. And a resistor for limiting the current to the Arduino pin.
我们使用 Arduino Nano 控制整个金属探测器项目。 LED 和蜂鸣器用作金属检测指示器。 线圈和电容器用于检测金属。 一个信号二极管用于降低电压。 还有一个电阻用于限制 Arduino 引脚的电流。
Working Explanation:
Working of this Arduino Metal Detector is bit tricky. Here we provide the block wave or pulse, generated by Arduino, to the LR high pass filter. Due to this, short spikes will be generated by the coil in every transition. The pulse length of the generated spikes is proportional to the inductance of the coil. So with the help of these Spike pulses, we can measure the inductance of Coil. But here it is difficult to measure inductance precisely with those spikes because those spikes are of very short duration (approx. 0.5 microseconds) and that is very difficult to be measured by Arduino.
Arduino 金属探测器的工作原理比较复杂。 在这里,我们将 Arduino 产生的块波或脉冲提供给 LR 高通滤波器。 因此,线圈在每次转换时都会产生短尖峰。 产生的尖峰脉冲长度与线圈的电感成正比。 因此,借助这些尖峰脉冲,我们可以测量线圈的电感。 但在这里,利用这些尖峰脉冲很难精确测量电感,因为这些尖峰脉冲持续时间很短(约 0.5 微秒),Arduino 很难测量。
So instead of this, we used a capacitor that is charged by the rising pulse or spike. And it required few pulses to charge the capacitor to the point where its voltage can be read by Arduino analog pin A5. Then Arduino read the voltage of this capacitor by using ADC. After reading voltage, the capacitor quickly discharged by making capPin pin as output and setting it to low. This whole process takes around 200 microseconds to complete. For better result, we repeat measurements and took an average of the results. That’s how we can measure the approximate inductance of Coil. After getting the result we transfer the results to the LED and buzzer to detect the presence of metal. Check the Complete code given at the end of this Article to understand the working.
Complete Arduino code is given at the end of this Article. In the programming part of this project, we have used two Arduino pins, one for generating block waves to be fed in Coil and second analog pin to read capacitor voltage. Other than these two pins, we have used two more Arduino pins for connecting LED and buzzer.
You can check the complete code and Demonstration Video of Arduino Metal Detector below. You can see that whenever it detects some metal the LED and Buzzer start to blink very fastly.
因此,我们使用了一个电容器,通过上升脉冲或尖峰脉冲为电容器充电。 需要几个脉冲才能将电容器充电到 Arduino 模拟引脚 A5 可以读取其电压的程度。 然后,Arduino 通过 ADC 读取电容器的电压。 读取电压后,通过将 capPin 引脚设置为输出低电平,电容器迅速放电。 整个过程大约需要 200 微秒。 为了得到更好的结果,我们重复测量并取平均值。 这样我们就能测量出线圈的大致电感值。 得到结果后,我们将结果传送到 LED 和蜂鸣器,以检测金属的存在。 请查看本文末尾给出的完整代码以了解其工作原理。 本文末尾给出了完整的 Arduino 代码。 在本项目的编程部分,我们使用了两个 Arduino 引脚,一个用于产生输入线圈的块波,另一个模拟引脚用于读取电容器电压。 下面是 Arduino 金属探测器的完整代码和演示视频。 您可以看到,每当检测到金属时,LED 指示灯和蜂鸣器都会快速闪烁。
Code
/*
Metal Detector Arduino Code
www.circuitdigest.com
*/
#define capPin A5
#define buz 9
#define pulsePin A4
#define led 10
long sumExpect=0; //running sum of 64 sums
long ignor=0; //number of ignored sums
long diff=0; //difference between sum and avgsum
long pTime=0;
long buzPeriod=0;
void setup()
{
Serial.begin(9600);
pinMode(pulsePin, OUTPUT);
digitalWrite(pulsePin, LOW);
pinMode(capPin, INPUT);
pinMode(buz, OUTPUT);
digitalWrite(buz, LOW);
pinMode(led, OUTPUT);
}
void loop()
{
int minval=1023;
int maxval=0;
long unsigned int sum=0;
for (int i=0; i<256; i++)
{
//reset the capacitor
pinMode(capPin,OUTPUT);
digitalWrite(capPin,LOW);
delayMicroseconds(20);
pinMode(capPin,INPUT);
applyPulses();
//read the charge of capacitor
int val = analogRead(capPin); //takes 13x8=104 microseconds
minval = min(val,minval);
maxval = max(val,maxval);
sum+=val;
long unsigned int cTime=millis();
char buzState=0;
if (cTime<pTime+10)
{
if (diff>0)
buzState=1;
else if(diff<0)
buzState=2;
}
if (cTime>pTime+buzPeriod)
{
if (diff>0)
buzState=1;
else if (diff<0)
buzState=2;
pTime=cTime;
}
if (buzPeriod>300)
buzState=0;
if (buzState==0)
{
digitalWrite(led, LOW);
noTone(buz);
}
else if (buzState==1)
{
tone(buz,2000);
digitalWrite(led, HIGH);
}
else if (buzState==2)
{
tone(buz,500);
digitalWrite(led, HIGH);
}
}
//subtract minimum and maximum value to remove spikes
sum-=minval;
sum-=maxval;
if (sumExpect==0)
sumExpect=sum<<6; //set sumExpect to expected value
long int avgsum=(sumExpect+32)>>6;
diff=sum-avgsum;
if (abs(diff)<avgsum>>10)
{
sumExpect=sumExpect+sum-avgsum;
ignor=0;
}
else
ignor++;
if (ignor>64)
{
sumExpect=sum<<6;
ignor=0;
}
if (diff==0)
buzPeriod=1000000;
else
buzPeriod=avgsum/(2*abs(diff));
}
void applyPulses()
{
for (int i=0;i<3;i++)
{
digitalWrite(pulsePin,HIGH); //take 3.5 uS
delayMicroseconds(3);
digitalWrite(pulsePin,LOW); //take 3.5 uS
delayMicroseconds(3);
}
}