본문 바로가기
life.hack

아두이노 금속 탐지기(Arduino Metal Detector) 만들기

by 조브 2020. 6. 3.

 

아이들과 모래밭에서 금속 탐지기로 보물찾기 놀이를 하면 재미있을 것 같습니다.

 

 

 

아두이노로 금속 탐지기를 만들어 봅니다.

 

 

 

구글神 에게  "arduino metal detector" 에 대해 여쭤봅니다. 아니라 다를까 만들어 놓은 분이 있습니다. 회로가 간단해 보이는 아래 사이트를 선택합니다.

 

https://circuitdigest.com/microcontroller-projects/arduino-metal-detector-circuit-code

 

Arduino Metal Detector Project with Code and Circuit Diagram

Next post Smart Blind Stick using Arduino

circuitdigest.com

 

 

 

대략적인 원리는 금속이 가까이 오면 코일의 인덕턴스가 변하게 됩니다. 그럼 인덕턴스의 변화를 측정하면 되는데, 인덕턴스의 값을 측정하기 위해 코일에 펄스를 인가합니다. 펄스를 인가하면 전압 피크가 발생합니다. 이 피크가 발생하는 시간을 알면, R값을 알고 있으므로 L값을 알 수 있게 됩니다. 하지만 아두이노로 전압이 피크가 되는 매우 짧은 시간을 측정할 수 없으므로, 콘덴서를 이용하여 충전되는 시간을 측정으로 대체하는 것 같습니다.

 

여기까지 이해한 바를 가지고 소스코드를 보면, 

쉬프트 연산하는 부분의 의미를 잘 모르겠습니다. 그대로 사용하기로 합니다.

 

 

 

 

 

 

 

먼저 필요한 준비물은 아래와 같습니다. ( 아래 판매처는 한 곳에서 모두 구매하실 수 있는 사이트(디바이스마트)에서 모두 골라보았습니다. 따로 저랑 관계가 없습니다. 아무 곳에서나 구하셔도 됩니다. )

 

 

 

품목 수량 판매처 Note
아두이노 나노


1 https://www.devicemart.co.kr/goods/view?no=1265700 어떤 종류든 관계없습니다만, 크기를 작게 하기 위해서 나노
9V 건전지 1 https://www.devicemart.co.kr/goods/view?no=2832  
9V 건전지 홀더 1 https://www.devicemart.co.kr/goods/view?no=1133978 전원 ON/OFF되는 타입으로 골랐습니다.
전선  5m https://www.devicemart.co.kr/goods/view?no=31197 아무 전선이나 괜찮습니다. 구리 단심선도 되고, UL 전선도 됩니다. 
(저는 UL 1007, AWG24전선을 사용해서 해당 링크 첨부합니다. 짧게 파는것은 없네요)
1N4148 다이오드 1 https://www.devicemart.co.kr/goods/view?no=25  
330Ω 저항 1 https://www.devicemart.co.kr/goods/view?no=886  
1kΩ 저 1 https://www.devicemart.co.kr/goods/view?no=876  
피에조 부저 1 https://www.devicemart.co.kr/goods/view?no=25041  

LED

1 https://www.devicemart.co.kr/goods/view?no=2851  
셀카봉 1    
다 쓴 테이프 심 1    
케이스 1    

 

 

 

 

연결할 회로는 아래와 같습니다. 다이오드는 피크 전압을 줄이기 위해, R1는 전류를 제한하기 위해 사용되었습니다.

 

 

 

 

소자가 많지 않아 만능기판 없이 바로 납땜했습니다. 5파이 LED가 없어서 10파이짜리로 알이 큰 걸로 사용했습니다.

 

 

 

 

 

다음으로 코일을 감아줄 차례입니다.

원작에서는 다 쓴 테이프 심에다 전선을 감아주었는데, 집에 다 쓴 테이프 심이 없습니다. 집 안 곳곳을 뒤지다, 맘에 쏙 드는 통을 발견했습니다. 예쁘게 잘라주고

 

 

 

 

 

전선을 감아줍니다. 남매 전쟁을 피하기 위해 2개를 완성했습니다. 노란색 선을 5m 조금 안되고, 파란색 선은 6m 정도 되는데 그냥 감아줍니다.

 

 

 

 

 

 

코일까지 연결한 모습입니다. 코일은 커넥터 처리 하였습니다.

 

 

 

 

 

 

이제 소스코드를 업로드합니다. 

 

#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);
    }
}

 

 

 

소스코드가 포함된 프로젝트파일도 첨부합니다.

 

arduino_metal_detector.zip
0.00MB

 

 

 

 

프로그램을 업로드하고 간단히 테스트를 해보니 잘 동작합니다.

 

 

 

 

 

이제 케이스를 만들어 줍니다. 적당한 케이스가 없어서 포맥스를 잘라서 만들어 주었습니다. (선 색깔이랑 깔맟춤 했습니다)

 

 

 

 

 

 

 

 

마지막으로 셀카봉에 장착해주면 끝입니다. (케이블 타이로 묶었습니다)

 

 

 

 

 

 

 

잘 동작하는지 동작 영상을 보겠습니다.

 

 

 

 

 


 

본 게시글은 아래 사이트를 참조하였습니다.

 

https://circuitdigest.com/microcontroller-projects/arduino-metal-detector-circuit-code

댓글