Code covered by the BSD License  

Highlights from
Sonar Demo

image thumbnail

Sonar Demo

by

 

22 May 2002 (Updated )

Sonic distance measurement using Windows sound card for data acquisition.

tof(varargin)
function varargout = tof(varargin)
% TOF demonstrates sound ranging (sonar) between PC
%   speaker and microphone (up to 6m away).
%
% This demo requires:
%   - Data Acquisition Toolbox,
%   - Signal Processing Toolbox
%   - Windows sound card
%   - files: sonar_anal.m tof.fig tof.m (this file)
%
% How does it work?
%   A pulse wave (chirp) is generated from the speaker,
%   which travels through air at the speed of sound.  
%   At the same time the microphone records the received
%   wave (plus possible reflections depending on room
%   acoustics).  The propagation time delay (sec) is 
%   measured and converted to distance (m).

% Copyright 2001-2010 The MathWorks, Inc.

% TOF Application M-file for tof.fig
%    FIG = TOF launch tof GUI.
%    TOF('callback_name', ...) invoke the named callback.

% Last Modified by GUIDE v2.0 18-Oct-2001 17:27:18

% Updated by R.Bemis July 5, 2007
%   * Removed hard coded calibrations - less accurate, more robust

if nargin == 0  % LAUNCH GUI

	fig = openfig(mfilename,'reuse');

	% Use system color scheme for figure:
	set(fig,'Color',get(0,'defaultUicontrolBackgroundColor'));

	% Generate a structure of handles to pass to callbacks, and store it. 
	handles = guihandles(fig);
	guidata(fig, handles);

    %sonar_setup(handles,0.0087)  % set up audio I/O
    sonar_setup(handles,0)      % set up audio I/O
    
	if nargout > 0
		varargout{1} = fig;
	end

elseif ischar(varargin{1}) % INVOKE NAMED SUBFUNCTION OR CALLBACK

	try
		if (nargout)
			[varargout{1:nargout}] = feval(varargin{:}); % FEVAL switchyard
		else
			feval(varargin{:}); % FEVAL switchyard
		end
	catch
		disp(lasterr);
	end

end


%| ABOUT CALLBACKS:
%| GUIDE automatically appends subfunction prototypes to this file, and 
%| sets objects' callback properties to call them through the FEVAL 
%| switchyard above. This comment describes that mechanism.
%|
%| Each callback subfunction declaration has the following form:
%| <SUBFUNCTION_NAME>(H, EVENTDATA, HANDLES, VARARGIN)
%|
%| The subfunction name is composed using the object's Tag and the 
%| callback type separated by '_', e.g. 'slider2_Callback',
%| 'figure1_CloseRequestFcn', 'axis1_ButtondownFcn'.
%|
%| H is the callback object's handle (obtained using GCBO).
%|
%| EVENTDATA is empty, but reserved for future use.
%|
%| HANDLES is a structure containing handles of components in GUI using
%| tags as fieldnames, e.g. handles.figure1, handles.slider2. This
%| structure is created at GUI startup using GUIHANDLES and stored in
%| the figure's application data using GUIDATA. A copy of the structure
%| is passed to each callback.  You can store additional information in
%| this structure at GUI startup, and you can change the structure
%| during callbacks.  Call guidata(h, handles) after changing your
%| copy to replace the stored original so that subsequent callbacks see
%| the updates. Type "help guihandles" and "help guidata" for more
%| information.
%|
%| VARARGIN contains any extra arguments you have passed to the
%| callback. Specify the extra arguments by editing the callback
%| property in the inspector. By default, GUIDE sets the property to:
%| <MFILENAME>('<SUBFUNCTION_NAME>', gcbo, [], guidata(gcbo))
%| Add any extra arguments after the last argument, before the final
%| closing parenthesis.



% --------------------------------------------------------------------
function varargout = Single_Callback(h, eventdata, handles, varargin)

set(handles.Repeat,'enable','off')      % disable Repeat button
sonar_once(handles.figure1)             % take one measurement



% --------------------------------------------------------------------
function varargout = Repeat_Callback(h, eventdata, handles, varargin)

