4G模块应用,内网穿透,前端网页的制作第七讲(智能头盔数据上传至网页端)

测试数据终端,以及数据是否能通过单片机上的串口5转发数据到串口6(重点)

打开串口助手(注意一定要注意使用的是要使用的是UTF-8编码,要不然会报错)
报错核心原因:编码不一致。
  • WebSocket 标准规定: 如果传输的是文本帧(Text Frame),内容必须是标准的 UTF-8 编码。

  • 你的现状: 你使用的串口调试助手(例如 XCOM, SSCOM, 或 Windows 默认终端)输入中文"温度"时,默认使用的是 GBKGB2312 编码(这是中文 Windows 的默认编码)。

  • 冲突: Node.js 的 ws 库接收到 GBK 编码的字节流,试图按 UTF-8 规则去校验,发现字节序列不对(UTF-8 的中文通常是 3 个字节,GBK 是 2 个字节),于是判定为"非法数据",直接抛出 Invalid WebSocket frame 错误。

  • 为何服务器挂了: 因为你没有在代码中捕获这个 error 事件,Node.js 遇到未捕获的异常会默认终止进程。

测试示例(记得在串口助手一定要修改当前编码规则)-这个通过我们的串口5传输数据至网页上,同时查看我们制作的网页上是否数据进行显示,数据异常时是否出现报警

温度:26°C,湿度:55%,摔倒标志:0,心率异常标志:0,气体异常标志:0,心率值:75 BPM(正常环境,正常标志位)

温度:28°C,湿度:80%,摔倒标志:1,心率异常标志:1,气体异常标志:1,心率值:145 BPM(正常环境,非正常标志位)

上传数据的示例代码(uart5_app.c)-现在请您返回RT-thread的开发

复制代码
/*
 * Copyright (c) 2006-2021, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2025-11-21     leader       the first version
 * 202x-xx-xx     leader       support communicate with uart6
 * 2026-01-17     leader       add sensor status print and forward to uart6
 */
#include <uart5_app.h>
// 包含串口6句柄声明(用于转发数据)

#define UART_NAME "uart5"

// 串口5设备句柄(区分串口6)
rt_device_t uart5_handle;
// 串口5接收信号量(区分串口6)
static struct rt_semaphore rx5_sem;

// 串口5接收回调函数
static rt_err_t uart5_input(rt_device_t dev, rt_size_t size)
{
    rt_sem_release(&rx5_sem);
    return RT_EOK;
}

// 串口5任务:保留原接收转发功能 + 新增传感器状态打印与转发
static void uart5_task(void *parameter)
{
    char ch;
    // 新增:定义格式化缓冲区,存储传感器状态信息(足够容纳所有打印内容)
    char sensor_buf[256];
    rt_size_t buf_len;

    while(1)
    {
        // 一、保留原功能:串口5接收字节数据,转发到串口6(阻塞式,有数据才处理)
        // 非永久等待(避免阻塞传感器状态打印,可根据需求调整超时时间,单位:时钟节拍)
        if (rt_sem_take(&rx5_sem, RT_TICK_PER_SECOND / 10) == RT_EOK)
        {
            // 读取串口5接收到的字节,逐个转发到串口6
            while(rt_device_read(uart5_handle, -1, &ch, 1) == 1)
            {
                rt_device_write(uart6_handle, 0, &ch, 1);
            }
        }

        // 二、新增功能:打印传感器状态,并转发到串口6
        // 1. 格式化传感器状态信息到缓冲区(替代直接rt_kprintf,方便转发)
        buf_len = rt_sprintf(sensor_buf,
                            "温度:%d°C\n"
                            "湿度:%d%%\n"
                            "摔倒标志:%d\n"
                            "心率异常标志:%d\n"
                            "气体异常标志:%d\n"
                            "心率值:%d BPM\n\n",
                            temp, humi, fall_flag, heartrate_flag, density_flag, hr);

        // 2. 串口打印(保留原有的控制台输出功能)
        rt_kprintf("%s", sensor_buf);

        // 3. 核心:将格式化后的状态信息通过串口5转发到串口6
        if (uart6_handle != RT_NULL)
        {
            rt_device_write(uart6_handle, 0, sensor_buf, buf_len);
        }

        // 4. 定时延时(避免高频打印占用CPU,可根据需求调整,单位:毫秒)
        // 例如:每1000ms(1秒)更新一次传感器状态
        rt_thread_mdelay(1000);
    }
}

static int uart5_init(void)
{
    // 查找串口5设备
    uart5_handle = rt_device_find(UART_NAME);
    if (uart5_handle == RT_NULL)
    {
        rt_kprintf("uart5 device find failed!\n");
        return -RT_ERROR;
    }

    // 打开串口5(中断接收模式)
    if (rt_device_open(uart5_handle, RT_DEVICE_FLAG_INT_RX) != RT_EOK)
    {
        rt_kprintf("uart5 device open failed!\n");
        return -RT_ERROR;
    }

    // 初始化接收信号量
    rt_sem_init(&rx5_sem, "rx5_sem", 0, RT_IPC_FLAG_FIFO);
    // 设置接收回调函数
    rt_device_set_rx_indicate(uart5_handle, uart5_input);

    // 创建串口5任务(命名唯一,避免冲突)
    rt_thread_t uart5_thread = rt_thread_create("uart5_task",
                                                uart5_task,
                                                RT_NULL,
                                                2048,  // 新增:增大栈大小(容纳格式化缓冲区,避免栈溢出)
                                                25,    // 优先级
                                                10);   // 时间片
    if (uart5_thread != RT_NULL)
    {
        rt_thread_startup(uart5_thread);
    }
    else
    {
        rt_kprintf("uart5 thread create failed!\n");
        return -RT_ERROR;
    }

    rt_kprintf("uart5 init success!\n");
    return 0;
}

INIT_APP_EXPORT(uart5_init);

效果图(中间代表的是3个标志位)

如果复刻到这一步恭喜您已经完成了智能头盔上传数据到我们自己制作的网页上了,也欢迎大家对我的项目进行复刻与优化,如果您有优化这个项目的思路可以在评论区或者私信我,让我们共同学习,感谢大家

相关推荐
GreenTea7 小时前
GrokBot 核心成员 Lauren Tan:每月交付 2000 个 PR 的人,是怎么用 AI 的
前端·后端·架构
码事漫谈7 小时前
FDE:一个缩写,两种命运
后端
mCell8 小时前
用 Knip 清理 AI Coding 留下的冗余代码
前端·ai编程·前端工程化
名字还没想好☜8 小时前
Go context.AfterFunc 实战(Go 1.21):context 一取消就自动跑清理,告别手写 goroutine 监听 Done
后端·golang·go
笃行3509 小时前
使用Rokid AIUI做了一个童年推箱子游戏
前端
明月_清风9 小时前
为什么最近开始关注 JEV?几个实战案例告诉你答案
人工智能·后端
GetcharZp10 小时前
5 分钟拥有自己的 S3:RustFS 上手(MinIO 的 Rust 替代,Apache 2.0 可商用)
后端
excel10 小时前
前端加密的作用与使用场景
前端
行百里er10 小时前
Redis 版本演进、新特性与协议那些事儿
redis·后端
Joy T11 小时前
Spring AI 2.0 Agent 进阶:Memory、State 与 Context Engineering 常见技术全景
java·人工智能·后端·spring·agent入门·agent state