The power of the Raspberry Pi

and the flexibility of the plot.ly API

make for fun weekend projects!

Having heard amazing things about the Raspberry Pi platform, I have been meaning to tinker with it for the longest time – and one weekend I did…

Overview

The Raspberry Pi is an awesome piece of hardware that’s great for rapid prototyping and hardware development. Using this platform, I created a real-time temperature sensor and wrote a Python front-end to plot temperature readings to a plot.ly web interface. Check out the real-time graphs here.

The code to make the magic happen is detailed below:

First, create a config.json file to hold your plot.ly credentials, like so:
{
"plotly_streaming_tokens": ["your_stream_token", "another_stream_token"],
"plotly_api_key": "api_key",
"plotly_username": "username"
}

Then install the necessary packages and dependencies on your Pi:
sudo apt-get install python-dev
wget https://bitbucket.org/pypa/setuptools/raw/bootstrap/ez_setup.py -O - | sudo python
sudo easy_install -U distribute
sudo apt-get install python-pip
sudo pip install rpi.gpio
sudo pip install plotly

The two scripts that are responsible for interfacing with the hardware are tmp36.py and readadc.py. tmp36.py is where all the fun happens and readadc.pyis a helper script that tmp36.py will use to poll for analog data from the MCP3008.

The readadc.py script is below:
import RPi.GPIO as GPIO
# change these as desired - they're the pins connected from the
# SPI port on the ADC to the GPIO Pins on the Raspi
#
# MCP3008 to Raspi (PiCobbler) Pin connections
class PINS:
SPICLK = 18
SPIMISO = 23
SPIMOSI = 24
SPICS = 25
#
# set up the SPI interface pins
def initialize():
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
GPIO.setup(PINS.SPIMOSI, GPIO.OUT)
GPIO.setup(PINS.SPIMISO, GPIO.IN)
GPIO.setup(PINS.SPICLK, GPIO.OUT)
GPIO.setup(PINS.SPICS, GPIO.OUT)
#
# Function to read data from Analog Pin 0 from MCP3008 (don't need to edit)
# This function will be called in our loop to get the current sensor value
def readadc(adcnum, clockpin, mosipin, misopin, cspin):
if ((adcnum > 7) or (adcnum < 0)):
return -1
GPIO.output(cspin, True)
#
GPIO.output(clockpin, False) # start clock low
GPIO.output(cspin, False) # bring CS low
#
commandout = adcnum
commandout |= 0x18 # start bit + single-ended bit
commandout <<= 3 # we only need to send 5 bits here
for i in range(5):
if (commandout & 0x80):
GPIO.output(mosipin, True)
else:
GPIO.output(mosipin, False)
commandout <<= 1
GPIO.output(clockpin, True)
GPIO.output(clockpin, False)
#
adcout = 0
# read in one empty bit, one null bit and 10 ADC bits
for i in range(12):
GPIO.output(clockpin, True)
GPIO.output(clockpin, False)
adcout <<= 1
if (GPIO.input(misopin)):
adcout |= 0x1
#
GPIO.output(cspin, True)
#
adcout /= 2 # first bit is 'null' so drop it
return adcout

The temp36.py script is below:
import plotly.plotly as py
import json
import time
import readadc
import datetime
#
with open('./config.json') as config_file:
plotly_user_config = json.load(config_file)
#
py.sign_in(plotly_user_config["plotly_username"], plotly_user_config["plotly_api_key"])
#
url = py.plot([
{
'x': [], 'y': [], 'type': 'scatter',
'stream': {
'token': plotly_user_config['plotly_streaming_tokens'][0],
'maxpoints': 200
}
}], filename='Raspberry Pi Streaming Example Values')
#
print "View your streaming graph here: ", url
#
# temperature sensor middle pin connected channel 0 of mcp3008
sensor_pin = 0
readadc.initialize()
#
stream = py.Stream(plotly_user_config['plotly_streaming_tokens'][0])
stream.open()
#
#the main sensor reading and plotting loop
while True:
sensor_data = readadc.readadc(sensor_pin,
readadc.PINS.SPICLK,
readadc.PINS.SPIMOSI,
readadc.PINS.SPIMISO,
readadc.PINS.SPICS)
millivolts = sensor_data * (3300.0 / 1024.0)
# 10 mv per degree
temp_C = ((millivolts - 100.0) / 10.0) - 40.0
# convert celsius to fahrenheit
temp_F = (temp_C * 9.0 / 5.0) + 32
# remove decimal point from millivolts
millivolts = "%d" % millivolts
# show only one decimal place for temprature and voltage readings
temp_C = "%.1f" % temp_C
temp_F = "%.1f" % temp_F
# write the data to plotly
stream.write({'x': datetime.datetime.now(), 'y': temp_C})
# delay between stream posts
time.sleep(0.25)