| 分类 | 项目 | 规格 / 说明 |
|---|---|---|
| 基础参数 | 模块型号 |
金属探测器模组 |
| PCB 外形尺寸 | 98.00mm × 80.00mm | |
| 感应线圈 | 圆形多层 PCB 线圈,直径约 80mm | |
| 检测方式 | 电磁感应式 | |
| 检测距离 | 典型距离:硬币约 1~3cm,金属螺丝约 2~5cm(距离随金属大小 / 材质变化) | |
| 输出信号 | 数字信号(DOUT) | |
| 供电电压 | 3.3V~5V(推荐 5V 供电) | |
| 板载功能 | 电源指示灯(PWR)、状态输出接口 | |
| 接口定义(CN1) | VCC | 电源正极,接 5V/3.3V |
| GND | 电源负极,需与单片机共地 | |
| DOUT | 数字检测信号输出,金属靠近时电平翻转 | |
| PULSE | 脉冲信号输出,可用于频率变化检测,提高抗干扰性 | |
| 关键特性 | PCB 线圈设计 | 线圈集成在 PCB 上,无额外绕线,体积小巧、结构稳定 |
|
|
||
| 低功耗设计 | 静态电流低,适合电池供电的便携设备 | |
| 安装孔设计 | 预留固定孔,可安装在外壳或设备上,方便 DIY 项目集成 |






#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C mylcd(0x26, 16, 2);
// 金属探测器
// 在与电阻串联的线圈上运行脉冲,线圈上的电压激增
// 同时通过二极管,给电容器充电
// 然后从A1口读取ADC值
// 线圈附近出现金属物体时会改变电感。
// 从而影响ADC值的变化。
// 对比有无金属物值的变化并通过LED和声音指示出来
// LED1亮时表示电感值增加
// LED2亮时表示电感值减少
// 闪烁和声音频率表示差值的大小
// 接线方式:
// A3------>OUT
// A2------>PULSE
// LED1---->D13
// LED2---->D12
// BEEP---->D10
const byte npulse = 50;
const bool sound = true;
const bool debug = false;//首次运行时修改debug为true,串口打印并调整npulse的值,使电容器读数在200到300之间
const byte pin_pulse = A2;//脉冲引脚
const byte pin_cap = A3;//ADC值读取引脚
const byte pin_LED1 = 12;
const byte pin_LED2 = 13;
const byte pin_tone = 10;//声音引脚
void setup() {
if (debug) Serial.begin(9600);
pinMode(pin_pulse, OUTPUT);
digitalWrite(pin_pulse, LOW);
pinMode(pin_cap, INPUT);
pinMode(pin_LED1, OUTPUT);
digitalWrite(pin_LED1, LOW);
pinMode(pin_LED2, OUTPUT);
digitalWrite(pin_LED2, LOW);
if (sound) pinMode(pin_tone, OUTPUT);
if (sound) digitalWrite(pin_tone, LOW);
// 初始化 LCD
mylcd.init();
mylcd.backlight();
// 在 LCD 上显示初始信息
mylcd.setCursor(0, 0);
mylcd.print(" Metal detector ");
mylcd.setCursor(0, 1);
mylcd.print(" System ");
// 延迟 2 秒
delay(2000);
// 清除 LCD 屏幕
mylcd.clear();
}
const int nmeas = 256; //measurements to take
long int sumsum = 0; //running sum of 64 sums
long int skip = 0; //number of skipped sums
long int diff = 0; //difference between sum and avgsum
long int flash_period = 0;//period (in ms)
long unsigned int prev_flash = 0; //time stamp of previous flash
void loop() {
int minval = 1023;
int maxval = 0;
//进行测量
long unsigned int sum = 0;
for (int imeas = 0; imeas < nmeas + 2; imeas++) {
//reset the capacitor
pinMode(pin_cap, OUTPUT);
digitalWrite(pin_cap, LOW);
delayMicroseconds(20);
pinMode(pin_cap, INPUT);
//apply pulses
for (int ipulse = 0; ipulse < npulse; ipulse++) {
digitalWrite(pin_pulse, HIGH); //takes 3.5 microseconds
delayMicroseconds(3);
digitalWrite(pin_pulse, LOW); //takes 3.5 microseconds
delayMicroseconds(3);
}
//read the charge on the capacitor
int val = analogRead(pin_cap); //takes 13x8=104 microseconds
minval = min(val, minval);
maxval = max(val, maxval);
sum += val;
//determine if LEDs should be on or off
long unsigned int timestamp = millis();
byte ledstat = 0;
if (timestamp < prev_flash + 10) {
if (diff > 0) ledstat = 1;
if (diff < 0) ledstat = 2;
}
if (timestamp > prev_flash + flash_period) {
if (diff > 0) ledstat = 1;
if (diff < 0) ledstat = 2;
prev_flash = timestamp;
}
if (flash_period > 1000) ledstat = 0;
//switch the LEDs to this setting
if (ledstat == 0) {
digitalWrite(pin_LED1, LOW);
digitalWrite(pin_LED2, LOW);
if (sound) noTone(pin_tone);
}
if (ledstat == 1) {
digitalWrite(pin_LED1, HIGH);
digitalWrite(pin_LED2, LOW);
if (sound) tone(pin_tone, 2000);
}
if (ledstat == 2) {
digitalWrite(pin_LED1, LOW);
digitalWrite(pin_LED2, HIGH);
if (sound) tone(pin_tone, 500);
}
}
//subtract minimum and maximum value to remove spikes
sum -= minval; sum -= maxval;
//process
if (sumsum == 0) sumsum = sum << 6; //set sumsum to expected value
long int avgsum = (sumsum + 32) >> 6;
diff = sum - avgsum;
if (abs(diff) < avgsum >> 10) { //adjust for small changes
sumsum = sumsum + sum - avgsum;
skip = 0;
} else {
skip++;
}
if (skip > 64) { // break off in case of prolonged skipping
sumsum = sum << 6;
skip = 0;
}
// one permille change = 2 ticks/s
if (diff == 0) flash_period = 1000000;
else flash_period = avgsum / (2 * abs(diff));
// 清除之前显示的数据
mylcd.setCursor(0, 0);
mylcd.print("Min: Max: ");
mylcd.setCursor(0, 1);
mylcd.print(" Dif: ");
mylcd.setCursor(4, 0);
mylcd.print(minval);
mylcd.setCursor(12, 0);
mylcd.print(maxval);
mylcd.setCursor(8, 1);
mylcd.print(diff);
if (debug) {
Serial.print(nmeas);
Serial.print(" ");
Serial.print(minval);
Serial.print(" ");
Serial.print(maxval);
Serial.print(" ");
Serial.print(sum);
Serial.print(" ");
Serial.print(avgsum);
Serial.print(" ");
Serial.print(diff);
Serial.print(" ");
Serial.print(flash_period);
Serial.println();
}
}