Você está na página 1de 8

Read serial data directly into Octave

Steve Hageman - October 23, 2015

GNU Octave 4 [1] with its graphical interface is allowing many more folks to explore the MATLAB
[2] programming language who never could have done so before because of the cost. While Octave
will never have the rich instrument control options available to MATLAB users, there are still ways
to get serial data directly from a connected device into Octave.
The Octave: Instrument Control Package [3] was updated mid-year 2015 and fixed a number of
serial port issues. Now that the serial port more or less works we can get some real work done.
Note: These instructions assume that the reader has some previous serial port knowledge and knows
how to hook up and use their device. The information here will help you get the serial package going
in Octave.
Install the instrument control package
The basic steps to install the instrument control package in Windows are:
1. Download the latest instrument control package [3] and place it in the Octave packages directory,
C:\Octave\Octave-4.0.0\src
Note: The exact path will depend on the version of Octave you are running. The example above is for
version: 4.0.0.
2. Start Octave.
3. Set the current directory to the directory where you placed the instrument control package in
step 1.
4. In the Octave Command Window, at the >> prompt type,
pkg install instrument-control-0.2.1.tar.gz
Note: Be sure to use the correct file name for the instrument control package that you are installing.
The above example is for version 0.2.1.
5. Press enter and wait. The install takes several minutes, even on a very fast computer.
Finally, the command prompt will come back and the package will be all compiled installed and
ready to go.

Using the serial commands in Octave


A number of steps need to be done to load the instrument-control package and then set it up for use.
You will need to load the instrument control package before you can use it in your Octave program.
In your Octave program you will need to place this command near the start of your program.
pkg load instrument-control
if (exist("serial") != 3)
disp("No Serial Support");
endif
The first line loads the package. The optional 'if' statement checks the serial port status. Three
means that the serial functions are OK, anything else is an error and no serial support has been
loaded. This check is useful if your program could ever run on a computer that does not have the
Instrument Control Package installed.
To open the serial port and get a handle to it for future reads and writes use the 'Serial()' command
as shown,
% Instantiate the Serial Port
% Naturally, set the COM port # to match your device
% Use this crazy notation for any COM port number: 1 - 255
s1 = serial("\\\\.\\COM15") % Open the port
pause(1);
% Optional wait for device to wake up
The returned value 's1' is the handle to the opened port that is used in subsequent port operations.
Your device may take a while to wake up when opened, so a pause() may be needed after opening
the port.
If you try to open a COM Port that does not exist, you will get this error on the command line,
error: serial: Error opening the interface: No such file or directory
The solution to this error is to: connect, power up, or specify the proper COM Port for your device.
The next step is to setup the serial port for the proper operating parameters. The get/set interface is
the preferred way to access the serial port. And the basic parameters are,
% Set the port parameters
set(s1, 'baudrate', 115200); % See List Below
set(s1, 'bytesize', 8);
% 5, 6, 7 or 8
set(s1, 'parity', 'n');
% 'n' or 'y'
set(s1, 'stopbits', 1);
% 1 or 2
set(s1, 'timeout', 123); % 12.3 Seconds as an example here
The terms above should be familiar to most folks who have ever set up a serial port.
Some things to note:

Handshaking is set to: None. At this time, there is no code support for any other settings.
The Data Terminal Ready (DTR) and Ready to Send (RTS) control lines are enabled by default
when the port is opened. If needed you can use the following commands to set the state to
anything you need.

% Optional commands, these can be 'on' or 'off'


set(s1, 'requesttosend', 'on');
% Sets the RTS line to on
set(s1, 'dataterminalready', 'off'); % Sets the DTR line to off

Baudrate can be: 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, 9600, 19200,
38400, 57600, 115200 and 230400.
Timeout is specified in 1/10 second units. -1 means no timeout and the port will wait forever for the
specified operation to complete.

Depending on your device you may need to flush the serial input and output buffers, so I do
something like this:
% Optional Flush input and output buffers
srl_flush(s1);

Reading and writing data


Reading and writing data
Now that we have opened and set up the COM Port, it's time to read and write data. The examples
that follow use a serial port with a loopback connector attached [4].
A basic Hello World! can be sent and received as follows,
% Example using srl_write & srl_read
srl_write(s1, "Hello World!");
% Reads back 12 bytes as an array of integers
read_back_int = srl_read(s1, 12);
% Convert the integers to a string
read_back_str = char(read_back_int);
The srl_write() command writes out everything in the buffer and it blocks further execution until the
buffer is empty. The srl_read() command reads back the number of bytes specified as an array of
integers. A conversion to a string is easily done as shown.
If there are fewer characters to read then you specify in the srl_read() call, the read will hang until
the port times out. If there are more characters to read than you specify they will be left in the input

buffer.
Naturally, this requirement to know the length of the input string is very restrictive and puts a real
damper on the serial port usability, but it is exactly the lowest level command that we need in order
to build upon.
Since most instruments communicate by some form of termination character, either a carriage
return, line feed, or both, we can just read each character as it comes in and terminate the read
when we get to the specified termination character.
This need led to my humble addition to the serial port operations, and the: ReadToTermination()
function was born (Appendix A). Its usage is as follows,
return_string = ReadToTermination(serialport, {termination_char})
First, it returns a string, which can be parsed for numbers later or can be used as a basis for
modified functions as you may need for your specific needs, like returning a double.
Second, it keeps reading the serial port a character at a time until the {termination_char} is read. If
you leave the {termination_char} blank, the default character used is the Carriage Return ('\r'). If
your device instead uses the New Line ('\n'), or some other termination character, then you can
specify this as needed.
The {term_character} is specified as an unsigned 8bit int. The most common termination codes are
listed below. You can look up other codes if needed on an ASCII chart.
Carriage Return
New Line

