目录

openvela AI 智能营养秤

把称重、食物识别、营养计算和饮食记录放在一台设备上。

演示视频 · 主要功能 · 系统架构 · 编译与运行 · 项目说明书

智能营养秤正面实物 智能营养秤侧面实物

项目简介

日常管理饮食时,称完重量,还要查营养、算份量、记摄入。本项目以 NXP FRDM-MCXN947 为主板,完成 openvela 平台适配,并在此基础上开发 AI 智能营养秤,希望减少这些分散的操作。

将食物放到秤上后,用户可以通过语音询问这份食物的营养、合适的食用份量,以及它是否符合当天的饮食目标。设备结合重量、照片和已有记录给出建议,用户确认后再保存摄入记录。手机网页也可以查看数据、提交修改。

项目对应“基于 openvela 的新平台适配与 AI Agent 智能应用开发”社区赛题,主要工作包括 MCXN947 芯片与板级适配、外设驱动开发,以及基于 openvela AI Agent 框架的应用开发。

主要功能

功能 使用方式
评估秤上的食物 结合称重和拍照识别,估算这一份食物的营养,并与当天剩余摄入目标比较,给出份量建议。
调整饮食计划 结合体重变化、训练安排和饮食记录,建议当天的热量与营养目标,由用户确认是否采用。
按预算推荐餐食 根据剩余营养目标、用餐次数和费用预算,推荐食物、份量与搭配。

日常管理支持个人资料、体重、饮食和训练记录,屏幕可查看当天摄入情况与体重趋势。此外,设备还可以读取空气质量、温度和湿度。

交互方式: 屏幕与按键用于查看和确认;语音用于 AI 对话;手机网页用于查看记录、调整计划;外部 AI 应用可通过 MCP 读取设备数据。AI 或手机提交的计划、记录修改,需要在秤端按键确认后生效。

系统架构

智能营养秤系统架构
部分 作用
MCXN947 Core0 · openvela 运行外设驱动、AI Agent、营养秤业务和屏幕界面,负责数据计算与记录。
MCXN947 Core1 · 裸机程序 对称重数据进行滤波,通过共享内存和 Mailbox 与 Core0 通信。
ESP32-S3 · ESP-IDF 提供无线网络、手机网页和 MCP 服务,并通过 Node 接口访问主板数据。
电脑 · OpenClaw Gateway 管理节点配对和跨设备工具调用,供主板与 S3 联动使用。
云端 AI 服务 DeepSeek 用于语言模型与营养、餐食参考查询,通义千问用于图像识别,豆包用于语音识别和语音合成。

Agent 运行在主板上,模型推理使用云端服务。 主板负责采集重量和图像、执行工具、换算营养以及保存记录。

主板访问云 API 与两板之间的 Node 调用是两条不同的通信路径:前者通过主板网络连接云服务,后者经电脑上的 Gateway 转发。使用手机网页或 MCP 联动时,需要保持 Gateway 运行。当前演示保留以太网连接;S3 无线通道的地址和路由按实际网络配置。

主要实现

openvela 平台适配

适配 MCXN947 的启动、中断、时钟及板级初始化,接入串口、I²C、SPI、以太网、DMA 和音频等外设。应用使用 HX711 称重、摄像头采集、ST7789 显示、W25Q64 存储,以及 ENS160、AHT20/AHT21 环境传感器。

称重、图像、音频和环境数据通过系统接口提供给上层应用,业务代码与驱动实现分开组织。平台适配和硬件连接见 BSP 移植指南。

查看平台适配图

MCXN947 平台适配

AI Agent 与营养业务

基于 openvela AI Agent 框架,为食物评估、每日饮食调整、预算配餐和环境查询编写 Skills,并实现称重读取、图像识别、营养查询、记录读取与修改等 C 工具。不同场景使用对应的工具集合。

食物名称和营养参考由模型提供,实际份量的营养换算由主板根据重量、可食比例等数据完成。AI 提交保存记录或修改计划的提案时,设备先展示待确认内容,用户按键确认后再写入。

双核协作与内存使用

Core0 采集 HX711 原始数据,Core1 负责异常点处理和滤波;核间通信超时时,Core0 可回退到本地处理。显示使用单色画布,刷新时分条转换为 RGB565;语音采用流式播放,减少一次性缓存完整音频的需要。

安全存储组件

实现基于 PUF 与 AES-256-GCM 的安全存储:PUF 负责生成、包装和恢复数据加密密钥,mbedTLS 负责业务数据的加密与完整性认证。PUF 不直接加密业务内容。

