本帖最后由 PY学习笔记 于 2026-6-14 11:29 编辑
在上一篇的基础上,将雷达采集到的人体存在、距离、运动状态等各类数据实时上传,在 WEB 页面完成可视化展示,直观呈现雷达的探测结果。 1、原理C4002 可以持续输出多项监测数据,包含人体存在状态、静止距离、运动距离、运动方向以及运动速度。 主控 ESP32 通过串口读取雷达原始数据,完成解析和处理后,依托 HTTP 协议将数据传输至前端页面。WEB 页面会自动实时刷新,以可视化形式展示全部探测信息,能够直观查看现场人体存在情况、大致位置以及运动相关参数。 2、测试效果代码分为两部分。 ESP32 通过串口驱动 C4002 雷达,完成参数配置后采集光照、目标状态、距离、速度及 GPIO 引脚数据,打包为 JSON 并以 UDP 协议发送至电脑。
- import time
- import machine
- import network
- import socket
- import json
-
- # 导入 C4002 库(需与 DFRobot_C4002.py 一起上传到板子)
- from DFRobot_C4002 import DFRobot_C4002, PresenceTarget, MotionTarget
-
- # ================== 网络配置 ==================
- WIFI_SSID = "SSID"
- WIFI_PASSWORD = "PASS"
- PC_IP = "192.168.31.156" # ← 改成你电脑在局域网中的实际 IP
- PC_PORT = 5001 # ← 与 PC 端保持一致
- # =============================================
-
- # 初始化 UART1,使用 GP0(TX) 和 GP1(RX)
- # 默认波特率: 115200
- c4002 = DFRobot_C4002(uart_num=1, baud=115200, tx=0, rx=1)
-
- # 初始化 GPIO2 作为雷达输出引脚的输入端
- radar_output_pin = machine.Pin(2, machine.Pin.IN, machine.Pin.PULL_DOWN)
- c4002.set_out_pin_mode(c4002.OUT_PIN_MODE1)
-
- # UDP 套接字(后面初始化)
- udp_sock = None
-
-
- def connect_wifi():
- wlan = network.WLAN(network.STA_IF)
- wlan.active(True)
- if wlan.isconnected():
- print("[WiFi] 已连接:", wlan.ifconfig()[0])
- return wlan
- print("[WiFi] 正在连接...")
- wlan.connect(WIFI_SSID, WIFI_PASSWORD)
- while not wlan.isconnected():
- time.sleep(1)
- print("[WiFi] 连接成功,IP:", wlan.ifconfig()[0])
- return wlan
-
-
- def setup():
- """完全复制你提供的测试代码初始化流程,一字未改"""
- while c4002.begin() != True:
- print("C4002 初始化失败!")
- time.sleep_ms(500)
-
- print("C4002 初始化成功!")
- time.sleep_ms(50)
-
- # 关闭指示灯
- if c4002.set_run_led_state(c4002.LED_OFF):
- print("设置运行指示灯成功!")
- else:
- print("设置运行指示灯失败!")
-
- if c4002.set_out_led_state(c4002.LED_OFF):
- print("设置输出指示灯成功!")
- else:
- print("设置输出指示灯失败!")
-
- # 设置分辨率模式(80cm 分辨率,支持 15 个距离门限)
- if c4002.set_resolution_mode(c4002.RESOLUTION_80CM):
- print("设置分辨率模式成功!")
- else:
- print("设置分辨率模式失败!")
-
- # 设置检测范围 0-1100cm
- if c4002.set_detect_range(0, 1100):
- print("设置检测范围成功!")
- else:
- print("设置检测范围失败!")
-
- # 设置光照阈值(0 = 无论光照条件如何始终检测)
- if c4002.set_light_thresh(0):
- print("设置光照阈值成功!")
- else:
- print("设置光照阈值失败!")
-
- # 启用所有距离门限
- gate_state = [
- c4002.C4002_ENABLE, c4002.C4002_ENABLE, c4002.C4002_ENABLE,
- c4002.C4002_ENABLE, c4002.C4002_ENABLE, c4002.C4002_ENABLE,
- c4002.C4002_ENABLE, c4002.C4002_ENABLE, c4002.C4002_ENABLE,
- c4002.C4002_ENABLE, c4002.C4002_ENABLE, c4002.C4002_ENABLE,
- c4002.C4002_ENABLE, c4002.C4002_ENABLE, c4002.C4002_ENABLE,
- ]
-
- if c4002.configure_gate(c4002.MOTION_DISTANCE_GATE, gate_state):
- print("启用运动距离门限成功!")
-
- if c4002.configure_gate(c4002.PRESENCE_DISTANCE_GATE, gate_state):
- print("启用存在距离门限成功!")
-
- # 设置上报周期(10 * 0.1s = 1s)
- if c4002.set_report_period(10):
- print("设置上报周期成功!")
-
-
- def get_gpio2_status():
- """读取 GPIO2 的状态并返回中文描述"""
- pin_value = radar_output_pin.value()
- if pin_value == 1:
- return "HIGH (检测到目标)"
- else:
- return "LOW (未检测到目标)"
-
-
- def get_target_state_text(state):
- if state == c4002.NO_TARGET:
- return "无目标"
- elif state == c4002.PRESENCE:
- return "静态存在"
- elif state == c4002.MOTION:
- return "运动"
- elif state == c4002.MOTION_OR_PRESENCE:
- return "运动或存在"
- elif state == c4002.MOTION_OR_NO_TARGET:
- return "运动或无目标"
- elif state == c4002.PRESENCE_OR_NO_TARGET:
- return "存在或无目标"
- else:
- return "未知"
-
-
- def get_direction_text(direction):
- if direction == c4002.AWAY:
- return "远离"
- elif direction == c4002.APPROACHING:
- return "靠近"
- elif direction == c4002.NODIRECTION:
- return "无方向"
- else:
- return "未知"
-
-
- def loop():
- global udp_sock
- ret_result = c4002.get_note_info()
-
- if ret_result.note_type == c4002.RESULT:
- # -------- 获取全部传感器数值(与你测试代码完全一致)--------
- light = c4002.get_light_intensity()
- target_state = c4002.get_target_state()
- presence_count_down = c4002.get_presence_count_down()
- presence_target = c4002.get_presence_target_info()
- motion_target = c4002.get_motion_target_info()
- gpio2_val = radar_output_pin.value()
- gpio2_text = get_gpio2_status()
-
- # -------- 串口打印(方便 Thonny 调试观察)--------
- print("------- 获取全部结果 --------")
- print("光照强度: {:.2f} lux".format(light))
- print("目标状态: {}".format(get_target_state_text(target_state)))
- print("存在倒计时: {} s".format(presence_count_down))
- print("存在距离: {:.2f} m".format(presence_target.distance))
- print("存在能量: {}".format(presence_target.energy))
- print("运动距离: {:.2f} m".format(motion_target.distance))
- print("运动能量: {}".format(motion_target.energy))
- print("运动速度: {:.2f} m/s".format(motion_target.speed))
- print("运动方向: {}".format(get_direction_text(motion_target.direction)))
- print("GPIO2 输出: {}".format(gpio2_text))
- print("--------------------------------")
-
- # -------- 打包全部数据通过 UDP 发往 PC --------
- payload = {
- "ts": time.ticks_ms(),
- "light": round(light, 2),
- "target_state": target_state,
- "target_state_text": get_target_state_text(target_state),
- "presence_count_down": presence_count_down,
- "presence": {
- "distance": round(presence_target.distance, 2),
- "energy": presence_target.energy
- },
- "motion": {
- "distance": round(motion_target.distance, 2),
- "energy": motion_target.energy,
- "speed": round(motion_target.speed, 2),
- "direction": motion_target.direction,
- "direction_text": get_direction_text(motion_target.direction)
- },
- "gpio2": gpio2_val,
- "gpio2_text": gpio2_text
- }
-
- try:
- udp_sock.sendto(json.dumps(payload).encode(), (PC_IP, PC_PORT))
- except Exception as e:
- print("[UDP] 发送失败:", e)
-
-
- def main():
- global udp_sock
- connect_wifi()
- udp_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
- setup()
- while True:
- loop()
- time.sleep_ms(10)
-
-
- if __name__ == "__main__":
- main()
复制代码
PC 端开启 UDP 监听接收数据,依托 Flask+SocketIO 搭建网页服务。前端借助图表组件、自定义雷达动画,将各类雷达数据动态可视化展示,实现毫米波雷达数据实时监控。 代码见附件

3、小结整套方案可以稳定实现毫米波雷达数据采集与网页可视化展示,搭建难度低,使用起来简单便捷。 C4002 对人体有无、动静状态的判断表现稳定,但模块输出的静止距离、运动距离、运动方向和运动速度等精细数据存在偏差,数值仅可作为参考,不能当作精准测量数据使用。后续可以通过增加数据滤波等方式,进一步优化数据表现,提升整体使用效果。
|