电子模块 · 继电器控制 · STM32实战⑮ · SKU 待补充

【STM32实战⑮】单路光耦继电器模块

STM32F103C8T6 使用 PB1 控制单路光耦继电器,OLED 同步显示 ON / OFF 状态与完整周期计数。继电器 DC+ 使用独立 5V,DC- 与 STM32 共地;黄色跳帽已实测确认为低电平触发。页面包含接线图、PlatformIO 代码、烧录与实拍视频、工程下载和低压测试安全提示。

Quick Facts

  • 控制:继电器 IN → PB1
  • 供电:DC+ → 独立 5V,DC- → GND 并与 STM32 共地
  • OLED:SCL=PB8 / SDA=PB9,3.3V 供电
  • 周期:每 1000ms 切换一次,OFF 时完整周期计数 +1
  • 触发:黄色跳帽已实测确认为低电平触发
  • 安全:首次测试仅接低压直流负载

Current status

验证状态与现有演示

部分待确认 页面依据现有接线记录、程序、烧录录像和实拍演示整理;没有把未完成的验证写成“实测通过”。

PB1继电器 IN 控制引脚
1000 ms程序状态切换周期
独立 5V继电器 DC+ 供电
PB8 / PB9OLED SCL / SDA
项目当前状态
接线图与程序已整理 IN→PB1;DC+→独立 5V;DC- 与 STM32 共地;OLED SCL→PB8、SDA→PB9
烧录与演示素材已有素材 已有 PlatformIO 烧录录像和继电器/OLED 运行画面
黄色跳帽 H/L 位置已验证 实测为低电平触发,与代码 RELAY_ACTIVE_LOW=true 一致
PB1 3.3V 触发兼容性、负载端用途待确认 不作为本页已验证结论
单路继电器、STM32F103C8T6 与 OLED 演示画面
现有演示素材:继电器、BluePill 与 OLED 同框

完整演示视频

Module

模块说明

单路光耦继电器模块让 STM32 用一个数字引脚控制继电器线圈,再由 NO / COM / NC 触点切换外部负载。控制侧和负载侧用途不同:本项目页面只确认控制侧接线,负载端实际用途仍需结合负载方案确认。

单路光耦继电器模块正面
模块正面:控制端 IN / DC- / DC+,负载端 NO / COM / NC
OLED 显示继电器状态和切换次数
OLED 演示画面:显示 ON / OFF 与 Count
本项目实测单元为低电平触发。黄色跳帽用于选择高/低电平触发,位置可由用户拨动;如果您手上的模块跳帽位置和本页不一样,控制逻辑会相反,请先按实物确认再套用本页代码。

Wiring

接线

接线基准 下面内容来自本项目 Fritzing 接线记录。

设备端子连接说明
继电器INPB1控制信号
继电器DC+独立 5V禁止接入 STM32 3.3V
继电器DC-STM32 GND与外部 5V 电源共地
OLEDVCC / GND3.3V / GND由 STM32 供电
OLEDSCLPB8软件 I²C 时钟
OLEDSDAPB9软件 I²C 数据
STM32、OLED、单路继电器和独立5V电源的Fritzing接线图
Fritzing 接线图:继电器独立 5V 供电,控制系统必须共地
最容易接错:继电器 DC+ 不能接 STM32 的 3.3V;外部电源 GND、继电器 DC- 和 STM32 GND 必须相连。

Principle

工作原理

资料参考 控制端收到符合跳帽模式的有效电平后,模块驱动继电器线圈,使 COM 与 NO/NC 的连接状态切换。光耦用于控制信号隔离,但本接线仍要求控制侧共地。

为什么使用独立 5V

继电器线圈由独立 5V 电源提供能量,STM32 只输出 PB1 控制电平。这样避免用 3.3V 引脚给线圈供电,并让控制与功率供电职责更清楚。

为什么代码要匹配跳帽

低电平触发时,ON 对应 PB1 输出 LOW;高电平触发时相反。代码中的 RELAY_ACTIVE_LOW 必须与黄色跳帽实际位置一致。

Logic

程序逻辑

  1. 上电时先写入关闭电平,再把 PB1 设置为输出,减少误动作风险。
  2. 每隔 1000ms 翻转一次继电器状态。
  3. 从 ON 回到 OFF 时,完整周期计数加一。
  4. OLED 同步显示 STATUS: ON/OFF 与 Count。
constexpr uint32_t RELAY_PIN = PB1;
constexpr unsigned long RELAY_INTERVAL_MS = 1000;
constexpr bool RELAY_ACTIVE_LOW = true; // 实测跳帽为低电平触发

