It's very easy to have Mathematica send data through the serial port, where Arduino and Mathematica can be linked.

There is this wonderful Mathematica package by Rob Raguet-Schofield called SerialIO that probably uses MathLink technology to provide Mathematica functions that can read, write and poll the serial port of your PC. It has not only the MS-Windows version, but also the Linux and the MacOS version as well. This can be a bit tricky to get working on MacOS. See this blog post.

In addiction to using the "SerialIO" package, you can access the serial port in another way on MS-Windows PC, provided that you have installed Microsoft .NET framework 2.0 or higher. The .NET framework (sort of like a Java virtual machine) can be freely downloaded from the Microsoft website. It has included a SerialPort type/component which then can be accessed in Mathematica via the magic spell called .NET/Link technology.

The Mathematica code for the serial port becomes really easy:

Needs["NETLink`"]
InstallNET[];

(* if this command shows the SerialPort informatins, you are on the right track *)
NETTypeInfo["System.IO.Ports.SerialPort"]

(* assuming your Arduino board appears as virtual port COM9, change it accordingly *)
ser = NETNew["System.IO.Ports.SerialPort", "COM9"]
ser@Open[]

You can certainly do "ser@ReadChar[]" after that, or use event driven method:

myEventFn[sender_, evt_] := (j = ser@ReadChar[])
AddEventHandler[ser@DataReceived, myEventFn]

If you have Mathematica 6.0, "Dynamic[j]" will give you updated value from the serial port whenever it's sent by Arduino's firmware. Thus, Arduino can become an external sensor or controller for the Mathematica program.

To write to Arduino, simply use "ser@Write[]" method. However if you simply type "ser@Write[FromCharacterCode[{254,1}]]", Arduino won't receive the byte <254>.

That's because the byte <254> was beyond the normal ASCII character range, and the SerialPort component encodes it differently. The trick is to use another form of the Write function, i.e. sending the bytes directly instead of as ASCII characters. For example

ser@Write[MakeNETObject[{254, 254}, "System.Byte[]"], 0, 2]

At last, a good habit to close the serial port after your experiment.

ser@Close[]

Share