tomzbj 发表于 2021-5-25 16:30:18

玩了一把LCR,软件解调,效果超出预期

本帖最后由 tomzbj 于 2021-5-25 22:01 编辑

学习了之前amobbs上N款LCR,基本都是用模拟开关鉴相, ADC用ICL7135.
感觉可以简单点,V和I输出直接进STM32的ADC,模拟开关之类都去掉,解调什么的,全部用软件来做。
激励源用DAC查表产生10kHz正弦波。
STM32F303的ADC能工作到5M,这次只用到1M。
估计效果不会太好,12位adc的动态太差,随便试试。

两通道同步采样,解调算法如下:
#include "misc.h"
#include "platform.h"
#include <math.h>

typedef struct {
    unsigned short i, v;
} sample_t;      // 单个采样点,32位的高16位和低16位分别是两个通道

static void sample(void)
{
    __disable_irq();
    DMA_Cmd(DMA1_Channel1, ENABLE);
    while(DMA_GetFlagStatus(DMA1_FLAG_TC1) == RESET);
    __enable_irq();
    DMA_Cmd(DMA1_Channel1, DISABLE);
    DMA_ClearFlag(DMA1_FLAG_TC1);
}

void LCR_DoMeasure(void)
{
    DataConfig_t* pdc = DC_Get();
    sample_t* pbuf = (sample_t*)pdc->data.adc_buf;

    float mean_v = 0, mean_i = 0, prod_i = 0, prod_q = 0, phase;
    float abs_v = 0, abs_i = 0, z, x, r;

    sample();   // 执行一次采样

    int buf_size = sizeof(pdc->data.adc_buf) / sizeof(pdc->data.adc_buf);
    for(int i = 0; i < buf_size; i++) {
      mean_v += pbuf.v;
      mean_i += pbuf.i;
    }
    mean_v /= buf_size;
    mean_i /= buf_size;         // 求平均值, 用于直流平衡

    for(int i = 50; i < buf_size - 50; i++) {
      prod_i += -(pbuf.v - mean_v) * (pbuf.i - mean_i);          // v和i做直流平衡后相乘, 累加得到同相分量
      prod_q += (pbuf.v - mean_v) * (pbuf.i - mean_i);    // 激励频率10k, 采样率1M, 每周期100个点, 因此移动25个点再平衡, 相乘, 累加就是正交分量了
      abs_v += fabs(pbuf.v - mean_v);            // 绝对值求和
      abs_i += fabs(pbuf.i - mean_i);
    }
    prod_i /= buf_size;
    prod_q /= buf_size;
    phase = atan2(prod_q, prod_i);            // 同相分量和正交分量, atan2即得到相位差
    z = abs_v / abs_i;                                  // v和i绝对值相除得到阻抗绝对值, 再分别乘以相位差的cos和sin即得阻抗实部和虚部
    r = 100 * z * cos(phase);
    x = 100 * z * sin(phase);

    printf("%f\n", phase * 180 / 3.141593);
    if(phase >= 0)
      printf("%f R + %.4e H\n", r, x / 2.0 / 3.141593 / 10e3);            // 相位差>0, 感抗, 否则为容抗
    else
      printf("%f R + %.4e F\n", r, -1 / x / 2.0 / 3.141593 / 10e3);
}

实测: 100pF, 68p, 47p, 12p电容:
951866.375000 R + 1.0172e-10 F
1414790.375000 R + 6.5711e-11 F
1966322.625000 R + 4.7291e-11 F
7668320.000000 R + 1.1785e-11 F
47uF电容误差比较大了
0.761227 R + 3.7138e-05 F

4.7uH, 68uH, 220uH电感:
0.036692 R + 4.5969e-06 H
4.750703 R + 6.7916e-05 H
5.105072 R + 2.4425e-04 H

比想象的强多了,如果用STM32H750的3.6M 16位ADC,应该还能改进不少。

