xjw01 发表于 2022-4-6 11:00:19

本帖最后由 xjw01 于 2022-4-6 11:04 编辑

abbey_tom 发表于 2022-4-6 09:00
单次采样结果有正有负,
我是取绝对值求和后再平均的。
代码如下:

直接求平均,不要取绝对值。
遇到24bit的负数,但他表示负数的话,转32bit时,在前面的8bit补上8个1就可以了。

sigma delta ADC,读数要取平均值,否则效果不好(有效位数会少了几个bit)。

abbey_tom 发表于 2022-4-6 12:30:02

washu 发表于 2022-4-6 10:16
这个测试不是叫你取平均值,而是统计 100 个样本的峰峰值(或者求其标准差、有效值),然后和手册对比。
...

有没有您用过的用于统计的测试代码?

abbey_tom 发表于 2022-4-6 12:31:39

xjw01 发表于 2022-4-6 11:00
直接求平均,不要取绝对值。
遇到24bit的负数,但他表示负数的话,转32bit时,在前面的8bit补上8个1就 ...

如果不取绝对值的话,
正负可能相互抵消,
结果会比较好看。

xjw01 发表于 2022-4-8 10:29:16

本帖最后由 xjw01 于 2022-4-8 10:33 编辑

abbey_tom 发表于 2022-4-6 12:31
如果不取绝对值的话,
正负可能相互抵消,
结果会比较好看。

这类ADC芯片,没有过多可以优化的。取平均值就可以了。
手册上说,非线性最大10ppm,因此,做成5位半的毫伏表是没有问题的。也就是说,最后一位就忽略了吧,这样省事。非要提取最后一位,要想办法降低噪声,同时要做非线性改正,那就太费劲。5位半的表头,相对于4位半的,能更有效的分辨温漂等现象。
我们常用的器件,温漂大,用5位到6位数字显示比较合适,能更突出显示出主要的字数,略去无用字。如果用7位的,环境状态轻微改变,末字就漂,看那飘忽不定末位数,很烦的,也很浪费时间。


正因为末位的不确定性,所以才有各种各样的“统计”方法,对于一般的使用,很讨厌那些统计方法,我们希望得到相对稳定的末位。比如跳动2字是可以接受的,如果跳动10字,还不如把末字隐藏。

abbey_tom 发表于 2022-4-8 15:13:39

本帖最后由 abbey_tom 于 2022-4-8 15:40 编辑

xjw01 发表于 2022-4-8 10:29
这类ADC芯片,没有过多可以优化的。取平均值就可以了。
手册上说,非线性最大10ppm,因此,做成5位半 ...

许老师说得有道理。
其实在我们业余环境下,
所能应用到的环境没有那么高的测量需求,
即使ADC芯片做得再好,
稳定的基准源也是一个大问题。

我现在的目标也不高,
能够做一个精度不低于我23S的毫伏表就可以,
300mV档是0.05%+3d。

但我现在大致比对了一下,
好像在毫伏量级,
能够稳定的有效位数并不如23S,
比如50mV左右,
连稳定的4位都很难做到(23S可测得稳定的50.00mV,末位会变但基本稳定)。
测1.5V的电池可以做到1580.64X
是不是因为基准太高(目前是2.5V)导致的。
还有,
也不知道PGA该怎么选取。

xjw01 发表于 2022-4-8 16:47:12

本帖最后由 xjw01 于 2022-4-8 17:11 编辑

abbey_tom 发表于 2022-4-8 15:13
许老师说得有道理。
其实在我们业余环境下,
所能应用到的环境没有那么高的测量需求,


我曾做过LTC2400和ads1232等,适当做平均处理后,一般可以达到手册中的指标。
当时,LTC2400测试过程比较长,虽然十几年了,却还有一些印象。可以做到500万字,约1uV左右。具体值我记不清了,但我当时保留到500万字,说明末字跳动2、3个uV以内,否则当年只会保留50万字

从手册上看,ads1256的PGA选大一些,噪声小,功耗也变大。功耗大了,容易引起基准的额外温漂。
    这种ADC,要注意电容的选用。因为瓷片电容(现在常用一些新名词,如x7r,cog,npo等等),容量大的,往往介电吸收也很大,噪声电流不可忽略。
    我实测过多种电容,uF级的瓷片电容,表现很糟糕,它会引起ADC读数不稳定。

    我曾在LM317+Ro的测试中讨论到:“有容乃大”的原理,相同容量,体积小容易受到温度的影响,电流噪声大,稳定性差。不管是晶体管还是电容器,基本上都是这样的。特别是温补型的陶瓷电容,哪怕0.01度的温度扰动,也会有噪声电流的。

   我看到你的板子上,用了超小型的电容器。要担心那些电容器对噪声的影响。

正品的ads1256、ads1232、LTC2400等,是很贵的,一般是淘宝上买了一些便宜的,这些ADC,指标差一点,我觉得也正常。芯片制造过程中,总有一些指标差一些的,厂家不要了,却流向市场。

washu 发表于 2022-4-8 17:42:30

