A:
Introduction
Communicating with USB devices in MATLAB, or
virtually any application software, involves a few
simple steps. Unlike RS232 based devices which are
connected to physical COM ports, USB devices are
assigned a logical handle
by operating systems when they are first plugged in.
This process is known as enumeration.
Once a USB device has been
enumerated, it is ready for use by the host computer
software. For the host application software to
communicate with the USB device, it must first obtain
the handle assigned to the USB device during the
enumeration process. The handle can be obtained using an
open function along with
some specific information about the USB device.
Information that can be used to obtain a handle to a USB
device include, serial number,
product ID, or vendor
ID. Once the handle is obtained, it is used to allow the
application to read and write information, to and from,
the USB device. Once the application has finished
with all communication with the USB device, the handle
is closed. The handle is generally closed when the
application terminates.
The AduHid DLL provides all the
functions to open a handle, read and write data, and
close the handle of ADU USB devices. The ADUHID dll can
be used directly from a MATLAB application.
For this tutorial we will use MATLAB to communicate
with an ADU70 USB Load Cell
Interface. The application will open the
ADU70, initiate a calibration, retrive 60 samples, and
then close the ADU70. Although we are using an
ADU70 in this tutorial, the code can be modified to suit
any of the ADU Data Acquisition
and Control Products.
Figure
1: ADU70 USB Load Cell Interface
Before we dissect the code, the
full MATLAB .m file is listed here, followed by the
Command Window Output. (Download entire project at bottom of page)
ptrResult=libpointer('int8Ptr',zeros(1,8));
ProductID = 70;
vp = libpointer('voidPtr',zeros(1,1));
if not(libisloaded('AduHid64'))
loadlibrary('AduHid64','AduHidMatlab.h');
end
device_handle = calllib('AduHid64','OpenAduDevice',1000);
result = calllib('AduHid64','WriteAduDevice',device_handle,libpointer('voidPtr',[int8('WC6111') 0 0]),8,vp,500);
if result == 0
fprintf('\nError During ADU70 Configuration word Write\n');
end
fprintf('\nCalibrating.........\n');
pause(5);
for n= 1:60
result = calllib('AduHid64','WriteAduDevice',device_handle,libpointer('voidPtr',[int8('RD') 0 0]),8,vp,500);
if result == 0
fprintf('\nError During ADU70 RD Write\n');
end
result = calllib('AduHid64','ReadAduDevice',device_handle,ptrResult,8,vp,500);
if result == 0
fprintf('\nError During ADU70 Read\n');
end
x=char(ptrResult.value);
reading=str2num(x);
formatSpec = 'Reading number %i is %i \n';
fprintf(formatSpec,n,reading)
pause(1)
end
clear vp ptrResult reading;
calllib('AduHid64','CloseAduDevice',device_handle);
unloadlibrary('AduHid64');
When run, the code displays the
60 samples in the Command Window.
Figure
2: Command Window Output
B:
Lets have a look at the code......
1. Set up variables and pointers to be used by
function calls.
The ADU products use NULL terminated ASCII strings to
communicate, with the longest string being 8 bytes.
Here we initiate a pointer to create a 8 byte array
to store the received data. We then set the
variable ProductID to 70 and then the vp
pointer is initalized as a single byte. This variable is
used to store bytes received and bytes sent
by the function calls.
ptrResult=libpointer('int8Ptr',zeros(1,8));
ProductID = 70;
vp = libpointer('voidPtr',zeros(1,1));
2. Load Libraries.
To allow function calls to the ADU70 within MATLAB we
must load the libraries including the AduHid64.dll and
AduHidMatlab.h files. It is important to use the
AduHidMatlab.h header file and NOT the AduHid.h file
normally included with our dll. This is because
MATLAB does not recognize the BOOL format used in the
original Windows header. The AduHidMatlab.h file was
created only for use in MATLAB.
if not(libisloaded('AduHid64'))
loadlibrary('AduHid64','AduHidMatlab.h');
end
3. Obtain handle to ADU Device.
To communicate with the ADU70 we must first open a
handle to it. This can be done in one three types
of calls. For this example we open a handle to the first ADU
device detected. This should only be used if there
is only one ADU connected to the host computer. If more
than one ADU is connected you can either open the handle
by SerialNumber or ProductID.
device_handle = calllib('AduHid64','OpenAduDevice',1000);
4. Write "WC6111" to configure the ADU70.
The ADU70 can be configured to operate at various speeds
and gains. This is done through the WCxxxx
command. (Details Here:
ADU70 QuickStart
Guide) The WCxxxx command also initiates a
calibration when sent, that takes up to six times the
sample time to complete. Because of this, we pauses the program for
5 seconds to allow the calibration process to complete.
Note that this step is not required on most ADU devices.
result = calllib('AduHid64','WriteAduDevice',device_handle,libpointer('voidPtr',[int8('WC6111') 0 0]),8,vp,500);
if result == 0
fprintf('\nError During ADU70 Configuration word Write\n');
end
fprintf('\nCalibrating.........\n');
pause(5);
5. Read ADU70 and print reading in Command
Window 60 times.
To read data from any ADU device a read command must be
sent. (RD for the ADU70) This is done using a
WriteAduDevice function call. Note the RD
command is sent with [int8('RD')
0 0] which produces the ASCII string "RD" followed
by two NULLs ( recommended). To retrieve
the data, a ReadAduDevice function call is
implemented. For details on all ADU function
calls see: ADUHid
Functions.
The returned data is in the format of 8 ASCII characters
ranging from 00000000 to 16777215 and it should be
converted to an actual number to allow use of the data
in calculations, plotting, etc. This is accomplished
with the x=char(ptrResult.value); and
reading=str2num(x); statements. For details on calculating actual
weight see: ADU70
QuickStart Guide.
for n= 1:60
result = calllib('AduHid64','WriteAduDevice',device_handle,libpointer('voidPtr',[int8('RD') 0 0]),8,vp,500);
if result == 0
fprintf('\nError During ADU70 RD Write\n');
end
result = calllib('AduHid64','ReadAduDevice',device_handle,ptrResult,8,vp,500);
if result == 0
fprintf('\nError During ADU70 Read\n');
end
x=char(ptrResult.value);
reading=str2num(x);
formatSpec = 'Reading number %i is %i \n';
fprintf(formatSpec,n,reading)
pause(1)
end
6. Before terminating program, clear variables,
release ADU70 Handle and unload the library.
Before exiting the program the variables are cleared,
the ADU70 handle is released, and the libraries are
unloaded.
It is important that the handle for an ADU device is
opened when the application opens, and closed only when
the application terminates. DO NOT open and
close the handle for each read or write as Windows may put the ADU70 into suspend mode causing a loss of
configuration data.
clear vp ptrResult reading;
calllib('AduHid64','CloseAduDevice',device_handle);
unloadlibrary('AduHid64');
Download the tutorial and associated libraries here:
MATLAB ADU70
Tutorial ( Windows 64-Bit) ZIP
Authored by Tom Fortin, March
2021
|