Using Matlab with TinyOS

Last updated 21 Sept 2002

This tutorial explains how to interact with a mote or sensor network using Matlab. There are three parts to the tutorial, but the second two are for advanced users.  You can focus on the first section, but before you begin, make sure you set up your Matlab environment to work with TinyOS.

  1. The first section explains how to connect to your network to send and receive packets.
  2. The second part shows you how to use the TinyOS Java tools from Matlab.
  3. The third section explains how to get data out of your Java tools and into your Matlab environment. 
Connecting to the Mote Network

Connecting to a port

All you need to do is use the connect command.  For example:

connect('COM1');
connect('localhost:9000');

Sending a message to the network

First, you need to instantiate a message, which should be a subclass of the net.tinyos.message.Message class.  In general, one can use the MIG tool to generate these classes directly from the NesC code (use net.tinyos.oscope.OscopeResetMsg an example).

msg=net.tinyos.oscope.OscopeResetMsg
send(1, msg)

If you have an Oscilloscope mote with moteID 1 and a generic base attached to COM1 or localhost:9000, the Oscilloscope will reset.

Receiving messages from the network

You need to instantiate a message of the type you want to receive.  You also need to create a function that takes two parameters: an address and a message. (Look at tools/matlab/util/printMsg.m as an example).  Then, type the following

omsg = net.tinyos.oscope.OscopeMsg
receive('printMsg', msg);

Whenever a message of type msg is received, the printMsg function will be called with the message passed to it as a parameter.  Typing the above command right now will cause all OscopeMsg messages to be passed to the printMsg function, which prints them to the screen.  If you have an Oscilloscope mote attached to COM1 or localhost:9000, the messages will start appearing on the screen.

Notice that both the send and receive commands take a port, e.g. COM1 or localhost:9000, as optional third arguments.  When this argument is passed, the connect function does not need to be used.  Furthermore, the send and receive commands are limited to the ports specified.

Using the Java tools from Matlab

In this part of the tutorial we see how to use Matlab simply as a Java interpreter from which we can use the TinyOS Java tools.  There are two parts:

  1. An overview of how to use Java from Matlab in general
  2. An example in which we use the Oscilloscope application (i.e. Lesson 6)

Overview of the Matlab/Java interface

The following table provides an overview of the Matlab syntax for using Java.  It is essentially the same as Java syntax except that there is no "new" operator and functions with no arguments do not terminate with empty parenthesis  "( )".  Type these commands into your Matlab command window to see what they do.

Overview of Matlab syntax for using Java objects

Instantiate an Object

f = java.awt.Frame
f = java.awt.Frame("My Frame")

Call a function

f.show
f.resize(500,500)
f.hide

Call a static function

java.awt.Frame.getFrames

Access public member variable

f.WIDTH

Introsection: class name

classname = class(f)

Introspection: methods

methods java.awt.Frame
methods java.awt.Frame -full
methodsview java.awt.Frame

Introspection: variables

fields(f)

Import

import java.awt.*

Conversion of function parameters and return values are taken care of automatically.  Essentially, all primitive types, including strings and arrays, are automatically converted and are passed by value.  Java objects are left as Java objects and are passed by reference.  Using Java from Matlab is completely supported by Mathworks and is well documented in the the "Matlab/Java interface" section of the Matlab help files. 

Example: Using Oscilloscope

Here, we see an example of using Java tools from Matlab.  Before beginning, be sure that

  1. The net.tinyos.oscope Java classes are compiled, including OscopeMsg.java and OscopeResetMsg.java
  2. A mote has been programmed with the OscilloscopeRF application
  3. A GenericBase mote is plugged into your serial port

Now, go to your matlab command window.  The following two commands will call the static main() functions of the SerialForwarder and Oscilloscope classes. We pass command-line arguments directly to 'main( )' as follows.

net.tinyos.sf.SerialForward.main({'-comm','COM1'})
net.tinyos.oscope.oscilloscope.main({'125'})

This starts the two applications.  After the first command, you should see a SerialForwarder GUI appear and say that it connected to COM1 and is waiting for clients.  What if this didn't happen?  Then the second command will create the oscilloscope client that will connect to the SerialForwarder, receive packets from it, and plot them on the screen.  What if this didn't happen? 

Now, let's inject a message to our Mote.  The following commands will

  1. Instantiate a moteIF object and pass parameters to its constructor telling it to connect to localhost:9000 and listen to group ID 125
  2. Instantiate an "OscopeResetMsg"
  3. Inject that message to our OscilloscopeRF mote, where XX is the node ID of that mote. 

mIF = net.tinyos.message.MoteIF('localhost', 9000, 125)
msg = net.tinyos.oscope.OscopeResetMsg
mIF.send( XX , msg)
 

You've now seen how to use Java from Matlab.  From this example you should understand how to use all the TinyOS Java tools, and in fact all Java objects, from Matlab.  See Making Java classes Matlab Friendly for a few other important facts.

Using the MatlabControl class

In the previous section we saw that we could easily manipulate Java objects from Matlab.  We could also get data into the Matlab workspace by storing the return value of a java function.  This type of interaction with Java is completely supported by Matlab.  For example

am=msg.amType

gets the AM type of your OscopeResetMsg message and stores it in the Matlab variable am

However, there are times when we would like to pass data into Matlab by calling a Matlab function from Java and passing the data as a parameter.  This is not supported by Matlab but is often much more useful.  For example, it allows the Java MIG tools to pass incoming messages into Matlab whenever they arrive.  In this section, we see how to use the net.tinyos.matlab.MatlabControl.java class to call Matlab commands from Java.  There are two parts to this section:

  1. An overview of the MatlabControl class itself
  2. An example in which we use MatlabControl with MIG, the Message Interface Generator

