# SmartScale **Repository Path**: ichang1636/smart-scale ## Basic Information - **Project Name**: SmartScale - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-10-12 - **Last Updated**: 2026-10-12 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 食刻 · SmartScale > 一台会算热量的厨房秤 + 一个管你热量缺口的 App。 > 选食物 → 放上去 → 秤出质量 → 自动算营养 → 上云 → App 告诉你今天缺口多少、下顿该吃什么。 --- ## 一、这东西是什么 一条完整闭环:**称重 → 营养计算 → 云端 → 移动端分析 → 建议**。 | 环节 | 载体 | 干什么 | |---|---|---| | 感知 | 1000 g 称重传感器 + HX711 24bit ADC | 把重量变成数字,分辨率 0.1 g | | 交互 | 旋转编码器 + OLED | 转一下选食物(米饭/鸡胸/苹果…),按一下确认 | | 主控 | STM32F103C8T6 | 滤波、标定、去皮、查食物营养表、算热量、驱动联网、管电池 | | 联网 | ESP-01S(ESP8266) | AT 指令走 WiFi,HTTPS 把这一次称量推到云端(**用完断电省电**) | | 电源 | 18650 锂电 + TP4056 充电 + TPS63031 升降压 | 脱机跑 45~60 天,电量条 + 屏幕电量 + App 里也能看 | | 云端 | Supabase(Postgres) | 存食物库、称量记录、用户档案与每日目标 | | App | React + Vite + Capacitor | 今日摄入 / 热量缺口 / 营养结构 / 趋势 / 建议 | **关键设计:食物库的单一事实来源在云端。** 秤上内置 40 种常用食物的本地缓存(编译进 Flash,断网也能算),App 里可增删改完整食物库;秤上传的是「食物名 + 每 100 g 营养快照 + 质量」,云端存快照并算出这次的总营养。食物改名或停用后,历史记录仍然可读。 --- ## 二、目录结构 ``` SmartScale/ ├── Doc/ # 设计文档(对标 RaceCore 的 Doc 范式) │ ├── 功能规格说明书.md # 目标、功能清单、可量化验收标准、风险 │ ├── 智能称系统框架图.drawio # 分层系统框架(drawio 可直接打开) │ ├── 硬件设计与BOM.md # 选型理由、接线表、电源、机械、标定流程 │ ├── 通信协议与云端接口.md # 串口协议 + HTTP 接口 + JSON 字段定义 │ └── 固件架构说明.md # 三层结构、任务调度、滤波与稳定判据 ├── Hardware/ │ ├── BOM.xlsx # 物料清单(含参考价) │ └── 引脚分配表.csv # STM32F103C8T6 引脚占用表 ├── Firmware/ # STM32 标准外设库工程(Keil MDK5) │ ├── Code/ │ │ ├── BSP/ # 板级驱动:hx711 / power(电池·低功耗)/ oled / encoder / key / buzzer / uart / flash │ │ ├── Middleware/ # 滤波 / 标定 / ESP8266 AT / JSON 构造 │ │ ├── App/ # 食物库 / 营养计算 / 状态机 / UI / 上云 │ │ └── User/ # main.c / 中断 / 库配置 │ ├── Project/ # Keil 工程放在这里(仓库不含 .uvprojx,建法见 README) │ └── README.md # 编译、烧录、标定步骤 ├── App/ # 移动端(与 BookHub 同构) │ ├── src/root/ # App 壳:选择页、全局设置、返回键处理 │ ├── src/sc/ # 食刻子系统:今日 / 记录 / 食物库 / 统计 / 设置 │ ├── src/shared/ # 与设备共用的计算内核(BMR/TDEE/缺口/建议引擎) │ ├── public/ # 图标与 favicon(tools/gen_icons.py 生成) │ ├── package.json │ └── README.md # 目录职责、核心公式、依赖安装踩坑 ├── Cloud/ │ └── schema.sql # Supabase 建表 + RLS + RPC + 触发器 + 40 条种子 └── tools/ ├── extract_font.py # 从源码提取汉字节集 → OLED 16x16 点阵 C 文件 └── gen_icons.py # 生成 favicon.svg 与 App 图标 ``` --- ## 三、硬件指标(验收线) | 项 | 标准 | |---|---| | 量程 | 1 ~ 1000 g | | 显示分辨率 | 0.1 g | | 静态精度 | ±1 g;<100 g 时 ±0.5 g | | 重复性 | ≤ ±0.5 g(同砝码 10 次) | | 零点漂移 | ≤ ±0.5 g / 10 min | | 稳定判定 | ≤ 1.5 s 出读数 | | 过载保护 | 机械限位 120% 量程(1200 g)+ 软件告警 | | 上传成功率 | ≥ 99%(失败 3 次内重传) | | 断网缓存 | ≥ 200 条(片内 Flash 环形队列) | | **供电** | **单节 18650 锂电 3.7 V / 2600 mAh,USB-C 充电 800 mA** | | **稳压** | **TPS63031 升降压 → 3.3 V,电池 3.0~4.2 V 全区间效率 ≥ 88%** | | **待机功耗** | **STOP 模式 ≤ 100 µA;浅睡 ≤ 15 mA;工作 ≤ 70 mA(ESP 断电)** | | **续航** | **≥ 45 天(每天 8~15 次称量);重度使用 20~25 天** | | **电量指示** | **4 档 LED 电量条(默认全灭)+ 双色充电灯 + OLED 顶栏图标** | --- ## 四、快速上手 **固件**:Keil MDK5 打开 `Firmware/Project/SmartScale.uvprojx` → 烧录 → 首次上电进标定流程(放 500 g 砝码)。详见 `Firmware/README.md`。 **云端**:Supabase 新建项目 → SQL Editor 执行 `Cloud/schema.sql` → 记下 URL 和 anon key。 **App**: ```bash cd App cp .env.example .env # 填 Supabase URL / anon key npm install npm run dev # 浏览器调试 npm run build:android # 出 APK(需 Android SDK) ``` **把秤和 App 绑到一起**:App → 设置 → 设备配对,填入秤的 `device_id`(默认 `SC-01`),之后每次称量自动落到你的账号下。 --- ## 五、当前状态 | 模块 | 状态 | |---|---| | 文档 / BOM / 引脚表 | ✅ 完成 | | 固件 BSP 层(HX711、OLED、编码器、按键、蜂鸣器、参数存储) | ✅ 代码完成,待上板验证 | | **固件电源管理(电池检测、电量条、充电状态、Sleep/Stop 低功耗)** | ✅ 代码完成,待上板验证 | | 固件 App 层(食物库、营养计算、UI 状态机、上云、断网缓存) | ✅ 代码完成,待上板验证 | | 云端 schema + RLS(含设备电量字段) | ✅ 完成 | | App(今日/记录/食物库/统计/设置 + 秤电量显示) | ✅ 完成,`tsc + vite build` 通过 | | 实机标定与精度测试 | ⬜ 待硬件到手 | | 续航实测(按 4.2 验收线) | ⬜ 待硬件到手 | ## 六、已知取舍 - **不跑 TLS 的裸 ESP-01S 很吃固件版本。** AT 固件低于 1.7 不支持 `CIPSTART="SSL"`。若你的模块不支持,两条退路:刷 AT 1.7.4,或让设备走局域网 HTTP 到一台自建中继(中继再转 HTTPS)。 - **称重传感器选 1 kg 档**:量程要装得下整份食材(一碗汤、盘子+食物),500 g 余量太紧。代价是绝对误差从 ±0.25 g 放到 ±0.5 g,验收线相应放宽到 ±1.5 g。5 kg 档就是 ±2.5 g,配不上 0.1 g 分辨率,不能要。 - **食物库不在秤里做全量同步**:40 种本地缓存够覆盖日常,全量同步会吃光 64 KB Flash。 - **电池版不用"一键软开关",改用滑动开关。** 软开关电路自身的漏电就有几 µA~几十 µA, 而滑动开关断位是真 0 µA;而且软开关的按键要让 MCU 读到,得接在 4.2 V 的栅极节点上, 3.3 V 域分压后的高电平裕量只有 0.1 V 左右,判读不可靠。代价是软件关不了机 —— 补偿办法是让固件自动进 Stop(77 µA,等价于关机)。 - **用升降压而不是 LDO。** 单节锂电 3.0~4.2 V,LDO 在 3.4 V 以下就掉出调节区, 等于白扔 30% 电量;而且 ESP8266 最大供电电压 3.6 V,把 4.2 V 的电池直接怼上去会烧模块。 - **电量条不做常亮。** 4 颗 LED 常亮一天要吃掉 10% 电量,改成"按键才亮 3 秒"后开销降到 0.1 mAh/天。 - **本地队列在 Flash 里是严格顺序追加的环形缓冲**,不能随机覆盖某一条 —— 因为写了就不擦不掉,只能整页擦(详见 `Doc/通信协议与云端接口.md` 第二节)。