原理图大体是参考许剑伟老师的, 要飞条线, 把ADC1改接到12脚, 因为F303只能ADC1和2, 或者3和4同步采样.

hunyuanqi00 发表于 2021-5-25 17:13:18

能不能把整个工程代码放上来学习学习?

bolizhicheng204 发表于 2021-5-25 17:19:06

赞!学习了,多谢

tomzbj 发表于 2021-5-25 17:27:15

hunyuanqi00 发表于 2021-5-25 17:13
能不能把整个工程代码放上来学习学习?

除了我贴的那段真的没啥特别的了,就是各个外设配置,照官方例子就行了。

albert_w 发表于 2021-5-25 17:51:25

for(int i = 50; i < buf_size - 50; i++) {
      prod_i += -(pbuf.v - mean_v) * (pbuf.i - mean_i);
      prod_q += (pbuf.v - mean_v) * (pbuf.i - mean_i);
      abs_v += fabs(pbuf.v - mean_v);
      abs_i += fabs(pbuf.i - mean_i);
    }
    prod_i /= buf_size;
    prod_q /= buf_size;
    phase = atan2(prod_q, prod_i);

这段代码是自相关求相位差?效果看起来不错啊

bad_fpga 发表于 2021-5-25 18:46:46

谢谢,好东西,学习了

kitten 发表于 2021-5-25 19:42:46

硬件可以用毛子的哪款,精度出来很不错的

lucky_jeck 发表于 2021-5-25 20:40:19

不错不错,学习了

TINXPST 发表于 2021-5-25 20:49:27

STM32H750的 16位ADC做出来的效果,并不比F303的好。老毛子做过对比测试。
另外做LCR类的设计,核心算法比如DFT等只占编程工作量的不足20%,其余的分档位校准,LCD界面显示菜单等工作量超过8成{:lol:}。

ilawp 发表于 2021-5-25 20:54:05

求教
pbuf.v
这个.是什么用法,二维数组?结构体?

rube 发表于 2021-5-25 21:12:40


看不大懂,如果有些文字说明就更好了。

tomzbj 发表于 2021-5-25 21:54:27

albert_w 发表于 2021-5-25 17:51
这段代码是自相关求相位差?效果看起来不错啊

关键是采样率除以激励频率, 得是4的倍数... 所以ADC不能自由运行, 得用一个timer来触发.

tomzbj 发表于 2021-5-25 21:55:21

TINXPST 发表于 2021-5-25 20:49
STM32H750的 16位ADC做出来的效果,并不比F303的好。老毛子做过对比测试。
另外做LCR类的设计,核心算法比 ...

是啊, 有GUI就得在GUI上花80%的时间. 做着玩玩, 以后再考虑要不要做成成品吧~

鲜衣怒马 发表于 2021-5-25 22:55:17

ilawp 发表于 2021-5-25 20:54
求教
pbuf.v
这个.是什么用法,二维数组?结构体?

结构体数组
引用某个数组元素的成员变量

fengyunyu 发表于 2021-5-26 08:12:44

不错,学习

brother_yan 发表于 2021-5-26 08:43:51

LCR电桥几百块钱的就行,不贵

tomzbj 发表于 2021-5-26 09:04:50

brother_yan 发表于 2021-5-26 08:43
LCR电桥几百块钱的就行,不贵

我有个VC4091C,就是做着玩玩的~

润持 发表于 2021-5-26 09:34:47

如果能把LCR的原理讲清楚最好了。我看了很多版本的LCR,一直都没有搞清楚鉴相器的工作原理,信号实部和虚部是怎么分开的?
如果大神不忙的话,还请讲讲,谢谢!

ilawp 发表于 2021-5-26 09:38:50

鲜衣怒马 发表于 2021-5-25 22:55
结构体数组
引用某个数组元素的成员变量