abbey_tom 发表于 2022-4-6 12:30
有没有您用过的用于统计的测试代码?

十几年前我用 Basic 写的,估计参考意义不大 :lol

写一个 FIFO(Move Window)数组,新的测量结果丢进去、最早的测量结果抛弃,数组长度就是样本数,然后对这个数组做统计(峰峰值、标注差、有效值)就可以了,挺简单的。我那个编译器很蹩脚(不支持 float 数组),所以用了比较蛋疼的方式去做这个 FIFO,你用普通 C 编译器要简单得多。

washu 发表于 2022-4-8 18:29:47

本帖最后由 washu 于 2022-4-8 18:31 编辑

abbey_tom 发表于 2022-4-8 15:13
...稳定的基准源也是一个大问题。

我现在的目标也不高,
能够做一个精度不低于我23S的毫伏表就可以,
300mV档是0.05%+3d。

但我现在大致比对了一下,
好像在毫伏量级,
能够稳定的有效位数并不如23S,
比如50mV左右,
连稳定的4位都很难做到(23S可测得稳定的50.00mV,末位会变但基本稳定)。
测1.5V的电池可以做到1580.64X
是不是因为基准太高(目前是2.5V)导致的。
还有,
也不知道PGA该怎么选取。


ADR4525 指标足够好(0.02% 精度、1ppm 温度系数、1.25uVpp 噪声),不是你系统中的短板。

你的问题,根据我玩 1232 的经验看主要是,

1、芯片电源、基准电源和基准、输入的退耦处理你做好没有?使用什么电容?你看我的 1232 用的据大个头的薄膜电容 :lol 你看看是否相关(环境温度稳定且无振动的话,铁电介质电容也不是那么糟糕,但如果确实有问题可以考虑 NP0 介质或薄膜)


2、进一步降低速度,作为肉眼观察的表,10Sa/s 速度还快了,1232 是慢不下来,你这个可以再慢到 2.5Sa/s

3、进一步滤波处理

此外,如果你要做一个 Range 50mV 的表,没有什么理由不开片内 PGA,人家本来就是给你干这活的。PGA 取到你的应用中的最大值或你的应用对 PGA 其它指标需求的最大值,比如失调和温度系数是否有额外的要求?

washu 发表于 2022-4-8 18:42:38

xjw01 发表于 2022-4-8 16:47
...正品的ads1256、ads1232、LTC2400等,是很贵的,一般是淘宝上买了一些便宜的,这些ADC,指标差一点,我觉得也正常。芯片制造过程中,总有一些指标差一些的,厂家不要了,却流向市场。


这些便宜货基本是翻新的,我当初发行 Voltgen 采购过几百片 LTC2400,和厂家样片对比没啥区别,除了外表...

我 4 月下旬可能会有点空,刚跑去买了点几块钱的 ADS1247 和 1255,到时候有机会测试看看,1255 我也是有样片的,可以对比。

当初也买过一批便宜的 1232,和徳姨样片对比,也没发现问题。

washu 发表于 2022-4-8 18:50:18

xjw01 发表于 2022-4-8 16:47
我曾做过LTC2400和ads1232等,适当做平均处理后,一般可以达到手册中的指标。
当时,LTC2400测试过程 ...

2400/1232 的噪声指标是硬指标,是不能做平均处理的,我前面贴的 1232 噪声就是没做平均处理的,直接采样连续若干样本,然后用其中最大值减去最小值得到的(峰峰值)。



washu 发表于 2022-4-8 19:04:59

abbey_tom 发表于 2022-4-6 12:30
有没有您用过的用于统计的测试代码?

不记得贴图用的代码是哪份了,反正都差不多,供参考

