使用uC和电流分流器测量平均电流


12

这是我的第一篇文章。我是一个尝试做硬件的软件人,所以要谦虚:)

电路图

我正在设计一个简单的小型电路(参见图片,对不起,电路图混乱),简单地说,就是一堆MOSFET和栅极驱动器,旨在切换微控制器的电阻性负载(在这种情况下为加热垫)。加热元件通常具有非常低的电阻,并且为了将功率保持在所需水平,可使用PWM来开关MOSFET。

测量

除了纯粹的功能方面,还有教育的重点。我希望能够获得有关当前消耗的一些反馈。而我幼稚的方法是简单地放入一些当前的并联传感器IC。当使用万用表测量传感器的输出电压时,由于电流表的“缓慢”,实际上我得到的东西看起来像是平均电流(带PWM开关)。但是,当将相同的输出连接到atmega328p ADC时,我得到了一些不好的读数-此处的速度将读数放置在PWM方波的任何位置。

因此,我的问题是,使用PWM切换时如何测量(平均)电流?

看起来设计还可以,但我可能在设计中以及在这种情况下应如何使用uC ADC方面都错过了一些东西。

原理图


我认为可以使用滤波器来提供PWM的平均电压。解释这样的过滤器和值时使用基于PWM频率有趣的文章是这一个
alexan_e 2014年

这个问题有一些相关的答案。但他们只是提到使用分流器和IC来测量电流。不过,没有提到PWM。
里卡多

感谢您的评论。@alexan_e:TI在INA197数据表中显示了一个输入滤波器,但我不确定其用途。电压不稳定时可能要走的路。
ltj 2014年

我认为这是解决您问题的方法,但我希望对此有更多的经验,以提供详细的答案,这就是为什么我将其发布为评论。
alexan_e 2014年

由于输出是可变占空比的PWM,因此可以使用峰值检测器电路并通过ADC进行测量。
马丁

Answers:


6

有时候看起来简单的事情并不那么简单。您需要进行相当复杂的测量,但是想要一个简单的结果。您想要测量的不是恒定的,而是随时间变化的。根据您的需求水平,您可以计算电流消耗的一个或多个属性。这些属性将帮助您更好地监视系统。我向您提出3种不同的解决方案,以提高复杂性。

解决方案1:平均

您想要一个单值结果->及时获得平均值。如@akellyirl所建议的,使用低通滤波器。计算float y = alpha*input + (1-alpha)*y每个样本,其中alpha的平滑因子。有关详细信息,请参见Wikipedia

解决方案2:最大+平均

您对获得平均值和最大值很感兴趣。例如,监视最大值可能对组件尺寸确定很有用。

if (y > max)
  max = y;

解决方案3:标准差+最大值+平均值

为什么?

请参见以下图表。有3种不同形状的信号。甲三角形,一个正弦和一个尖峰信号。它们都是周期性的,具有相同的周期,相同的幅度,相同的平均值以及相同的minmax。但是,它们具有不同的形状,实际上它们的故事完全不同...

信号及其直方图

差异之一是标准偏差。因此,我建议您扩展测量范围并包括标准偏差。问题是计算它的标准方法消耗CPU。希望有一种解决方案。

怎么样?

使用直方图方法。建立所有测量值的直方图,并有效地提取数据集的统计信息(最小,最大,平均,标准差)。直方图将具有相同值或相同值范围的值组合在一起。优点是避免存储所有样本(时间计数增加),并且可以对有限数量的数据进行快速计算。

在开始获取测量值之前,创建一个数组来存储直方图。它是一维整数数组,大小为32,例如:

int histo[32];

根据电流表的范围,调整以下功能。例如,如果范围为256mA,则表示直方图的bin 0将增加0到8 mA之间的值,bin 1将增加8到16 mA之间的值等等...因此,您需要一个整数来表示直方图箱号:

short int index;

每次获取样本时,请找到相应的bin索引:

index = (short int) floor(yi);

并增加这个垃圾箱:

histo[index] += 1;

要计算平均值,请运行以下循环:

float mean = 0;
int N = 0;
for (i=0; i < 32 ; i++) {
  mean = i * histo[i]; // sum along the histogram
  N += i; // count of samples
}
mean /= N; // divide the sum by the count of samples.
mean *= 8; // multiply by the bin width, in mA: Range of 256 mA / 32 bins = 8 mA per bin.

要计算标准偏差,请运行以下循环:

float std_dev = 0;

for (i=0; i < 32 ; i++) {
  std_dev = (i - mean) * (i - mean) * histo[i]; // sum along the histogram
}
std_dev /= N; // divide the sum by the count of samples.
std_dev = sqrt(std_dev); // get the root mean square to finally convert the variance to standard deviation.

直方图方法的策略是对几个bin进行慢速操作,而不是对所有采集的信号样本进行慢速操作。样本量越长越好。如果需要更多详细信息,请阅读此有趣的页面直方图,Pmf和Pdf


非常详尽清晰的解释。从实际的角度来看,如何确保ADC采样“以一种良好的方式”分配,即不以任何方式被PWM信号锁定?我必须承认,现在我只使用Arduino(hw + sw)进行PWM和ADC采样。可能是我应该自己设置内置计时器。我猜采样频率应该比PWM频率高很多吧?
ltj 2014年

1
一旦开始采样,事情就会变得很复杂。首先要记住的是奈奎斯特-香农定理。直观的是,采样频率越高,您拥有的信息越多。但是,虽然很基本,但不直观的是,在以频率Fs采样之前,必须对Fs / 2的信号进行绝对低通滤波(在模拟/电子领域)。否则,您将受到别名的影响。我建议您选择最高的采样频率。如果可能的话,大约是PWM频率的10倍左右。
RawBean

这是对Nyquist-Shannon定理的一个普遍误解,该定理实际上指出需要您以两倍的带宽进行采样。混叠可能会有所帮助。没有不尊重的意图,但这似乎是texbook的答案。建议在这种情况下,最可能与高频细节无关的〜10倍PWM采样是过大的。
akellyirl 2014年

1

您正确理解了这个问题:您需要获得PWM的“平均值”,就像用于测量的电表一样。

您可以对A1,2,3信号使用RC滤波器,其时间常数至少是PWM周期的十倍。这意味着,如果您的PWM周期为10微秒,则RC时间常数应为100微秒。例如10kOhms x 10nF = 100us

更好的解决方案是像这样在微控制器中数字滤波信号:

float y = (1-0.99)*input + 0.99*y; 

更改“ 0.99”值以更改此数字滤波器的时间常数。


1
如果在代码中使用别名,请当心。
安迪(aka)2014年

混叠不一定是问题。我们都知道,要重构信号,采样率必须至少是最高频率的两倍。但是,当信号受到带宽限制时,您只需以两倍的带宽进行采样。这称为欠采样。由于信号可能是低频信号,因为它正在驱动加热板,因此100至1000 SPS范围内的合理采样率应该很好。参见:ni.com/newsletter/50078/en
akellyirl 2014年

如果使用欠采样,确保PWM速率和采样速率互质是明智的。
akellyirl 2014年

正是我的想法-如果通过ADC进行测量并在同一MCU中生成PWM,则两者都有可能被及时锁定。
安迪(aka)2014年

信号处于pwm频率,而不是低频率。如果它的频率较低,那么与仅使用一个浮点数学运算相比,仅在一个时间段内取平均值并进行平均可能要少一些资源。
Scott Seidman 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.