%
% File:   getscopedat.m
% Date:   02-Feb-02
% Author: I. Chuang <ike@media.mit.edu>
%
% function to get trace via serial connection to Agilent 54621A digital scope
% 
% Usage:   [vdat,tdat] = getscopedat(tracenum)
%
% Where: 
%
% tracenum	= channel number of the data you want (ie 1 or 2)
% vdat		= voltage data (y-axis), in units of volts
% tdat		= time data (x-axis), in units of seconds
%
% Example: [y,x] = getscopedat(1)
%          plot(x,y);
%          grid on;
%
% The scope should be connected to /dev/ttyS0 and have the serial
% parameters already set properly.  Use stty for this, or kermit, or
% minicom.  A good choice of parameters is to use RTS/CTS (DTR on the
% scope) for handshaking, and 57600 baud.  Note that the serial cable
% between the computer and scope should be a null modem cable, since
% both the PC and scope are DTE.
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% Main routine

function [vdat,tdat] = getscopedat(tracenum)
  [nx xincr xorig yref yincr yorig] = getscale;
  data = getrawdat(tracenum);
  tdat = (0:(nx-1))*xincr + xorig;
  vdat = (data-yref)*yincr + yorig;
% plot(tdat,vdat);

return

% Subroutine to read raw data from scope

function data = getrawdat(chan)
  sendscope(['WAV:SOURCE CHAN' num2str(chan)]); % set trace channel to get
  sendscope('WAV:POINTS ALL');	% get all waveform points in deep buf
  fp = fopen('/dev/ttyS0','r+');	% open scope
  fwrite(fp,['WAV:DATA?' 10],'char');	% get raw data
  s1 = char(fread(fp,1,'char'));	% skip initial '#' char
  s2 = char(fread(fp,1,'char'));	% next is number of bytes in length
  numy = str2num(s2);
  s3 = char(fread(fp,numy,'char'))'; 	% next is length (number of bytes of data)
  numdat = str2num(s3);
  data = fread(fp,numdat,'uchar');	% finally, the data!
  fclose(fp);			% close serial connection to scope
return

% Subroutine to read waveform preamble (to get scale) from scope

function [nx,xincr,xorig,yref,yincr,yorig] = getscale()
  s = queryscope('WAV:PRE?');	% waveform preamble
  % result is:
  % format, type, points, count, xincr, xorig, xref, yincr, yorig, yref
  param = sscanf(s,'%f,');	% parse it 
  yparam = param(end-2:end);
  xparam = param(end-5:end-3);
  xincr = xparam(1);
  xorig = xparam(2);
  xref = xparam(3);
  yincr = yparam(1);
  yorig = yparam(2);
  yref = yparam(3);
  nx = param(3);
return

% Subroutine to query scope

function resp = queryscope(query)
  fp = fopen('/dev/ttyS0','r+');
  fwrite(fp,[query 10],'char');
  resp = fgetline(fp);
  fclose(fp);
return

% Subroutine to send command to scope

function sendscope(query)
  fp = fopen('/dev/ttyS0','r+');
  fwrite(fp,[query 10],'char');
  fclose(fp);
return

% Subroutine to get a line from a file - up to a LF

function s = fgetline(fp)
  s = [];
  c = 0;
  while(c ~= 10)
    c = fread(fp,1,'char');
    s = [s char(c)];
  end
return