仓库提供独立的 secure_selftest 配置,用于验证密钥恢复、对象读写和篡改检测。当前 product 配置未启用 Agent 凭据和 Node 配置的加密存储,也未将现有健康记录迁移到该组件。构建方式见下方的安全存储自检说明。

赛题完成情况

项目围绕“新平台适配”和“AI Agent智能应用开发”开展,并实现语音、视觉、跨设备协作和MCP接入等扩展功能。

第一阶段:openvela平台适配

赛题方向 项目完成内容
芯片与板级适配 完成MCXN947启动、时钟、中断、内存布局及FRDM-MCXN947板级初始化,运行openvela系统。
系统基础能力 实现串口控制台、NSH交互、GPIO和定时器等基础功能,为外设与应用提供运行环境。
网络连接 接入以太网,实现TCP/IP、TLS及云端API访问;同时实现通过SPI连接ESP32-S3的无线联网通道。
上层框架适配 在主板上运行AI Agent与uORB,并接入Sensor、视频采集、音频及文件系统接口。
外设驱动开发与适配 实现称重、摄像头、LCD、麦克风、扬声器和外部Flash接入;开发ENS160、AHT2x传感器驱动,向应用提供空气质量与温湿度数据。
BSP配置与文档 提供Kconfig、defconfig、链接脚本、CMake构建配置及BSP移植指南,包含硬件连接与编译部署说明。

第二阶段:AI Agent智能应用开发

赛题要求 项目完成内容
运行Agent并接入LLM 基于openvela AI Agent框架,在MCXN947主板上运行Agent,接入DeepSeek完成对话与工具调用。
至少2个自定义Markdown Skill 编写4个Skill:食物评估、每日健康教练、预算配餐和空气质量助手。
至少1个与硬件交互的自定义C Tool 实现实时称重、环境读取等硬件工具,并结合拍照、视觉分析、营养查询和业务记录工具完成任务。
真机多工具任务闭环 实现用户指令输入、模型推理、板端工具执行及结果回复;食物评估场景结合称重、图像识别、营养查询和当天预算分析给出建议。
具有实际应用价值的智能助手 将食物评估、摄入记录、体重管理、训练计划和预算配餐集中在一台设备上,支持语音与屏幕交互。

扩展功能

扩展方向 项目完成内容
语音交互 接入麦克风采集、豆包ASR与TTS,实现按键录音、语音问答及流式播放。
视觉能力 接入摄像头与通义千问视觉模型,结合实际重量进行食物识别和营养估算。
MCP Server 在ESP32-S3上提供MCP服务,使外部AI客户端能够读取主板重量、环境、个人资料、营养、饮食和训练数据。
多设备协作 基于OpenClaw Node与电脑Gateway,实现NXP主板和ESP32-S3双向工具调用。
手机网页 提供“今日、记录、计划、我的”等页面,支持查看设备数据、提交修改并在秤端确认。
屏幕交互 基于ST7789实现自绘界面,展示称重、营养、饮食记录、体重趋势及AI交互状态。

仓库结构

项目根目录/
├── README.md                             # 项目介绍、构建、运行与测试说明
├── LICENSE                               # 项目许可证
├── src/                                  # 项目源代码
│   ├── openvela/                         # NXP主板平台适配与应用
│   │   ├── overlay/
│   │   │   ├── vendor/nxp/
│   │   │   │   ├── chips/mcx-nxxx/       # 芯片适配与底层驱动
│   │   │   │   └── boards/mcxn947/       # 板级配置与外设接入
│   │   │   ├── nuttx/                    # 内核相关适配与传感器驱动
│   │   │   └── packages/
│   │   │       ├── ai_agent/             # Agent框架、模型接入与语音处理
│   │   │       ├── demos/smart_scale/    # 营养秤业务、界面、Skills与Tools
│   │   │       └── security/             # PUF密钥管理接口与安全存储组件
│   │   └── patches/                      # 上游代码补丁
│   ├── esp32-s3/                         # 无线联网、Node、MCP及网页服务
│   ├── mobile-web/                       # 手机网页界面
│   ├── host/
│   │   ├── gateway/                      # 电脑端跨设备调用网关
│   │   └── mcp-client/                   # 外部AI客户端接入桥接
│   └── SHA256SUMS                        # 源码校验清单
├── docs/                                 # 项目说明书、创新说明、移植指南等文档与配图
├── tests/                                # 源码完整性、MCP及手机接口测试脚本
├── demo/nxp/                             # 主板固件、构建信息与固件校验清单
├── presentation/                         # 决赛现场演示PPT与演示视频
└── 作品原创承诺书.pdf                    # 参赛作品原创承诺材料

