連続でアナログ信号を​出力するにはどうすれ​ばよいですか?

12 views (last 30 days)
MathWorks Support Team
MathWorks Support Team on 30 Dec 2013
アナログの実信号として出力したい大きなサイズのデータがあります。実際にはある程度の大きさに分解して連続的に出力します(ただし、あるデータの繰り返しではありません)。出力の際に、データの区切れ目がわからないようにしたいです。
現在、デバイスによる"SamplesOutputFcn" コールバックを使用していますが、これは1つのデータセットのみ有効に動作しています。
%sample data size
datasize = 150000;
%sample output rate
fs=96000;
% Build sample data
t=linspace(0,2*pi,131072);
data=sin(100*t);
data=data';
% Construct analog output object
ao=analogoutput('winsound',0);
addchannel(ao,1);
%Set properties for analog output object
set(ao, 'BufferingMode', 'Auto')
set(ao,'TriggerType','Immediate');
set(ao,'SampleRate',fs);
% Configure callback to regularly queue chunks of data
set(ao,'SamplesOutputFcn',{'queuedata',data});
set(ao,'SamplesOutputFcnCount',datasize);
% Queue the data in the analog output buffer and start data output
putdata(ao,data);
start(ao)
SamplesOutputFcn コールバック関数は以下のように記述されています。
function queuedata(obj,event,data)
putdata(obj,data);
start(obj)
end
  しかしこのコードではデータのセットの区切りごとに一瞬信号が途切れます。途切れなく信号を出力する方法を教えてください。

Accepted Answer

MathWorks Support Team
MathWorks Support Team on 3 Jan 2014
アナログ出力デバイスの"SamplesAcquiredFcnCount"プロパティがキューされたデータのデータ長と同じ値になりますが、出力信号にはギャップが存在します。
対策として、"samplesAcquiredFcnCount" をキューされるデータより短く設定し、データバッファーが空になる前に次のデータをキューするようにします。たとえば、以下のようにします。
set(ao,'SamplesOutputFcnCount',0.9*datasize);
さらに信頼性の高い方法として、"TimerFcn"コールバックを使用する方法があります。TimerFcnコールバックの機能は指定された時間に1つのデータをキューすることです。
TimerFcn のもう一つの特徴として、キュー内にデータが存在する場合、それが廃棄されることです。以下の例では、TimerFcn プロパティはアナログ信号出力を実現しています。(サンプルでは'winsound' デバイスを使用しています。)
%%Create ANALOGOUTPUT device and add 1 channel to it (mono)
ao=analogoutput('winsound',0);
addchannel(ao,1);
%%Configure Analog Output
set(ao, 'BufferingMode', 'Auto')
set(ao,'TriggerType','Immediate');
%Define output samples per second as necessary
set(ao,'SampleRate',fs);
%%configure callback to quuee another chunk of data
% set(ao,'SamplesOutputFcn',{'qmoredata',data});
% set(ao,'SamplesOutputFcnCount',bufsize);
% Use a TimerFcn to queue the next chunk of data
set(ao,'TimerFcn',{'qmoredataForTimerFcn',data});
% Set the Timer to fire when 90% of the buffer has been output
set(ao,'TimerPeriod',(bufsize/ao.SampleRate)*0.9);
%run the machine
putdata(ao,data);
start(ao)
% Examine how much data is in the queue.
for ii=1:100
ao.SamplesAvailable
pause(1)
end
stop(ao)
% Delete ANALOGOUTPUT object when you are done
delete(ao)
clear ao
注意点として、コールバックはバッファーが空になる少し前に開始されることです。これはANALOGINPUT関数によるオブジェクトを使用するうえで重要なことですが、動作中にバッファーを空にするとその時点で停止します。また、各データ間に途切れ目を作らないことです。
以下の例は、上記を実現するための"qmoredataForTimerFcn"コールバックの例です。
function qmoredataForTimerFcn(obj,event,data)
% We would like to make sure we are not going to over run the buffer
% If we do, the PUDATA function become a blocking function
% That is, we will no longer have access to the command line
% Use any ONE of the next two IF statements.
% This one guarantees that we will never get more than twice the amount
% of data we have to queue.
% if (obj.SamplesAvailable + length(data)) >= length(data)*2
% This one will continue to add to the queue until adding more would
% cause PUTDATA to block.
if (obj.SamplesAvailable + length(data)) >= obj.MaxSamplesQueued
return
end
% Else, It is safe to put the data.
putdata(obj,data);
% Restart the object only if it is not already running.
if strcmp(obj.Running, 'Off')
start(obj)
end
end
この例では、Data Acquisition エンジン内にどれだけのデータが残っているかと、どれだけのデータが要求されているかを確認することができます。
要求よりも残りの合計が大きい場合、追加データは不要という応答を返します。
追加データが不要であるという判断をするための目安は以下の通りです。
1. データの2倍であること
2. MaxSmplesQueued
 

More Answers (0)

Categories

Find more on 関数 in Help Center and File Exchange

Tags

No tags entered yet.

Community Treasure Hunt

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

Start Hunting!