# Connecting two Raspberry Pi's using MathLink

Posted 5 years ago
7770 Views
|
2 Replies
|
3 Total Likes
|
 This post explains how you can use MathLink to connect two Raspberry Pi's together and evaluate Wolfram Language commands remotely.For this experiment you will need:Two Raspberry Pi's, connected to the internet.The first step is to set up passwordless ssh between your RPi's, so that the Wolfram Language can set up an automated connection without the need for entering passwords. To set up passwordless ssh, evaluate the following command in a terminal shell (don't type the 'my-pi>'):my-pi> ssh-keygenHit enter as needed to accept all the prompted defaults. This command will create a .ssh subdirectory in your home directory. Change into that directory:my-pi> cd .sshAnd then authorize your public key by copying it to a file called 'authorized_keys':my-pi> scp id_rsa authorized_keysNext you will need to copy this entire  directory to the second Raspberry Pi:my-pi> cd ~my-pi> scp -r .ssh pi@my-other-pi.example.com:/home/piFor this 'scp' command you will still need to enter your password, but after this you should be able to use 'ssh' and 'scp' without entering your password. In my case I use a machine called 'demo-pi' as the first machine and 'test-pi' as the second machine:pi@demo-pi ~ $ssh test-piLinux test-pi 3.10.25+ #622 PREEMPT Fri Jan 3 18:41:00 GMT 2014 armv6lThe programs included with the Debian GNU/Linux system are free software;the exact distribution terms for each program are described in theindividual files in /usr/share/doc/*/copyright.Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extentpermitted by applicable law.pi@test-pi ~$Exit your remote pi shell. Now, we can work on the Wolfram Language code to make a MathLink connection. Here is the code, explained line by line:link = LinkCreate[LinkProtocol->"TCPIP"];This sets up a MathLink connection end point on the local machine. The protocol is TCPIP which means that it uses the network. Next we need to create the end point on the remote machine.linkname = First[link];This extracts the linkname from the link object. It is passed to the remote machine.process = StartProcess[ $SystemShell ];This launches a local system shell that we can feed shell commands to.WriteLine[ process, "/usr/bin/ssh pi@test-pi.wri.wolfram.com /usr/bin/wolfram -mathlink -linkmode connect -linkprotocol tcpip -linkname "<>linkname<>" -subkernel -noinit &" ];This is a shell command which launches the Wolfram Engine on the remote machine. Again we use TCPIP as the link protocol, so the connection will be on the network.Attributes[PiEvaluate]={HoldAllComplete};PiEvaluate[e_]:=(LinkWrite[link,Unevaluated[e]];First[LinkRead[link]]);This is utility function which takes an expression 'e' and sends it to the other Raspberry Pi to be evaluated.LinkWrite[link,"hi"]; LinkRead[link]; LinkRead[link];This line is to test out the connection. The extra LinkRead is to read the first InputNamePacket (which the remote machine always writes to the link).Here is the full code, change 'test-pi.wri.wolfram.com' to your actual remote machine name and save it under 'connect.m':link = LinkCreate[LinkProtocol->"TCPIP"];linkname = First[link];process = StartProcess[$SystemShell ];WriteLine[ process, "/usr/bin/ssh pi@test-pi.wri.wolfram.com /usr/bin/wolfram -mathlink -linkmode connect -linkprotocol tcpip -linkname "<>linkname<>" -subkernel -noinit &" ];Attributes[PiEvaluate]={HoldAllComplete};PiEvaluate[e_]:=(LinkWrite[link,Unevaluated[e]];First[LinkRead[link]]);LinkWrite[link,"hi"]; LinkRead[link]; LinkRead[link];We can now launch the Wolfram Language engine and load the 'connect.m' package:pi@demo-pi ~ $wolframWolfram Language (Raspberry Pi Pilot Release)Copyright 1988-2014 Wolfram ResearchInformation & help: wolfram.com/raspiIn[1]:= Get["connect.m"]In[2]:=After a few seconds (it blocks until the remote engine has started and is connected) you will be able to use the PiEvaluate command. A simple test is to remotely evaluate$MachineName, which should return the name of the remote machine:In[2]:= PiEvaluate[$MachineName]Out[2]= test-piIn[3]:=$MachineNameOut[3]= demo-piIn[4]:= $MachineName != PiEvaluate[$MachineName]Out[4]= True
2 Replies
Sort By:
Posted 5 years ago
 Very nice... thanks. You may want to edit your post to ensure that you consistently use "RemoteEvaluate" or "PiEvaluate"  (I prefer "RemoteEvaluate").-Joe