src/openvela 保存的是项目对上游的修改,不是完整的 openvela 源码。构建前需要同步 upstream-manifest.xml 中固定的上游版本,再应用补丁与覆盖文件。对应版本和文件校验信息见 source-lock.json。

编译与运行

只使用预编译主板固件,可直接进入 烧录与使用;从源码构建需要先准备下列环境。

环境要求

用途 所需环境
主板编译 Linux、Git、Repo、Python 3.10+、CMake、Ninja,以及包含 arm-none-eabi-gcc、arm-none-eabi-g++、arm-none-eabi-objcopy、arm-none-eabi-nm 的 ARM GNU 工具链。
S3 编译 ESP-IDF 6.0.1 及其 Python 环境,组件版本见 dependencies.lock。
Gateway Node.js 24.x 且不低于 24.16.0,或不低于 26.1.0,以及 npm;仓库固定使用 OpenClaw 2026.9.4。
MCP 桥接与接口测试 Node.js 22+;整套部署可统一使用满足 Gateway 要求的版本。
主板烧录 pyOCD,以及支持 MCXN947 的 CMSIS-Pack。

1. 获取源码

以下命令使用 Linux Bash。私有仓库需先为本机配置有访问权限的 SSH 密钥。

git clone --branch master git@gitlink.org.cn:HUG7HXyMCc/jyovdxptspyaiaznyykf.git smart-scale
cd smart-scale
PROJECT_DIR="$(pwd)"
PROJECT_COMMIT="$(git rev-parse HEAD)"

# 在安装依赖、生成配置和构建产物之前检查源码
python3 -B tests/check_source.py

# 在仓库外新建 openvela 工作目录
VELA_WS="$(dirname "$PROJECT_DIR")/openvela-workspace"
mkdir "$VELA_WS"
cd "$VELA_WS"
repo init -u "$PROJECT_DIR" -b "$PROJECT_COMMIT" -m src/openvela/upstream-manifest.xml
repo sync -c -j4

工作目录已存在时,请换一个新目录。上述 Repo 命令使用本地 Git 仓库中的 manifest,因此不能直接用解压后的 ZIP 目录代替 Git 检出目录。

2. 应用项目代码并编译

# 检查上游版本与文件冲突
python3 -B "$PROJECT_DIR/src/openvela/prepare.py" --workspace "$VELA_WS"

# 应用补丁和覆盖文件
python3 -B "$PROJECT_DIR/src/openvela/prepare.py" --workspace "$VELA_WS" --apply

# 替换为本机工具链目录
ARM_GNU_BIN="/path/to/arm-none-eabi/bin"
python3 -B "$PROJECT_DIR/src/openvela/build.py" \
  --workspace "$VELA_WS" --profile product --toolchain "$ARM_GNU_BIN"

构建使用 CMake/Ninja,产物位于 $VELA_WS/out/contest-product/,包括 nuttx、nuttx.bin 和 nuttx.hex。构建脚本不会自动烧录,可加 --dry-run 查看将执行的命令。

可选:构建安全存储自检固件

安全存储自检使用独立的 secure_selftest 配置,并额外依赖 MCUXpresso SDK 中 MCXN947 的 PUFv3、reset、clock 和 CMSIS 文件。MCUX_SDK_ROOT 指向 SDK 的 mcuxsdk 根目录。

MCUX_SDK_ROOT="/path/to/mcuxsdk"
python3 -B "$PROJECT_DIR/src/openvela/build.py" \
  --workspace "$VELA_WS" --profile secure_selftest \
  --toolchain "$ARM_GNU_BIN" --puf-sdk "$MCUX_SDK_ROOT" --stat-compat on

--stat-compat 必须显式指定:on 启用针对 LittleFS fstat 问题的诊断兼容处理,off 关闭该处理。该配置用于独立验证,不会自动迁移业务配置和个人记录。

3. 烧录主板固件

可以使用自行编译的 nuttx.hex,也可以使用 仓库提供的主板固件。该文件的构建信息、验证状态和摘要见 metadata.json 与 SHA256SUMS。

在项目仓库根目录执行,替换 CMSIS-Pack 路径和探针标识:

PROJECT_DIR="$(pwd)"
MCXN947_PACK="/path/to/NXP.MCXN947_DFP.pack"
NXP_PROBE_UID="<探针标识>"
NXP_HEX="$PROJECT_DIR/demo/nxp/nuttx.hex"