MatlabControl.java

MatlabControl only has two functions

void MatlabControl.eval(String)
void MatlabControl.feval(String, Object[])

The first function 'eval' takes a string and evaluates it in the Matlab workspace.  Create a MatlabControl object and test this function as follows:

matlabControl = net.tinyos.matlab.MatlabControl
matlabControl.eval('x=255')
x

The last command illustrates that our 'eval' command actually created a variable 'x' and assigned it the value 255.

The second function 'feval' takes a string and an array of java.lang.Object.  The string must be a function name. Matlab will call this function as pass each element in the array of Objects as a parameter to this function.  For example

matlabControl.feval('help', {'plot', 'axis'})

will call matlab 'help' for 'plot' and 'axis'.

Note that MatlabControl or at least the object that creates MatlabControl must be instantiated from Matlab.  Since you can have many Matlab sessions running at once, this is the only way for MatlabControl to know which Matlab session it should control.

Example: Using MatlabControl with MIG

Recall that MIG is the Message Interface Generator.  It automatically generates Java 'Message' objects that correspond to TinyOS messages.  As data streams in on the serial port, MoteIF will give such Message objects to objects that implement the MessageListener interface.  MoteIF will also send Message objects to motes over the serial port.  

In this example, we will see how to use MoteIF to send data into Matlab instead of to a Java object.  From the Matlab command window, go to your matlab/doc/demo/ directory using a command like this one:

cd TINYOS/tools/matlab/doc/demo

where TINYOS is the location of your tinyos-1.x directory.  You should find a file called messageReceived.m.  This file defines a Matlab function called messageReceived, which is the function we want MoteIF to call whenever a new message is received.  Double-click it to open it in the Matlab editor.  Notice that it takes two arguments, address and message, just like the messageListener.java interface requires.  The body of the function simply prints the message to the screen.

Now, let's instantiate a Java Message object that will be used to parse the incoming data.  We will be getting data from OscilloscopeRF so we use

OscopeMsg = net.tinyos.oscope.OscopeMsg

Now, let's create a MoteIF object to receive data from our SerialForwarder (which should still be running from the previous section of the tutorial). 

mIF = net.tinyos.message.MoteIF('localhost', 9000, 125)

Normally we would register a Java object that implements the MessageListener interface with MoteIF.  Instead, let's instantiate a wrapper class called MatlabMessageListener which implements the MessageListener interface and then uses MatlabControl to call our Matlab function whenever a message is received.

ml = net.tinyos.matlab.MatlabMessageListener
ml.registerMessageListener('messageReceived')

Finally, let's register our messageListener to listen to OscopeMsg messages and start the MoteIF object

mIF.registerListener(OscopeMsg, ml)
mIF.start

You should see the packets printing to the screen.  You've essentially just created a new 1-line version of ForwarderListen.java! 

Now, put a break point in the messageReceived function by clicking to the left of line 3 in the Matlab editor.  A red dot should appear indicating a break point has been placed, and a green arrow should appear indicating that program control has reached the break point and stopped.  You are now in debug mode and the prompt in the Matlab command window should turn to a "K>>" to indicate that.  Turn your mote off so that you don't get any more packets while you are in debug mode.  Why do I need to turn my mote off?

From debug mode, type message to print the message contents to the screen.  Now, get the data out of the message with the following commands

id = message.get_sourceMoteID
sampleNumber = message.get_lastSampleNumber
channel = message.get_channel
dataReadings = message.get_data

Now, you have your sensor data in the Matlab workspace and you can start analyzing it using all the Matlab commands!   For example

plot(message.get_data)
hist(message.get_data)

Setting up your Matlab/Java environment

Step 1:  Change your Matlab path

You need to tell Matlab where your TinyOS tools are located.  Open Matlab, go to the "file" menu and choose "set path."   Click the "add with subfolders" button and choose your tinyos-1.x/tools/matlab/ directory.  click "save" and "close"

Step 2:  Change your Matlab classpath

You need to tell Matlab where your TinyOS Java tools are located.  Open Matlab and type the following command in the Matlab command window:

edit classpath.txt

The Matlab editor will open with the classath.txt file.  This file lists the directories where Matlab looks for the Java classes that it uses.  You need to add the directory of both your TinyOS Java tools and of your comm.jar file.  The resulting file should look something like this, where the bold lines are the ones you just added.   Save this file and then close and restart Matlab for your changes to take place.

Step 3:  Compile MatlabControl.java

The net.tinyos.matlab.MatlabControl class is needed to call matlab commands from Java.  When you compile it, you must have the .jar file C:\MATLAB\java\jar\jmi.jar in your CLASSPATH environment variable variable.  Once this is done, do the following:

cd ~/TINYOS/tools/java
javac net/tinyos/matlab/MatlabControl.java

Step 4 (optional):  Changing Matlab's JRE

Matlab comes with it's own JRE.  To maximize consistency with your TinyOS programming environment, replace Matlab's JRE with the one you usually use with TinyOS (probably1.3.1_01).  Execute the following two commands, where MATLAB and JAVA are the root directories of your matlab and java installations, respectively  (What if I don't want to do this?):

mv C:\MATLAB\sys\java\jre\win32\jre C:\MATLAB\sys\java\jre\win32\jreOld

cp C:\JAVA\jre C:\MATLAB\sys\java\jre\win32\jre

 

More Info

For the curious

For the advanced

For the beginner


Tutorial Index