setRelay(!relayOn);
if (!relayOn) ++relayCycleCount;
updateOLED();
VS Code PlatformIO 编译和烧录演示画面
现有成片中的 PlatformIO 编译与烧录画面

Source

完整代码

代码来自本项目 src/main.cpp,页面展示内容与下载包一致。

src/main.cpp · PlatformIO / STM32duino
#include <Arduino.h>
#include <U8g2lib.h>

// ============================================================
// 15_继电器测试程序
// 模块:单路光耦隔离继电器,高/低电平触发由黄色跳帽选择,本项目实测为低电平触发
//
// 接线:
// 继电器 IN  -> PB1
//         DC+ -> 外部 5V
//         DC- -> GND(必须与 STM32 共地)
// OLED   SCL -> PB8
//        SDA -> PB9
//
// 功能:每 1000 ms 切换一次继电器,OLED 同步显示状态和次数。
// ============================================================

constexpr uint32_t RELAY_PIN = PB1;
constexpr uint32_t OLED_SCL_PIN = PB8;
constexpr uint32_t OLED_SDA_PIN = PB9;
constexpr unsigned long RELAY_INTERVAL_MS = 1000;

// 本项目实测黄色跳帽为低电平触发,保持 true;
// 如果您手上模块的跳帽位置不同,请改为 false 并以实物验证结果为准。
constexpr bool RELAY_ACTIVE_LOW = true;

U8G2_SSD1306_128X64_NONAME_F_SW_I2C u8g2(
    U8G2_R0,
    OLED_SCL_PIN,
    OLED_SDA_PIN,
    U8X8_PIN_NONE
);

bool relayOn = false;
unsigned long previousMillis = 0;
unsigned long relayCycleCount = 0;

uint8_t relayLevel(bool on)
{
    if (RELAY_ACTIVE_LOW)
    {
        return on ? LOW : HIGH;
    }
    return on ? HIGH : LOW;
}

void setRelay(bool on)
{
    relayOn = on;
    digitalWrite(RELAY_PIN, relayLevel(on));
}

void updateOLED()
{
    u8g2.clearBuffer();
    u8g2.setFont(u8g2_font_6x12_tf);
    u8g2.drawStr(0, 12, "15 RELAY");
    u8g2.drawHLine(0, 17, 128);
    u8g2.drawStr(0, 32, "STATUS:");

    u8g2.setFont(u8g2_font_logisoso18_tf);
    u8g2.drawStr(55, 39, relayOn ? "ON" : "OFF");

    u8g2.setFont(u8g2_font_6x12_tf);
    char countText[24];
    snprintf(countText, sizeof(countText), "Count: %lu", relayCycleCount);
    u8g2.drawStr(0, 61, countText);
    u8g2.sendBuffer();
}

void setup()
{
    // 先写入关闭电平,再切换为输出,减少上电瞬间误吸合风险。
    digitalWrite(RELAY_PIN, relayLevel(false));
    pinMode(RELAY_PIN, OUTPUT);
    setRelay(false);

    Serial.begin(115200);
    Serial.println("15 RELAY test start");
    Serial.println(RELAY_ACTIVE_LOW ? "Trigger: ACTIVE LOW (confirmed)" : "Trigger: ACTIVE HIGH (confirmed)");

    u8g2.begin();
    updateOLED();
}

void loop()
{
    const unsigned long currentMillis = millis();
    if (currentMillis - previousMillis < RELAY_INTERVAL_MS)
    {
        return;
    }

    previousMillis = currentMillis;
    setRelay(!relayOn);

    if (!relayOn)
    {
        ++relayCycleCount;
    }

    Serial.print("Relay: ");
    Serial.println(relayOn ? "ON" : "OFF");
    updateOLED();
}

Download

下载

PlatformIO 完整工程包含 platformio.ini、src/main.cpp、BIN/ELF 固件、接线图与技术状态说明
下载 ZIP

Troubleshooting

常见问题排查

现象检查方法
继电器不动作先查 DC+ 是否为独立 5V、DC- 是否共地,再确认黄色跳帽与 RELAY_ACTIVE_LOW 是否一致。
上电瞬间误动作确认代码先写关闭电平再设置 OUTPUT,并检查跳帽极性。
OLED 不显示确认 VCC=3.3V、GND 共地、SCL=PB8、SDA=PB9。
OLED 状态与继电器相反通常是代码触发极性与黄色跳帽不一致。
想接市电负载本页不提供裸露市电接线指导;应使用合规外壳、保险与专业电工方案。

Sources

资料来源