Моя разработка металлоискателя на базе Arduino
Заинтересовавшись и сделав простой металлодетектор на микроконтроллеле PIC ( вот тут), и найдя в интернете,
что люди делали металлоискатели на Ардуино, решил сделать подобное на базе платы Freeduino (аналог Arduino).
Задающий генератор делал на триггере Шмидта (чтобы стабильно запускался), индикатор - на 2-х световых шкалах
(чтобы видеть все изменения сигнала). Все монтировал на макетной плате Freeduino.
Принципиальная схема:
Программа ( Arduino sketch ):
В первоначальном варианте написал простую программу на "ардуиновском" языке:
int calibration_mode = 0; // переменная, определяющая режим (работа или
калибровка)
int pin_A5_level=0; // уровень напряжения на входе
unsigned long sum_time = 0; // суммарное время 200 импульсов положительной
полярности в поисковой катушке
int delta = 0; // разница во времени
int etalon_time = 25000; // эталонное время
int num_click = 200; // Измерения ведем за время 200 колебаний в поисковой
катушке
int last_time = 0; // последнее измеренное время одного импульса в катушке
int low_cif=0; // младшие 8 разрядов , выводимые на индикатор
int high_cif=0; // старшие 6 разрядов , - // -
void setup()
{
pinMode(13,OUTPUT); // Устанавливаем цифровые пины как выходы
pinMode(12,OUTPUT);
pinMode(11,OUTPUT);
pinMode(10,OUTPUT);
pinMode(9,OUTPUT);
pinMode(8,OUTPUT);
pinMode(7,OUTPUT);
pinMode(6,OUTPUT);
pinMode(5,OUTPUT);
pinMode(4,OUTPUT);
pinMode(3,OUTPUT);
pinMode(2,OUTPUT);
pinMode(1,OUTPUT);
pinMode(0,OUTPUT);
pinMode(14,INPUT); // Устанавливаем аналоговые пины как цифровые входы
pinMode(15,INPUT);
pinMode(16,INPUT);
pinMode(17,INPUT);
pinMode(18,INPUT);
pinMode(19,INPUT);
digitalWrite(14,HIGH); // Подключаем подтягивающие резисторы на входы
digitalWrite(15,HIGH);
digitalWrite(16,HIGH);
digitalWrite(17,HIGH);
digitalWrite(18,HIGH);
digitalWrite(19,HIGH);
}
void loop()
{
sum_time = 0;
calibration_mode=digitalRead(14); // Опрашиваем вход А0, не нажата ли кнопка и
пишем соответственное значение в переменную
num_click = 0; // Сброс счетчика количества колебаний в поисковой катушке
while(num_click < 200) // Повторяем, пока не обсчитаем 200 колебаний в поисковой
катушке
{
while(pin_A5_level > 0) // Если в данный момент происходит импульс положительной
полярности, ждем когда закончится
{
pin_A5_level=digitalRead(19); // Определения напряжения на входном порту
}
last_time = pulseIn(19, HIGH); // Функция определения длительности импульса
положительной полярности
num_click = num_click + 1; // увеличиваем на 1 значение счетчика
sum_time = sum_time + last_time; // Прибавляем полученное значение к сумме
}
if (calibration_mode < 1){ // Если была нажата кнопка калибровки...
etalon_time = (etalon_time + sum_time)/2; // ... корректируем эталонное значение
}
num_click=0; // Сброс счетчика
delta=sum_time - etalon_time; // Вычисляем разницу во времени
low_cif = abs(delta) % 256; // Определяем младшие 8 бит разницы...
PORTD = low_cif; // ... и посылаем их на индикатор
high_cif = abs(delta)/256; // То же и со старшими разрядами
PORTB = high_cif; // То же
if (delta < 0) // Если разница отрицательная...
{
digitalWrite(13, HIGH); // ... зажигается нижний индикатор
}
else // иначе -
{
digitalWrite(13, LOW); // зажигается верхний индикатор
}
потом для повышения чувствительности решил задействовать прерывания микроконтроллера:
// metal detector for arduino
// version_6 (C)alex---1967 February
2014
// Connect search coil oscillator to pin A5
// Connect NULL button
between pin A0 and GND
// PRESS NULL BUTTON AFTER POWER UP!
unsigned long
sum_time = 0; // суммарное число тактов генератора за время 16 импульсов в
поисковой
катушке
//the total number of clock cycles during 16 pulses in the search coil
long
delta = 0; // разница между измеренным и эталонным значением// difference
between the measured value and the reference value
unsigned long etalon_time
= 3000; // эталонное значение//reference value
// Измерения ведём за время 16
колебаний в поисковой катушке//make measurements during 16 oscillations in the
search coil
// (стоит внешний предделитель /16 на жёсткой логике)//( here is
an external prescaler / 16 )
byte low_cif=0; // младшие 8 разрядов ,
выводимые на индикатор//lower 8 bits output by the indicator
volatile byte
num_H=0; // старшие разряды, читаемые из счётчика//upper bits are read from the
counter
volatile byte num_L=0; // младшие разряды, читаемые из
счётчика//lower bits are read from the counter
unsigned int num_circle =
0;
unsigned long time = 0;
unsigned long time_H = 0;
unsigned long
time_L = 0;
void setup()
{
pinMode(13,OUTPUT); // Устанавливаем
цифровые пины как выходы
pinMode(12,OUTPUT); // Set the digital pins as
outputs
pinMode(11,OUTPUT);
pinMode(10,OUTPUT);
pinMode(9,OUTPUT);
pinMode(8,OUTPUT);
pinMode(7,OUTPUT);
pinMode(6,OUTPUT);
pinMode(5,OUTPUT);
pinMode(4,OUTPUT);
pinMode(3,OUTPUT);
pinMode(2,OUTPUT);
pinMode(1,OUTPUT);
pinMode(0,OUTPUT);
pinMode(14,INPUT);
// Устанавливаем аналоговые пины как цифровые входы
pinMode(15,INPUT); // Set
the analog pins as digital
inputs
pinMode(16,INPUT);
pinMode(17,INPUT);
pinMode(18,INPUT);
pinMode(19,INPUT);
digitalWrite(14,HIGH);
// Подключаем подтягивающие резисторы на входы
digitalWrite(15,HIGH); //
Connect the pull-up resistors on the
inputs
digitalWrite(16,HIGH);
digitalWrite(17,HIGH);
digitalWrite(18,HIGH);
digitalWrite(19,HIGH);
TCCR1B
= 129; // режим подавления шума; коэффициент деления предделителя: 1 // noise
reduction mode; prescaler = 1
TCCR1A = 0; // ШИМ не задействуется,
выходы OC1A, OC1B не задействуются
PCICR = B00000010; // разрешаем прерывания
на пинах 16...19 // allow interrupts on pines 16 ... 19
PCMSK1 = B00100000;
// выбираем 19 пин для прерываний // choose 19 pin interrupt
sei();
//прерывания разрешаются // interrupts allowed
}
void
loop()
{
num_circle = 0;
time_H = 0;
time_L = 0;
while
(num_circle < 32)
{
time_L = time_L + num_L;
time_H = time_H +
num_H;
++num_circle;
}
time_H = time_H << 8;
sum_time = time_H
+ time_L;
sum_time = sum_time >> 4;
delta = (sum_time -
etalon_time); // Вычисляем разницу // calculate a difference
low_cif =
abs(delta) % 256; // Определяем младшие 8 бит разницы... // Determine the lower
8 bit of difference ...
PORTD = low_cif; // ... и посылаем их на индикатор //
...and send them to the indicator
if (delta < 0) // Если разница
отрицательная... // If the difference is negative ...
{
PORTB = B00100000;
// ... зажигается верхний индикатор // ... the upper indicator lights
up
if (digitalRead(14) < 1) // Если была нажата кнопка калибровки...
// If you pressed the calibration button ...
{
etalon_time = etalon_time
- 1; // ... то корректируем эталонное значение // ... then adjust the reference
value
}
}
if (delta > 0) // иначе - // If the difference is positive
...
{
PORTB = B00000000; // ...зажигается нижний индикатор // ...lower
indicator lights up
if (digitalRead(14) < 1) // Если была нажата
кнопка калибровки... // If you pressed the calibration button
...
{
etalon_time = etalon_time + 1; // ... то корректируем эталонное
значение // ... then adjust the reference value
}
}
}
ISR(PCINT1_vect) // это прерывание происходит при
изменении уровня на 13 пине (А5) // this interrupt occurs when the voltage is
changed by 13 pin (A5)
{
num_L = TCNT1L; //
num_H = TCNT1H ;
TCNT1H
= 0;
TCNT1L = 0;
}
Разницы в чувствительности практически никакой не заметил :-))
фото реального девайса:
Проект в Протеусе:
http://alex---1967.narod.ru/my_metal_detector_ver_7_15_rab_half.DSN
http://alex---1967.narod.ru/my_metal_detector_ver_7_15_rab_half.PWI
http://alex---1967.narod.ru/sketch_metal_detector_ver_7_15_rab_half.cpp.hex
Чувствительность конечно так себе, на уровне простейшего Малыша FM.
Главная страница Страница Всякое-разное
слова для поиска металлоискатель на ардуино, металлодетектор на ардуино, миноискатель на ардуино, metal detector Arduino Uno, металлоискатель на Arduino Uno, металлоискатель на Freeduino, простой металлоискатель на Ардуино, простейший металлоискатель на Ардуино