Using NodeJS to develop a temperature server with the Raspberry Pi

The Raspbian Linux distribution for the Raspberry Pi includes some useful kernel drivers for accessing devices connected to the Pi’s GPIO pins. Based on the tutorial from the University of Cambridge Computer Laboratory I’ve been playing around with the DS18B20 digital thermometer on the Pi. I’ve connected the sensor to the Pi using a standard electronics breadboard and the excellent Adafruit Pi Cobbler breakout connector kit (kudos to Mills for her excellent soldering skills). When the required GPIO kernel modules are loaded a file containing sensor output is written to the /sys/bus directory (see tutorial link above for more) which contains the current thermometer reading.

Raspberry Pi & DS18B20

Raspberry Pi & DS18B20 digital thermometer

Developing with NodeJS

I originally wrote a Python CGI script as part of the CPC Pi Hack event to parse the sensor file and display the temperature on a web page (although we didn’t submit our hack in the end), but I’ve also been looking for a project for a while to try out NodeJS.The result is a prototype JavaScript server/client app to serve temperature from the Pi as a JSON string and display a graph of current temperature on the client.

This was my first NodeJS app and I was impressed with the speed of development and the readability of documentation/examples – so much so that I managed to write the bulk of the server on my netbook during a flight from Leeds to London! The biggest disadvantage of using NodeJS on the Pi is the time it takes to compile (1hr 58 minutes, Pi CPU clocked at 950MHz). While this may put some developers off, the build process was painless and is more than made up for by the efficient asynchronous nature of NodeJS once you get it running (first-pass testing shows no noticeable increase in memory/CPU when the server is under load although I’ve not investigated this thoroughly).

The server code is divided into two parts: a dynamic server response which is called when a request for the “temperature.json” URL is received. The server reads the sensor file, parses the data and returns the temperature with a Unix time-stamp in JSON notation. Here’s a snippet from the server code parsing and returning the temperature data:

// Read data from file (using fast node ASCII encoding).
var data = buffer.toString('ascii').split(" "); // Split by space

// Extract temperature from string and divide by 1000 to give celsius
var temp = parseFloat(data[data.length-1].split("=")[1])/1000.0;

// Round to one decimal place
temp = Math.round(temp * 10) / 10

// Add date/time to temperature
var jsonData = [Date.now(), temp];

// Return JSON data
response.writeHead(200, { "Content-type": "application/json" });
response.end(JSON.stringify(jsonData), "ascii");

The second section of the server uses the node-static module to serve a client-side page which performs an AJAX call for “temperature.json” and plots current temperature. The plot is created using the highcharts JavaScript package to create a dynamic graph which moves along the x-axis over time (check out the highcharts demo page to get a better idea of dynamic charts). One thing to note is that the sensor precision is ±0.5 °C, and while the temperature data is rounded to one decimal place, the default highcharts y-axis precision may be a bit misleading. Overall though the highcharts package is pretty slick, and the plot looks great on my new Nexus 7!

Temperature Plot

Raspberry Pi Temperature Sensor Plot

I’ve pushed the code to GitHub as it may be useful to others who are also new to the Pi and NodeJS. One of the features of NodeJS I like the most is the ease of testing and deployment – you can run the server right in the terminal window without super-user permissions and get debugging info straight away. Furthermore, given the ease of creating web-apps and the small resource footprint (obviously depending on what you’re doing) I’ll definitely be looking to use NodeJS/JavaScript as development platform for the Pi in the future.