Interface and Application Programming

This involved a lot of walking around. Unfortuniately it was also cold this week. Working with GPS devices is more of a summer project.

This week I wanted to learn about node.js and javascript. I've also never used python, but I'm getting to learn that a little bit through the machine building project. node.js was easy to get set up. The packages that we like to use are serialport to talk to the embedded device through a serial port (via the FTDI cable) and web sockets to talk to a html page that serves as the GUI.

An important thing to figure out for this week is JSON which is used to pass data from the node.js script to the website. JSON is quite powerful an can be used to pass many parameters at the same time.

I wanted to continue playing with my GPS module. For my GUI I used the mapbox.js API which is a powerful toolset for making really nice and powerful maps online.

Writing the Program

The most difficult part of writing the program was passing the latitude and longitude from the embedded program to the node.js script. Latitude and Longitude are represented either as 32 bit fixed intergers or 32 bit floats (which can be in a dddmm.mmm or ddd.ddddd format!). The mapping software likes to work with decimal degrees (ddd.ddddd) so I figured I would figure out how to pass floating point values. I'm using some Arduino libaries on the embedded side of things, so I passed the data from the embedded processor by pretending that the float was just four characters in a row that were passed along, after framing bytes of 0x01 0x02 0x03 and 0x04.

// framing Serial.write((byte)1); Serial.write((byte)2); Serial.write((byte)3); Serial.write((byte)4); // send floats as 4 characters unsigned char *c = reinterpret_cast<unsigned char *>(&GPSbuffer[LAT]); Serial.write(c, 4); c = reinterpret_cast<unsigned char *>(&GPSbuffer[LON]); Serial.write(c, 4);

I could then have my node.js script read the buffer of characters as a floating point value (after it confirmed that the first four bytes were the framing bytes). It took a bit of thinking and experimenting to figure out that the data was being passed as little endian.

if ((data[0] == 1) & (data[1] == 2) & (data[2] == 3) & (data[3] == 4)) { lat = data.readFloatLE(4) lon = data.readFloatLE(8) }

This data could then be passed to the website GUI using the stringify function

ws.send(JSON.stringify({ lat: lat.toFixed(6), lon: lon.toFixed(6)}))

On the receiving end it's as simple as calling received = JSON.parse(dataIn) on the received data and then accessing and received.lon to make something fun happen.

Walking Around

To test my code I had to walk around the neighbourhood with my laptop and GPS device.

My application has a marker at your current location, and records a track of the path you have followed.

Interface Screen Capture

And here is a video of the interface for the entire walk around the block sped up 30x:

embedded GPSserial.ino
node.js gps.js
GUI gps.htm