for(int i = 50; i < buf_size - 50; i++) {
      prod_i += -(pbuf.v - mean_v) * (pbuf.i - mean_i);          // v和i做直流平衡后相乘, 累加得到同相分量
      prod_q += (pbuf.v - mean_v) * (pbuf.i - mean_i);    // 激励频率10k, 采样率1M, 每周期100个点, 因此移动25个点再平衡, 相乘, 累加就是正交分量了
      abs_v += fabs(pbuf.v - mean_v);            // 绝对值求和
      abs_i += fabs(pbuf.i - mean_i);
    }

我复制错了,是想问 pbuf . i ,这里i是整数,不是变量名

albert_w 发表于 2021-5-26 10:06:23

tomzbj 发表于 2021-5-25 21:54
关键是采样率除以激励频率, 得是4的倍数... 所以ADC不能自由运行, 得用一个timer来触发. ...

这里好像是有个90度正交在里面

tomzbj 发表于 2021-5-26 10:10:02

润持 发表于 2021-5-26 09:34
如果能把LCR的原理讲清楚最好了。我看了很多版本的LCR,一直都没有搞清楚鉴相器的工作原理,信号实部和虚部 ...

就是做了个乘法,和电压信号同相就是实部,正交就是虚部呗~

可以先在excel里试验一下,两个同频同相位的正弦波相乘(记得先直流平衡),然后求平均值,结果不为零,如果相位相差90度,最后的平均数就接近零了

鲜衣怒马 发表于 2021-5-26 10:14:25

ilawp 发表于 2021-5-26 09:38
我复制错了,是想问 pbuf . i ,这里i是整数,不是变量名

pbuf.i
第一个i是数组下标
值就是for循环的那个i值

第二个i是结构体成员
见结构体的声明
typedef struct {
    unsigned short i, v;
} sample_t;   

整体就是取第i个数组元素中结构体成员i的值
不知道是不是我没理解你的问题

TINXPST 发表于 2021-5-26 10:23:43

润持 发表于 2021-5-26 09:34
如果能把LCR的原理讲清楚最好了。我看了很多版本的LCR,一直都没有搞清楚鉴相器的工作原理,信号实部和虚部 ...

“每周期100个点, 移动25个点再平衡, 相乘, 累加”。就相当于移相90度,相乘,累加。这就是数字相敏检波。

ilawp 发表于 2021-5-26 10:36:30

鲜衣怒马 发表于 2021-5-26 10:14
第一个i是数组下标
值就是for循环的那个i值



哦,我好像明白了。两个i不是一个意思{:3_41:}
多谢多谢。这样写感觉不是很严谨吧

tomzbj 发表于 2021-5-26 11:41:28

ilawp 发表于 2021-5-26 10:36
哦,我好像明白了。两个i不是一个意思
多谢多谢。这样写感觉不是很严谨吧 ...

确实, 这里有三个i, 一个是循环变量i, 一个是iq的i,一个是vi的i

后两个没办法了,前面这个可以改个名

qwe2231695 发表于 2021-5-26 12:40:08

求出套件 , 让大家用起来

zlutian 发表于 2021-5-26 23:11:27

电路简洁很多。

ywd518 发表于 2021-5-27 08:32:21

建议楼主也做个开源项目

tomzbj 发表于 2021-5-27 09:37:35

ywd518 发表于 2021-5-27 08:32
建议楼主也做个开源项目

我的VIP 6月10日就过期了,过期我就不来了

Kengcc 发表于 2021-5-27 11:16:33

求出套件 , 让大家用起来

ywd518 发表于 2021-5-27 11:52:19

tomzbj 发表于 2021-5-27 09:37
我的VIP 6月10日就过期了,过期我就不来了

你可以申请开源项目,论坛会支持你的

lb0857 发表于 2021-5-27 12:40:16

tomzbj 发表于 2021-5-27 09:37
我的VIP 6月10日就过期了,过期我就不来了

不来了?   可惜! 你也是位技术大牛

xwkj 发表于 2021-5-27 13:38:35

建议楼主弄个套件

