Introduction: Orange Pi One Analog Devices Using MCP3008 Via SPI

Here's how to use analog devices with your Orange Pi One.

These devices are designed to work with an Arduino, as it has analog inputs but using an MCP3008 analog to digital converter chip, we can use these on the Pi.

I currently use this for getting readings from an LDR (photocell) to measure light levels and a resistive soil sensor to measure soil moisture. but should work most analog devices.

Step 1: Wire Up the Mcp3008 Chip

Check out the very good tutorial from rasberry pi spy here:

http://www.raspberrypi-spy.co.uk/2013/10/analogue-...

This will show you how to wire up the chip, its basically pins 1&2 to 3.3v, pins 2 & 8 goto ground and the other 4 connect to the SPI pins on the GPIO. You then have 8 analog channels to play with.

(i'm pretty sure you don't have to enable the SPI interface on the orange pi but I may be wrong. I spent alot of time trying to get this to work so I may have forgotten a step!)

Step 2: Install the Library

In order to read from the A/D converter you will need the library: SPI-Pi (the pyA20's SPI didn't work for me)

its best to do this from your home directory:

cd /home/pi

First lets update and make sure python dev is installed:

sudo apt-get update
sudo apt-get install python-dev

Then to get the library type:

git clone https://github.com/lthiery/SPI-Py
cd SPI-Py

and finally:

sudo python setup.py install

That's the library installed.

Step 3: The Code

The code is pretty much the same as the tutorial, the changes needed were the way the SPI bus is opened and the function that reads and writes to the chip.

So create a file spi_test.py:

#!/usr/bin/python
import spi
import time
import os
 
# Open SPI bus
status = spi.openSPI(speed=1000000)
 
# Function to read SPI data from MCP3008 chip
# Channel must be an integer 0-7
def ReadChannel(channel):
  adc = spi.transfer((1,(8+channel)<<4,0))
  data = ((adc[1]&3) << 8) + adc[2]
  return data
 
# Function to convert data to voltage level,
# rounded to specified number of decimal places.
def ConvertVolts(data,places):
  volts = (data * 3.3) / float(1023)
  volts = round(volts,places)
  return volts
 
# Function to calculate temperature from
# TMP36 data, rounded to specified
# number of decimal places.
def ConvertTemp(data,places):
 
  # ADC Value
  # (approx)  Temp  Volts
  #    0      -50    0.00
  #   78      -25    0.25
  #  155        0    0.50
  #  233       25    0.75
  #  310       50    1.00
  #  465      100    1.50
  #  775      200    2.50
  # 1023      280    3.30
 
  temp = ((data * 330)/float(1023))-50
  temp = round(temp,places)
  return temp
 
# Define sensor channels
light_channel = 0
temp_channel  = 1
 
# Define delay between readings
delay = 5
 
while True:
 
  # Read the light sensor data
  light_level = ReadChannel(light_channel)
  light_volts = ConvertVolts(light_level,2)
 
  # Read the temperature sensor data
  temp_level = ReadChannel(temp_channel)
  temp_volts = ConvertVolts(temp_level,2)
  temp       = ConvertTemp(temp_level,2)
 
  # Print out results
  print "--------------------------------------------"
  print("Light: {} ({}V)".format(light_level,light_volts))
  print("Temp : {} ({}V) {} deg C".format(temp_level,temp_volts,temp))
 
  # Wait before repeating loop
  time.sleep(delay) 

To run it type:

sudo python spi_test.py

All credit goes to Matt @ raspberry pi spy & Louis Thiery for the SPI-Py Library