Arduino + Network + Bash (Eye-to-Eye, Part 3)

This is Part 3 of my “Eye-to-Eye” adventure: figuring out how the Arduino network shield works, and how to interface with it from the OpenGazer program I discussed previously.

Arduino + Network Shield

As it turns out, the example sketch ChatServer provided with the Arduino library already provides a very good starting point. All I needed was to hook up the Arduino shield to the network, load up the library and I could already telnet into the shield and see my output. Those from the old school of telnet recognize that “echo” is on, and thus you’ll see double characters in your terminal as you type. Ah, memories: unset localecho.

Anyway, this is what the setup looks like in real life:

That’s the easy part.

Opengazer Output to the Network?

The hard part is what to do with Opengazer. Opengazer outputs coordinates in two different ways: to the standard output and through the network using UDP on port 20320. Hmm.. network. I looked in the source code how to define the destination IP address, but it is hardcoded, and I *really* don’t want to recompile it (the target IP *should be* in a config file somewhere, but I digress). Besides, the point is to use Opengazer as is and maybe we can substitute it for some other service later.

But wait! Everything in unix is a file, right? What if I could redirect stdout to the network? Turns out, I can. I’ve always been wary of redirection (other than just the standard >), so I found this handy tutorial on bash network programming. Side note: I’ve been working with linux for a number of years now, and every time I roll up my sleeves, I am blown away by some feature I never knew about (previously, the screen command blew my mind).

So to redirect any output to the network, all we have to do is create a new file descriptor that points to the TCP ip/port of my Arduino, and start outputting stuff to the new descriptor, like so:

exec 3<> /dev/tcp/192.168.0.102/23
echo "123 456 789" 1>&3 #watch the Arduino Serial Monitor! COOL!
cat /etc/hosts 1>&3
cat ~/Documents/war_and_peace.txt 1>&3 #kidding!
exec 3<&- #terminate the connection

To output code to the network from Opengazer, I simply run it and point its output to that IP address. Opengazer outputs three sets of numbers to stdout in the following format:

X Y -> SCREEN_ANCHOR

In order to make my Arduino code more portable and easier to write, I removed the "->" with sed, right from the command line before outputting it to the network:

./opengazer | sed 's/-> //g' 1>&3

And voila, Opengazer's output goes to my device as three integers, separated by spaces, sets separated by newlines (I should note, I haven't actually done this yet, that part comes later)

Finally, to make my Arduino code more portable, I accept any three numbers in sequence, whether they're separated by newline, return carriage or space, where the first number is the X coordinate, the second number is the Y coordinate, and third number is the screen anchor position. This is my first stab at it in a somewhat unfamiliar language (you can thank years of corporate development in higher level languages, for better or for worse) - download the sketch.

That's it for Part 3. In part 4, I will try to get Opengazer to communicate directly with my Arduino (there will be some challenges there I can foresee) and maybe even hook up some servos.

Leave a Reply