連続でアナログ信号を出力するにはどうすればよいですか?
12 views (last 30 days)
Show older comments
MathWorks Support Team
on 30 Dec 2013
Answered: 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
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
0 Comments
More Answers (0)
See Also
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!