pyocd list
pyocd flash --pack "$MCXN947_PACK" -t mcxn947vdf \
  -u "$NXP_PROBE_UID" -f 4000000 "$NXP_HEX"

4. 配置云服务并使用

通过 115200 波特率串口进入 NSH。主板启动后会运行界面和后台 Agent,并尝试通过以太网获取地址。首次使用时,按 BSP 移植指南 完成硬件连接和称重标定。

云服务配置保存在 /data/ai_agent/config/config.json。首次使用时,按下面的命令填写自己的服务密钥:

echo '{"vision_api_key":"<视觉API_KEY>","volc_api_key":"<豆包语音API_KEY>"}' > /data/ai_agent/config/config.json
ai_agent set_llm deepseek <DEEPSEEK_API_KEY>
reboot

set_llm 会保存语言模型接口和密钥。重启后,用上、下、确认键切换页面;进入 AI 语音页,按键开始录音,再次按键结束。称重和本地页面不依赖云端推理,AI 对话、图像识别和语音功能需要网络及相应服务凭据。

后台 Agent 使用 --no-cli,串口由 NSH 使用。配置时使用上述一次性命令,不要另外启动一个完整的 Agent 实例。

手机网页与外部 AI 接入

手机网页和 MCP 服务由 ESP32-S3 提供,主板数据通过 Gateway 获取。完成下面的部署后,手机浏览器访问 http://<S3局域网地址>:8787/,输入连接码即可使用;外部 AI 的 MCP 地址为 http://<S3局域网地址>:8787/mcp。

展开部署步骤:Gateway、ESP32-S3、手机网页与 MCP

以下命令接续前面的 PROJECT_DIR。本节以两板 Node 身份已初始化并核对为前提;首次部署需先准备各自的 Node ID,已有设备沿用原身份。

在仓库外保存本地配置和构建产物:

PRIVATE_DIR="$(dirname "$PROJECT_DIR")/smart-scale-private"
mkdir "$PRIVATE_DIR"

1. 启动 Gateway

cp -a "$PROJECT_DIR/src/host/gateway" "$PRIVATE_DIR/gateway"
cd "$PRIVATE_DIR/gateway"
npm ci
npm run init
npm run check
npm start

初始化会生成 config.local.json 和随机访问令牌。电脑需要与两块板网络互通,并允许对应端口通过防火墙。保持 Gateway 运行,后续命令在另一个终端执行,重新设置相同的目录变量。

配置对应关系如下:

位置 填写内容
Gateway 的 config.local.json gateway.port 默认为 18789;gateway.auth.token 为两板连接 Gateway 使用的令牌。
S3 的 s3.local.json 填写 Wi-Fi、电脑的局域网地址及 Gateway 端口和令牌;mainboard_node_id 填 NXP 主板的 Node ID。
NXP 的 /data/esp_node.json 填写同一 Gateway 的 gateway_host、gateway_port、gateway_token;node_id 填 S3 的 Node ID。
S3 的服务凭据 mcp_token 用于 MCP;web_access_key 用于手机网页登录,与 Gateway 令牌分开。

2. 构建 ESP32-S3 固件

先生成本地配置,再按上表填写:

python3 -B "$PROJECT_DIR/src/esp32-s3/build.py" \
  --init-config --config "$PRIVATE_DIR/s3.local.json"

脚本会生成随机的 MCP 令牌和网页连接码。填写 Wi-Fi、Gateway 和主板 Node ID 后,在准备好的 ESP-IDF 环境中构建:

IDF_PATH="/path/to/esp-idf"
IDF_PYTHON="/path/to/esp-idf-python-env/bin/python"
python3 -B "$PROJECT_DIR/src/esp32-s3/build.py" \
  --config "$PRIVATE_DIR/s3.local.json" \
  --idf-path "$IDF_PATH" --idf-python "$IDF_PYTHON" \
  --output "$PRIVATE_DIR/s3-build"

脚本检查 ESP-IDF 6.0.1,使用 spinet 配置,并把 src/mobile-web 打包进固件。输出中的 private_staging_directory 是构建副本目录,private_build_directory 是编译产物目录。可用 --prepare-only 仅准备文件,或通过 --managed-components 指定匹配的组件缓存。

S3 固件包含本地网络和服务凭据,因此需要自行构建,不能随源码一起公开上传。

3. 烧录与节点配对

使用上一步输出的目录和实际串口烧录:

S3_STAGE="/path/to/private_staging_directory"
S3_PORT="<S3串口>"
"$IDF_PYTHON" "$IDF_PATH/tools/idf.py" \
  -C "$S3_STAGE" -B "$S3_STAGE/build" -p "$S3_PORT" flash

两板需共地,并连接 SPI 与控制线。S3 GPIO12、11、13、10 分别对应时钟、MOSI、MISO、片选;GPIO17、4、EN 分别用于握手、数据就绪和复位。NXP 端接线见 BSP 移植指南。

将节点配置保存到主板后,在 NSH 中执行:

scale_node start
scale_node status

在电脑上检查配对请求:

cd "$PRIVATE_DIR/gateway"
npm run gateway -- devices list
npm run gateway -- nodes pending

核对设备身份后批准配对,具体参数见 npm run gateway -- devices --help 和 npm run gateway -- nodes --help。主板 scale_node status 显示 connected 与 ready 后,再访问手机页面。

手机页面包含“今日、记录、计划、我的”。提交修改后,需要在秤端按键确认,再查看处理结果。网页和 MCP 使用局域网 HTTP,请勿直接映射到公网。

4. 连接 MCP 客户端

S3 提供重量、环境、个人资料、营养、饮食记录和训练六类只读工具,使用独立的 MCP 令牌认证。只支持 STDIO 的客户端可通过仓库中的桥接程序接入:

cp -a "$PROJECT_DIR/src/host/mcp-client" "$PRIVATE_DIR/mcp-client"
cd "$PRIVATE_DIR/mcp-client"
npm ci
cp -n config.example.json config.local.json

在 config.local.json 中填写 MCP 地址 url、NXP 主板 ID expectedNodeId 和 MCP 令牌 token,然后检查配置:

npm run check

在 AI 客户端中,将 STDIO 命令设为本机 Node 可执行文件,参数设为上述私有目录中 stdio-bridge.mjs 的绝对路径。MCP 提供只读工具;业务修改可通过手机或秤端界面操作,手机提交的修改需在秤端确认。

测试

测试 内容 条件
python3 -B tests/check_source.py 检查源码文件是否完整、是否与 src/SHA256SUMS 一致。 干净源码目录,离线可运行。
node tests/test_mcp_read.mjs 通过 MCP 读取重量,检查返回格式、状态和主板身份。 Node.js 22+,设备与 Gateway 已连接。
node tests/test_mobile_read.mjs 登录手机服务,读取重量和个人资料,检查结果后退出。 Node.js 22+,已配置网页连接码与主板身份。

源码检查只覆盖 src/,并且会将额外文件视为错误,应在安装依赖或生成本地文件之前运行。

运行联网测试前,在本地终端设置并导出 SCALE_MCP_URL、SCALE_WEB_URL、SCALE_NODE_ID、SCALE_MCP_TOKEN 和 SCALE_WEB_ACCESS_KEY。地址格式与前面的服务地址一致,SCALE_NODE_ID 使用 NXP 主板身份。

cd "$PROJECT_DIR"
node tests/test_mcp_read.mjs --url "$SCALE_MCP_URL" --node-id "$SCALE_NODE_ID"
node tests/test_mobile_read.mjs --url "$SCALE_WEB_URL" --node-id "$SCALE_NODE_ID"

联网测试不修改饮食或训练记录,也不需要额外安装 MCP SDK。返回 PASS 表示本次读取、数据格式和设备身份检查通过。各脚本均可使用 --help 查看参数。

文档与演示

资料 内容
项目说明书 功能介绍、系统设计与实现。
BSP 移植指南 平台适配、硬件接线与部署说明。
项目创新说明 项目的设计与技术特点。
决赛 PPT · 演示视频 答辩展示与设备操作。
成员分工及主要贡献说明 工作分工与贡献。
人工智能及第三方工具使用说明 开发辅助工具与第三方组件使用情况。
作品原创承诺书 参赛承诺材料。

许可证

项目新增代码按文件中的 Apache-2.0 声明提供,详见 LICENSE。上游代码与第三方组件遵循各自的许可证及 NOTICE;外部 NXP SDK 按其自身许可获取和使用。第三方标识的权利归原权利人。

关于
151.8 MB
邀请码
    Gitlink(确实开源)
  • 加入我们
  • 官网邮箱:gitlink@ccf.org.cn
  • QQ群
  • QQ群
  • 公众号
  • 公众号

版权所有:中国计算机学会技术支持:开源发展技术委员会
京ICP备13000930号-9 京公网安备 11010802047560号