TINXPST 发表于 2021-5-28 10:53:57

tomzbj 发表于 2021-5-27 09:37
我的VIP 6月10日就过期了,过期我就不来了

看过楼主的几个帖子和分享的代码链接:

-- 与毛子的MCU高手有类似的编程风格。编译一律是make,基本上没见过用keil的工程,其本人是高手或者正接近高手。
-- 乐于分享,自己的git上的代码很早就将链接发到坛子里了。很多帖子也都是心得体会。
-- 对F303系列的片子可以说是情有独钟,估计是多个5M的ADC可以支持更高阶的应用这点具有吸引力。
-- 基本上100%都是技术贴。

如果楼主决定离开确实有些遗憾。

tomzbj 发表于 2021-5-28 13:09:25

TINXPST 发表于 2021-5-28 10:53
看过楼主的几个帖子和分享的代码链接:

-- 与毛子的MCU高手有类似的编程风格。编译一律是make,基本上没 ...

我水平和大牛们差远了...
倒是有好几个大牛朋友, 他们登不上来就不来了. 我到时候看吧, 能上就上, 登不上就算了, 交钱买VIP我是不干的.

colinzhao 发表于 2021-5-28 13:16:55

谢谢楼主分享

huike 发表于 2021-5-28 18:21:23

tomzbj 发表于 2021-5-28 13:09
我水平和大牛们差远了...
倒是有好几个大牛朋友, 他们登不上来就不来了. 我到时候看吧, 能上就上, 登不 ...

这个号我用了10多年。所以弄个VIP养着吧。至于别的我也没兴趣。确实很多人见不着了!

gaolf_2012 发表于 2021-5-31 10:02:22

做µGUI时加中文,参考过楼主的帖子,收益很多,多谢

xxc007 发表于 2021-6-1 00:31:31

mark一下

hunyuanqi00 发表于 2021-6-1 07:57:05

是不是可以这样理解prod_i是有功功率,prod_q是无功功率。

hunyuanqi00 发表于 2021-6-1 08:00:24

z = abs_v / abs_i;这个公式是否正确?用v和i的绝对值来求阻抗对吗?应该用v 和i的有效值,即均方根来求阻抗,即v的有效值除以i的有效值。

EMC菜鸟 发表于 2021-6-1 09:18:42

tomzbj 发表于 2021-5-27 09:37
我的VIP 6月10日就过期了,过期我就不来了

楼主常混哪里,到时候跟着去啊

No.5 发表于 2021-6-1 22:17:29

tomzbj 发表于 2021-5-27 09:37
我的VIP 6月10日就过期了,过期我就不来了

我的vip也是提示7天后到期,倒计时啦

rube 发表于 2021-6-2 13:46:29

tomzbj 发表于 2021-5-28 13:09
我水平和大牛们差远了...
倒是有好几个大牛朋友, 他们登不上来就不来了. 我到时候看吧, 能上就上, 登不 ...

莫总赠送一年vip++,以后常来哦{:lol:}

tomzbj 发表于 2021-6-2 15:54:11

rube 发表于 2021-6-2 13:46
莫总赠送一年vip++,以后常来哦

惭愧惭愧,感谢大家的支持~

tomzbj 发表于 2021-6-9 17:13:18

完整源程序我传到github了
链接: https://github.com/tomzbj/diy/tree/master/lcr

hunyuanqi00 发表于 2021-6-9 21:01:01

技术大牛,请回答这个问题,z = abs_v / abs_i;这个公式是否正确?用v和i的绝对值来求阻抗对吗?应该用v 和i的有效值,即均方根来求阻抗,即v的有效值除以i的有效值。

tomzbj 发表于 2021-6-10 09:59:23

hunyuanqi00 发表于 2021-6-9 21:01
技术大牛,请回答这个问题,z = abs_v / abs_i;这个公式是否正确?用v和i的绝对值来求阻抗对吗?应该用v...

