一种简单的时序压缩算法WDTCA

最近在做红外遥控器的学习功能, 需要记录红外的高/低电平持续时间, 我把它叫做时序(timing?)。

记录的时间单位为μs, 1μs=10^-6s。

由于遥控器发射的光持续时间不会超过65535μs, 于是选择8位单片机上的16位的unsigned int来存储每个高/低电平的持续时间。

经过计算, 遥控器发射的每一位, 一般改变高/低电平一次, 也就是说需要记录高/低电平各1个。

另外, 我有的空调遥控器最多不会超过112位, 也就是224个高/低电平, 加上同步码的2个高/低电平, 一共是226个高/低电平。因此, 我使用固定长度为256的unsigned int数组来存放时间信息。

这样一个记录就占掉了256*2=512bytes的存储器空间, 而在单片机上, 资源是十分紧张的, EEPROM只有1KB(flash有32KB但是不方便使用)。

于是EEPROM只能存储2个。

所以, 我需要一种压缩算法。

我的想法是:

时序中高/低电平持续时间的长度只有很少几种, 比如某编码的引导码有2种, 数据码有3种, 一共是5种。同时, 接收器接收的时候允许有一定的误差(具体数值未知)。

可以通过某种转换关系, 把相差不大的几个持续时间算为一种, 存放在一个数组中, 数组的下标就是该持续时间的id号码。由于时序中高/低电平持续时间的长度只有很少几种, id号码最大值也不会很大。

我假定id号码最大为15。于是这个数组大小就为(15-0+1)*2bytes=32bytes

这样就可以把长16bit的unsigned int转化为4bit的id号。256个数据就从512bytes变为了128bytes。

加上存放持续时间和id的数组32bytes, 一共需要160bytes, 压缩率为160/512=31.25%。

如果有持续时间很长的部分, 用unsigned long来存储, 那么原本需要1024bytes的数据只需要4*16+128=192bytes, 压缩率为192/1024=18.75%。

如果使用N字节的某数据类型来存储, 那么原本需要256N的数据, 现在只需要16N+128, 压缩率为(16N+128)/256N。

WDTCA=Wandai’s Timing Compression Algorithm

代码后附。

另外, 如果知道了红外的编码方式, 就可以解码之后再存储, 发射的时候重新编码, 这样比任何压缩算法都要好。可惜红外遥控器没有一个编码标准:(

 

发表评论

注意 - 你可以用以下 HTML tags and attributes:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

:wink: :twisted: :roll: :oops: :mrgreen: :lol: :idea: :evil: :cry: :arrow: :?: :-| :-x :-o :-P :-D :-? :) :( :!: 8-O 8)

本文链接:https://twd2.me/archives/5926QrCode