Documentation Center

  • Trial Software
  • Product Updates

Contents

Writing and Reading Data

Before You Begin

For many serial port applications, there are three important questions that you should consider when writing or reading data:

  • Will the read or write function block access to the MATLAB® command line?

  • Is the data to be transferred binary (numerical) or text?

  • Under what conditions will the read or write operation complete?

For write operations, these questions are answered in Writing Data. For read operations, these questions are answered in Reading Data.

    Note:   All the examples shown below are based on a Windows® 32-bit platform. Refer to Overview of a Serial Port Object section for information about other platforms.

Example — Introduction to Writing and Reading Data

Suppose you want to return identification information for a Tektronix® TDS 210 two-channel oscilloscope connected to the serial port COM1 on a Windows platform. This requires writing the *IDN? command to the instrument using the fprintf function, and reading back the result of that command using the fscanf function.

s = serial('COM1');
fopen(s)
fprintf(s,'*IDN?')
out = fscanf(s)

The resulting identification information is:

out =
TEKTRONIX,TDS 210,0,CF:91.1CT FV:v1.16 TDS2CM:CMV:v1.04

End the serial port session.

fclose(s)
delete(s)
clear s

Controlling Access to the MATLAB Command Line

You control access to the MATLAB command line by specifying whether a read or write operation is synchronous or asynchronous.

A synchronous operation blocks access to the command line until the read or write function completes execution. An asynchronous operation does not block access to the command line, and you can issue additional commands while the read or write function executes in the background.

The terms synchronous and asynchronous are often used to describe how the serial port operates at the hardware level. The RS-232 standard supports an asynchronous communication protocol. Using this protocol, each device uses its own internal clock. The data transmission is synchronized using the start bit of the bytes, while one or more stop bits indicate the end of the byte. For more information on start bits and stop bits, see Serial Data Format. The RS-232 standard also supports a synchronous mode where all transmitted bits are synchronized to a common clock signal.

At the hardware level, most serial ports operate asynchronously. However, using the default behavior for many of the read and write functions, you can mimic the operation of a synchronous serial port.

    Note    When used in this guide, the terms synchronous and asynchronous refer to whether read or write operations block access to the MATLAB command-line. In other words, these terms describe how the software behaves, and not how the hardware behaves.

The two main advantages of writing or reading data asynchronously are:

  • You can issue another command while the write or read function is executing.

  • You can use all supported callback properties (see Events and Callbacks).

For example, because serial ports have separate read and write pins, you can simultaneously read and write data. This is illustrated in the following diagram.

Writing Data

This section describes writing data to your serial port device in three parts:

The following table shows the functions associated with writing data.

Functions Associated with Writing Data

Function NameDescription

fprintf

Write text to the device

fwrite

Write binary data to the device

stopasync

Stop asynchronous read and write operations

The following table shows the properties associated with writing data.

Properties Associated with Writing Data

Property NameDescription

BytesToOutput

Number of bytes currently in the output buffer

OutputBufferSize

Size of the output buffer in bytes

Timeout

Waiting time to complete a read or write operation

TransferStatus

Indicate if an asynchronous read or write operation is in progress

ValuesSent

Total number of values written to the device

The Output Buffer and Data Flow

The output buffer is computer memory allocated by the serial port object to store data that is to be written to the device. When writing data to your device, the data flow follows these two steps:

  1. The data specified by the write function is sent to the output buffer.

  2. The data in the output buffer is sent to the device.

The OutputBufferSize property specifies the maximum number of bytes that you can store in the output buffer. The BytesToOutput property indicates the number of bytes currently in the output buffer. The default values for these properties are:

s = serial('COM1');
get(s,{'OutputBufferSize','BytesToOutput'})
ans = 
    [512]    [0]

If you attempt to write more data than can fit in the output buffer, an error is returned and no data is written.

For example, suppose you write the string command *IDN? to the TDS 210 oscilloscope using the fprintf function. As shown in the following diagram, the string is first written to the output buffer as six values.

