我试图从我的Arduino ADC中获得10位以上的精度,但是我无法真正弄清其背后的理论。经常引用的Atmel应用说明(http://www.atmel.com/Images/doc8003.pdf)指出:
重要的是要记住,正常平均不会增加转换的分辨率。抽取或插值是求平均的方法,结合过采样可以提高分辨率
然后他们提出的“抽取”建议是移动小数点。这相当于将移动的每个位置的二进制读数减半,因此您最好将基数10的值除以2或4或8或除以已有的值。我了解抽取错误吗?
我试图从我的Arduino ADC中获得10位以上的精度,但是我无法真正弄清其背后的理论。经常引用的Atmel应用说明(http://www.atmel.com/Images/doc8003.pdf)指出:
重要的是要记住,正常平均不会增加转换的分辨率。抽取或插值是求平均的方法,结合过采样可以提高分辨率
然后他们提出的“抽取”建议是移动小数点。这相当于将移动的每个位置的二进制读数减半,因此您最好将基数10的值除以2或4或8或除以已有的值。我了解抽取错误吗?
Answers:
我看了一下便笺,这确实是一个奇怪的说法(或者说它们实际上是什么意思的令人困惑的方式)。
也许它们的实际含义是,如果您想获得更高的分辨率,就不能再将数字除/移位为与单个样本相同的标度,因为(以整数算术)这会丢弃您获得的位。
如果您的ADC样本有噪声,那么您当然可以进行分频以获得原始比例下的较低噪声值。
我仅从您的问题中想到的另一件事是要进行正确的过采样,您需要使用有效的低通滤波器,而直接的移动平均值并不像经过适当设计的FIR一样,不适合作为低通滤波器(或IIR)过滤器-注释的文本似乎不支持这种过滤器。
如果您要求某人测量一个精确到最接近厘米的45.2厘米木板,他们将(或应该)回答45。如果您要求然后再对其进行测量,他们将再次回答45。再重复练习8次,所有测量的平均值应恰好是45。无论对一个输入进行多少次采样,最终的结果都是45。所有这些读数的平均值当然是45(即使木板长45.2厘米)。
如果您让人员调整测量仪器,以便在第一次测量之前读取0.45厘米长,在第二次测量之前读取0.35厘米长,在第五次之前读取0.05厘米,第六次之前读取0.05厘米,依此类推,直到之前的0.45厘米较短第十,那么其中两个测量结果将显示为46,其他八个测量结果将显示为45。所有这些测量的平均值为45.2。
在实践中,很难如此精确地偏向事物。如果在每次测量前随机调整测量设备以读取长度介于0.5厘米至0.5厘米之间的某处,那么大约1/5的测量值将读取46,其余的则读取45,但是由于调整是随机的,因此实际分数可能更高或更低。进行十次测量不会增加相当可观的精度值,但平均大约会达到100。
我不确定我是否完全理解本文关于平均和右移之间区别的理由。需要注意的是,通过平均获得的表观精度可能会超出有意义的精度水平,但是根据我的经验,何时以及向右偏移多少应该由处理器数值范围的限制来驱动。只要不对少量噪声造成不必要的影响,使用尽可能按比例放大的数字而不引起溢出通常会最大程度地减少舍入误差的影响。
顺便说一句,在最初的用法中,“消灭”一支军队是要杀死其中的1/10士兵。从ADC抽取数据就是丢弃一部分数据。带有短语“小数点”的通用前缀并不表示关联。
简短的答案是噪音,它不一定重要,而只是噪音的类型。另一个问题是像INL这样的非线性效应会抵消平均值
首先介绍噪声:
如果我们要采样一个高斯分布,它将看起来像这样:
红线更接近实际热分布(随时间平均),蓝色直方图代表许多ADC样本。如果我们继续对该分布进行采样,我们将获得更好的统计数据,并且能够以更高的准确度找到平均值或均值(通常是这样做的,是的,我意识到信号会四处移动,存在滤波和信噪比取决于频率的内容,但仅考虑信号暂时不移动的直流情况)。
问题是闪烁噪声或1 / f噪声,由于分布不再是高斯分布,它使高斯平均数左右移动并导致统计数据崩溃。
这是一个较差的模型,但是您可能会认为它看起来像这样的INL也是一个问题,因为它可能会引入一些错误,这也可能会偏离均值。
这可能令人困惑,让我们看一下时域,如下所示
在顶部的图像中,您可以看到带有高斯噪声的信号,很容易在中间“画一条线”并找到平均值。您从这样的信号中获得的样本越多,您对均值的准确性和知识就越好。
在下面的图像中,您可以看到闪烁的噪声,平均在这里无济于事。
问题在于大多数电子设备都有闪烁噪声,电阻没有(假设不受室温影响),但晶体管和IC却有。有一些称为斩波放大器的放大器确实可以克服这些影响。
要知道的另一件事是,ADC(线性具有一个新的SAR内核)使工程师们努力将1 / f噪声的影响(以及ADC的其他非线性影响(如INL))降低到比ADC位低得多的水平值。您可以进行大量的过采样,并从14位内核中获取32位值。
然后他们提出的“抽取”建议是移动小数点。
不完全是。在我看来,抽取的一部分是正确的,即对多个样本进行常规的“平均”,但保留了位宽度,却没有保留太多的信息。因此,如果对m个n位ADC读数求平均值,则得到的平均值仍然是n位ADC读数。
坦率地说,建议的方法是对n位ADC读数求平均值,以便得到的平均值具有更高的位宽。例如,将4个10位ADC读数相加并将其总和除以2可得出11位ADC读数。
我认为这一直是专业进行过采样的方式。人们在网络上进行这种简单的平均计算被普遍认为是错误的方法。
另一方面,为了降低噪声,只有在存在噪声的情况下,过采样才是正确的选择。如果您有上帝设计的10位ADC(即每个读数都是绝对真实读数,没有变化),则过采样将无法工作。
在文章末尾有关使用pwm来添加噪声的特定电路是不正确的:添加噪声的引脚应具有一个隔直流电容器。实质性的一点是,它不必是PWM引脚。普通的GPIO引脚可以工作。
首先,ADC仅与其参考电压一样好。如果您的arduino使用+ 5V作为参考,则您可能会忘记任何一种精度,因为+ 5V稳压器非常嘈杂,精度低,例如1-5%,其输出电压将取决于从中汲取的电流量。无论是在测量时还是在最后几毫秒内。
因此,如果您需要精度或精度,请选择符合您要求的参考电压。如果您不需要绝对的电压精度,它会便宜一些,因为您只需要使它稳定即可,而不是准确和稳定的电压。
我尚未在arduino中测试SAR ADC。我有一个与AT90PWM3B有密切关系的经验。很好 在恒定的输入电压下,如果电压介于两个值之间,则一遍又一遍地获得相同的ADC读数,且1 LSB波动。不能期望从SAR ADC获得更好的结果。(我确实使用了高质量的外部参考电压)
因此,这里的噪音不是问题...
实际上,噪音是您的朋友...
假设您要测量的电压落在ADC值100.1上
您进行了10次测量,但是由于ADC很好,因此每次您可以得到100次!
因此,您需要在信号上产生一点噪声,例如一个LSB噪声,以确保您测量到100.1,那么您将获得十分之九的100倍,十分之一的101。那么平均会得到100.1,知道吗?
如果来自传感器,通常会产生足够的免费噪声。
您所缺少的是“抽取”的含义。
严格来说,“抽取”减少到1/10。即从10减少到1。
采样中使用的“抽取”失去了严格的含义。而不是1/10,它的意思是“减少数量”。
这意味着您要平均一些样本,并减少相同数目的样本。
例如,如果以1000Hz采样并平均4次采样,则仅保留平均值。最后,您每秒只有250个样本,而不是1000个。您失去了时间分辨率,但获得了1位电压分辨率。
对于每个4因子,您将获得1位。对4进行平均和抽取,并从10位分辨率变为11位分辨率。
另一个4因子(总共4 * 4 = 16)使您从10位增加到12位。另一个4因子使您达到13位分辨率。
但是,请注意,您现在的采样率提高了64倍。有效采样率降低了相同的因子。以1000Hz采样率为例,每秒可减少约15个有效采样。
这是抽取,是多少个高位ADC获得高分辨率。他们以高速率,平均(或使用数字低通滤波器)采样并抽取。
在最末端,您有一个单比特ADC(一个简单的比较器),对它进行过几毫秒的过采样,以提供16位有效比特深度。
为此,您需要牢记的一件事是,信号中的噪声大约等于ADC可以测量的最小值。对于使用5V参考电压的10位ADC,峰间噪声约为5mV。
平均噪声是位增益的实际来源。想象一下,您的信号(DC)恰好位于512个ADC计数值和513个ADC计数值之间。在没有噪声的情况下,测得的值将始终相同-平均将为您提供与样本相同的值。
以大约最小的可测量值添加噪声,并且看起来非常不同。尽管信号本身不会改变,但测量值将围绕信号的真实值“摆动”。现在的平均值不同于样本,并且您使用的样本越多,越接近信号的真实值
我已将此技术与Arduino(使用带有10位ADC的Atmel处理器)一起使用,以为我进行的某些测量获得更好的分辨率。
我最多可以使用13位,但是发现我还需要更多。我本可以再加上4倍,但这对于每个样本来说都花费了太长时间,而且只让我多了一点。
进行过采样的实验表明,我所做的事情可以工作(我得到了认可,但结果嘈杂),而无需花费时间和金钱来获得更好的ADC。有了概念证明,我可以继续前进并获得更好的ADC-而得到证明仅花费了我几行代码和一点时间。
我发现我至少需要16位。那将意味着平均4096个样本。
使用Arduino软件进行最快的采样,大约需要半秒钟。
由于我需要14400次测量,因此整个过程将花费2个小时。
我不是那个病人,我测量的东西不会持续那么长时间。我不得不改用内部使用更高采样率的ADC,并且以更低的采样率提供更高分辨率的样本。
与许多事情一样,抽取是一种折衷,可以在一个方向(位深度)上为您提供更好的性能,而在另一个方向(采样率)上却使您付出了代价。
因此,您可以研究该理论,但是我可以告诉您,实际上只有一个简单的模型很重要。只要您发出信号在噪声范围内,就可以求平均值。然后,噪声分量的平均值将被清零,而信号将保持不变。这样,您将以带宽为代价获得分辨率。
例如,如果您有一个16位的ADC,而最后四位是嘈杂的,则可以对其进行滤波并获得信号。但是,如果您只有一点点嘈杂,那么平均水平就不高了,因此您不会获得太多新信息。
如果您确实需要高分辨率(和低带宽),请查看sigma-delta ADC的工作原理。它们具有1位的高速率信号,然后将其过滤为高分辨率的某些带宽,有时甚至达到20位或更多。
怎么不行 可以,但是您必须考虑所有错误和干扰源,以确保您的计划有效。
平均可以通过减少标准偏差来提高分辨率, 。要满足的标准是,高斯噪声必须刚好超过量化误差。要定义的规范是总误差,并使量化误差或分辨率仅占总误差预算的一小部分。
例如,如果您想将分辨率提高2位,但噪声已经是3位,则必须考虑如何将噪声降低2 + 3 = 5位,同时将分辨率提高2位。
其中n是所需的分辨率额外位,则右移二进制数(或抽取)x1等于/ 2。
对于平均而言,这意味着 的噪音降低了 对于x个样本,还需要增加x个时间样本的延迟,因此需要过采样以减少延迟。
注意,术语“抽取”适用于十进制值和二进制编码的十进制数。您可以看到是否有一个读取整数值的计数器,然后对10个结果求平均值,然后除以10,得到一个额外的小数位,但是 的噪音仅减少 对于x个样本,还需要将延迟增加x个时间样本,因此需要过采样来减少延迟,
但是在那个采样率下的噪声 必须足以使x个样本中的+/- 1位抖动,以获得最佳的分辨率提高。
量化误差过大或随机噪声过多将需要更多的平均值以减少误差,而更多的平均值会增加结果的等待时间。
为了优化ADC的速度和误差,必须为整个测量范围内的任何给定信号定义总误差预算和可用分辨率(位),所需SNR或绝对误差。首先定义所有错误源似乎很困难,但有必要包括:
例如增益误差,偏移误差,量化误差,CM噪声误差,DM噪声误差,Vref噪声或偏移误差,环境噪声等,等待时间误差(取平均值)
然后确定所有其他误差源最小化后,要达到上述设计误差预算,还需要多少位分辨率。
这同样适用于平均(对于慢速信号)和过采样信号带宽以及实时ADC的抽取。
这将无法校正增益或失调误差,如果随机噪声不足,则必须添加噪声以使信号抖动。理想情况下,所有其他噪声和误差源都不要超过1位,以使标准偏差或抖动在整个样本数量中仅为+/- 1值。但是,必须有足够的噪声,以使两种方法中的连续采样均无法获得相同的读数。
可以从Wikipedia文章中有关过采样的这句话中简短地得出其背后的理论:
但是,SNR增加sqrt(N)(...)。对不相关的噪声求和,将其幅度增加sqrt(N),而对相干信号求和,则将其平均值增加N。结果,SNR(或信号/噪声)将增加sqrt(N)。在该示例中,这意味着在N = 256的情况下,动态范围增加了8位,“相干信号”的内容增加了N,但是噪声的变化幅度为sqrt(N)= sqrt(256) )= 16(在示例中不要与16位的增加相混淆),因此SNR的变化为16倍。
因此,只要您的信号符合特定标准(例如足够慢并且噪声低),您实际上确实每4个采样增加一位。然后,对于每个得到的4个样本,您可以先“加入”,然后再次形成另一个更高分辨率的样本,这样最后,您在ADC上读取的每n个样本将获得log_4(n)位。
至于抽取部分,它并不是真正的平均,特别是如果您考虑到我们在这里谈论整数(ADC样本)的话。例如,如果您有,,和样本1
,则平均值将为:1
3
2
int result = (1+1+3+2)/4;
由于您使用整数数学求平均值,因此您的1.75的“数学结果”将向下舍入为1。如果再乘以2,您将得到2
。
现在,如果您使用以下方法进行抽取:
int result = (1+1+3+2)>>1;
您的结果将是3
。您可以辩称这与除以2相同,但是可以肯定地说,您不能认为3是1、1、3和2的平均值。看到不同?
现在,您可能会想只对所有内容求和而不丢弃最后一位。但是请记住,这就是噪音:您无法真正使用它。
N/sqrt(N) = sqrt(N)
。
听起来每个人都已经涵盖了问题的理论部分,但是由于您使用的是Arduino,因此您可能希望通读我的冒险经历,以尝试通过这种技术来提高ADC的分辨率:
噪声的特性是故事的关键部分,事实证明,在异步读取ADC时,只需在引脚上用电阻器脉冲就可以产生合理的抖动。这不是完美的,并且您确实会得到一个小的同步偏移量,该偏移量将根据您要达到的额外采样数/位数而变化。我也接受这样的批评,即该技术取决于Arduino中较差的导轨稳定性,因此实际上是在设计缺陷,而不是遵循良好实践。但这很容易做到。