Do
      ' --------------- Wait the Convert ---------------
   FontSet F0HD
   iBusystp = 0
   Do
   iBusystp = iBusystp + 1
   WaitMs 1   
   Loop While IO_ADC_DAT = 1 ' theAnalog to Digtial Convert Busy Bit at ADChipset DOUT Pin
   
   GLcd (80,7), "Setp:"; Hex(iBusystp)
   ' --------------- Wait the Convert ---------------
   
   ' --------------- Read the ADC ---------------
   ' Read all Analog to Digtial Convert Byte
   iDa = ReadSPI()
   iDb = ReadSPI()
   iDc = ReadSPI()

   ' Config the Negative numbers from the Complement Code.
   'If iDa > 128 Then
      'iDraw = iDa - 128
   'Else
      'iDraw = iDa
   'End If
   iDa = iDa - 128
    ' Set the ADChipset Busy-wait Bit
   IO_ADC_CLK = 1 : WaitUs 1 : IO_ADC_CLK = 0
   ' --------------- Read the ADC ---------------
   
   ' --------------- Automatic theRange ---------------

   ' --------------- Automatic theRange ---------------   

   
   ' --------------- Print the Convert Result ---------------
   'Print the Current Convert Result
   FontSet F0HD
   Format (1,5)
   fTrn = 2.5 * (65536 * iDa + 256 * iDb + iDc - 8388608) / 8388608
   'Print fTrn
   'GLcd (0,4), "Cur:"; fTrn; " VDC"
   ' --------------- Print the Convert Result ---------------
   fOut = fTrn / Gainerr - Offseterr
   FontSet F3HD
   Format(2,4)
   GLcd(0, 2), fOut   

   
   For i = 0 To bSmthlength - 1
       bREGc(i) = bREGc(i + 1)
       bREGb(i) = bREGb(i + 1)
       bREGa(i) = bREGa(i + 1)               
   Next i
   bREGc(bSmthlength) = iDc
   bREGb(bSmthlength) = iDb
   bREGa(bSmthlength) = iDa

   '排查最大最小值   
   lrec = 65536 * iDa + 256 * iDb + iDc - 8388608
   lMax = lrec
   lMin = lrec
   iMax = 1
   iMin = 1
   fOut = 0
   For i = 1 To bSmthlength
       iTa = bREGa(i)
       iTb = bREGb(i)
       iTc = bREGc(i)
      
       lrec = 65536 * iTa + 256 * iTb + iTc - 8388608
       fTrn = 2.5 * (65536 * iTa + 256 * iTb + iTc - 8388608) / 8388608
       If lrec > lMax Then   ' 找到最大值
          lMax = lrec
          iMax = i
       End If
       If lrec < lMin Then   ' 找到最小值
          lMin = lrec
          iMin = i
       End If            
       fOut = fOut + fTrn
   Next i
   
   fOut = fOut / bSmthlength
   fOut = fOut / Gainerr - Offseterr
   'fOut = 2.5 + fOut
   'GLcd (1,1), "SMT:"; fOut; " VDC"
   FontSet F0HD
   Format(2,6)
   GLcd (0,4), "SMT:"; fOut; " VDC"

   'FontSet F3HD
   'Format(1,6)
   'GLcd(0, 2), fOut

   FontSet F0HD
   Format(1,6)
   iTa = bREGa(iMax)
   iTb = bREGb(iMax)
   iTc = bREGc(iMax)
   fMax = 2.5 * (65536 * iTa + 256 * iTb + iTc - 8388608) / 8388608
   'GLcd (1,2), "MIN:"; fMax; " VDC"
   iTa = bREGa(iMin)
   iTb = bREGb(iMin)
   iTc = bREGc(iMin)
   fMin = 2.5 * (65536 * iTa + 256 * iTb + iTc - 8388608) / 8388608
   'GLcd (1,3), "MAX:"; fMin; " VDC"
   GLcd(0, 5), fMin; " ~ "; fMax
   fOut = 1000000 * (fMax - fMin)   
   Format(3,1)
   GLcd (0, 6), "Noise:"; fOut; " uVpp"
   

Loop

xjw01 发表于 2022-4-8 20:45:21

本帖最后由 xjw01 于 2022-4-8 20:48 编辑

刚才找到了LTC2400,测试了15分钟。前几分钟等待稳定。之后,读数基本稳定为0uV,概率分布为:
0 uV,90%以上
- 1uV,5%
+1uV,5%(1分钟内,难得见到一两次+-1uV)
数字由0跳变为-1uV时,偶尔会同步出现-2uV,可能是数码管驱动电流比较大,产生了额坏的干扰。
也就是说,当时的制作,零点稳定性(短路),噪声电压小于1uV
手册止的指标是,0.5ppm跳动占比60%左右,也就是说跳动+-2uV以内。当时做了平均处理,噪声略有下降。


pgldyx 发表于 2022-4-8 21:07:10

对于这么高级的芯片ad转换,外围设计可不能马虎,费的功夫可能比编程还要多。采用低纹波三端稳压,高精度基准芯片(如果有的话),供电采用磁珠+电容的LC滤波,数字地与模拟地分离。还有人提到前面加缓冲运放,芯片下面不做覆铜处理。。。。。。。这些可能比修改程序有效。我以前用TM7705的16bitdac,根本不用多次采样取平均值,输出数值只跳动1个字。

abbey_tom 发表于 2022-4-8 21:17:04

xjw01 发表于 2022-4-8 16:47
我曾做过LTC2400和ads1232等,适当做平均处理后,一般可以达到手册中的指标。
当时,LTC2400测试过程 ...

这块板子我买的是半成品,
我对焊接这种贴片已经无缘了。
不过,
从对电池的测量来看,
可以达到1580.06x
我基本还是满意的,
噪声略大也就是偶尔超出5个uV,
现在比较头大的是,
测量小信号不行,
试了改变PGA还是不行,
我没有来得及仔细研究手册,
改变PGA(基本代码不动),
显示也没有什么变化。

就我的理解,
输入50mV,
假如PGA选择64,
输入到ADC的电压应该是50*64=3200mV
但显示仍然是50mV

abbey_tom 发表于 2022-4-8 21:17:43

washu 发表于 2022-4-8 19:04
不记得贴图用的代码是哪份了,反正都差不多,供参考

谢谢,收到代码。
有时间测试一下。
页: 1 [2] 3 4 5 6 7 8 9 10 11
查看完整版本: 24bitADC芯片ADS1256的测量精度