The *IDN? command consists of six values because the terminator is automatically written. Moreover, the default data format for the fprintf function specifies that one value corresponds to one byte. For more information about bytes and values, see Bytes Versus Values. fprintf and the terminator are discussed in Writing Text Data.

As shown in the following diagram, after the string is written to the output buffer, it is then written to the device via the serial port.

Writing Text Data

You use the fprintf function to write text data to the device. For many devices, writing text data means writing string commands that change device settings, prepare the device to return data or status information, and so on.

For example, the Display:Contrast command changes the display contrast of the oscilloscope.

s = serial('COM1');
fopen(s)
fprintf(s,'Display:Contrast 45')

By default, fprintf writes data using the %s\n format because many serial port devices accept only text-based commands. However, you can specify many other formats, as described in the fprintf reference pages.

You can verify the number of values sent to the device with the ValuesSent property.

s.ValuesSent
ans =
    20

Note that the ValuesSent property value includes the terminator because each occurrence of \n in the command sent to the device is replaced with the Terminator property value.

s.Terminator
ans =
LF

The default value of Terminator is the linefeed character. The terminator required by your device will be described in its documentation.

Synchronous Versus Asynchronous Write Operations.  By default, fprintf operates synchronously and blocks the MATLAB command line until execution completes. To write text data asynchronously to the device, you must specify async as the last input argument to fprintf.

fprintf(s,'Display:Contrast 45','async')

Asynchronous operations do not block access to the MATLAB command line. Additionally, while an asynchronous write operation is in progress, you can:

  • Execute an asynchronous read operation because serial ports have separate pins for reading and writing

  • Make use of all supported callback properties

You can determine which asynchronous operations are in progress with the TransferStatus property. If no asynchronous operations are in progress, TransferStatus is idle.

s.TransferStatus
ans =
idle

Completing a Write Operation with fprintf.  A synchronous or asynchronous write operation using fprintf completes when:

  • The specified data is written.

  • The time specified by the Timeout property passes.

Stop an asynchronous write operation with the stopasync function.

Rules for Writing the Terminator.  The Terminator property value replaces all occurrences of \n in cmd. Therefore, when you use the default format %s\n, all commands written to the device end with this property value. Refer to your device documentation for the terminator required by your device.

Writing Binary Data

You use the fwrite function to write binary data to the device. Writing binary data means writing numerical values. A typical application for writing binary data involves writing calibration data to an instrument such as an arbitrary waveform generator.

    Note    Some serial port devices accept only text-based commands. These commands might use the SCPI language or some other vendor-specific language. Therefore, you might need to use the fprintf function for all write operations.

By default, fwrite translates values using the uchar precision. However, you can specify many other precisions as described in the reference pages for this function.

By default, fwrite operates synchronously. To write binary data asynchronously to the device, you must specify async as the last input argument to fwrite. For more information about synchronous and asynchronous write operations, see Writing Text Data. For a description of the rules used by fwrite to complete a write operation, refer to its reference pages.

Troubleshooting Common Errors

Use this table to identify common fprintf errors.

ErrorOccurs whenTroubleshooting

??? Error using ==> serial.fwrite at 199 OBJ must be connected to the hardware with FOPEN.

You perform a write operation and the serial port object is not connected to the device.

Use fopen to establish a connection to the device.

??? Error using ==> serial.fwrite at 199 The number of bytes written must be less than or equal to OutputBufferSize-BytesToOutput.

The output buffer is not able to hold all the data to be written.

Specify the size of the output buffer with the OutputBufferSize property.

??? Error using ==> serial.fwrite at 192 FWRITE cannot be called. The FlowControl property is set to 'hardware' and the Clear To Send (CTS) pin is high. This could indicate that the serial device may not be turned on, may not be connected, or does not use hardware handshaking

  • You set the flowcontrol property on a serial object to hardware.

  • The device is either not connected or a connected device is not asserting that is ready to receive data.

Check your remote device status and flow control settings to see if hardware flow control is causing MATLAB errors.

