Skip to content

概述

官方基础工程已预置继电器驱动(components/relay)并在任务中完成初始化;relay 工具已在创建 MCP 工具第 5 章注册。本章接线(PB5)→ 确认工具 → 实现 AI 语音控制继电器开/关。


🎯本页目标使用示例工程预置的继电器驱动(PB5)与第 5 章注册的工具,实现 AI 语音控制继电器开/关。
🧰前置条件① 完成 [创建 MCP 工具](./create-mcp-tool)(relay 工具已注册)② 继电器模块(SRD-05VDC)与杜邦线。
🔗相关章节后续案例(温湿度/OLED/电源/灯带)均沿用"官方预置模块 + 新增 MCP 工具"的模式。
确认官方已预置 relay 驱动

示例工程已预置继电器驱动(components/relay,STM32 HAL 直调版),无需复制或修改。驱动接口如下(对照理解):

/* components/relay/relay.c —— HAL 直调版 */
#include "relay.h"
#include "gpio.h"
#include "log.h"
#include "stm32f1xx_hal_gpio.h"

static unsigned char axk_relay_state = 0;

/* 上电时把继电器置为断开(PB5 输出低) */
void axk_relay_init(void) {
  if (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_5) != GPIO_PIN_RESET) {
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_RESET);
    return;
  }
}

/* 设置继电器:state=ON(1) 吸合,state=OFF(0) 释放 */
void axk_relay_set(unsigned char state) {
  axk_relay_state = state;
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, state);
}

void axk_relay_toggle(void) {
  axk_relay_state = !axk_relay_state;
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, axk_relay_state);
}

unsigned char axk_relay_get(void) { return axk_relay_state; }

头文件 relay.h 接口:

#ifndef __RELAY_H__
#define __RELAY_H__

#define ON 1    // 吸合
#define OFF 0   // 释放

void axk_relay_init(void);
void axk_relay_set(unsigned char state);
unsigned char axk_relay_get(void);
void axk_relay_toggle(void);
#endif
确认 CMake 构建已包含 relay

示例工程的 components/CMakeLists.txt 已包含 relay 目录(源文件与头文件路径),无需修改

接线

🧩 九章板继电器已板载接好(PB5 控制),无需接线。下表供对照认识引脚,或扩展外部继电器模块时参考。

继电器模块 接开发板 说明
IN / SIG(信号输入) PB5 高电平吸合、低电平释放
VCC 5V 继电器线圈供电
GND GND 共地
COM / NO(触点) 被控负载回路 如灯泡:火线串入 COM–NO

⚠️ 安全提醒:继电器触点常用于控制 220V 交流电器,接线务必断电操作,裸露线头做好绝缘。新手建议先用 LED + 电阻蜂鸣器 当负载测试,确认逻辑正确后再接强电。

确认 relay 工具已注册(第 5 章已完成)

relay 工具的回调与注册已在创建 MCP 工具第 5 章完成(relay_set_handler 控制继电器、relay_check_handler 查询状态)。工具回调中的核心动作就是调用驱动:

/* 工具回调里调用驱动 */
if (strcmp(s, "on") == 0) { relay_on = true; axk_relay_set(ON); log_info("Relay -> ON"); }
else if (strcmp(s, "off") == 0) { relay_on = false; axk_relay_set(OFF); log_info("Relay -> OFF"); }

/* 任务初始化时调用一次 */
axk_relay_init();

别忘了在 freertos.c 顶部 #include "relay.h",并定义全局状态 static bool relay_on = false;

烧录 + AI 语音控制
  1. 编译烧录(见 例程运行验证),板子上电。

  2. 手动验证(俗称"冒烟测试"——不依赖 AI,先用串口直接发指令,确认硬件和工具逻辑正常):串口助手连 USART2(115200)发送:

    {"role":"AI","msgType":"MCP","data":{"name":"relay","args":{"state":"on"}}}
    

    继电器应吸合;将 "on" 改为 "off",继电器释放。

  3. AI 语音控制:确认 AI 模组已配网后,对模组说:

    • “你好小安”(唤醒,日志出现 WakeUP)
    • “打开继电器” → 继电器吸合
    • “关闭继电器” → 继电器释放
    • “继电器现在是什么状态?” → AI 调用 check 回调并回复

    AI 查询继电器状态

AI 不执行指令?① 模组未联网 → 重新配网;② 工具未注册成功 → 看日志是否有 mcp-tool sent;③ 描述不匹配 → 工具的 description 写清楚(“打开/关闭继电器”),AI 依靠 description 理解工具;④ 手动 JSON 能控制但语音不行 → 确认模组固件为 UART-MCP 版本。


常见问题与踩坑提示

🔧 继电器不动作(无吸合声)
原因:① 模块供电不足 ② 触发极性不对 ③ 未共地
解决:① 模块 VCC 必须接 5V(接 3.3V 时线圈吸合力不足)② 部分模块为低电平触发,可将接线接至常闭端,或修改 axk_relay_set 逻辑 ③ GND 必须与板子共地

🔧 上电时继电器乱跳一下
原因:芯片复位瞬间引脚电平不定
解决:正常现象;如需消除可在模块 IN 加下拉电阻,或接受它(本项目 axk_relay_init 上电即拉低)

🔧 手动 JSON 能控制,AI 语音不行
原因:工具描述不清晰或模组未唤醒
解决:说"你好小安"先唤醒;把 description 写成"打开/关闭继电器"这类大白话

🔧 继电器吸合但负载不工作
原因:触点接线错
解决:COM 和 NO 是常开端(吸合才通);要常通就接 COM/NC;确认负载回路有电

🔧 继电器动作了,但 AI 播报"打开失败";且指令要过一会才执行原因:⚠️ USART2 中断未使能(.ioc 没勾 USART2 global interrupt) 解决:在 STM32 工程创建 勾选 USART2 global interrupt 并重新生成,这是本项目最容易踩的坑

🔧 继电器能开、AI 也播报正常,但温湿度/灯带等长消息工具总失败原因:接收消息字节丢失 解决:串口日志乱码/丢字节时见温湿度案例的日志互斥锁说明

🔧 控制 220V 电器时模块发热/异味
原因:电流超过继电器触点额定
解决:SRD-05VDC 触点额定约 10A;大功率负载换更大继电器,接线务必断电操作

🔧 测试时 LED 直接烧了
原因:LED 没串限流电阻
解决:LED 必须串电阻(220Ω~1kΩ),或直接用蜂鸣器模块/万用表蜂鸣档

🔧 PB5 电平一直高
原因:CubeMX 里 PB5 没配置或初始状态不对
解决:确认 .ioc 里 PB5 为 GPIO_Output(本项目初始为低电平,断开状态)

高压负载测试顺序

先空载测试(确认继电器吸合/释放动作正常)→ 再接 LED+电阻 或蜂鸣器 → 确认逻辑无误后,最后才接强电负载,且全程断电接线。


下一步

Released under the MIT License. Build Time 2026-08-07 22:59:19