Introduction: Spark.io Remote Serial Port

About: Hackerspace Budapest

The Spark.io Remote Serial port (SpaReS) can be used for a variety of tasks at a lab, office or home. It connects a device with a serial port to the local network or the internet using TCP/IP. Serial ports are present on lots of devices, it was even used on PCs 15 years ago for connecting modems and mice. Its design is really simple, thus it's still present on devices designed for simple integration by tinkerers or for engineering purposes.

Since the Spark.io uses Wi-Fi, this way, even an Android device that normally doesn't have a physical serial port exposed can be used to debug devices that have a serial port, so you don't have to open your laptop just for that. It can also expose a console interface for things that are hard to access (for example a beamer or TV mounted on the ceiling or wall).

The Spark.io has two serial ports, one is exposed on the RX/TX pins (USART), while the other is exposed over the USB interface, and acts as a USB-serial interface to the PC (/dev/ttyACMx under Linux).

Step 1: Firmware

The firmware that runs on the Spark.io can be found in our GitHub repository, for most purposes, this can be used directly, but if you'd like, feel free to customize it, you can even publish or sell your version, since it's under MIT license.

The simplest way is to copy the source code from GitHub into the web IDE, follow the instructions on the Spark.io documentation to claim your device and register an account if you don't have one already.

If you're using the command line version, use the compile and flash commands to compile the firmware and flash to the device, or you can download a precompiled firmware from our GitHub releases page.

$ wget https://github.com/hsbp/spares/releases/download/v1.0/spares-firmware-v1.0.bin

$ spark flash your-device-name spares-firmware-v1.0.bin

If you've done everything correctly, after the Spark.io boots up, the LED should be solid (not flashing) red, which means it's waiting for an incoming connection.

Step 2: (optional) Add a Level Shifter

The Spark.io uses 3.3 volts signals, which means it's serial lines (RX/TX pins) uses 3.3 volts as "1" or mark and 0 volts (ground) as "0" or space. You can connect the serial port directly to any device that uses these same voltages (for example, a Raspberry Pi), but many devices (especially the ones using a DB-9 connector) use the RS-232 standard, which is quite different. In case of latter, +12 and -12 volts are used, and connecting such voltages can damage your Spark.io, so in case of doubt, use a volts meter to check before connecting.

If your device uses RS-232, you can still use a Spark.io, but you have to include a simple level converter that "translates" between the two standards. These can be bought in various formats, and usually consist of a single chip, sometimes accompanied with 4 small capacitors.

You can find instructions, datasheets and links to buy such parts at the relevant embedded Linux page.

Step 3: Connect the Port

Now that either the device matches the voltages of the Spark.io or you've added a level converter, the serial lines can be connected to the Spark.io. First, connect the ground (GND) of the two devices, this is the only line that needs to be connected regardless the configuration.

The other two lines are used for sending data in each direction, and while most people use both, you are free to connect only one, if you only need to send or receive data, but not both. You can also connect the RX and TX signal together for testing, this is called a loopback, and should result in the send data being sent back immediately.

Don't forget that you have to match the data lines, so the receive (RX) line of the device must be connected of the transmit (TX) line of the Spark.io and vice versa.

Step 4: Set Up the Client

Now that you have the hardware in place, first you'll need to get the IP address of the device. This can be done in a number of ways, the easiest is to use the Spark CLI, replace XXX with your device name:

$ spark variable get XXX local_ip
C0A80169

Alternatively, if you have an access token, you can use cURL (usually
installed by default on Linux, OS X and other Unix-like systems). You can get your access token in the web IDE by selecting the gear icon in the bottom left corner (Settings).

$ curl "https://api.spark.io/v1/devices/XXX/local_ip/?access_token=YYY"
{ "cmd": "VarReturn", "name": "local_ip", "result": "C0A80169", "coreInfo": { "last_app": "", "last_heard": "2014-12-28T10:18:03.802Z", "connected": true, "deviceID": "XXX" } }

The IP address is encoded as 8 hexadecimal characters, the two client apps accept it either in this form, or you can decode it by a calculator.

On Unix-like systems, Python is usually installed, and you can use the Python client from a terminal. Just download the script from the GitHub repository and launch it from a terminal. (No external dependencies are required, everything is included in the Python standard libraries.)

$ python spares.py -h
usage: spares.py [-h] host baudrate {usb,usart}

Connects to a Spark.io Remote Serial port

positional arguments: host IP address (can be in hex) or host name baudrate baud rate (300 .. 115200) {usb,usart} serial port on the device (usart: RX/TX pins)

optional arguments: -h, --help show this help message and exit

$ python spares.py C0A80169 9600 usb
Connected, press ^C or ^D to terminate the connection.

On Android, just enable installing applications from external sources, and install the APK from the GitHub release or the QR code in the images section.

Upon opening the app, enter the 8-digit hexadecimal or normal IP address, you can also use a host name. The serial port and baud rate can be selected from dropdown lists (spinners), and clicking on the Connect button displays a new window.

With any client, the Spark.io light will go orange when connection is established and then green or yellow when it becomes usable, depending on the port used (USB or USART, respectively). In the Python terminal, just type and the keystrokes are sent immediately; on Android, type in the top right field, and press the top left button to send it. The dropdown list (spinner) between the button and the field can be used to switch between different modes.

- In text mode, the contents of the field is sent as-is (accented
characters are encoded in UTF-8), optionally with postfix character(s)

- In hex mode, two-digit hexadecimal chunks are sent as bytes, so you can either use no spaces (414243), spaces (41 42 43) or any other separator (41:42,43).

With both clients, received data will be displayed on the screen, in case of Android, non-printable characters will be printed in hexadecimal, prefixed with [HEX].