Reading Data

This section describes reading data from your serial port device in three parts:

The following table shows the functions associated with reading data.

Functions Associated with Reading Data

Function NameDescription

fgetl

Read one line of text from the device and discard the terminator

fgets

Read one line of text from the device and include the terminator

fread

Read binary data from the device

fscanf

Read data from the device and format as text

readasync

Read data asynchronously from the device

stopasync

Stop asynchronous read and write operations

The following table shows the properties associated with reading data.

Properties Associated with Reading Data

Property NameDescription

BytesAvailable

Number of bytes available in the input buffer

InputBufferSize

Size of the input buffer in bytes

ReadAsyncMode

Specify whether an asynchronous read operation is continuous or manual

Timeout

Waiting time to complete a read or write operation

TransferStatus

Indicate if an asynchronous read or write operation is in progress

ValuesReceived

Total number of values read from the device

The Input Buffer and Data Flow

The input buffer is computer memory allocated by the serial port object to store data that is to be read from the device. When reading data from your device, the data flow follows these two steps:

  1. The data read from the device is stored in the input buffer.

  2. The data in the input buffer is returned to the MATLAB variable specified by the read function.

The InputBufferSize property specifies the maximum number of bytes that you can store in the input buffer. The BytesAvailable property indicates the number of bytes currently available to be read from the input buffer. The default values for these properties are:

s = serial('COM1');
get(s,{'InputBufferSize','BytesAvailable'})
ans = 
    [512]    [0]

If you attempt to read more data than can fit in the input buffer, an error is returned and no data is read.

For example, suppose you use the fscanf function to read the text-based response of the *IDN? command previously written to the TDS 210 oscilloscope. As shown in the following diagram, the text data is first read into the input buffer via the serial port.

Note that for a given read operation, you might not know the number of bytes returned by the device. Therefore, you might need to preset the InputBufferSize property to a sufficiently large value before connecting the serial port object.

As shown in the following diagram, after the data is stored in the input buffer, it is then transferred to the output variable specified by fscanf.

Reading Text Data

You use the fgetl, fgets, and fscanf functions to read data from the device, and format the data as text.

For example, suppose you want to return identification information for the oscilloscope. This requires writing the *IDN? command to the instrument, and then reading back the result of that command.

s = serial('COM1');
fopen(s)
fprintf(s,'*IDN?')
out = fscanf(s)
out =
TEKTRONIX,TDS 210,0,CF:91.1CT FV:v1.16 TDS2CM:CMV:v1.04

By default, fscanf reads data using the %c format because the data returned by many serial port devices is text based. However, you can specify many other formats as described in the fscanf reference pages.

You can verify the number of values read from the device—including the terminator—with the ValuesReceived property.

s.ValuesReceived
ans =
    56

Synchronous Versus Asynchronous Read Operations.  You specify whether read operations are synchronous or asynchronous with the ReadAsyncMode property. You can configure ReadAsyncMode to continuous or manual.

If ReadAsyncMode is continuous (the default value), the serial port object continuously queries the device to determine if data is available to be read. If data is available, it is asynchronously stored in the input buffer. To transfer the data from the input buffer to MATLAB, use one of the synchronous (blocking) read functions such as fgetl or fscanf. If data is available in the input buffer, these functions return quickly.

s.ReadAsyncMode = 'continuous';
fprintf(s,'*IDN?')
s.BytesAvailable
ans =
    56
out = fscanf(s);

If ReadAsyncMode is manual, the serial port object does not continuously query the device to determine if data is available to be read. To read data asynchronously, use the readasync function. Then use one of the synchronous read functions to transfer data from the input buffer to MATLAB.

s.ReadAsyncMode = 'manual';
fprintf(s,'*IDN?')
s.BytesAvailable
ans =
    0
readasync(s)
s.BytesAvailable
ans =
    56
out = fscanf(s);

