多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

Waterius 水表数据永不丢失的秘密:EEPROM 环形缓冲 + CRC8 校验存储原理全解析

Waterius 水表数据永不丢失的秘密:EEPROM 环形缓冲 + CRC8 校验存储原理全解析 Waterius 水表数据永不丢失的秘密EEPROM 环形缓冲 CRC8 校验存储原理全解析【免费下载链接】wateriusПередача показаний воды по Wi-Fi. Watermeter Wi-Fi transmitter.项目地址: https://gitcode.com/gh_mirrors/wa/wateriusWaterius 是一款 Wi-Fi 水表数据发射器把水、气、热量、电表读数自动上传到服务器。它最被低估的设计是让水表读数永不丢失的存储机制EEPROM 环形缓冲 CRC8 校验。即使突然断电、电池耗尽或芯片重启下次开机时最新的水表读数依然完好如初。先搞懂架构为什么水表数据容易丢失Waterius 由两颗芯片协作完成ATtiny85大部分时间处于深度睡眠只负责数水表传来的脉冲并把累计值写进片内 EEPROM 存储器ESP8266每 15 分钟默认被唤醒一次通过 I2C 总线读取 ATtiny85 的数据连上 Wi-Fi 发送到服务器然后立刻休眠省电。危险就出在这里ATtiny85 随时可能断电换电池、电压跌落、看门狗重启。如果它把计数值存在普通 RAM 里一断电数据就清零你辛苦攒了几个月的水表读数瞬间归零。所以必须把数据落盘到掉电不丢的 EEPROM 中——但 EEPROM 也有自己的烦恼写入次数有限约 10 万次。直接每个脉冲都写一次存储器很快就报废了。Waterius 用两个精巧的机制解决了这个问题。EEPROM 环形缓冲20 个槽位把寿命延长 20 倍 核心思路一句话不把数据反复写进同一格而是轮流写进 20 个槽位转圈写。存储区被划分成环形布局前 20 块存数据后面 20 格存对应的校验和| 数据块0 | 数据块1 | … | 数据块19 | CRC0 | CRC1 | … | CRC19 |每次保存新读数时写入指针向前移动一格写到第 20 格后再回到第 0 格。这样任何一个物理位置只有等转完一整圈20 次写入后才会被再次覆写——单个单元的实际写入次数被摊薄了 20 倍。算一笔账EEPROM 寿命约 10 万次写入 × 20 个槽位 ≈ 200 万次有效存储。按水表 1 个脉冲 10 升计算足够记录约 10,000 立方米的用水量对普通家庭来说完全用不完。这套逻辑实现在模板类EEPROMStorage中水表读数Data结构两个 32 位计数器用 20 个槽位配置信息Config结构用 2 个槽位做冗余备份源码在 Attiny85/src/Storage.cpp。CRC8 校验给每个数据块加一枚指纹 ✅光存下来还不够还得保证读出来的是没坏的数据。EEPROM 在极端情况下写入瞬间断电可能出现半写状态数据损坏得悄无声息。Waterius 的做法每个数据块旁边都存了一个 1 字节的 CRC8 校验和Dallas/Maxim 多项式。读取时重新计算一遍与存储的校验和比对一致 → 这个块是可信的不一致 → 判定为损坏直接跳过这个块绝不会把乱码当成水表读数。连 ATtiny85 与 ESP8266 之间的 I2C 通信也复用了同一个 CRC8 函数22 字节数据 1 字节校验从芯片内部到总线传输全程都有指纹护航。断电重启后如何自动找回最新读数 开机时storage.init()会做一次考古逐个扫描 20 个数据块用 CRC8 检查哪块是完好的在所有完好的块中选择计数器数值最大的那一个作为当前读数。为什么取最大值就行因为水表脉冲只增不减最新的读数一定是最高的。哪怕断电时刚写到一半、最新块损坏了系统也能退回到上一个完好块最多损失一小段数据绝不会出现读数归零。由于 AVR 是 little-endian 存储比较两个块时从最低字节开始逐字节对比见compare()函数实现非常省资源。省电设计一分钟才写一次 EEPROM 除了环形缓冲摊薄写入Waterius 还在软件层面限流每收到一个脉冲立即更新 RAM 中的计数但向 EEPROM 落盘最多每分钟一次由 250ms 看门狗中断计时连续 240 个周期才允许写一次。这意味着在正常用水场景下EEPROM 的写入频率极低配合深度睡眠模式整个设备仅靠 3 节 AA 电池就能工作 2~4 年。想深入源码看这几个文件就够啦环形缓冲 CRC8 核心实现Attiny85/src/Storage.cpp、Attiny85/src/Storage.h数据/配置结构体定义Attiny85/src/Setup.h存储初始化、限流写入的调用现场Attiny85/src/main.cpp用虚拟 EEPROM 做的宿主端单元测试Utils/tests/test_eeprom/main.cpp小结Waterius 用环形缓冲延长寿命 CRC8 校验防损坏 取最大值自恢复三板斧在只有 1 KB 级 EEPROM 的微型芯片上实现了水表数据的可靠存储。这套思路对任何需要掉电不丢数据的嵌入式项目都是值得抄作业的范本。【免费下载链接】wateriusПередача показаний воды по Wi-Fi. Watermeter Wi-Fi transmitter.项目地址: https://gitcode.com/gh_mirrors/wa/waterius创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表