项目介绍
本项目创新性地结合Seeed XIAO ESP32S3 Sense开发板的硬件优势,打造了具备环境感知、AI分析与动态交互的恐怖主题机械姬装置。系统通过10G雷达检测人体接近,触发多模态响应链:包括摄像头拍摄、LED眼睛发光、语音播放及舵机驱动的机械面罩动作,形成完整的恐怖体验闭环。技术亮点在于低功耗传感与高性能计算的协同架构设计,以及机械动作、声光反馈与AI分析的实时交互逻辑。装置可扩展应用于密室逃脱、主题展馆等场景,具有显著的商业转化潜力。
本项目依托于互动标牌:https://www.eetree.cn/task/845
设计思路
随着沉浸式娱乐需求的快速增长,我们创新性地将边缘计算与机电控制技术相结合,打造具有恐怖主题交互体验的智能装置。本项目基于Seeed XIAO ESP32S3 Sense开发板的硬件特性,构建了从环境感知到动态反馈的完整技术闭环。
核心设计理念
多模态协同交互架构:通过10G毫米波雷达实现非接触式人体检测,配合环境光传感器确保夜间触发效果,形成"感知-决策-执行"的实时响应链条。系统采用分层设计:
传感层:雷达+光照双重检测
计算层:ESP32S3双核处理(事件核+AI核)
执行层:机械动作+LED+音效同步输出
关键技术实现
硬件协同设计:
低功耗触发机制:HLK人体感应雷达模块通过硬件连接A1,中断唤醒深度睡眠的主控
实时图像处理:OV5640摄像头采用DVP接口直连ESP32S3,配合8MB PSRAM实现:
320x240分辨率下30FPS捕获
JPEG压缩耗时<80ms
YOLOv8n模型推理时间150ms
硬件配置清单
1. 主控模块:Seeed XIAO ESP32S3 Sense开发板
l 集成Xtensa®双核处理器,支持WiFi/BLE 5.0双模通信
l 板载8MB PSRAM+8MB Flash,配备OV2640摄像头的升级版OV5640与数字麦克风
2. 感知单元
l 10G毫米波雷达(检测距离2-8m,响应时间<50ms,上电稳定时间<17s)
l BH1750光照传感器(采集环境光亮度数据,确保晚上才吓人^_^)
3. 执行机构
l WS2811+ RGB LED灯珠x2(眼珠特效),加RGB灯带接口。
l SG90舵机(面罩抬升机构,行程角度0-90°)
4. 存储与通信
l 32GB microSD卡(通过SPI接口扩展)
l WIFI上传,WEB服务,MQTT协议等
系统架构设计
方案框图
设计思路
1. 触发逻辑:雷达信号经硬件消抖后,通过GPIO中断主控开始执行。
2. 处理:
l 1:雷达人体检测&BH1750光照检测
l 2:摄像头捕获→JPEG压缩→SD卡存储
l 3:PWM控制舵机+NeoPixel驱动LED芯片
l 4:摄像头捕获→轻量级AI模型运行(人脸表情识别)→JPEG压缩→SD卡存储
软件实现
关键流程图
stateDiagram-v2
[*] --> 雷达人体检测
雷达人体检测 --> 光照检测
光照检测 --> 符合
光照检测 --> 不符合
不符合 -->雷达人体检测
符合 -->摄像头捕获1
摄像头捕获1-->JPEG压缩
JPEG压缩-->SD卡存储
SD卡存储--> PWM控制舵机到60°
SD卡存储--> 播放恐怖声音
SD卡存储--> NeoPixel驱动LED芯片
PWM控制舵机到60°--> 摄像头捕获2
播放恐怖声音--> 摄像头捕获2
NeoPixel驱动LED芯片--> 摄像头捕获2
摄像头捕获2-->JPEG压缩SD卡存储
JPEG压缩SD卡存储-->延迟5秒
延迟5秒-->LED关闭
LED关闭-->舵机恢复0°
舵机恢复0° --> [*]
原理图
接入两路人体存在感应,挂墙上时,无论从哪个方向都能触发……吓人。
检测光照,白天时候不吓人,做个安静的好宝宝~
触发舵机控制
使用WS2811芯片,以便接入草帽RGB灯珠,并且还能外接一圈灯带。
使用音频芯片,播放各种吓人音效,同时带动LED-R闪烁,增加氛围感。
PCB图
为了适配开发板,PCB画的比较小,又是多个插件元件,导致可用区域非常紧凑,不得不做了很多让步。
pcb实物图
硬件连接示意图
本项目使用了先进的接口接线方式,使用不同型号、规格的接口,将外设和控制板连接一起,安装简单方便,为以后量产做了很好的铺垫。本次项目也都是用成品线连接的。舵机使用排针焊接,可以直接连接到舵机连线;开发板和控制板连接使用加长排母;其他未说明的地方不焊接。
硬件连接图
开发
本项目使用circuitpython9.2.8开发,在开发时候,意外发现了可以在线烧录固件,为开发节省了大量搭建开发环境,烧录固件的时间。大概在线烧录固件流程如下:
1.进入开发板固件网页https://circuitpython.org/board/seeed_xiao_esp32s3_sense/
第一次要选全功能
然后点下一步。
再按照提示步骤,会自动下载tiny固件,自动烧录。
是的,这里要烧录两次,一次tiny固件,一次circuitpython固件。
烧录好后,要选择文件夹,保存SSID,方便自动联网,当然,也可以跳过。
然后可以在线编辑Python脚本,很方便吧?
就能连接上了。
代码演示
# MG90S舵机控制演示
import time
import board
import pwmio
from adafruit_motor import servo
# 初始化PWM输出
pwm = pwmio.PWMOut(board.D10, frequency=50)
# 创建舵机对象
my_servo = servo.Servo(pwm, min_pulse=500, max_pulse=2500)
def set_servo_angle(angle):
"""设置舵机角度"""
if 0 <= angle <= 180:
my_servo.angle = angle
print(f"舵机已转到 {angle}°")
else:
print("错误:角度必须在0-180度之间")
# 主程序
print("MG90S舵机控制演示")
set_servo_angle(60) # 转到45度位置 0-70
time.sleep(2) # 保持2秒
# 高电平时候点亮双眼
import time
import board
import digitalio
import neopixel_write
# 输入引脚配置(D1对应A1)
input_pin = digitalio.DigitalInOut(board.A1)
input_pin.direction = digitalio.Direction.INPUT
# 输出引脚配置(WS2812控制)
led_pin = digitalio.DigitalInOut(board.A3)
led_pin.direction = digitalio.Direction.OUTPUT
# LED颜色定义(GRB格式)
BLUE = bytearray([0, 255, 255]) # 全亮蓝色
OFF = bytearray([0, 0, 0]) # 关闭状态
while True:
if input_pin.value: # 检测高电平
neopixel_write.neopixel_write(led_pin, BLUE)
print("D1:HIGH → LED ON")
else:
neopixel_write.neopixel_write(led_pin, OFF)
print("D1:LOW → LED OFF")
time.sleep(0.1) # 100ms检测间隔
#该代码实现BH1750光照传感器数据采集,通过I2C接口连接ESP32-S3,每秒输出1次光照值。包含错误处理机制,当通信异常时自动重试。需先安装CircuitPython的BH1750库。
import time
import board
import busio
import adafruit_bh1750
# 初始化I2C总线
i2c = busio.I2C(board.A5, board.A4) # SCL=A5, SDA=A4
# 创建传感器实例
sensor = adafruit_bh1750.BH1750(i2c)
# 主循环读取并打印光照数据
while True:
try:
lux = sensor.lux
print(f"光照强度: {lux:.2f} lx")
time.sleep(1)
except OSError as e:
print(f"传感器读取错误: {e}")
time.sleep(5)
# 拍照保存到SD.py
import os
import time
import board
import busio
import displayio
import busdisplay
import fourwire
import espcamera
import espidf
import keypad
import sdcardio
import storage
print("Initializing display")
displayio.release_displays()
i2c = busio.I2C(scl=board.CAM_SCL, sda=board.CAM_SDA)
print("Initializing SD card")
sd_spi = busio.SPI(clock=board.D8, MOSI=board.D10, MISO=board.D9)
sd_cs = board.LED
sdcard = sdcardio.SDCard(sd_spi, sd_cs)
vfs = storage.VfsFat(sdcard)
storage.mount(vfs, "/sd")
print("Initializing camera")
cam = espcamera.Camera(
data_pins=board.CAM_DATA,
external_clock_pin=board.CAM_XCLK,
pixel_clock_pin=board.CAM_PCLK,
vsync_pin=board.CAM_VSYNC,
href_pin=board.CAM_HREF,
pixel_format=espcamera.PixelFormat.RGB565,
frame_size=espcamera.FrameSize.QVGA,
i2c=i2c,
external_clock_frequency=20_000_000,
framebuffer_count=1)
print("initialized")
def exists(filename):
try:
os.stat(filename)
return True
except OSError:
return False
_image_counter = 0
def open_next_image(extension="jpg"):
global _image_counter # pylint: disable=global-statement
while True:
filename = f"/sd/img{_image_counter:04d}.{extension}"
_image_counter += 1
if exists(filename):
continue
print("#", filename)
return open(filename, "wb")
while True:
frame = cam.take(1)
cam.reconfigure(
pixel_format=espcamera.PixelFormat.JPEG,
frame_size=espcamera.FrameSize.SVGA,
)
frame = cam.take(1)
if isinstance(frame, memoryview):
jpeg = frame
print(f"Captured {len(jpeg)} bytes of jpeg data")
with open_next_image() as f:
f.write(jpeg)
cam.reconfigure(
pixel_format=espcamera.PixelFormat.JPEG,
frame_size=espcamera.FrameSize.QVGA,
)
time.sleep(10)
整合后代码在附件中。
功能演示
1. 恐怖场景还原
l 图1:待机状态
l 图2:触发后
2. 数据看板
l 图3:Web界面展示历史触发记录与拍照图片
技术难点与突破
1. 实时性冲突:
l 问题:摄像头初始化耗时导致动作反馈延迟
l 解决:预加载驱动+RAM缓存帧,将响应时间从2.1s压缩至0.8s
2. 电源干扰:
l 问题:舵机启动引起电压骤降导致系统偶尔重启
l 解决:增加电容+分步供电策略
项目总结
1. 创新价值:验证了边缘计算设备在沉浸式娱乐场景的应用可行性
2. 改进方向:
l 引入热成像传感器提升环境适应性
l 开发Unity3D插件实现虚拟与现实联动
l 开发看板,集中统计分析数据
3. 活动建议:希望提供更多传感器融合开发的实战案例
经验总结
1.画图没有仔细看规格书,导致购买了共阴RGB灯珠,导致灯珠连接困难;
2.没设计好位置,导致开发板需要使用加长排针才能连接,否则应该在控制板背面连接开发板,不过又导致散热和拍照位置不行,最好是摄像头在两侧和正面,防止漏拍,并做AI识别后保存。
3.3D模型建模还不熟悉,导致多次修改,多次打印,产生很多废料,也没有把开发板控制板都放模型中,没有改充电方式,导致导线外漏,不利于量产,还需要改进。
4.使用的9g舵机转动角度不稳定,很难实现闭环,最好改步进电机,以便精确控制角度。
5.关闭面具时候可以缓慢关闭,不至于一抽一抽的。
6.待定……
附件
l 完整代码包
l 3D打印模型STL文件(机械结构部分)
l PCB打样文件