啊,这里可能是有问题。不过原pcb我已经拆了...
有空模拟计算一下

peteryzm 发表于 2021-6-15 10:48:52

这个adc采样的结果缓冲区,应该有好几个周期的数据吧?

tomzbj 发表于 2021-6-15 11:28:14

peteryzm 发表于 2021-6-15 10:48
这个adc采样的结果缓冲区,应该有好几个周期的数据吧?

嗯,采了4000个点,一个周期100个点,总共有40周期。
mcu ram够大的话还可以再多采点

foxfire 发表于 2021-6-18 09:20:53

看起来很不错

maomao190190 发表于 2021-7-27 21:30:51

求问一下,电路里面-5V电压是怎么生成的?L79L05这个芯片应该是负压转负压的吧,输入的负压没看明白怎么产生的,求指导

tomzbj 发表于 2021-7-27 22:22:30

C232和DN200组成负倍压整流呀, 挺常见的用法吧

mainbp 发表于 2021-7-27 22:53:59

本帖最后由 mainbp 于 2021-7-27 22:55 编辑

请教,
1:原理图上r233 0r不是把204短路了吗?
2:c1a c1b接一起吗?

tomzbj 发表于 2021-7-27 23:14:08

mainbp 发表于 2021-7-27 22:53
请教,
1:原理图上r233 0r不是把204短路了吗?
2:c1a c1b接一起吗?

1. 那个0R是我抄俄版还是哪个原理图, 抄错位置了...
2. 接一起, 开尔文接法么.

严格地说, 应该是DG409的C1A和C1B两个管脚分别引线出来, 在左边R225的右端接一起, 而不能从R225走线到C1A再接C1B. 不过在这个场合倒是无所谓.

maomao190190 发表于 2021-7-30 21:17:58

tomzbj 发表于 2021-7-27 23:14
1. 那个0R是我抄俄版还是哪个原理图, 抄错位置了...
2. 接一起, 开尔文接法么.



再请教一下,您这里用的是双刀联动的模拟开关,这里用单刀多选一的模拟开关就可以吧?我看到论坛上几个设计和您这个类似,都是用双刀联动的模拟开关,请问这样用有什么好处吗?谢谢

mainbp 发表于 2021-7-30 21:42:00

maomao190190 发表于 2021-7-30 21:17
再请教一下,您这里用的是双刀联动的模拟开关,这里用单刀多选一的模拟开关就可以吧?我看到论坛上几个设 ...

按照我的理解这样类似于4线制测量类似,减少线阻引入的误差。

maomao190190 发表于 2021-7-30 22:10:56

mainbp 发表于 2021-7-30 21:42
按照我的理解这样类似于4线制测量类似,减少线阻引入的误差。

好像看明白了,应该是这样接模拟开关的内阻就不引入到I/V转换里面了,消除了模拟开关内阻的影响,谢谢

tomzbj 发表于 2021-7-30 22:18:55

maomao190190 发表于 2021-7-30 21:17
再请教一下,您这里用的是双刀联动的模拟开关,这里用单刀多选一的模拟开关就可以吧?我看到论坛上几个设 ...

开尔文接法, 类似四线法测电阻, 可以消除开关内阻造成的误差.

maomao190190 发表于 2021-7-30 22:31:48

tomzbj 发表于 2021-7-30 22:18
开尔文接法, 类似四线法测电阻, 可以消除开关内阻造成的误差.

明白了,谢谢

honger518 发表于 2021-8-1 23:16:04

mark一下

jsh560 发表于 2021-12-15 14:32:50

tomzbj 发表于 2021-7-30 22:18
开尔文接法, 类似四线法测电阻, 可以消除开关内阻造成的误差.

老师,你好,我私信你了,方便请教你几个问题吗?谢谢

huangqi412 发表于 2021-12-17 20:15:52

楼主你好,这个有多余板子吗。{:smile:}
页: [1]
查看完整版本: 玩了一把LCR,软件解调,效果超出预期