Простейший детектор металла на Arduino


При помощи контроллера Arduino можно собрать простейший детектор металла.
Кроме контроллера, для этого понадобится всего несколько деталей: катушка из проволоки (60 витков провода 0.4 мм, диаметр — 6.3 см), резистор (100 Ом) и конденсатор (10 мкФ). Для звуковой индикации используется обычный бузер.

Используя Arduino Nano и 9-вольтовую батарейку (типа Крона) — можно уместить всё устройство в коробочку из-под тик-така.

Код для Arduino — metal_detector.ino

//Metal detector based on pulse delay in LR circuit
//Connect a coil beween pin 10 and pin 8,
//a 100 Ohm resistor between pin 8 and ground,
//a speaker in series with a 10muF capacitor between pin 12 and ground,
//a reset-button between A0 and ground.
//Reference coil: 60 turns, diameter 6cm, AWG26 (0.4mm) wire. L~300muH, R~2Ohm
//
//R. Oldeman Oct 11 2020, CC BY-NC-SA 4.0 licence

#define debug false

//some parameters
#define sensitivity  5000 //threshold as a fraction of reference
#define aimtime    160000 //aim for measurement every 160k cycles (=10ms)
#define LEDpulselen 16000 //length of the LED pulse in clock cycles
#define cycles         40 //number of clock cycles reserved for calculations
#define printfrac      50 //fraction of measurements printed when in debug mode

//pin definitions - cannot change freely!
#define pulsepin 10 //must be pin 10 - TIMER1B output
#define probepin  8 //must be pin 8  - input capture pin
#define LEDpin   13 //if changed also need to update the direct-port writing
#define soundpin 12 //if changed also need to update the direct-port writing
#define resetpin A0 //can be changed freely

//global variables - shared between main loop and measurement function
long int imeas=0;  //counts the number of measurements performed
int absdiff;       //absolute value of difference wrt reference
long int phase=0;  //tracks integral of absdiff
long int phasemax; //value at which the phase counter turns over
int LEDcycles=0;   //number of cycles that the LED pin stays high
int LEDcycle=0;    //cycle index of the LED pulse

void setup() {
  noInterrupts(); //disable all inerrupts to avoid glitches

  if(debug)Serial.begin(9600);

  pinMode(pulsepin,OUTPUT);
  digitalWrite(pulsepin,LOW);
  pinMode(probepin,INPUT);
  pinMode(LEDpin,OUTPUT);
  digitalWrite(LEDpin,LOW);
  pinMode(soundpin,OUTPUT);
  digitalWrite(soundpin,LOW);
  pinMode(resetpin,INPUT_PULLUP);

  //setup timer1 to FASTPWM on pin 10
  TCCR1A=0B00100011;
  TCCR1B=0B00011001;
}

//perform measurement of delay of the trailing edge
long int meas(int period, int minlen, int maxlen, int steplen, int nloop){
  long int sum=0;
  int nmiss=0;
  OCR1A=period;        //set the period
  TIFR1 |= 0B00000001; //clear the timer overflow bit
  for(int iloop=0; iloopphasemax){
        phase-=phasemax;
        LEDcycle=LEDcycles;
        PORTB=(PORTB|0B00100000); //switch on LED
        PORTB=(PORTB^0B00010000); //invert sound pin - click!
      }
      //switch off LED when it's been on long enough
      if(LEDcycle>0){
        LEDcycle--;
        if(LEDcycle==0)PORTB=(PORTB&(!0B00100000));
      }
    }
  }
  if (nmiss>0)sum=0; //invalidate the result if there have been missing pulses
  return sum;
}

//flash LED with error code indefinitely if there's been an error
void go_error(byte errorcode){
  if(debug){
    Serial.print("ERROR ");
    Serial.print(errorcode);
    if(errorcode==1)Serial.println(": No pulse on probe pin - check connections");
    if(errorcode==2)Serial.println(": Delay too short - try more windings");
    if(errorcode==3)Serial.println(": Delay too long - try fewer windings");
    if(errorcode==4)Serial.println(": No robust pulse on pulselength scan - check coil resistance");
  }
  //enable in interrupts to use delay() and flash to indicate error code
  interrupts();
  while(true){
    for(byte i=0; i800)go_error(3);           // too long

  //choose pulsing parmeters based on measured delay time
  int minlen=3*tau;
  int maxlen=5*tau;
  int period=maxlen+2*tau+cycles;
  LEDcycles=LEDpulselen/period+1;

  // repeat loop or speed up loop to approach aimed duration of measurement
  int steplen=1;
  int nloop=1;
  float tottime=float(period)*(maxlen-minlen);
  if (tottime>aimtime*(3.0/2.0)) steplen=round(tottime/aimtime);
  if (tottime0)ref+=1;      //absorb slow drifts
      if(diff<0)ref-=1;
    }

    if(debug){
      sum+=diff;
      sumsq+=long(diff)*long(diff);
      if (imeas%printfrac==0){
        float mean=float(sum)/printfrac;
        float rms=sqrt( (float(sumsq)/printfrac) - pow(mean,2.0) );
        Serial.print(imeas);
        Serial.print(" val ref diff phase ");
        Serial.print(val);
        Serial.print(" ");
        Serial.print(ref);
        Serial.print(" ");
        Serial.print(diff);
        Serial.print(" ");
        Serial.print(mean);
        Serial.print(" ");
        Serial.print(rms);
        Serial.println("");
        sum=0; sumsq=0;
      }
    }
    imeas++;
  }
}

Ссылки
Minimal Arduino Metal Detector

По теме
Металлоискатель на Arduino

Arduino
Arduino, термины, начало работы
КМБ для начинающих ардуинщиков
Состав стартера (точка входа для начинающих ардуинщиков)


Добавить комментарий

Arduino

Что такое Arduino?
Зачем мне Arduino?
Начало работы с Arduino
Для начинающих ардуинщиков
Радиодетали (точка входа для начинающих ардуинщиков)
Первые шаги с Arduino

Разделы

  1. Преимуществ нет, за исключением читабельности: тип bool обычно имеет размер 1 байт, как и uint8_t. Думаю, компилятор в обоих случаях…

  2. Добрый день! Я недавно начал изучать программирование под STM32 и ваши уроки просто бесценны! Хотел узнать зачем использовать переменную типа…

3D-печать AI Android Arduino Bluetooth CraftDuino DIY IDE iRobot Kinect LEGO OpenCV Open Source Python Raspberry Pi RoboCraft ROS swarm ИК автоматизация андроид балансировать бионика версия видео военный датчик дрон интерфейс камера кибервесна манипулятор машинное обучение наше нейронная сеть подводный пылесос работа распознавание робот робототехника светодиод сервомашинка собака управление ходить шаг за шагом шаговый двигатель шилд юмор

OpenCV
Робототехника
Будущее за бионическими роботами?
Нейронная сеть - введение