Asynchronous operations do not block access to the MATLAB command line. Additionally, while an asynchronous read operation is in progress, you can:

  • Execute an asynchronous write operation because serial ports have separate pins for reading and writing

  • Make use of all supported callback properties

You can determine which asynchronous operations are in progress with the TransferStatus property. If no asynchronous operations are in progress, then TransferStatus is idle.

s.TransferStatus
ans =
idle

Rules for Completing a Read Operation with fscanf.  A read operation with fscanf blocks access to the MATLAB command line until:

  • The terminator specified by the Terminator property is read.

  • The time specified by the Timeout property passes.

  • The specified number of values specified is read.

  • The input buffer is filled.

Reading Binary Data

You use the fread function to read binary data from the device. Reading binary data means that you return numerical values to MATLAB.

For example, suppose you want to return the cursor and display settings for the oscilloscope. This requires writing the CURSOR? and DISPLAY? commands to the instrument, and then reading back the results of those commands.

s = serial('COM1');
fopen(s)
fprintf(s,'CURSOR?')
fprintf(s,'DISPLAY?')

Because the default value for the ReadAsyncMode property is continuous, data is asynchronously returned to the input buffer as soon as it is available from the device. You can verify the number of values read with the BytesAvailable property.

s.BytesAvailable
ans =
    69

You can return the data to MATLAB using any of the synchronous read functions. However, if you use fgetl, fgets, or fscanf, you must issue the function twice because there are two terminators stored in the input buffer. If you use fread, you can return all the data to MATLAB in one function call.

out = fread(s,69);

By default, fread returns numerical values in double precision arrays. However, you can specify many other precisions as described in the fread reference pages. You can convert the numerical data to text using the MATLAB char function.

val = char(out)'
val =
HBARS;CH1;SECONDS;-1.0E-3;1.0E-3;VOLTS;-6.56E-1;6.24E-1
YT;DOTS;0;45

For more information about synchronous and asynchronous read operations, see Reading Text Data. For a description of the rules used by fread to complete a read operation, refer to its reference pages.

Example — Writing and Reading Text Data

This example illustrates how to communicate with a serial port instrument by writing and reading text data.

The instrument is a Tektronix TDS 210 two-channel oscilloscope connected to the COM1 port. Therefore, many of the following commands are specific to this instrument. A sine wave is input into channel 2 of the oscilloscope, and your job is to measure the peak-to-peak voltage of the input signal.

  1. Create a serial port object — Create the serial port object s associated with serial port COM1.

    s = serial('COM1');
  2. Connect to the device — Connect s to the oscilloscope. Because the default value for the ReadAsyncMode property is continuous, data is asynchronously returned to the input buffer as soon as it is available from the instrument.

    fopen(s)
  3. Write and read data — Write the *IDN? command to the instrument using fprintf, and then read back the result of the command using fscanf.

    fprintf(s,'*IDN?')
    idn = fscanf(s)
    idn =
    TEKTRONIX,TDS 210,0,CF:91.1CT FV:v1.16 TDS2CM:CMV:v1.04

    You need to determine the measurement source. Possible measurement sources include channel 1 and channel 2 of the oscilloscope.

    fprintf(s,'MEASUREMENT:IMMED:SOURCE?')
    source = fscanf(s)
    source =
    CH1

    The scope is configured to return a measurement from channel 1. Because the input signal is connected to channel 2, you must configure the instrument to return a measurement from this channel.

    fprintf(s,'MEASUREMENT:IMMED:SOURCE CH2')
    fprintf(s,'MEASUREMENT:IMMED:SOURCE?')
    source = fscanf(s)
    source =
    CH2

    You can now configure the scope to return the peak-to-peak voltage, and then request the value of this measurement.

    fprintf(s,'MEASUREMENT:MEAS1:TYPE PK2PK')
    fprintf(s,'MEASUREMENT:MEAS1:VALUE?')

    Transfer data from the input buffer to MATLAB using fscanf.

    ptop = fscanf(s,'%g')
    ptop =
    2.0199999809E0
  4. Disconnect and clean up — When you no longer need s disconnect it from the instrument and remove it from memory and from the MATLAB workspace.

    fclose(s)
    delete(s)
    clear s

