%% Eagle PCI30 Analogue Input Example
% This example shows how MATLAB's Generic DLL Interface
% Functions allow you to interact with an *Eagle PC30*
% device and acquire analogue data. Only a single buffer
% of data is acquired in this example. It is benneficial
% to be familiar with MATLAB's Generic DLL Interface
% Functions and the PC30's DLL methods for this example.
%
% This code 'runs' but due to the lack of a terminal board
% we dont know if it actually 'works'! Any feedback/
% enhancements to the code presented here would be welcomed.
%% Getting More Information
% More information about interfacing with .DLLs from MATLAB can be found
% in MATLAB 7.0's HTML documentation contents at:
%
% MATLAB/External Interfaces Reference/Generic DLL Interface
% Functions
%
% Pointers are required when setting up the various device properties. The
% LIBPOINTER function is used to create these pointers in MATLAB, for more
% information type:
%
% doc libpointer
%
% at the MATLAB command line. See the PCI30 device driver
% manual for more information on the devices .dll calls. This should be
% downloadable from Eagle's website: http://www.eagle.co.za.
%% Loading the Dynamic Link Library into MATLAB
% In order to call methods belonging to the device driver we need to load
% the .DLL into MATLAB. We use the LOADLIBRARY function to load the
% functions defined in header file 'EDRAPI.H' and found in shared library
% 'edrapi.dll' into MATLAB. The LIBFUNCTIONS function is useful for seeing
% the names of the library functions available.
% Load the driver .dll
loadlibrary ('c:\WINDOWS\system32\edrapi.dll', ...
'C:\Prog\Eagle\include\EDRAPI.H');
% Find the methods offered by the .dll
m = libfunctions('edrapi', '-full')
%% Creating a Buffer Variable to Store Acquired Data
% When the device starts acquiring data we need to have somewhere in memory
% to store this data. The .DLL's methods require a pointer to this memory
% location, which is created in this section.
% Get the maximum number of samples we can store
% swBufferSize = calllib('edrapi','EDRE_Query', ...
% deviceSerialNumber, 106, 0);
% 1048576 apparently
swBufferSize = 1000000; % 1048576 gave issues so hardcoded
% for the time being
% NOTE: The variable 'inputDataBuffer' just contains the
% values with which the memory pointed to by 'buffPointer'
% is initialised. The variable 'inputDataBuffer' is not
% actually the buffer into which the data is put (the data
% is actually put into the memory pointed to by 'buffPointer').
inputDataBuffer = int32(zeros(swBufferSize,1));
% Create a pointer to our buffer and the size of the buffer
buffPointer = libpointer('int32Ptr',inputDataBuffer);
buffSizePointer = libpointer('uint32Ptr',swBufferSize);
%% Defining Device Properties
% We need to define the following properties of the device:
%
% * Sample rate
% * Clock source
% * Mode of operation
% * Input voltage range
% * List of the devices analog input channels we are going to use
%
% It is necessary to have the device manual in order to know what valid
% property values are.
% The Eagle EDRE_DAConfig method requires the device serial
% number to be specified
deviceSerialNumber = 1000000379;
% Specify the frequency at which the data must be
% sampled (Hertz)
samplingFrequency = 100000;
% Specify the clocksource:
% 0: Internal and to External Gate
% 1: Internal
% 2: External Clock
% 3: External Clock and Gate
clockSource = 1;
% Use burst mode?
% 0: Normal Mode
% 1: Burst Mode
burstMode = 0;
% Input range
% 0: -5V to +5V, Single Ended
% 1: 0 to +10V, Single Ended
% 2: -10V to +10V, Single Ended
% 3: -5V to +5V, Differential
% 4: 0 to +10V, Differential
% 5: -10V to +10V, Differential
inputRange = 0;
% Channel list. Must be a pointer to unsigned long.
chanList = 1; % Can be array of channels
chanListPointer = libpointer('uint32Ptr',chanList);
% Gain List. Must be a pointer to unsigned long.
gainList = 1;
gainListPointer = libpointer('uint32Ptr',gainList);
% Channel/gain list size
listSize = length(chanList);
%% Configuring, Starting and Stopping the Device
% After configuring the device with the properties defined above we can
% start the acquisition. Currently the the device is stopped after the
% buffer is filled, but there may be a more elegent way of stopping the
% device after a certain amount of samples have been acquired (for example
% a timer object could be used to query the device after a certain interval
% of time).
% Configure the device for analogue input operation using
% the parameters defined above
%
% From the PCI30 manual:
%
% EDRE_ADConfig (ulng Sn, pulng Freq, ulng ClkSrc, ulng
% Burst, ulng Range, pulng ChanList, pulng GainList,
% ulng ListSize)
disp('Configuring for AI...');
calllib('edrapi','EDRE_ADConfig', deviceSerialNumber, ...
samplingFrequency, clockSource, burstMode, inputRange, ...
chanListPointer, gainListPointer, listSize)
% The EDRE_Query method can be used to ask the device about
% itself. Here are some examples of queries (QueryCodes can be
% found in the manual):
%
% Syntax:
% EDRE_Query (ulng Sn, ulng QueryCode, ulng Param)
%
% disp('Query FIFO size:')
% calllib('edrapi','EDRE_Query', deviceSerialNumber, 104, 0)
%
% disp('Query FIFO buffer allocation:')
% calllib('edrapi','EDRE_Query', deviceSerialNumber, 108, 0)
%
% disp('Get ADC range:')
% calllib('edrapi','EDRE_Query', deviceSerialNumber, 113, 0)
%
% disp('Check if ADC system is busy:');
% calllib('edrapi','EDRE_Query', deviceSerialNumber, 103, 0)
%
% disp('Get number of samples available:');
% calllib('edrapi','EDRE_Query', deviceSerialNumber, 109, 0)
% Start the analogue input operation
disp('Starting AI...');
calllib('edrapi','EDRE_ADStart', deviceSerialNumber) % Start
pause(25); % Would be better to query the driver and stop
% after enough samples are acquired
% Stop the analogue input operation
disp('Stopping AI...');
calllib('edrapi','EDRE_ADStop', deviceSerialNumber) % Stop
% EDRE_Query (ulng Sn, ulng QueryCode, ulng Param)
disp('Get number of samples available:');
samplesAvailable = calllib('edrapi','EDRE_Query',...
deviceSerialNumber, 109, 0)
%% Getting the acquired Data
% In this section we retrieve the data stored acquired during the analog
% input session and unload the .dll.
% Getting data from the driver buffer
% From PCI30 manual:
% Long EDRE_ADGetData (ulng Sn, plong Buf, pulng BufSize)
disp('Getting data from device buffer...');
calllib('edrapi','EDRE_ADGetData', deviceSerialNumber,...
buffPointer, buffSizePointer);
% Unload the driver library. Horrible things can happen
% if you dont unload
% the library in a timely fashion...
disp('Unloading library...');
unloadlibrary('edrapi')
aiData = get(buffPointer,'Value');
plot(double(aiData)/1e6) % Converting to Volts