继电器控制与应用实战教程¶
学习目标¶
完成本教程后,你将能够:
- 理解继电器的工作原理和类型
- 掌握继电器驱动电路的设计方法
- 学会使用继电器模块控制大功率负载
- 实现单路和多路继电器控制
- 添加隔离保护和安全措施
前置要求¶
在开始本教程之前,你需要:
知识要求: - 了解C语言基础编程 - 熟悉基本电路知识(电压、电流、功率) - 掌握GPIO输出控制 - 了解交流电和直流电的区别
技能要求: - 能够使用Arduino IDE或STM32开发环境 - 会使用万用表测量电压和电流 - 了解基本的电气安全知识
准备工作¶
硬件准备¶
| 名称 | 数量 | 说明 | 参考价格 |
|---|---|---|---|
| 开发板 | 1 | Arduino Uno 或 STM32F103 | ¥30-80 |
| 继电器模块 | 1-4 | 5V单路或多路继电器模块 | ¥3-20 |
| LED灯 | 1-2 | 用于测试(或小功率负载) | ¥1 |
| 电源 | 1 | 5V/12V电源(根据负载选择) | ¥15-30 |
| 杜邦线 | 若干 | 公对公、公对母 | ¥5 |
软件准备¶
Arduino平台: - Arduino IDE 1.8.x 或 2.x - USB驱动程序(CH340或CP2102)
STM32平台: - STM32CubeIDE 或 Keil MDK - ST-Link驱动程序
安全注意事项¶
⚠️ 重要提醒: - 继电器可以控制高压电(220V AC),操作时务必小心 - 接线时必须断电,避免触电危险 - 首次测试使用低压负载(如LED、12V灯泡) - 确保继电器额定参数大于负载要求 - 高压电路必须有专业人员指导 - 使用绝缘工具和防护措施
理论基础¶
继电器工作原理¶
继电器(Relay)是一种电控开关,通过小电流控制大电流,实现电气隔离和功率放大。
基本结构:
┌─────────────────────────────────┐
│ 继电器内部结构 │
│ │
│ 控制端(线圈) │
│ ┌──────────┐ │
│ │ │ │
│ │ 电磁线圈 │ │
│ │ │ │
│ └────┬─────┘ │
│ │ │
│ ┌───▼───┐ │
│ │ 铁芯 │ │
│ └───┬───┘ │
│ │ │
│ ┌───▼───┐ │
│ │ 衔铁 │◄─── 弹簧 │
│ └───┬───┘ │
│ │ │
│ ┌────▼────┐ │
│ │ 触点开关 │ │
│ └─────────┘ │
│ │
│ 输出端(触点) │
│ COM ─┬─ NO (常开) │
│ └─ NC (常闭) │
└─────────────────────────────────┘
工作过程:
- 未通电状态:
- 线圈无电流
- 弹簧拉动衔铁
- COM与NC连接(常闭触点闭合)
-
COM与NO断开(常开触点断开)
-
通电状态:
- 线圈产生磁场
- 磁场吸引衔铁
- COM与NC断开(常闭触点断开)
-
COM与NO连接(常开触点闭合)
-
断电状态:
- 线圈失去磁场
- 弹簧恢复衔铁
- 回到未通电状态
继电器的关键参数¶
线圈参数: - 额定电压:线圈工作电压(如5V、12V、24V) - 额定电流:线圈工作电流(通常20-100mA) - 线圈电阻:决定工作电流(如5V/70mA = 71Ω)
触点参数: - 额定电压:触点可承受的最大电压(如250V AC、30V DC) - 额定电流:触点可承受的最大电流(如10A、30A) - 触点形式:SPST、SPDT、DPDT等 - 寿命:机械寿命(1000万次)、电气寿命(10万次)
其他参数: - 动作时间:从通电到触点闭合的时间(通常5-15ms) - 释放时间:从断电到触点断开的时间(通常5-10ms) - 绝缘电阻:线圈与触点之间的绝缘性能(>100MΩ)
继电器类型¶
按触点形式分类:
| 类型 | 全称 | 触点数 | 说明 | 应用 |
|---|---|---|---|---|
| SPST | Single Pole Single Throw | 2个 | 单刀单掷,简单开关 | 灯光控制 |
| SPDT | Single Pole Double Throw | 3个 | 单刀双掷,一个COM,一个NO,一个NC | 双向控制 |
| DPST | Double Pole Single Throw | 4个 | 双刀单掷,两组独立开关 | 双路控制 |
| DPDT | Double Pole Double Throw | 6个 | 双刀双掷,两组SPDT | 电机正反转 |
按工作原理分类:
- 电磁继电器(最常用)
- 利用电磁铁原理
- 成本低,可靠性高
-
有机械磨损
-
固态继电器(SSR)
- 无机械触点
- 寿命长,无噪音
-
成本较高,有漏电流
-
簧片继电器
- 体积小,灵敏度高
- 功率较小
- 用于弱信号控制
继电器模块介绍¶
市面上常见的继电器模块已经集成了驱动电路和保护元件,使用更加方便。
典型继电器模块组成:
┌─────────────────────────────────┐
│ 继电器模块电路 │
│ │
│ VCC ────┬────────────────── │
│ │ │
│ IN ────┤ 光耦隔离 │
│ │ ┌────┐ │
│ └──┤ ├──┐ │
│ └────┘ │ │
│ │ │
│ ┌───▼───┐ │
│ │三极管 │ │
│ └───┬───┘ │
│ │ │
│ ┌───▼───┐ │
│ │继电器 │ │
│ │线圈 │ │
│ └───────┘ │
│ │ │
│ GND ───────────────┴─────── │
│ │
│ 触点输出:COM、NO、NC │
└─────────────────────────────────┘
模块特点: - ✅ 内置光耦隔离,保护MCU - ✅ 内置续流二极管,保护线圈 - ✅ 内置驱动电路,直接GPIO控制 - ✅ LED指示灯,显示工作状态 - ✅ 即插即用,降低开发难度
常见模块型号: - 单路继电器模块:1个继电器,3个控制引脚 - 2路继电器模块:2个继电器,4个控制引脚 - 4路继电器模块:4个继电器,6个控制引脚 - 8路继电器模块:8个继电器,10个控制引脚
触点配置说明¶
SPDT继电器的三个端子:
| 端子 | 名称 | 说明 |
|---|---|---|
| COM | Common | 公共端,连接电源或负载 |
| NO | Normally Open | 常开端,未通电时断开 |
| NC | Normally Closed | 常闭端,未通电时闭合 |
接线方式:
方式1:控制负载的通断(常用)
电源+ ──> COM
NO ──> 负载 ──> 电源-
NC ──> 不接
方式2:双向控制
电源+ ──> COM
NO ──> 负载A ──> 电源-
NC ──> 负载B ──> 电源-
电路连接¶
使用继电器模块(推荐)¶
继电器模块简化了驱动电路,直接连接即可:
Arduino/STM32 继电器模块 负载
D2 ----------> IN
5V ----------> VCC
GND ----------> GND
COM <---------- 电源+
NO ----------> 负载+ ──> 电源-
NC (不接)
详细连接说明¶
控制信号连接(以Arduino为例):
| Arduino引脚 | 继电器模块引脚 | 功能 |
|---|---|---|
| D2 | IN | 控制信号(高/低电平) |
| 5V | VCC | 模块电源 |
| GND | GND | 公共地 |
负载连接(以LED为例):
| 继电器模块引脚 | 连接 |
|---|---|
| COM | 电源正极(5V或12V) |
| NO | LED正极 |
| LED负极 | 电阻 → 电源负极 |
| NC | 不接 |
注意事项: 1. ⚠️ 电源选择:模块VCC通常为5V,负载电源根据负载选择 2. ⚠️ 触发电平:有些模块是低电平触发,有些是高电平触发 3. ⚠️ 负载功率:确保继电器额定参数大于负载要求 4. ⚠️ 高压隔离:控制电路与高压负载完全隔离
自制驱动电路(进阶)¶
如果使用裸继电器,需要自己设计驱动电路:
Arduino/STM32 驱动电路 继电器
D2 ──────┬──────> 三极管基极(B)
│ (通过1kΩ电阻)
│
GND ─────┴──────> 三极管发射极(E)
5V ──────────────> 继电器线圈+
│
└──> 三极管集电极(C)
│
└──> 续流二极管负极
GND ─────────────> 继电器线圈-
│
└──> 续流二极管正极
元件清单: - NPN三极管(如2N2222、S8050) - 1kΩ电阻(基极限流) - 1N4007二极管(续流保护) - 继电器(5V线圈)
步骤1:基础测试 - 单路继电器控制¶
1.1 创建Arduino项目¶
- 打开Arduino IDE
- 选择 文件 → 新建
- 保存项目为
relay_control_basic
1.2 定义引脚¶
// 继电器引脚定义
const int RELAY_PIN = 2; // 继电器控制引脚
void setup() {
// 设置引脚模式
pinMode(RELAY_PIN, OUTPUT);
// 初始化为关闭状态
digitalWrite(RELAY_PIN, LOW);
// 初始化串口
Serial.begin(9600);
Serial.println("Relay Control Test");
}
1.3 实现基本开关控制¶
void loop() {
// 打开继电器
Serial.println("Relay ON");
digitalWrite(RELAY_PIN, HIGH);
delay(2000); // 保持2秒
// 关闭继电器
Serial.println("Relay OFF");
digitalWrite(RELAY_PIN, LOW);
delay(2000); // 保持2秒
}
1.4 上传和测试¶
- 选择正确的开发板和端口
- 点击上传按钮
- 观察继电器和负载的工作情况
预期结果: - 继电器每2秒切换一次状态 - 听到继电器"咔哒"的吸合声 - LED指示灯随继电器状态变化 - 负载(LED)随继电器开关
调试技巧: - 打开串口监视器(波特率9600)查看状态 - 如果继电器不动作,检查触发电平(高/低) - 如果负载不工作,检查COM和NO的接线 - 用万用表测量触点通断状态
步骤2:串口控制继电器¶
2.1 创建控制函数¶
// 继电器引脚
const int RELAY_PIN = 2;
// 继电器状态
bool relayState = false;
void setup() {
pinMode(RELAY_PIN, OUTPUT);
digitalWrite(RELAY_PIN, LOW);
Serial.begin(9600);
Serial.println("=== Relay Control System ===");
Serial.println("Commands:");
Serial.println(" 1 or ON - Turn relay ON");
Serial.println(" 0 or OFF - Turn relay OFF");
Serial.println(" T or t - Toggle relay");
Serial.println(" S or s - Show status");
}
void loop() {
if (Serial.available() > 0) {
String cmd = Serial.readStringUntil('\n');
cmd.trim(); // 去除空格和换行
cmd.toUpperCase(); // 转为大写
handleCommand(cmd);
}
}
void handleCommand(String cmd) {
if (cmd == "1" || cmd == "ON") {
turnRelayOn();
} else if (cmd == "0" || cmd == "OFF") {
turnRelayOff();
} else if (cmd == "T") {
toggleRelay();
} else if (cmd == "S") {
showStatus();
} else {
Serial.println("Unknown command");
}
}
void turnRelayOn() {
digitalWrite(RELAY_PIN, HIGH);
relayState = true;
Serial.println("Relay: ON");
}
void turnRelayOff() {
digitalWrite(RELAY_PIN, LOW);
relayState = false;
Serial.println("Relay: OFF");
}
void toggleRelay() {
relayState = !relayState;
digitalWrite(RELAY_PIN, relayState ? HIGH : LOW);
Serial.print("Relay: ");
Serial.println(relayState ? "ON" : "OFF");
}
void showStatus() {
Serial.print("Relay Status: ");
Serial.println(relayState ? "ON" : "OFF");
}
2.2 测试串口控制¶
- 打开串口监视器(波特率9600)
- 输入命令测试:
- 输入
1或ON→ 继电器打开 - 输入
0或OFF→ 继电器关闭 - 输入
T→ 切换继电器状态 - 输入
S→ 显示当前状态
步骤3:多路继电器控制¶
3.1 控制多个继电器¶
使用数组管理多个继电器:
// 继电器引脚定义
const int RELAY_COUNT = 4;
const int RELAY_PINS[RELAY_COUNT] = {2, 3, 4, 5};
// 继电器状态
bool relayStates[RELAY_COUNT] = {false, false, false, false};
void setup() {
// 初始化所有继电器
for (int i = 0; i < RELAY_COUNT; i++) {
pinMode(RELAY_PINS[i], OUTPUT);
digitalWrite(RELAY_PINS[i], LOW);
}
Serial.begin(9600);
Serial.println("=== Multi-Relay Control System ===");
Serial.println("Commands:");
Serial.println(" ON <n> - Turn relay n ON (1-4)");
Serial.println(" OFF <n> - Turn relay n OFF (1-4)");
Serial.println(" ALL ON - Turn all relays ON");
Serial.println(" ALL OFF - Turn all relays OFF");
Serial.println(" STATUS - Show all relay status");
}
void loop() {
if (Serial.available() > 0) {
String cmd = Serial.readStringUntil('\n');
cmd.trim();
cmd.toUpperCase();
handleMultiRelayCommand(cmd);
}
}
void handleMultiRelayCommand(String cmd) {
if (cmd.startsWith("ON ")) {
int relay = cmd.substring(3).toInt();
if (relay >= 1 && relay <= RELAY_COUNT) {
setRelay(relay - 1, true);
} else {
Serial.println("Invalid relay number (1-4)");
}
} else if (cmd.startsWith("OFF ")) {
int relay = cmd.substring(4).toInt();
if (relay >= 1 && relay <= RELAY_COUNT) {
setRelay(relay - 1, false);
} else {
Serial.println("Invalid relay number (1-4)");
}
} else if (cmd == "ALL ON") {
setAllRelays(true);
} else if (cmd == "ALL OFF") {
setAllRelays(false);
} else if (cmd == "STATUS") {
showAllStatus();
} else {
Serial.println("Unknown command");
}
}
void setRelay(int index, bool state) {
digitalWrite(RELAY_PINS[index], state ? HIGH : LOW);
relayStates[index] = state;
Serial.print("Relay ");
Serial.print(index + 1);
Serial.print(": ");
Serial.println(state ? "ON" : "OFF");
}
void setAllRelays(bool state) {
for (int i = 0; i < RELAY_COUNT; i++) {
digitalWrite(RELAY_PINS[i], state ? HIGH : LOW);
relayStates[i] = state;
}
Serial.print("All relays: ");
Serial.println(state ? "ON" : "OFF");
}
void showAllStatus() {
Serial.println("Relay Status:");
for (int i = 0; i < RELAY_COUNT; i++) {
Serial.print(" Relay ");
Serial.print(i + 1);
Serial.print(": ");
Serial.println(relayStates[i] ? "ON" : "OFF");
}
}
3.2 顺序控制¶
实现继电器的顺序开关:
void sequentialControl() {
Serial.println("Sequential control starting...");
// 顺序打开
for (int i = 0; i < RELAY_COUNT; i++) {
setRelay(i, true);
delay(500); // 每个间隔500ms
}
delay(2000); // 全部打开后保持2秒
// 顺序关闭
for (int i = 0; i < RELAY_COUNT; i++) {
setRelay(i, false);
delay(500);
}
Serial.println("Sequential control complete");
}
步骤4:定时控制¶
4.1 简单定时器¶
实现继电器的定时开关功能:
// 继电器引脚
const int RELAY_PIN = 2;
// 定时器变量
unsigned long relayOnTime = 0;
unsigned long relayDuration = 0;
bool timerActive = false;
void setup() {
pinMode(RELAY_PIN, OUTPUT);
digitalWrite(RELAY_PIN, LOW);
Serial.begin(9600);
Serial.println("=== Relay Timer Control ===");
Serial.println("Commands:");
Serial.println(" TIMER <seconds> - Turn ON for specified seconds");
Serial.println(" CANCEL - Cancel active timer");
}
void loop() {
// 检查串口命令
if (Serial.available() > 0) {
String cmd = Serial.readStringUntil('\n');
cmd.trim();
cmd.toUpperCase();
if (cmd.startsWith("TIMER ")) {
int seconds = cmd.substring(6).toInt();
if (seconds > 0) {
startTimer(seconds);
} else {
Serial.println("Invalid duration");
}
} else if (cmd == "CANCEL") {
cancelTimer();
}
}
// 检查定时器
if (timerActive) {
if (millis() - relayOnTime >= relayDuration) {
// 定时时间到,关闭继电器
digitalWrite(RELAY_PIN, LOW);
timerActive = false;
Serial.println("Timer expired - Relay OFF");
}
}
}
void startTimer(int seconds) {
digitalWrite(RELAY_PIN, HIGH);
relayOnTime = millis();
relayDuration = seconds * 1000UL;
timerActive = true;
Serial.print("Relay ON for ");
Serial.print(seconds);
Serial.println(" seconds");
}
void cancelTimer() {
if (timerActive) {
digitalWrite(RELAY_PIN, LOW);
timerActive = false;
Serial.println("Timer cancelled - Relay OFF");
} else {
Serial.println("No active timer");
}
}
4.2 循环定时器¶
实现周期性的开关控制:
// 循环定时器参数
unsigned long lastToggleTime = 0;
unsigned long onDuration = 5000; // 打开持续时间(ms)
unsigned long offDuration = 3000; // 关闭持续时间(ms)
bool cycleEnabled = false;
bool relayState = false;
void setup() {
pinMode(RELAY_PIN, OUTPUT);
digitalWrite(RELAY_PIN, LOW);
Serial.begin(9600);
Serial.println("=== Relay Cycle Control ===");
Serial.println("Commands:");
Serial.println(" START - Start cycle");
Serial.println(" STOP - Stop cycle");
Serial.println(" SET <on_sec> <off_sec> - Set cycle times");
}
void loop() {
// 处理串口命令
if (Serial.available() > 0) {
String cmd = Serial.readStringUntil('\n');
cmd.trim();
cmd.toUpperCase();
if (cmd == "START") {
startCycle();
} else if (cmd == "STOP") {
stopCycle();
} else if (cmd.startsWith("SET ")) {
// 解析参数
int spaceIndex = cmd.indexOf(' ', 4);
if (spaceIndex > 0) {
int onSec = cmd.substring(4, spaceIndex).toInt();
int offSec = cmd.substring(spaceIndex + 1).toInt();
setCycleTimes(onSec, offSec);
}
}
}
// 执行循环控制
if (cycleEnabled) {
unsigned long currentTime = millis();
unsigned long elapsed = currentTime - lastToggleTime;
if (relayState) {
// 当前是打开状态,检查是否到关闭时间
if (elapsed >= onDuration) {
digitalWrite(RELAY_PIN, LOW);
relayState = false;
lastToggleTime = currentTime;
Serial.println("Cycle: Relay OFF");
}
} else {
// 当前是关闭状态,检查是否到打开时间
if (elapsed >= offDuration) {
digitalWrite(RELAY_PIN, HIGH);
relayState = true;
lastToggleTime = currentTime;
Serial.println("Cycle: Relay ON");
}
}
}
}
void startCycle() {
cycleEnabled = true;
lastToggleTime = millis();
relayState = false;
digitalWrite(RELAY_PIN, LOW);
Serial.println("Cycle started");
Serial.print("ON: ");
Serial.print(onDuration / 1000);
Serial.print("s, OFF: ");
Serial.print(offDuration / 1000);
Serial.println("s");
}
void stopCycle() {
cycleEnabled = false;
digitalWrite(RELAY_PIN, LOW);
relayState = false;
Serial.println("Cycle stopped");
}
void setCycleTimes(int onSec, int offSec) {
if (onSec > 0 && offSec > 0) {
onDuration = onSec * 1000UL;
offDuration = offSec * 1000UL;
Serial.print("Cycle times set - ON: ");
Serial.print(onSec);
Serial.print("s, OFF: ");
Serial.print(offSec);
Serial.println("s");
} else {
Serial.println("Invalid times");
}
}
步骤5:传感器联动控制¶
5.1 光控继电器¶
使用光敏电阻实现自动照明控制:
// 引脚定义
const int RELAY_PIN = 2;
const int LDR_PIN = A0; // 光敏电阻
// 阈值设置
const int LIGHT_THRESHOLD = 300; // 光照阈值(0-1023)
const unsigned long DEBOUNCE_TIME = 5000; // 防抖时间(ms)
// 状态变量
bool relayState = false;
unsigned long lastChangeTime = 0;
void setup() {
pinMode(RELAY_PIN, OUTPUT);
pinMode(LDR_PIN, INPUT);
digitalWrite(RELAY_PIN, LOW);
Serial.begin(9600);
Serial.println("=== Light-Controlled Relay ===");
}
void loop() {
int lightLevel = analogRead(LDR_PIN);
// 显示光照值(每秒一次)
static unsigned long lastPrintTime = 0;
if (millis() - lastPrintTime >= 1000) {
Serial.print("Light level: ");
Serial.println(lightLevel);
lastPrintTime = millis();
}
// 防抖处理
if (millis() - lastChangeTime < DEBOUNCE_TIME) {
return;
}
// 光照控制逻辑
if (lightLevel < LIGHT_THRESHOLD && !relayState) {
// 光线暗,打开灯
digitalWrite(RELAY_PIN, HIGH);
relayState = true;
lastChangeTime = millis();
Serial.println("Light ON (dark detected)");
} else if (lightLevel >= LIGHT_THRESHOLD + 50 && relayState) {
// 光线亮(加50防止抖动),关闭灯
digitalWrite(RELAY_PIN, LOW);
relayState = false;
lastChangeTime = millis();
Serial.println("Light OFF (bright detected)");
}
delay(100);
}
5.2 温控继电器¶
使用温度传感器控制风扇或加热器:
// 引脚定义
const int RELAY_PIN = 2;
const int TEMP_PIN = A0; // 温度传感器(如LM35)
// 温度阈值
const float TEMP_HIGH = 28.0; // 高温阈值(℃)
const float TEMP_LOW = 25.0; // 低温阈值(℃)
// 状态变量
bool relayState = false;
void setup() {
pinMode(RELAY_PIN, OUTPUT);
digitalWrite(RELAY_PIN, LOW);
Serial.begin(9600);
Serial.println("=== Temperature-Controlled Relay ===");
Serial.print("High threshold: ");
Serial.print(TEMP_HIGH);
Serial.println("°C");
Serial.print("Low threshold: ");
Serial.print(TEMP_LOW);
Serial.println("°C");
}
void loop() {
// 读取温度(LM35: 10mV/°C)
int sensorValue = analogRead(TEMP_PIN);
float voltage = sensorValue * (5.0 / 1023.0);
float temperature = voltage * 100.0; // LM35转换
// 显示温度
Serial.print("Temperature: ");
Serial.print(temperature);
Serial.println("°C");
// 温度控制逻辑(带滞后)
if (temperature >= TEMP_HIGH && !relayState) {
// 温度过高,打开风扇/关闭加热器
digitalWrite(RELAY_PIN, HIGH);
relayState = true;
Serial.println("Relay ON (temperature high)");
} else if (temperature <= TEMP_LOW && relayState) {
// 温度正常,关闭风扇/打开加热器
digitalWrite(RELAY_PIN, LOW);
relayState = false;
Serial.println("Relay OFF (temperature normal)");
}
delay(2000); // 每2秒检测一次
}
步骤6:完整示例程序¶
6.1 智能家居控制系统¶
综合多种控制方式的完整程序:
// ========================================
// 智能继电器控制系统
// 功能:手动控制、定时控制、传感器联动
// ========================================
// 引脚定义
const int RELAY_PINS[] = {2, 3, 4, 5};
const int RELAY_COUNT = 4;
const int SENSOR_PIN = A0;
// 继电器状态
bool relayStates[RELAY_COUNT] = {false};
// 定时器
struct Timer {
bool active;
unsigned long startTime;
unsigned long duration;
int relayIndex;
};
Timer timers[RELAY_COUNT];
// 自动模式
bool autoMode = false;
int sensorThreshold = 500;
void setup() {
// 初始化继电器
for (int i = 0; i < RELAY_COUNT; i++) {
pinMode(RELAY_PINS[i], OUTPUT);
digitalWrite(RELAY_PINS[i], LOW);
timers[i].active = false;
}
pinMode(SENSOR_PIN, INPUT);
Serial.begin(9600);
printMenu();
}
void loop() {
// 处理串口命令
if (Serial.available() > 0) {
String cmd = Serial.readStringUntil('\n');
cmd.trim();
handleCommand(cmd);
}
// 检查定时器
checkTimers();
// 自动模式
if (autoMode) {
handleAutoMode();
}
delay(100);
}
void printMenu() {
Serial.println("\n=== Smart Relay Control System ===");
Serial.println("Manual Control:");
Serial.println(" ON <n> - Turn relay n ON (1-4)");
Serial.println(" OFF <n> - Turn relay n OFF (1-4)");
Serial.println(" ALL ON - Turn all relays ON");
Serial.println(" ALL OFF - Turn all relays OFF");
Serial.println("\nTimer Control:");
Serial.println(" TIMER <n> <sec> - Set timer for relay n");
Serial.println(" CANCEL <n> - Cancel timer for relay n");
Serial.println("\nAuto Mode:");
Serial.println(" AUTO ON - Enable auto mode");
Serial.println(" AUTO OFF - Disable auto mode");
Serial.println(" THRESHOLD <val> - Set sensor threshold");
Serial.println("\nInfo:");
Serial.println(" STATUS - Show all status");
Serial.println(" HELP - Show this menu");
Serial.println("=====================================\n");
}
void handleCommand(String cmd) {
cmd.toUpperCase();
if (cmd.startsWith("ON ")) {
int n = cmd.substring(3).toInt();
if (n >= 1 && n <= RELAY_COUNT) {
setRelay(n - 1, true);
}
} else if (cmd.startsWith("OFF ")) {
int n = cmd.substring(4).toInt();
if (n >= 1 && n <= RELAY_COUNT) {
setRelay(n - 1, false);
}
} else if (cmd == "ALL ON") {
for (int i = 0; i < RELAY_COUNT; i++) {
setRelay(i, true);
}
} else if (cmd == "ALL OFF") {
for (int i = 0; i < RELAY_COUNT; i++) {
setRelay(i, false);
}
} else if (cmd.startsWith("TIMER ")) {
handleTimerCommand(cmd);
} else if (cmd.startsWith("CANCEL ")) {
int n = cmd.substring(7).toInt();
if (n >= 1 && n <= RELAY_COUNT) {
cancelTimer(n - 1);
}
} else if (cmd == "AUTO ON") {
autoMode = true;
Serial.println("Auto mode enabled");
} else if (cmd == "AUTO OFF") {
autoMode = false;
Serial.println("Auto mode disabled");
} else if (cmd.startsWith("THRESHOLD ")) {
sensorThreshold = cmd.substring(10).toInt();
Serial.print("Threshold set to: ");
Serial.println(sensorThreshold);
} else if (cmd == "STATUS") {
showStatus();
} else if (cmd == "HELP") {
printMenu();
} else {
Serial.println("Unknown command. Type HELP for menu.");
}
}
void setRelay(int index, bool state) {
digitalWrite(RELAY_PINS[index], state ? HIGH : LOW);
relayStates[index] = state;
Serial.print("Relay ");
Serial.print(index + 1);
Serial.print(": ");
Serial.println(state ? "ON" : "OFF");
}
void handleTimerCommand(String cmd) {
// 解析 "TIMER <n> <sec>"
int firstSpace = cmd.indexOf(' ');
int secondSpace = cmd.indexOf(' ', firstSpace + 1);
if (secondSpace > 0) {
int n = cmd.substring(firstSpace + 1, secondSpace).toInt();
int sec = cmd.substring(secondSpace + 1).toInt();
if (n >= 1 && n <= RELAY_COUNT && sec > 0) {
startTimer(n - 1, sec);
} else {
Serial.println("Invalid parameters");
}
}
}
void startTimer(int index, int seconds) {
setRelay(index, true);
timers[index].active = true;
timers[index].startTime = millis();
timers[index].duration = seconds * 1000UL;
timers[index].relayIndex = index;
Serial.print("Timer started for Relay ");
Serial.print(index + 1);
Serial.print(" (");
Serial.print(seconds);
Serial.println(" seconds)");
}
void cancelTimer(int index) {
if (timers[index].active) {
timers[index].active = false;
setRelay(index, false);
Serial.print("Timer cancelled for Relay ");
Serial.println(index + 1);
} else {
Serial.println("No active timer");
}
}
void checkTimers() {
for (int i = 0; i < RELAY_COUNT; i++) {
if (timers[i].active) {
if (millis() - timers[i].startTime >= timers[i].duration) {
setRelay(i, false);
timers[i].active = false;
Serial.print("Timer expired for Relay ");
Serial.println(i + 1);
}
}
}
}
void handleAutoMode() {
static unsigned long lastCheck = 0;
if (millis() - lastCheck < 2000) return;
lastCheck = millis();
int sensorValue = analogRead(SENSOR_PIN);
// 根据传感器值控制第一个继电器
if (sensorValue < sensorThreshold && !relayStates[0]) {
setRelay(0, true);
Serial.print("Auto: Sensor=");
Serial.println(sensorValue);
} else if (sensorValue >= sensorThreshold + 50 && relayStates[0]) {
setRelay(0, false);
Serial.print("Auto: Sensor=");
Serial.println(sensorValue);
}
}
void showStatus() {
Serial.println("\n--- System Status ---");
// 继电器状态
Serial.println("Relays:");
for (int i = 0; i < RELAY_COUNT; i++) {
Serial.print(" Relay ");
Serial.print(i + 1);
Serial.print(": ");
Serial.print(relayStates[i] ? "ON" : "OFF");
if (timers[i].active) {
unsigned long remaining = (timers[i].duration -
(millis() - timers[i].startTime)) / 1000;
Serial.print(" (Timer: ");
Serial.print(remaining);
Serial.print("s)");
}
Serial.println();
}
// 自动模式
Serial.print("Auto Mode: ");
Serial.println(autoMode ? "ON" : "OFF");
if (autoMode) {
Serial.print("Sensor Value: ");
Serial.println(analogRead(SENSOR_PIN));
Serial.print("Threshold: ");
Serial.println(sensorThreshold);
}
Serial.println("--------------------\n");
}
STM32继电器控制¶
使用HAL库¶
STM32通过GPIO控制继电器:
// STM32 HAL库版本
// 假设使用PA0控制继电器
// GPIO初始化(在main.c中配置)
// PA0设为GPIO_Output
// 继电器控制函数
void Relay_On(void) {
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_SET);
}
void Relay_Off(void) {
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_RESET);
}
void Relay_Toggle(void) {
HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_0);
}
// 定时控制示例
void Relay_TimedControl(uint32_t duration_ms) {
Relay_On();
HAL_Delay(duration_ms);
Relay_Off();
}
// 主循环示例
int main(void) {
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
while (1) {
Relay_On();
HAL_Delay(2000);
Relay_Off();
HAL_Delay(2000);
}
}
STM32CubeMX配置要点: 1. 选择GPIO引脚(如PA0) 2. 设置为GPIO_Output模式 3. 设置输出电平(初始为Low) 4. 设置输出速度(Low即可) 5. 无需上拉/下拉电阻
安全与保护¶
1. 电气隔离¶
继电器模块通常内置光耦隔离,提供电气隔离保护:
隔离的重要性: - 保护MCU免受高压干扰 - 防止负载故障影响控制电路 - 提高系统可靠性
检查隔离: - 用万用表测量控制端和负载端的电阻 - 应该是无穷大(完全隔离)
2. 续流保护¶
对于感性负载(电机、电磁阀),必须添加续流保护:
继电器触点 ──┬── 感性负载+ ──┐
│ │
│ ┌────▼────┐
│ │ 续流二极管│
│ │ (反向) │
│ └────┬────┘
│ │
└─────────────── 负载-
续流二极管选择: - 电压:大于负载电压的2倍 - 电流:大于负载额定电流 - 常用型号:1N4007(1A/1000V)
3. 浪涌抑制¶
对于大功率负载,添加浪涌抑制器(MOV或TVS):
4. 软件防抖¶
避免继电器频繁切换:
// 防抖函数
bool safeRelayControl(int pin, bool state) {
static unsigned long lastChangeTime = 0;
const unsigned long MIN_INTERVAL = 1000; // 最小间隔1秒
if (millis() - lastChangeTime < MIN_INTERVAL) {
Serial.println("Too frequent! Ignored.");
return false;
}
digitalWrite(pin, state ? HIGH : LOW);
lastChangeTime = millis();
return true;
}
5. 过载保护¶
在负载电路中添加保险丝或断路器:
| 负载功率 | 保险丝规格 | 说明 |
|---|---|---|
| 100W | 1A | 小功率负载 |
| 500W | 3A | 中功率负载 |
| 1000W | 5A | 大功率负载 |
| 2000W | 10A | 高功率负载 |
常见问题与解决方案¶
问题1:继电器不动作¶
现象:发送控制信号,继电器不吸合
排查步骤: 1. 检查电源是否接通(用万用表测量VCC) 2. 检查控制信号是否正确(高/低电平触发) 3. 检查IN引脚是否有信号(用万用表或LED测试) 4. 检查继电器模块LED是否亮起 5. 更换继电器模块测试
解决方法: - 确认触发电平(有些模块是低电平触发) - 检查代码中的引脚配置 - 确保电源电流充足(每个继电器约70mA)
问题2:继电器频繁吸合释放¶
现象:继电器不停地"咔哒咔哒"响
可能原因: 1. 控制信号不稳定 2. 电源电压不足 3. 程序逻辑错误(死循环) 4. 传感器信号在阈值附近抖动
解决方法:
// 添加滞后(Hysteresis)
const int THRESHOLD_HIGH = 550;
const int THRESHOLD_LOW = 450;
if (sensorValue > THRESHOLD_HIGH && !relayState) {
// 打开继电器
relayState = true;
} else if (sensorValue < THRESHOLD_LOW && relayState) {
// 关闭继电器
relayState = false;
}
问题3:负载不工作¶
现象:继电器吸合,但负载不工作
排查步骤: 1. 用万用表测量COM和NO之间的通断 2. 检查负载本身是否正常 3. 检查负载电源是否接通 4. 检查接线是否正确(COM、NO、NC)
常见错误: - COM和NC接反(应该用NO) - 负载电源未接通 - 负载功率超过继电器额定值
问题4:继电器寿命短¶
现象:继电器使用一段时间后失效
原因分析: 1. 频繁切换(超过额定寿命) 2. 负载电流过大(触点烧蚀) 3. 感性负载无续流保护 4. 环境潮湿或灰尘
延长寿命的方法: - 减少切换频率 - 选择额定参数更大的继电器 - 添加续流保护 - 使用固态继电器(SSR)替代
问题5:干扰问题¶
现象:继电器切换时MCU复位或误动作
原因:继电器切换产生电磁干扰
解决方法: 1. 电源分离:继电器和MCU使用独立电源 2. 滤波电容:在电源端并联100μF电容 3. 接地优化:使用星型接地,减少地线干扰 4. 屏蔽:使用屏蔽线或金属外壳 5. 软件防护:添加看门狗定时器
实际应用案例¶
案例1:智能插座¶
使用继电器制作WiFi智能插座:
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
const int RELAY_PIN = D1;
bool relayState = false;
ESP8266WebServer server(80);
void setup() {
pinMode(RELAY_PIN, OUTPUT);
digitalWrite(RELAY_PIN, LOW);
Serial.begin(115200);
// 连接WiFi
WiFi.begin("YourSSID", "YourPassword");
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\nWiFi connected");
Serial.print("IP: ");
Serial.println(WiFi.localIP());
// 设置Web服务器路由
server.on("/", handleRoot);
server.on("/on", handleOn);
server.on("/off", handleOff);
server.on("/toggle", handleToggle);
server.on("/status", handleStatus);
server.begin();
Serial.println("HTTP server started");
}
void loop() {
server.handleClient();
}
void handleRoot() {
String html = "<html><body>";
html += "<h1>Smart Socket</h1>";
html += "<p>Status: " + String(relayState ? "ON" : "OFF") + "</p>";
html += "<button onclick=\"location.href='/on'\">Turn ON</button>";
html += "<button onclick=\"location.href='/off'\">Turn OFF</button>";
html += "<button onclick=\"location.href='/toggle'\">Toggle</button>";
html += "</body></html>";
server.send(200, "text/html", html);
}
void handleOn() {
digitalWrite(RELAY_PIN, HIGH);
relayState = true;
server.send(200, "text/plain", "Relay ON");
}
void handleOff() {
digitalWrite(RELAY_PIN, LOW);
relayState = false;
server.send(200, "text/plain", "Relay OFF");
}
void handleToggle() {
relayState = !relayState;
digitalWrite(RELAY_PIN, relayState ? HIGH : LOW);
server.send(200, "text/plain", relayState ? "ON" : "OFF");
}
void handleStatus() {
String json = "{\"state\":\"" + String(relayState ? "ON" : "OFF") + "\"}";
server.send(200, "application/json", json);
}
案例2:自动浇花系统¶
使用土壤湿度传感器和继电器控制水泵:
const int RELAY_PIN = 2;
const int MOISTURE_PIN = A0;
const int DRY_THRESHOLD = 300; // 干燥阈值
const int WET_THRESHOLD = 600; // 湿润阈值
const unsigned long WATER_DURATION = 5000; // 浇水时长(ms)
const unsigned long CHECK_INTERVAL = 3600000; // 检查间隔(1小时)
unsigned long lastCheckTime = 0;
bool watering = false;
unsigned long waterStartTime = 0;
void setup() {
pinMode(RELAY_PIN, OUTPUT);
digitalWrite(RELAY_PIN, LOW);
Serial.begin(9600);
Serial.println("=== Auto Watering System ===");
}
void loop() {
unsigned long currentTime = millis();
// 定期检查土壤湿度
if (currentTime - lastCheckTime >= CHECK_INTERVAL) {
checkMoisture();
lastCheckTime = currentTime;
}
// 控制浇水时长
if (watering) {
if (currentTime - waterStartTime >= WATER_DURATION) {
stopWatering();
}
}
delay(100);
}
void checkMoisture() {
int moisture = analogRead(MOISTURE_PIN);
Serial.print("Moisture level: ");
Serial.println(moisture);
if (moisture < DRY_THRESHOLD) {
Serial.println("Soil is dry - Starting watering");
startWatering();
} else if (moisture > WET_THRESHOLD) {
Serial.println("Soil is wet - No watering needed");
} else {
Serial.println("Soil moisture is OK");
}
}
void startWatering() {
digitalWrite(RELAY_PIN, HIGH);
watering = true;
waterStartTime = millis();
Serial.println("Water pump ON");
}
void stopWatering() {
digitalWrite(RELAY_PIN, LOW);
watering = false;
Serial.println("Water pump OFF");
}
案例3:定时喂食器¶
使用RTC模块和继电器实现定时喂食:
#include <Wire.h>
#include <RTClib.h>
RTC_DS3231 rtc;
const int RELAY_PIN = 2;
// 喂食时间表(小时:分钟)
struct FeedTime {
int hour;
int minute;
};
FeedTime feedTimes[] = {
{8, 0}, // 早上8:00
{12, 0}, // 中午12:00
{18, 0} // 晚上18:00
};
const int FEED_COUNT = sizeof(feedTimes) / sizeof(FeedTime);
const unsigned long FEED_DURATION = 3000; // 喂食时长(ms)
bool fedToday[FEED_COUNT] = {false};
void setup() {
pinMode(RELAY_PIN, OUTPUT);
digitalWrite(RELAY_PIN, LOW);
Serial.begin(9600);
if (!rtc.begin()) {
Serial.println("RTC not found!");
while (1);
}
// 如果RTC丢失电源,设置时间
if (rtc.lostPower()) {
Serial.println("RTC lost power, setting time!");
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}
Serial.println("=== Auto Feeder System ===");
}
void loop() {
DateTime now = rtc.now();
// 显示当前时间(每分钟一次)
static int lastMinute = -1;
if (now.minute() != lastMinute) {
printTime(now);
lastMinute = now.minute();
}
// 检查是否到喂食时间
for (int i = 0; i < FEED_COUNT; i++) {
if (now.hour() == feedTimes[i].hour &&
now.minute() == feedTimes[i].minute &&
!fedToday[i]) {
Serial.print("Feeding time ");
Serial.print(i + 1);
Serial.println("!");
feed();
fedToday[i] = true;
}
}
// 每天0点重置喂食标记
if (now.hour() == 0 && now.minute() == 0) {
for (int i = 0; i < FEED_COUNT; i++) {
fedToday[i] = false;
}
Serial.println("Daily reset");
}
delay(1000);
}
void feed() {
Serial.println("Feeding...");
digitalWrite(RELAY_PIN, HIGH);
delay(FEED_DURATION);
digitalWrite(RELAY_PIN, LOW);
Serial.println("Feeding complete");
}
void printTime(DateTime dt) {
Serial.print(dt.year());
Serial.print('/');
Serial.print(dt.month());
Serial.print('/');
Serial.print(dt.day());
Serial.print(' ');
Serial.print(dt.hour());
Serial.print(':');
if (dt.minute() < 10) Serial.print('0');
Serial.print(dt.minute());
Serial.print(':');
if (dt.second() < 10) Serial.print('0');
Serial.println(dt.second());
}
测试验证¶
基本功能测试清单¶
- 电源测试:确认模块电源电压正确(5V)
- 静态测试:上电后继电器不应自动吸合
- 吸合测试:发送高电平,继电器吸合,听到"咔哒"声
- 释放测试:发送低电平,继电器释放
- 触点测试:用万用表测量COM-NO通断状态
- LED指示:模块LED随继电器状态变化
- 负载测试:连接实际负载,测试开关功能
- 连续测试:连续切换100次,检查可靠性
性能测试¶
测试1:响应时间测试
void testResponseTime() {
Serial.println("=== Response Time Test ===");
unsigned long startTime = micros();
digitalWrite(RELAY_PIN, HIGH);
unsigned long onTime = micros() - startTime;
delay(100);
startTime = micros();
digitalWrite(RELAY_PIN, LOW);
unsigned long offTime = micros() - startTime;
Serial.print("Turn ON time: ");
Serial.print(onTime);
Serial.println(" us");
Serial.print("Turn OFF time: ");
Serial.print(offTime);
Serial.println(" us");
}
测试2:负载能力测试
void testLoadCapacity() {
Serial.println("=== Load Capacity Test ===");
Serial.println("Testing with different loads...");
// 测试不同负载
const char* loads[] = {"LED (20mA)", "Lamp (500mA)", "Motor (2A)"};
for (int i = 0; i < 3; i++) {
Serial.print("Load: ");
Serial.println(loads[i]);
digitalWrite(RELAY_PIN, HIGH);
delay(5000); // 保持5秒
digitalWrite(RELAY_PIN, LOW);
delay(2000);
Serial.println("Test passed");
}
}
测试3:寿命测试
void testLifetime() {
Serial.println("=== Lifetime Test ===");
Serial.println("Testing 1000 cycles...");
for (int i = 0; i < 1000; i++) {
digitalWrite(RELAY_PIN, HIGH);
delay(100);
digitalWrite(RELAY_PIN, LOW);
delay(100);
if ((i + 1) % 100 == 0) {
Serial.print("Completed ");
Serial.print(i + 1);
Serial.println(" cycles");
}
}
Serial.println("Lifetime test complete");
}
故障排除¶
常见问题解决方案¶
| 问题 | 可能原因 | 解决方法 |
|---|---|---|
| 继电器不吸合 | 电源未接通 | 检查VCC和GND连接 |
| 触发电平错误 | 确认高/低电平触发 | |
| 控制信号无输出 | 检查代码和引脚 | |
| 负载不工作 | COM/NO接线错误 | 检查接线,用万用表测试 |
| 负载本身故障 | 更换负载测试 | |
| 负载功率过大 | 更换大功率继电器 | |
| 继电器频繁切换 | 程序逻辑错误 | 添加防抖和滞后 |
| 传感器信号抖动 | 添加滤波算法 | |
| MCU复位 | 电磁干扰 | 电源分离,添加滤波 |
| 电源电压跌落 | 使用独立电源 | |
| 继电器发热 | 负载电流过大 | 降低负载或更换继电器 |
| 触点接触不良 | 清洁或更换继电器 |
进阶扩展¶
扩展1:固态继电器(SSR)¶
固态继电器无机械触点,寿命更长:
// SSR控制与机械继电器相同
const int SSR_PIN = 2;
void setup() {
pinMode(SSR_PIN, OUTPUT);
digitalWrite(SSR_PIN, LOW);
}
void loop() {
// SSR可以实现PWM调光(部分型号)
analogWrite(SSR_PIN, 128); // 50%功率
delay(2000);
analogWrite(SSR_PIN, 255); // 100%功率
delay(2000);
}
SSR优点: - 无机械磨损,寿命长(>10亿次) - 无噪音,无火花 - 切换速度快 - 可以PWM调光
SSR缺点: - 成本较高 - 有漏电流(约1-5mA) - 需要散热
扩展2:MQTT远程控制¶
使用MQTT协议实现远程控制:
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
const char* ssid = "YourSSID";
const char* password = "YourPassword";
const char* mqtt_server = "broker.hivemq.com";
WiFiClient espClient;
PubSubClient client(espClient);
const int RELAY_PIN = D1;
void setup() {
pinMode(RELAY_PIN, OUTPUT);
digitalWrite(RELAY_PIN, LOW);
Serial.begin(115200);
setup_wifi();
client.setServer(mqtt_server, 1883);
client.setCallback(callback);
}
void loop() {
if (!client.connected()) {
reconnect();
}
client.loop();
}
void setup_wifi() {
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\nWiFi connected");
}
void callback(char* topic, byte* payload, unsigned int length) {
String message;
for (int i = 0; i < length; i++) {
message += (char)payload[i];
}
Serial.print("Message: ");
Serial.println(message);
if (message == "ON") {
digitalWrite(RELAY_PIN, HIGH);
client.publish("relay/status", "ON");
} else if (message == "OFF") {
digitalWrite(RELAY_PIN, LOW);
client.publish("relay/status", "OFF");
}
}
void reconnect() {
while (!client.connected()) {
Serial.print("Connecting to MQTT...");
if (client.connect("ESP8266Client")) {
Serial.println("connected");
client.subscribe("relay/control");
} else {
Serial.print("failed, rc=");
Serial.println(client.state());
delay(5000);
}
}
}
扩展3:能耗监测¶
添加电流传感器监测负载功耗:
const int RELAY_PIN = 2;
const int CURRENT_SENSOR_PIN = A0;
float voltage = 220.0; // 电压(V)
float sensitivity = 0.066; // ACS712-30A灵敏度(V/A)
void setup() {
pinMode(RELAY_PIN, OUTPUT);
Serial.begin(9600);
}
void loop() {
if (Serial.available() > 0) {
char cmd = Serial.read();
if (cmd == '1') {
digitalWrite(RELAY_PIN, HIGH);
Serial.println("Relay ON");
delay(1000);
measurePower();
} else if (cmd == '0') {
digitalWrite(RELAY_PIN, LOW);
Serial.println("Relay OFF");
}
}
}
void measurePower() {
// 采样100次求平均
float sum = 0;
for (int i = 0; i < 100; i++) {
int sensorValue = analogRead(CURRENT_SENSOR_PIN);
float voltage = sensorValue * (5.0 / 1023.0);
sum += voltage;
delay(10);
}
float avgVoltage = sum / 100.0;
float current = (avgVoltage - 2.5) / sensitivity; // 2.5V是零点
float power = voltage * abs(current);
Serial.print("Current: ");
Serial.print(current);
Serial.println(" A");
Serial.print("Power: ");
Serial.print(power);
Serial.println(" W");
}
总结¶
关键要点¶
- 工作原理:
- 继电器通过电磁铁控制触点开关
- 实现小电流控制大电流
-
提供电气隔离保护
-
触点配置:
- COM:公共端
- NO:常开端(未通电时断开)
-
NC:常闭端(未通电时闭合)
-
驱动方式:
- 使用继电器模块(推荐):内置驱动和保护
-
自制驱动电路:需要三极管和续流二极管
-
安全措施:
- 电气隔离(光耦)
- 续流保护(二极管)
- 过载保护(保险丝)
-
软件防抖
-
应用场景:
- 智能家居控制
- 工业自动化
- 定时控制系统
- 传感器联动
最佳实践¶
- ✅ 使用继电器模块简化开发
- ✅ 添加续流保护(感性负载)
- ✅ 实现软件防抖避免频繁切换
- ✅ 电源与MCU分离
- ✅ 高压电路必须有专业指导
- ❌ 避免频繁切换(减少磨损)
- ❌ 不要超过额定参数
- ❌ 不要忽视电气安全
下一步学习¶
相关教程¶
进阶主题¶
项目实践¶
参考资料¶
数据手册¶
- SRD-05VDC-SL-C Datasheet - 常用5V继电器规格书
- PC817 Datasheet - 光耦隔离芯片
- 1N4007 Datasheet - 续流二极管
技术文章¶
- "Relay Basics and Applications" - 继电器基础知识
- "Relay Driver Circuit Design" - 驱动电路设计
- "Solid State Relay vs Mechanical Relay" - SSR与机械继电器对比
- "Relay Protection Techniques" - 继电器保护技术
视频教程¶
- "Arduino Relay Control Tutorial" - YouTube基础教程
- "Building a Smart Home with Relays" - 智能家居制作
- "Relay Safety and Best Practices" - 安全使用指南
开源项目¶
- Home Automation - Home Assistant智能家居平台
- ESP8266 Relay Control - ESP8266继电器控制固件
- Arduino Relay Shield - Arduino继电器扩展板
附录¶
A. 继电器选型参考¶
| 应用场景 | 推荐型号 | 触点容量 | 线圈电压 | 价格 |
|---|---|---|---|---|
| LED灯控制 | SRD-05VDC-SL-C | 10A/250VAC | 5V | ¥3 |
| 家用电器 | HF115F-012-1ZS4 | 16A/250VAC | 12V | ¥5 |
| 工业设备 | G2R-1-E | 16A/250VAC | 24V | ¥8 |
| 大功率负载 | JQX-30F | 30A/250VAC | 12V | ¥12 |
| 无噪音应用 | SSR-25DA | 25A/380VAC | 3-32VDC | ¥15 |
B. 负载类型与保护¶
| 负载类型 | 特点 | 保护措施 |
|---|---|---|
| 阻性负载 | 灯泡、电热器 | 基本保护即可 |
| 感性负载 | 电机、电磁阀 | 必须添加续流二极管 |
| 容性负载 | 电容器、开关电源 | 添加限流电阻 |
| 混合负载 | 计算机、电视 | 综合保护措施 |
C. 故障诊断流程图¶
继电器不工作?
│
├─ 检查电源
│ ├─ VCC电压正常?(5V)
│ │ ├─ 是 → 继续
│ │ └─ 否 → 修复电源
│ └─ 电流充足?(>70mA)
│ ├─ 是 → 继续
│ └─ 否 → 更换电源
│
├─ 检查信号
│ ├─ IN引脚有信号?
│ │ ├─ 是 → 继续
│ │ └─ 否 → 检查代码/接线
│ └─ 触发电平正确?
│ ├─ 是 → 继续
│ └─ 否 → 修改代码
│
├─ 检查继电器
│ ├─ LED指示灯亮?
│ │ ├─ 是 → 继电器可能损坏
│ │ └─ 否 → 模块故障
│ └─ 听到吸合声?
│ ├─ 是 → 检查触点
│ └─ 否 → 更换继电器
│
└─ 检查负载
├─ COM-NO通断正常?
│ ├─ 是 → 检查负载
│ └─ 否 → 更换继电器
└─ 负载本身正常?
├─ 是 → 检查接线
└─ 否 → 更换负载
版权声明:本文档采用 CC BY-SA 4.0 协议,欢迎分享和改编,但请注明出处。
反馈与支持: - 发现错误或有改进建议?请在评论区留言 - 分享你的继电器项目,与社区交流 - 需要技术支持?访问我们的论坛
最后更新:2024-01-15