= '\r'
= '\n'

= 13dec
= 10dec

(The Default)

You can look up other codes if needed on an ASCII chart.

As an example of using the ReadToTermination() function, consider the following:


% Use the ReadToTermination to read an entire line back
% using the default termination_char = Carriage Return
srl_write(s1, "Hello world!\r");
read_back = ReadToTermination(s1);
The notation below will also work exactly like above, it just specifies the termination character.
srl_write(s1, "Hello world!\r");
read_back = ReadToTermination(s1, 13);
Likewise, to use a Newline character ('\n') this can be written as,
% Use the ReadToTermination to read an entire line back
% using the newline as the termination_char
srl_write(s1, "Hello world!\n");
read_back = ReadToTermination(s1, 10);

Finally, this example shows how to read and write multiple lines.
% Read two lines back
srl_write(s1, "Hello world!\r Next Line\r");
line1 = ReadToTermination(s1);
line2 = ReadToTermination(s1);
After running the lines above, the result will be:
line1 = Hello World
line2 = Next Line
Appendix B lists the entire demonstration program.
Wrapping it all up
Now you should have enough information to be able to set up and open read and write to the serial
port both using the primitive srl_read() & srl_write() functions and the described higher level
ReadToTermination() functions.
The ReadToTermination() function is a higher level function that overcomes the limitations of
needing to know the exact number of characters to be read by instead using the more common:
Read until a termination character is found method.
While my simple version of ReadToTermination() currently only returns a string, the reader will note
how easy it would be to modify this function for any purpose as the code is extremely
straightforward and easy to modify.
Now you should be a ready to use Octave with your Arduino or Rasberry PI and even with lab
equipment like that great old HP34401 multimeter on your workbench. Enjoy!
Author information
Steve Hageman is a confirmed analog-a-holic since about the fifth grade when he
built his first shortwave receiver. After acquiring his first Apple computer in 1982, he
has continued using software to control analog hardware and building useful
measurement systems. Steve has had the pleasure of designing such diverse
products as modular data acquisition systems, switching power supplies, RFIC test
systems, software defined radios, and most recently, high frequency lock in
amplifiers for biological sample investigation. He would be happy to discuss your custom project
needs and can be reached via his website AnalogHome.
Appendix A
Code listing of the ReadToTermination() Function
function [char_array] = ReadToTermination (srl_handle, term_char)
% parameter term_char is optional, if not specified
% then CR = '\r' = 13dec is the default.
if(nargin == 1)
term_char = 13;

end
not_terminated = true;
i = 1;
int_array = uint8(1);
while not_terminated
val = srl_read(srl_handle, 1);
if(val == term_char)
not_terminated = false;
end
% Add char received to array
int_array(i) = val;
i = i + 1;
end
% Change int array to a char array and return a string array
char_array = char(int_array);
endfunction
You can place this function in a file named ReadToTermination.m and place it in your projects
current working directory.

Appendix B
The complete demonstration program for use with a loopback serial connection [4].
% Octave - Serial Test - Using a loopback connection
clc; clear;
% Load the package
pkg load instrument-control
% Check if serial support exists
if (exist("serial") != 3)
disp("No Serial Support");
endif
% Instantiate the Serial Port
% Naturally, set the COM port # to match your device
% Use this crazy notation for any COM port number: 1 - 255
s1 = serial("\\\\.\\COM10");
pause(1); % Wait a second as it takes some ports a while to wake up
% Set the port parameters

set(s1,
set(s1,
set(s1,
set(s1,
set(s1,

'baudrate', 115200);
'bytesize', 8);
'parity', 'n');
'stopbits', 1);
'timeout', 123); % 12.3 Seconds as an example here

% Optional commands, these can be 'on' or 'off'


%set(s1, 'requesttosend', 'on');
% Sets the RTS line
%set(s1, 'dataterminalready', 'on'); % Sets the DTR line
% Optional - Flush input and output buffers
srl_flush(s1);
%----- Loopback Communication Test ----% Looback using srl_write & srl_read
srl_write(s1, "Hello World!");
% reads back 12 bytes as integers
read_back_int = srl_read(s1, 12);
% Convert the integers to a string
read_back_str = char(read_back_int);
% Use the ReadToTermination to read an entire line back
srl_write(s1, "Hello world!\r");
read_back = ReadToTermination(s1);
% Change the termination character to newline ('\n' = 10)
srl_write(s1, "Hello world!\n");
read_back2 = ReadToTermination(s1, 10);
% Read two lines back
srl_write(s1, "Hello world!\r Next Line\r");
line1 = ReadToTermination(s1);
line2 = ReadToTermination(s1);
% Finally, Close the port
fclose(s1);

References
1. GNU Octave
2. MATLAB is a registered trademark of The Mathworks, Inc.
3. The latest instrument control package may be downloaded here. This article is written for
version: 0.2.1 (2015-02-05). Future versions may change things significantly. Be sure to check the
release notes. More information on the functions contained in the package is also located there.
4. A simple Web search will locate many examples of how to make a loopback plug for your serial
port.

Want more programming? Join over 2,000 technical professionals and embedded
systems hardware, software, and firmware developers at ESC Minneapolis Nov 45, 2015 and learn about the latest techniques and tips for reducing time, cost,
and complexity in the embedded development process.
Make sure to follow updates about ESC Minneapolis's talks, programs, and announcements in the
ESC Collection and social media accounts Twitter, Facebook, LinkedIn, and Google+.
The Embedded Systems Conference and EDN are owned by UBM Canon.

Você também pode gostar