This demo explores callback functions and callback properties using a serial port object.
The information obtained for this demonstration was pre recorded. Therefore, you do not need an actual instrument to learn about callbacks and events. The instrument connected to the serial port object was a Tektronix TDS 210 oscilloscope.
When an event occurs, you can execute a related function known as a callback function. An event occurs after a condition is met. The event types supported by all instrument objects include
Type Description ---- -----------
Bytes Available A predefined amount of data has been
read from the instrument and stored
in the input buffer.
Error An error occurred during an asynchronous
operation.
Output Empty The completion of an asynchronous write
operation.
Timer A predefined period of time passes.Callback functions are M-file functions that can perform essentially any task during your instrument control session, such as processing data, displaying data, or displaying a message. Callbacks are initiated by specifying a callback function as the value for a callback property. All event types have an associated callback property. A callback function is associated with an event by setting one of the callback properties to the name of the callback function.
Callbacks Common to All Objects:
BytesAvailableFcn - Executed when a specified amount of bytes are available. ErrorFcn - Executed when an error occurs during an asynchronous operation. OutputEmptyFcn - Executed when an asynchronous write operation has completed. TimerFcn - Executed when a predefined period of time passes.
Additional Serial Port Callbacks:
BreakInterruptFcn - Executed when a break-interrupt occurs.
PinStatusFcn - Executed when the CarrierDetect, ClearToSend,
DataSetReady, or RingIndicator pins change value.Additional VXI Callbacks:
InterruptFcn - Executed when a VXI bus signal or interrupt is received. TriggerFcn - Executed when a trigger occurs.
Additional UDP Callbacks:
DatagramReceivedFcn - Callback function executed when a datagram is received.
A callback function can be defined as a string, function handle, or cell array.
The following table illustrates the different types of callback functions and how they are evaluated:
Callback Definition Callback Evaluation
------------------- -------------------
'mycallback' eval('mycallback')
@mycallback feval(@mycallback, obj, event)
{'mycallback', arg1} feval('mycallback', obj, event arg1)
{@mycallback, arg1} feval(@mycallback, obj, event, arg1)If the callback function is defined as a string, the string is evaluated in the MATLAB workspace when the event occurs. The string can be any combination of MATLAB functions. For example, 'fclose(obj);delete(obj);'.
If the callback function is defined as a function handle, the object that caused the event and an event structure is automatically passed to the function represented by the function handle.
If the callback function is defined as a cell array, the first element of the cell array must be either a string or a function handle. The object that caused the event and an event structure are passed to the function defined by the first element of the cell array along with the remaining elements of the cell array.
To begin, create a serial port object associated with the COM1 port. A TDS 210 Tektronix oscilloscope is connected to the COM1 port.
>> s = serial('COM1');The oscilloscope is configured for no flow control, no parity checking, a baud rate of 9600, and a carriage return terminator.
>> set(s, 'FlowControl', 'none'); >> set(s, 'Terminator', 'CR', 'Parity', 'none') >> s
Serial Port Object : Serial-COM1
Communication Settings
Port: COM1
BaudRate: 9600
Terminator: 'CR' Communication State
Status: closed
RecordStatus: off Read/Write State
TransferStatus: idle
BytesAvailable: 0
ValuesReceived: 0
ValuesSent: 0Before you can read or write data, you must connect the serial port object to the instrument with the FOPEN function. If the serial port object was successfully connected, its Status property is automatically configured to open.
>> fopen(s) >> s
Serial Port Object : Serial-COM1
Communication Settings
Port: COM1
BaudRate: 9600
Terminator: 'CR' Communication State
Status: open
RecordStatus: off Read/Write State
TransferStatus: idle
BytesAvailable: 0
ValuesReceived: 0
ValuesSent: 0Next, create the M-file callback function DISPCALLBACK, which displays the event and time of the event to the MATLAB command window.
Since we are interested in the event information, the callback property must be defined as either a function handle or a cell array so that the event structure is passed automatically to the callback function.
In this case, the callback function must have at least two input arguments. The first input argument is the object that caused the event to occur. The second input argument is a structure containing information regarding the event that occurred.
>> type dispcallback
function dispcallback(obj, event) %DISPCALLBACK Display event information for the specified event. % % DISPCALLBACK(OBJ, EVENT) a callback function that displays % a message containing the type of the event, the name % of the object that caused the event to occur, and the % time the event occurred. % % See also INSTRCALLBACK.
callbackTime = datestr(datenum(event.Data.AbsTime)); fprintf(['A ' event.Type ' event occurred for ' obj.Name ' at ' callbackTime '.\\n']);
Now, configure the object to acquire data continuously and to notify you when a BytesAvailable, OutputEmpty, or Error event occurs.
>> set(s, 'ReadAsyncMode', 'continuous');
>> set(s, 'BytesAvailableFcn', {'dispcallback'});
>> set(s, 'OutputEmptyFcn', {'dispcallback'});
>> set(s, 'ErrorFcn', {'dispcallback'});To execute DISPCALLBACK, write the 'RS232?' command to the oscilloscope. This command will query the RS-232 settings. It returns the BaudRate, the software flow control setting, the hardware flow control setting, the parity, and the terminator.
Because the object is reading continuously, the data is read from the oscilloscope as soon as it is available (after the asynchronous write command finished executing). The data read from the oscilloscope is placed in the input buffer. The amount of data in the input buffer is given by the BytesAvailable property. Once the terminator is read from the oscilloscope, the bytes available callback is executed. The data can be brought into the MATLAB workspace with the FSCANF function.
>> fprintf(s, 'RS232?', 'async');
A OutputEmpty event occurred for Serial-COM1 at 20-Dec-1999 16:12:00. A BytesAvailable event occurred for Serial-COM1 at 20-Dec-1999 16:12:00.
>> get(s, 'BytesAvailable')
ans =
16
>> fscanf(s)
ans =
9600;0;0;NON;CR
>> fclose(s)
You can construct callback functions to accept additional input arguments. For example, if you want to pass the arguments 'range1' and 'range2' to the M-file callback, function MYCALLBACK, define the callback property as follows.
>> set(s, 'OutputEmptyFcn', {'mycallback', range1, range2});The callback function would have the following function line.
function mycallback(obj, event, range1, range2)
Create a simple callback function that takes two additional input arguments. The callback function SIMPLECALLBACK is created to sum two input values and assign the resulting value to the UserData property.
>> type simplecallback
function simplecallback(obj, event, value1, value2) %SIMPLECALLBACK Callback function for modifying object's UserData. % % SIMPLECALLBACK(OBJ, EVENT, VALUE1, VALUE2) sets OBJ's % UserData property to value1+value2. %
set(obj, 'UserData', value1+value2);
Using the same serial port object, configure the BytesAvailableFcn property to execute 'simplecallback' when 10 bytes are available in the object's input buffer.
>> set(s, 'BytesAvailableFcn', {'simplecallback', 4, 10});
>> set(s, 'BytesAvailableFcnCount', 10);
>> set(s, 'BytesAvailableFcnMode', 'byte');
>> set(s, 'OutputEmptyFcn', '');
>> set(s, 'ErrorFcn', '');SIMPLECALLBACK executes when 10 bytes are available.
>> fopen(s) >> fprintf(s, 'Display:Contrast?') >> get(s, 'BytesAvailable')
ans =
3
>> get(s, 'UserData')
ans =
[]
>> fprintf(s, 'RS232?') >> get(s, 'BytesAvailable')
ans =
19
>> get(s, 'UserData')
ans =
14
If you are finished with the serial port object, disconnect it from the instrument, remove it from memory, and remove it from the workspace.
>> fclose(s) >> delete(s) >> clear s