123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109 |
- #!/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 = 11
- MISO = 9
- MOSI = 10
- CS0 = 8
- CS1 = 7
- 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)
|