一、问题描述
-有多台adc检测不稳定的设备,每一台设备计算出来的adc最大值不等、最小值不等,相差在-3到3之间。设置200个格子,计算当前adc值落在那个格子里以用来控制另一个功能。
二、解决思路
-策略1:设置adc采样的最小值否则一律看作0,设置adc采样的最大值否则一律设置为最大。格子中设置有效触发区间,若落入有效触发区间则直接出结果,若落在无效区域就要分情况讨论-----adc值就在格子的临界处、adc值不在格子的临界处。
-adc值就在格子的临界处:跳变的adc值随时在两个格子a、b的无效触发区间跳动,若只是简单的设置为:触发在格子a的临界处就直接认为格子a有效,触发在格子b的临界处就直接认为格子a有效,这会导致每一次计算结果时哪怕不扭动旋钮等器件控制adc值改变,单单adc值的跳变以及不稳定就概率让计算的结果为:落在格子a、落在格子b,但这是显然没有扭动器件。而且这种情况下使用平均值的方式消抖不总是有用的,平均值消抖的本质是:采样一周期的周期变化的adc值,让波峰掩盖波谷。但是这平均值方式在面对周期长的是需要长时间采样,在实时性要求比较高的应用,这简直是灾难,可以想象每次扭动旋钮结果要采样几秒种才能出结果,这很离谱。当然也可以说直接保存之前记录的值就好了,新得出的校验值与之前的做平均就能保证实时性,这也是一个好办法。但值得一提,设置过长的记录数据长度其实是带来一种延迟响应的问题,人去扭动旋钮但经过平均值一计算的值与所想要的值相比总会滞后,这是平均所带来的。设置过短的长度又会直接没效果。实在是太难了。
-正确方式:
.当adc值落在临界段,计算第一次落入临界段的值是更偏向格子a还是格子b,记录该值,但下一次adc值继续落入临界段,无论更偏向格子a还是格子b一律以记录的值为准并将当前结果设置为记录的值,并与之前保存的adc采样值做平均以得出结果。当然值得指出,这种方式不是万能的,临界段的设置利用了adc值的概率变化更多落在设置的临界段这个规律。当临界段选取得不好,那么adc值有可能直接在临界段以及无效区间徘徊,而由此计算的结果就仍有可能在格子a以及b跳动。
-adc值不在格子的临界处
-adc值落在无效段:直接记录当前adc值,与之前记录的adc值做平均得出结果,平均的结果不讨论如果继续落入临界区的情况,直接得结果。
-adc值落入有效段:直接记录当前adc值,不参与平均值计算,直接更新记录的adc值全部设置为该值。
-策略2:策略1也太tm麻烦了,为难程序员写这玩意?我只想说:艹,我搬砖的。策略1是仅仅考虑值本身,每一个记录的值当成独立的。但想想都不可能,相邻的值怎么可能没有相关性。将采样adc的值丢经保存的数组里,计算这次采样值与之前的采样值的微分,观察微分值起伏从大到小就有足够的理由认为:旋钮扭动停止了,这次采样的值不是更改输出结果的理由,选定相邻的最小值作为结果输出,若观察到微分值一直都很小,那么应当认为:没有扭动旋钮,不输出结果。这个所谓的“观察”在数学上就是算方差。
见上图所示,快速变化的切线最终平缓,这是旋钮的随时间微分变化图。
-策略3:参考策略1,但是不再存在临界区,当adc值落入有效区间直接出结果,当落入无效区间输出上一次输出的结果。例如上一次输出的结果为格子a,但之后落入了格子b的无效区间,那么仍旧输出结果为a,若之后由于adc的采样不稳落入了格子b的有效区间,输出结果为b,哪怕之后采样的值落入了格子a的无效区间,仍旧输出为结果为b。这种方式下,扭动旋钮不一定是实际上最靠近的结果,但肯定是很好写代码的策略。