Permalink
Branch: master
Find file Copy path
10a6333 Sep 27, 2013
1 contributor

Users who have contributed to this file

108 lines (83 sloc) 2.82 KB
#!/usr/bin/env python
#
# Bitbang'd SPI interface with an MCP3008 ADC device
# MCP3008 is 8-channel 10-bit analog to digital converter
# Connections are:
# CLK => 18
# DOUT => 23 (chip's data out, RPi's MISO)
# DIN => 24 (chip's data in, RPi's MOSI)
# CS => 25
import RPi.GPIO as GPIO
import time
import sys
CLK = 18
MISO = 23
MOSI = 24
CS = 25
def setupSpiPins(clkPin, misoPin, mosiPin, csPin):
''' Set all pins as an output except MISO (Master Input, Slave Output)'''
GPIO.setup(clkPin, GPIO.OUT)
GPIO.setup(misoPin, GPIO.IN)
GPIO.setup(mosiPin, GPIO.OUT)
GPIO.setup(csPin, GPIO.OUT)
def readAdc(channel, clkPin, misoPin, mosiPin, csPin):
if (channel < 0) or (channel > 7):
print "Invalid ADC Channel number, must be between [0,7]"
return -1
# Datasheet says chip select must be pulled high between conversions
GPIO.output(csPin, GPIO.HIGH)
# Start the read with both clock and chip select low
GPIO.output(csPin, GPIO.LOW)
GPIO.output(clkPin, GPIO.HIGH)
# read command is:
# start bit = 1
# single-ended comparison = 1 (vs. pseudo-differential)
# channel num bit 2
# channel num bit 1
# channel num bit 0 (LSB)
read_command = 0x18
read_command |= channel
sendBits(read_command, 5, clkPin, mosiPin)
adcValue = recvBits(12, clkPin, misoPin)
# Set chip select high to end the read
GPIO.output(csPin, GPIO.HIGH)
return adcValue
def sendBits(data, numBits, clkPin, mosiPin):
''' Sends 1 Byte or less of data'''
data <<= (8 - numBits)
for bit in range(numBits):
# Set RPi's output bit high or low depending on highest bit of data field
if data & 0x80:
GPIO.output(mosiPin, GPIO.HIGH)
else:
GPIO.output(mosiPin, GPIO.LOW)
# Advance data to the next bit
data <<= 1
# Pulse the clock pin HIGH then immediately low
GPIO.output(clkPin, GPIO.HIGH)
GPIO.output(clkPin, GPIO.LOW)
def recvBits(numBits, clkPin, misoPin):
'''Receives arbitrary number of bits'''
retVal = 0
for bit in range(numBits):
# Pulse clock pin
GPIO.output(clkPin, GPIO.HIGH)
GPIO.output(clkPin, GPIO.LOW)
# Read 1 data bit in
if GPIO.input(misoPin):
retVal |= 0x1
# Advance input to next bit
retVal <<= 1
# Divide by two to drop the NULL bit
return (retVal/2)
if __name__ == '__main__':
try:
GPIO.setmode(GPIO.BCM)
setupSpiPins(CLK, MISO, MOSI, CS)
while True:
val = readAdc(0, CLK, MISO, MOSI, CS)
print "ADC Result: ", str(val)
time.sleep(5)
except KeyboardInterrupt:
GPIO.cleanup()
sys.exit(0)