I'm trying to do simple averaging in Simulink and need some help with it.

21 ビュー (過去 30 日間)
Guillermo
Guillermo 2011 年 11 月 9 日
回答済み: Martin Murtagh 2021 年 3 月 23 日
Assume AI'm acquiring a noisy signal at 1 mS interval and I want to get 1 point every 50 mS. I would like to collect the data for the 50 mS and spit out an average for logging. I'm not sure how to do it.
Any simple solutions would be appreciated.

採用された回答

Alexander Bottema
Alexander Bottema 2011 年 11 月 9 日
function y = my_average(u) %# codegen
persistent i buf bufSum;
if isempty(buf)
buf = zeros(1,50);
bufSum = 0;
i = 1;
end
bufSum = bufSum - buf(i);
buf(i) = u;
bufSum = bufSum + u;
i = i + 1;
if i > numel(buf)
i = 1;
end
y = bufSum / numel(buf);
  2 件のコメント
Guillermo
Guillermo 2011 年 11 月 9 日
Thank you, I will try to make this a sub-system and I hope it works in simulink...
Guillermo
Guillermo 2011 年 11 月 9 日
It seems to have worked. It generates a warning at every iteration but I can live with that.
Thank you,

サインインしてコメントする。

その他の回答 (4 件)

Fangjun Jiang
Fangjun Jiang 2011 年 11 月 9 日
Use the "Weighted Moving Average" block from Simulink>Discrete, click help for details.
  2 件のコメント
Guillermo
Guillermo 2011 年 11 月 9 日
I don't have a Weighted Moving Average" block. I tried to create one with the following:
****************************************************
function Vector_out = fcn(Raw_In, Vector_in)
%#codegen
Vector_in = circshift(Vector_in, [1,1]);
Vector_in(1) = Raw_In;
Vector_out(:) = Vector_in(:);
******************************************************
Vector_in is initialized by a data store block
and then Vector_out would be summed with the Sum of elements block then divided by the dimension. In this way I would have a moving average which is more desirable but a block average would do too.
If this sparks ideas let me know. It didn't work for me because I could not use the data store block to define the vector_in or Out I don't recall which.
Fangjun Jiang
Fangjun Jiang 2011 年 11 月 9 日
Hah, it is obsolete! http://www.mathworks.com/help/toolbox/simulink/ref_obsolete_blocks/weightedmovingaverageobsolete.html
Use the new Discrete FIR Filter, http://www.mathworks.com/help/toolbox/simulink/slref/discretefirfilter.html

サインインしてコメントする。


Walter Roberson
Walter Roberson 2011 年 11 月 9 日
Feed the signal in to an integration block that is reset to 0 every 50 samples; take the 50th output and divide it by 50 to get the average for that period.
There might be a cleaner way to only trigger the output collection every 50 outputs and tie that in to the integration block being cleared right afterwards.
  1 件のコメント
Guillermo
Guillermo 2011 年 11 月 9 日
I would like to try this, but I'm not yet very familiar with simulink. How do it set up the integration block?
The initial condition is set to 0, how about the saturation limits? and the Ignore limit and reset when linearizing check box?
Thanks again,

サインインしてコメントする。


Guillermo
Guillermo 2011 年 11 月 9 日
I got my code to work too, thanks to the sample by Alexander. The two codes give the same result and I'm not sure either which is more efficient. I tried passing the number of elements n to acquire so that I can pass a number of points to average but got an error...
function y = fcn(u)
%#codegen
persistent i n buf;
if isempty (buf)
i = 0;
n = 50;
buf = NaN(50,1);
end
buf = circshift(buf, [1,1]);
buf(1) = u;
n = numel(~isnan(buf));
y = sum(buf)/n;

Martin Murtagh
Martin Murtagh 2021 年 3 月 23 日
I have replaced the moving average block in my models with the subsystem shown. By setting the delay length to the moving average value divided by the time-step and the gain value to one over the moving average value, this subsystem will calcuate the moving average in the same way as the moving average function with a sliding window.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by