Using MATLAB with the ADU70 USB Load Cell Interface (Windows)

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)

 ADU70 MATLAB Example V2

% 1. set up variables and pointers to be used by function calls
ptrResult=libpointer('int8Ptr',zeros(1,8));
ProductID = 70;
vp = libpointer('voidPtr',zeros(1,1));

% 2. Load libraries
if not(libisloaded('AduHid64'))
    loadlibrary('AduHid64','AduHidMatlab.h'); %Will need MinGW-w64 add-on
end

% 3. Obtain Handle to ADU Device
device_handle = calllib('AduHid64','OpenAduDevice',1000); %if only one ADU is connected
%device_handle = calllib('AduHid64','OpenAduDeviceBySerialNumber','T00626',1000); %to connect by Serial Number
%device_handle = calllib('AduHid64','OpenAduDeviceByProductId',ProductID,1000);%to connect by Product ID

% 4. Write "WC6111" to configure the ADU70 ( Gain=128,1.56Hz sample rate, BUFFER and CHOP enabled)
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); % wait for calibration to complete

% 5. Read ADU70 and print reading in command window 60 times
for n= 1:60
% Write "RD" to ADU70 to request present reading
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
% Read data from ADU70
result = calllib('AduHid64','ReadAduDevice',device_handle,ptrResult,8,vp,500);
    if result == 0
    fprintf('\nError During ADU70 Read\n');
    end
% Convert returned string to number
x=char(ptrResult.value);
reading=str2num(x);
% Print the Reading to the Command Window
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(s)
clear vp ptrResult reading;
calllib('AduHid64','CloseAduDevice',device_handle);
unloadlibrary('AduHid64');

% Revison History
% V2 -March 29, 2021
% V2 -added second NULL to end of WriteAduDevice command strings
% V2 -set bytes sent to 8 for all WriteAduDevice calls.

 

 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.

 
% 1. set up variables and pointers to be used by 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.

% 2. Load libraries
if not(libisloaded('AduHid64'))
    loadlibrary('AduHid64','AduHidMatlab.h'); %Will need MinGW-w64 add-on
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.


% 3. Obtain Handle to ADU Device
device_handle = calllib('AduHid64','OpenAduDevice',1000); %if only one ADU is connected
%device_handle = calllib('AduHid64','OpenAduDeviceBySerialNumber','T00626',1000); %to connect by Serial Number
%device_handle = calllib('AduHid64','OpenAduDeviceByProductId',ProductID,1000);%to connect by Product ID

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.

% 4. Write "WC6111" to configure the ADU70 ( Gain=128,1.56Hz sample rate, BUFFER and CHOP enabled)
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); % wait for calibration to complete

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.


% 5. Read ADU70 and print reading in command window 60 times
for n= 1:60
% Write "RD" to ADU70 to request present reading
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
% Read data from ADU70
result = calllib('AduHid64','ReadAduDevice',device_handle,ptrResult,8,vp,500);
    if result == 0
    fprintf('\nError During ADU70 Read\n');
    end
% Convert returned string to number
x=char(ptrResult.value);
reading=str2num(x);
% Print the Reading to the Command Window
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.

% 6. Before terminating program, clear variables, release ADU70 handle
% and unload the library(s)
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