| 参数分类 | 项目 | 规格详情 |
|---|---|---|
| 基础参数 | 模块型号 | 金属探测器模组 (A058),可用于简易寻宝、流水线金属异物检测、DIY 安检设备等场景 |
| 基础参数 | PCB 外形尺寸 | 98.00mm × 80.00mm,矩形板型适配外壳封装、平面安装固定 |
| 基础参数 | 感应线圈 | PCB 集成圆形多层线圈,线圈直径约 80mm,多层布线提升感应磁场强度,扩大探测范围 |
| 基础参数 | 检测原理 | 电磁感应式金属探测,金属靠近会改变线圈谐振参数,电路捕捉变化输出检测信号 |
| 基础参数 | 典型检测距离 | 硬币 1~3cm;金属螺丝 2~5cm,检测距离随金属体积、材质变化,大块铁类金属探测距离更远 |
| 基础参数 | 输出信号 | DOUT 数字电平信号、PULSE 脉冲信号双输出,可按需选用两种信号对接主控 |
| 基础参数 | 供电电压 | 3.3V~5V DC,推荐 5V 供电,兼容主流单片机供电体系,适配开发板、锂电池供电 |
| 基础参数 | 板载硬件 | PWR 电源指示灯、CN1 四针信号输出插座,通电状态、接线状态可直观确认 |
| 基础参数 | 产品重量 | 裸 PCB 约 18g,焊接线圈、元器件后成品约 30g,批量生产重量浮动 ±2g,适配便携设备装配 |
| CN1 接口引脚定义 | VCC | 电源正极,接 5V/3.3V,为线圈谐振电路、信号处理电路、指示灯供电 |
| CN1 接口引脚定义 | GND | 电源负极,必须与单片机共地,统一电平基准,避免感应信号受地电位干扰漂移 |
| CN1 接口引脚定义 | DOUT | 数字检测输出,金属靠近时电平翻转,单片机普通 IO 即可读取有无金属,程序开发简单 |
| CN1 接口引脚定义 | PULSE | 频率脉冲输出,可采集频率变化提升抗干扰能力,通过频率数值判断金属大小、距离 |
| 核心特性 - PCB 一体化线圈 | 线圈蚀刻在 PCB 内部,无需外部绕制线圈,结构紧凑稳定,不易变形脱线 | 省去手工绕线工序,线圈一致性高,长期震动、搬运也不会出现线圈移位,探测性能稳定 |
| 核心特性 - 双信号输出 | 数字 DOUT 快速判定有无金属;PULSE 脉冲可读取频率做精准识别,适配复杂干扰环境 | 简单场景用 DOUT 快速检测;电磁干扰强、需要估算金属尺寸距离的场景采集 PULSE 频率,适配多种开发需求 |
| 核心特性 - 低功耗静态设计 | 待机电流小,适合电池供电便携探测设备 | 长时间依靠干电池、移动锂电池工作也能维持不错续航,适合手持便携式金属探测装置 |
| 核心特性 - 预留固定孔位 | 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();
}
}