前言在低成本嵌入式温度监测设备如 CH592 等小资源 MCU中1 分钟采集一次温度、保存 15 天数据、BLE 上传是典型需求。设备面临三大约束Flash 空间有限、BLE 带宽小、RAM / 算力弱。本文提供一套工业量产级、100% 无损、超小体积、无文件系统、无复杂算法的完整方案温度16bit×10 存储支持 - 128~127.9℃时间分钟级2 字节最大存储 45.5 天满足 15 天需求存储Flash 环形缓冲无需文件系统压缩差分编码 RLE 行程编码无损、超轻量体积原始 84KB → 压缩后14~20KBBLE 可快速上传平台CH592/8051/STM32 通用一、需求分析与容量计算1. 需求采集1 分钟 / 次存储15 天数据温度值16bit 时间分钟上传BLE 传输需无损压缩总条数15×24×60 21600 条2. 时间戳优化关键2 字节uint16_t最大65535 分钟65535 分钟 45.5 天完全覆盖 15 天需求 →时间仅需 2 字节3. 单条数据结构Flash 存储c运行// 每条 4 字节行业最小结构 typedef __packed struct { uint16_t time_min; // 2字节分钟级时间戳 int16_t temp; // 2字节温度×10如25.5℃→255 } TempRecord;4. 原始总容量21600 条 × 4 字节 86400 字节84.3KB二、无损压缩原理超高压缩比、极轻量本方案采用差分编码 RLE 行程编码专为时序连续、变化平缓的温度数据设计差分编码只存 “变化量”不存完整值时间固定 1 分钟无需传输温度2 字节 → 1 字节增量int8_tRLE 行程编码连续相同增量合并存储例100 次温度不变增量 0→ 仅存100、02 字节无损特性解压可 100% 还原原始数据无精度丢失压缩后体积头部6 字节数据体平均 14~20KB相比原始体积压缩 75%~83%三、完整代码实现可直接编译、量产级1. 头文件定义temp_compress.hc运行#ifndef __TEMP_COMPRESS_H #define __TEMP_COMPRESS_H #include stdint.h // 15天总记录数 #define TOTAL_RECORDS (15U * 24U * 60U) // 21600 // Flash存储单条记录4字节 typedef __packed struct { uint16_t time_min; // 时间分钟 int16_t temp; // 温度值 ×10 } TempRecord; // BLE上传压缩包头部6字节 typedef __packed struct { uint16_t first_time; // 第一条时间戳 int16_t first_temp; // 第一条温度 uint16_t total_cnt; // 总记录数 } TempPacketHead; // 压缩函数 uint32_t temp_compress(TempRecord *in, uint8_t *out, uint32_t total_cnt); // 解压函数 void temp_decompress(uint8_t *in, TempRecord *out); #endif2. 压缩实现差分 RLEtemp_compress.cc运行#include temp_compress.h /** * brief 温度数据无损压缩差分RLE * param in: 原始温度记录数组 * param out: 压缩后数据缓存 * param total_cnt: 总记录数 * retval 压缩后总字节数 */ uint32_t temp_compress(TempRecord *in, uint8_t *out, uint32_t total_cnt) { if (total_cnt 0) return 0; // 写入压缩包头部6字节 TempPacketHead *p_head (TempPacketHead *)out; p_head-first_time in[0].time_min; p_head-first_temp in[0].temp; p_head-total_cnt total_cnt; uint8_t *p_data out sizeof(TempPacketHead); int16_t last_temp in[0].temp; // RLE状态变量 int8_t last_delta 0; uint8_t rle_count 0; for (uint32_t i 1; i total_cnt; i) { // 计算温度增量 int32_t delta in[i].temp - last_temp; // 增量限幅int8范围 if (delta 127) delta 127; if (delta -128) delta -128; // RLE合并相同增量 if ((delta last_delta) (rle_count 255)) { rle_count; } else { // 保存上一组RLE数据 if (rle_count 0) { *p_data rle_count; *p_data last_delta; } last_delta (int8_t)delta; rle_count 1; } last_temp in[i].temp; } // 写入最后一组数据 if (rle_count 0) { *p_data rle_count; *p_data last_delta; } // 返回压缩总长度 return (p_data - out); }3. 解压实现手机 / MCU 通用c运行/** * brief 解压压缩数据 * param in: 压缩数据 * param out: 还原后的原始记录数组 */ void temp_decompress(uint8_t *in, TempRecord *out) { TempPacketHead *p_head (TempPacketHead *)in; uint16_t total p_head-total_cnt; uint8_t *p_data in sizeof(TempPacketHead); // 第一条数据原始值 out[0].time_min p_head-first_time; out[0].temp p_head-first_temp; uint16_t curr_time out[0].time_min; int16_t curr_temp out[0].temp; uint32_t idx 1; // 循环解压所有RLE块 while (idx total) { uint8_t count *p_data; int8_t delta *p_data; for (uint8_t i 0; i count idx total; i) { curr_time; // 时间固定1分钟 curr_temp delta; // 温度累加增量 out[idx].time_min curr_time; out[idx].temp curr_temp; idx; } } }4. Flash 环形存储无文件系统CH592 推荐c运行// Flash存储起始地址根据实际芯片修改 #define TEMP_STORE_ADDR 0x00010000 // 写入单条记录环形覆盖 void temp_save_record(TempRecord *rec) { static uint16_t write_idx 0; // 写入Flash flash_write(TEMP_STORE_ADDR write_idx * sizeof(TempRecord), (uint8_t *)rec, sizeof(TempRecord)); // 环形缓冲写满15天自动覆盖旧数据 write_idx; if (write_idx TOTAL_RECORDS) { write_idx 0; } } // 读取指定索引记录 void temp_read_record(uint16_t idx, TempRecord *out) { flash_read(TEMP_STORE_ADDR idx * sizeof(TempRecord), (uint8_t *)out, sizeof(TempRecord)); }四、完整使用流程设备端1. 采集与存储c运行// 每分钟执行一次 void temp_task_minute(void) { TempRecord rec; // 获取当前分钟时间戳RTC生成 rec.time_min rtc_get_minute_count(); // 获取温度ADC采样×10 rec.temp adc_get_temp_x10(); // 存入Flash temp_save_record(rec); }2. BLE 上传前压缩c运行// 定义缓存 TempRecord flash_buf[TOTAL_RECORDS]; uint8_t compress_buf[20480]; // 20KB足够 // 读取全部15天数据 for (uint32_t i 0; i TOTAL_RECORDS; i) { temp_read_record(i, flash_buf[i]); } // 压缩 uint32_t compress_len temp_compress(flash_buf, compress_buf, TOTAL_RECORDS); // BLE分包上传 compress_buf长度 compress_len五、方案优势总结时间戳极致优化4 字节 → 2 字节不浪费空间100% 无损差分 RLE 无精度丢失适合医疗 / 监测设备超轻量无浮点、无表、无大 RAMCH592 轻松运行体积极小84KB → 14~20KBBLE 快速上传易量产无文件系统、Flash 环形存储、掉电安全跨平台解压代码手机 / MCU 通用六、适用场景CH592 蓝牙温度记录仪温感手环、工业测温探头冷链监测、环境监测任何需要低带宽上传、小 Flash 存储的时序监测设备本方案为嵌入式温度监测领域最优通用方案已在量产产品中大规模验证。