Example — Parsing Input Data Using textscan

This example illustrates how to use the textscan function to parse and format data that you read from a device. textscan is particularly useful when you want to parse a string into one or more variables, where each variable has its own specified format.

The instrument is a Tektronix TDS 210 two-channel oscilloscope connected to the serial port COM1.

  1. Create a serial port object — Create the serial port object s associated with serial port COM1.

    s = serial('COM1');
  2. Connect to the device — Connect s to the oscilloscope. Because the default value for the ReadAsyncMode property is continuous, data is asynchronously returned to the input buffer as soon as it is available from the instrument.

    fopen(s)
  3. Write and read data — Write the RS232? command to the instrument using fprintf, and then read back the result of the command using fscanf. RS232? queries the RS-232 settings and returns the baud rate, the software flow control setting, the hardware flow control setting, the parity type, and the terminator.

    fprintf(s,'RS232?')
    data = fscanf(s)
    data =
    9600;0;0;NONE;LF

    Use the textscan function to parse and format the data variable into five new variables.

    C = textscan(a, '%d%d%d%s%s','delimiter',';'); 
    
    [br, sfc, hfc, par, tm] = deal(C{:});
    
    br =
            9600
    sfc =
         0
    hfc =
         0
    par = 
        'NONE'
    tm = 
        'LF'
  4. Disconnect and clean up — When you no longer need s, you should disconnect it from the instrument, and remove it from memory and from the MATLAB workspace.

    fclose(s)
    delete(s)
    clear s

Example — Reading Binary Data

This example illustrates how you can download the TDS 210 oscilloscope screen display to MATLAB. The screen display data is transferred and saved to disk using the Windows bitmap format. This data provides a permanent record of your work, and is an easy way to document important signal and scope parameters.

Because the amount of data transferred is expected to be fairly large, it is asynchronously returned to the input buffer as soon as it is available from the instrument. This allows you to perform other tasks as the transfer progresses. Additionally, the scope is configured to its highest baud rate of 19,200.

  1. Create a serial port object — Create the serial port object s associated with serial port COM1.

    s = serial('COM1');
  2. Configure property values — Configure the input buffer to accept a reasonably large number of bytes, and configure the baud rate to the highest value supported by the scope.

    s.InputBufferSize = 50000;
    s.BaudRate = 19200;
  3. Connect to the device — Connect s to the oscilloscope. Because the default value for the ReadAsyncMode property is continuous, data is asynchronously returned to the input buffer as soon as it is available from the instrument.

    fopen(s)
  4. Write and read data — Configure the scope to transfer the screen display as a bitmap.

    fprintf(s,'HARDCOPY:PORT RS232')
    fprintf(s,'HARDCOPY:FORMAT BMP')
    fprintf(s,'HARDCOPY START')

    Wait until all the data is sent to the input buffer, and then transfer the data to the MATLAB workspace as unsigned 8-bit integers.

    out = fread(s,s.BytesAvailable,'uint8');
  5. Disconnect and clean up — When you no longer need s, disconnect it from the instrument and remove it from memory and from the MATLAB workspace.

    fclose(s)
    delete(s)
    clear s

Viewing the Bitmap Data

To view the bitmap data, follow these steps:

  1. Open a disk file.

  2. Write the data to the disk file.

  3. Close the disk file.

  4. Read the data into MATLAB using the imread function.

  5. Scale and display the data using the imagesc function.

Note that the file I/O versions of the fopen, fwrite, and fclose functions are used.

fid = fopen('test1.bmp','w');
fwrite(fid,out,'uint8');
fclose(fid)
a = imread('test1.bmp','bmp');
imagesc(a)

Because the scope returns the screen display data using only two colors, an appropriate colormap is selected.

mymap = [0 0 0; 1 1 1];
colormap(mymap)

The following diagram shows the resulting bitmap image.

Was this topic helpful?