Driving a SRS Model SR830 Lock-in Amplifier from Matlab.

Introduction

We had a requirement to capture very small signals from the auditory system of fish. The fish were to stimulated with sine waves of varying frequency, while recording the second harmonic signal from the auditory system. A SR830 Lock-in Amplifier can be controlled via a serial line. Under computer control, it can vary its output frequency over the audio range and its output amplitude over a factor of 1000. The input magnitude and phase can be directly read back to the computer.

Three programs were produced to:

Two of the programs are shown below.

The programs

The following matlab produces a calibration curve.

%=====Control a SRS Model SR830 Lockin Amp==================
%Produces a series of tones and makes a spreadsheet of the 
%resulting amp.
%This program is intended to produce a relative amplitude 
%file to be used with GetDataLockIn.m
%===========================================================
%Written by Bruce Land, BRL4@cornell.edu
%  12 May 2003
%Written for Joe Sisneros

%=====clean up any leftover serial connections==============
clear all
try
    fclose(instrfind) %close any bogus serial connections
end

%=====Data output file name=================================
[filename,pathname] = uiputfile( 'c:\my documents\*.wk1','Calibrate SpreadSheet Name');
if isnumeric(filename) %check to see if Cancel buttion was hit
    return             %if so, stop program
end

%=====open a serial connection===============================
%set its rate to 9600 baud
%SR830 terminator character is  (ACSII 13)
%use fprintf(s,['m' mode]) to write
%and fscanf(s) to read the SR830
s = serial('COM1',...
    'baudrate',9600,...
    'terminator',13); 
fopen(s)

%=====define stimulus parameters=============================
PlayFreq = [60:10:100, 120:20:400]; %60 to 100 step 10 and 120 to 400, step 20 Hz.
PlayAmp = 0.1 * ones(size(PlayFreq)); %uncorrected initial amplitude for each frequency
PlayTime = 1.0 * ones(size(PlayFreq)); %Actual play time for each frequency
WaitTime = 1.0 ; %Silcence time between tones

%=====Set up the SR830=======================================
%turn on synchronous filter below 200  Hz
fprintf(s,'sync 1')
%time const to 100 mS
fprintf(s,'oflt 8')
%filter slope to 12 db
fprintf(s,'ofsl 1')

%=====Now generate the tones and pauses======================
%and collect amp and phase
for i=1:length(PlayFreq)   
    fprintf(s,['freq ',num2str(PlayFreq(i))])
    fprintf(s,['slvl ',num2str(PlayAmp(i))])
    pause(PlayTime(i))
    fprintf(s,'outp?3')
    OutAmp(i) = fscanf(s,'%f');
    fprintf(s,'outp?4')
    OutPhase(i) = fscanf(s,'%f');
    fprintf(s,'freq .001')
    fprintf(s,'slvl .004')
    pause(WaitTime)
end

%=====write an excel file===================================
%Note that a Lotus file is actully written because
%Matlab cannot currently write an Excel file.
%Excel will read this format
%This version appends a date/time string to each file name
wk1write([pathname,filename,datestr(datevec(now),30)], [PlayFreq',PlayAmp',OutAmp',OutPhase'])

%=====close the serial port=================================
fclose(s)
The next program plays serveral repetitions of random ordered tones in the frequency range to 60 to 400 Hz. The tones are amplitude-corrected by the results of the previous program.
%=====Control a SRS Model SR830 Lockin Amp==================
%Produces a series of tones and makes a spreadsheet of the 
%resulting amp,phase.
%===========================================================
%Written by Bruce Land, BRL4@cornell.edu
%  12 May 2003
%Written for Joe Sisneros

%=====clean up any leftover serial connections==============
clear all
try   %Try is necessary because fclose will throw an error sometimes at startup
    fclose(instrfind) %close any bogus serial connections
end

%=====Data output file name================================
[filename,pathname] = uiputfile( 'c:\my documents\*.wk1','Data Output SpreadSheet Name');
if isnumeric(filename) %check to see if Cancel buttion was hit
    return             %if so, stop program
end

%=====Amplitude Correction file name=======================
[cfilename,cpathname] = uigetfile('c:\my documents\*.wk1','Calibration SpreadSheet Name') ;
if isnumeric(cfilename)
    return
end
CorrectionData = wk1read([cpathname,cfilename]) ;
%separate out the amplitudes
CorrectionAmp = CorrectionData(:,3)' ;

%=====open a serial connection===============================
%set its rate to 9600 baud
%SR830 terminator character is  (ACSII 13)
%use fprintf(s,['m' mode]) to write
%and fscanf(s) to read the SR830
s = serial('COM1',...
    'baudrate',9600,...
    'terminator',13); 
fopen(s)

%=====define stimulus parameters=============================
PlayFreq = [60:10:100, 120:20:400]; %60 to 100 step 10 and 120 to 400, step 20 Hz.
PlayAmp = 0.1 * ones(size(PlayFreq)); %uncorrected initial amplitude for each frequency
PlayAmp = 0.1 * PlayAmp ./ CorrectionAmp ; %Corrected amplitude
PlayTime = 0.5*ones(size(PlayFreq)); %Actual play time for each frequency
WaitTime = 1.0 ; %Silcence time between tones
NumberReps = 2 ; %tone repeats

%Play the list of frequencies in random order
list = randperm(length(PlayFreq));

%=====Set up the SR830=======================================
%turn on synchronous filter below 200  Hz
fprintf(s,'sync 1')
%time const to 100 mS
fprintf(s,'oflt 8')
%filter slope to 12 db
fprintf(s,'ofsl 1')
pause(WaitTime)

%=====Now generate the tones and pauses======================
%and collect amp and phase
for i=list
    for j=1:NumberReps
        fprintf(s,['freq ',num2str(PlayFreq(i))])
        fprintf(s,['slvl ',num2str(PlayAmp(i))])
        pause(PlayTime(i))
        fprintf(s,'outp?3')
        OutAmp(i,j) = fscanf(s,'%f') ;
        fprintf(s,'outp?4')
        OutPhase(i,j) = fscanf(s,'%f');
        fprintf(s,'freq .001')
        fprintf(s,'slvl .004')
        pause(WaitTime)
    end
end

%set amp to minimum
%fprintf(s,'slvl 0.004')

%=====write an excel file===================================
%Note that a Lotus file is actully written because
%Matlab cannot currently write an Excel file.
%Excel will read this format
%This version appends a date/time string to each file name
wk1write([pathname,filename,datestr(datevec(now),30)], [PlayFreq',PlayAmp',OutAmp,OutPhase])

%=====close the serial port=================================
fclose(s)