set(h,'enable','off')                   % disable Repeat button
set(handles.Single,'enable','off')      % disbale Single button
set(handles.Stop,'enable','on')         % enable Stop button
sonar_run(handles.figure1)              % measure repeatedly



% --------------------------------------------------------------------
function varargout = Stop_Callback(h, eventdata, handles, varargin)

set(h,'enable','off')                   % disable Stop button
set(handles.Repeat,'enable','on')       % enable Repeat button
set(handles.Single,'enable','on')       % enable Single button
sonar_stop(handles.figure1)             % stop repeats



% --------------------------------------------------------------------
function sonar_setup(handles,cal_dist)

fig = handles.figure1;  % figure handle

if nargin<2
  cal_dist = 0; 
end

% physics
c = 330;            % speed of sound (m/sec)
d = 50;             % max distance (m)
Td = d/c;           % max return time (sec)
pw = 0.01;          % pulse width (sec)
Tmax = Td+pw;       % total response time (sec)

% DAQ parameters
ai = analoginput('winsound');               % create AI object
addchannel(ai,1);                           % single channel (mono)
Fs = setverify(ai,'samplerate',44100);      % sample rate (Hz)
N = 2^ceil(log2(Tmax*Fs));                  % buffer size (samples)
ao = analogoutput('winsound');              % create AO object
addchannel(ao,1);                           % single channel (mono)
ao.SampleRate=Fs;                           % output Fs same as input

% excitation chirp
f0 = 4e3;                       % low freq (Hz)
f1 = 8e3;                       % high freq (Hz) 
t = (0:(1/Fs):pw)';             % time index (sec)
n = length(t);                  % pulse length (samples)
pulse = chirp(t,f0,pw,f1);      % chrip waveform (short)
pulse = pulse.*hanning(n);      % pulse envelope
pad = zeros(N-n,1);             % silence trailing chirp
x = [pulse; pad];               % excitation (zero padded)

% response waveform
ai.SamplesPerTrigger = N;           % total samples to acquire
ai.TriggerDelayUnits = 'sec';
ai.TriggerDelay = cal_dist/c;       % calibration lag (sec)
ai.SamplesAcquiredFcnCount = N;
ai.SamplesAcquiredFcn = ['sonar_anal(' num2str(fig) ')'];

% user data
ud.ai = ai;                 % audio input
ud.ao = ao;                 % audio output
ud.c = c;                   % wave speed in air
ud.x = x;                   % excitation waveform
ud.h = handles;             % guide figure handles
set(fig,'userdata',ud)      % store bundle with figure



% --------------------------------------------------------------------
function sonar_once(fig)

% user data
ud = get(fig,'userdata');       % user data fields
ai = ud.ai;                     % audio input
ao = ud.ao;                     % audio output
x = ud.x;                       % excitation chirp pulse
ai.samplesacquiredfcn = '';     % don't repeat measurement
putdata(ao,x)                   % arm audio output
start([ai ao])                  % start measurement
sonar_anal(fig)                 % manually analyze data



% --------------------------------------------------------------------
function sonar_run(fig)

% user data
ud = get(fig,'userdata');   % user data fields
ai = ud.ai;                 % audio input
ao = ud.ao;                 % audio output
x = ud.x;                   % excitation chirp pulse

% callback function to analyze when done acquiring data
ai.samplesacquiredfcn = ['sonar_anal(' num2str(fig) ')'];
% NOTE: sonar_anal will rearm output and repeat measurement

putdata(ao,x)       % arm audio output
start([ai ao])      % start measuring (will repeat)



% --------------------------------------------------------------------
function sonar_stop(fig)

% user data
ud = get(fig,'userdata');       % user data fields
ai = ud.ai;                     % audio input
ai.samplesacquiredfcn = '';     % stop repeating



% --------------------------------------------------------------------
function sonar_cleanup(fig)

% user data
ud = get(fig,'userdata');     % user data fields
ai = ud.ai; delete(ai)        % remove audio input
ao = ud.ao; delete(ao)        % remove audio output



% --------------------------------------------------------------------
function varargout = figure1_CloseRequestFcn(h, eventdata, handles, varargin)

sonar_stop(handles.figure1)         % stops if still repeating
sonar_cleanup(handles.figure1)      % remove audio objects
delete(handles.figure1)             % remove figure window

Contact us