Goal / Turnin
In yesterday’s lab we learned how to use a serial connection to read data off a sensor. The goal of today’s lab is to learn how to use a socket connection. Whereas serial connections are essential for communicating with peripheral devices – ordinary peripherals like keyboard and mouse, as well as microcontrollers like Arduino – sockets are the basis of communication between computers, and hence the basis of the internet itself. Every time you connect to a website, your web browser is acting as a client, receiving data from and making requests to the server that’s providing the content you see. Indeed, sockets are so popular for communication that they are also used for controlling, and getting video from, many robot toys: the Parrot AR.Drone and the Brookstone Rover tank being just two examples.
In this lab you will learn how to use Python’s simple sockets library to send messages between computers. The lab will culminate with a remote sensing exercise, in which you will use your Arduino-based sensor code from yesterday’s lab to retrieve data from a sensor not directly connected to your computer. As with yesterday’s lab, you do not need to turn anything in; instead, you will demo each stage of your work to me, and then sign the sign-out sheet before leaving.
Part 1: Talk to yourself
I have written two simple socket programs, server,py and client,py, which your should now download (right-click / save-as) to your desktop. Their roles match their names: the server waits for a client to connect, and then allows you to send text messages to the client, which prints them out as it receives them. Although sockets readily support two-way communication between a server and multiple clients, this simple one-way communication to a single client is adequate to give you a feel for the power of sockets, especially their use in remote sensing.
As with yesterday’s lab, you will find it easier to run these programs from the command line in a terminal window. Typing
python3 server.py
will give you a brief instruction and example on how to use the server. As you’ll see, you’ll need to know your computer’s IP address to run this program. A good way to do this, that works on both Linux and Mac OS X, is to issue the ifconfig (interface-configuration) command in your terminal window. You’ll see several paragraphs of information scroll by, with cryptic interface names like enp2s0f0, followed by a line starting with inet, which precedes the IP address. Our IP addresses start with 137.113.118, but it is also worthwhile looking at the other addresses: addresses starting with 127 are reserved for “loopback” testing between the computer and itself, and addresses starting with 192 are for private networks, both of which you should ignore for this exercise.
Once you’ve got your computer’s IP address, you’ll also need to pick a port number on which to serve the socket connection. (If the IP address is like a phone number, the port is like an extension). Port numbers are arbitrary, but must be above a certain minimum, because low values are reserved for standard, always-on services (e.g., 25 is for the SMTP service behind email). So, as the example shows, you should use a big value like 20000. After launching the server, launch the client using the same IP address and port. You should now be able to type messages at the server’s prompt; hitting ENTER will cause the message be sent to and echoed in the client’s terminal.
The operating system gives your server programs exclusive access to the port you choose, which is held for a brief period if the program exits abnormally. So, if you have to restart the server and client, and you get a message that the port is unavailable, just use a higher one (20001, 20002, etc.)
Part 2: Talk to your friend
As you might have guessed, the next step is to send messages between computers. Have one member of your team run the server on one computer, and another member run the client on a different computer, with the client using the IP address of the server computer (like making a phone call, you call someone else’s number, not your own!)
Of course, you could just as easily use these programs to send messages across the world. For people who grew up with the internet, that may not seem like a big deal, but it would be worth a few minutes of your time now to simply look at the client and server code: with a few dozen lines of Python, you have the basis for an international communications network! Note the use of the string encode() method by the server, and the corresponding decode() method by the client. These methods are necessary because Python3 (unlike Python2) requires that all transmitted messages, including strings, be sent as byte arrays, rather than strings. So, if you’re ever working with serial or socket code in Python, and you get a weird message about encodings (or something else at the point where you’re trying to send, receive, or display your data), it’s probably an encoding issue resulting from old Python code being run under Python3.
Part 3: Talk to your sensor
This is a robotics class, not a networking class, so we’ll want to use our little client/server network for more than sending text messages: we want to get sensor telemetry from a robot! So, first copy sensor.py to a new script sensorerver.py. Then merge in your PyFirmata code from yesterday’ssensorlab.py so that instead of waiting for user input and sending it to the client, sensorserver.py reads data from your sensor and sends it as text messages. (You won’t need any of the RealtimePlotter stuff, but you will need the pyfirmata folder to be in the same location as sensorserver.py.)
Part 4: Go wireless!
Robots wouldn’t be much fun if they had to be connected to a computer over a wire (though I’m kinda relieved that this robot still seems to need one!) So, if we have time at the end (and the computers are behaving), we will attempt to create an ad-hoc wifi network to run our server – allowing us in principle to read its data using a smartphone, tablet, or other handheld device. For a real robot, we’d run the server on an inexpensive single-board computer like Raspberry Pi, which now comes with a wifi chip built in, for easy ad-hoc networking.
Extra Credit
For extra credit, merge the RealtimePlotter part of your serialsensor.py code into client.py, so that instead of just printing out the sensor values, the client displays them in real time.
Finishing Up
Once you’re done with all parts, please give me a demo, and have each of your team members sign the sign-out sheet to receive full credit for the lab.