I’ve been tinkering with my Raspberry Pi for quite a few weeks now. It’s a great little thing. Like many, though, I’ve been a little frustrated with the lack of analogue inputs into the Pi. I was for a while using a barebones arduino to service serial comms from the Pi but this had it’s own limitations. (One day I’ll post the code I used for that on this blog!). Adafruit industries have been doing a great job of promoting the use of the Pi to hobbyists and showing examples of hardware control. One of these was to control the SPI controlled 8 channel ADC chip known as the MCP3008 from Microchip. Find it here!
In my naivety I thought that the control would be exactly the same for its 2 channel sibling, the MCP3002. I was wrong! It’s still an SPI chip and when I started to delve into the datasheets it was relatively straight forward to modify the code. I thought I’d post that here so others could make use of it. You’ll notice I haven’t changed the meat of the code and all credit goes to Adafruit for their hard work on which I build!
#!/usr/bin/env python # just some bitbang code for testing the 2 channels import RPi.GPIO as GPIO, time, os DEBUG = 1 GPIO.setmode(GPIO.BCM) # read SPI data from MCP3002 chip, 2 possible adc's (0 thru 1) def readadc(adcnum, clockpin, mosipin, misopin, cspin): if ((adcnum > 1) or (adcnum < 0)): return -1 if (adcnum == 0): commandout = 0x6 else: commandout = 0x7 GPIO.output(cspin, True) GPIO.output(clockpin, False) # start clock low GPIO.output(cspin, False) # bring CS low #commandout = 0x6 #start bit and 1, 0 to select single ended ch0 commandout <<= 5 # we only need to send 3 bits here for i in range(3): 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 # change these as desired SPICLK = 11 SPIMOSI = 9 SPIMISO = 10 SPICS = 18 # set up the SPI interface pins GPIO.setup(SPIMOSI, GPIO.OUT) GPIO.setup(SPIMISO, GPIO.IN) GPIO.setup(SPICLK, GPIO.OUT) GPIO.setup(SPICS, GPIO.OUT) adcnum = 0 # Note that bitbanging SPI is incredibly slow on the Pi as its not # a RTOS - reading the ADC takes about 30 ms (~30 samples per second) # which is awful for a microcontroller but better-than-nothing for Linux while True: print "------------" for adcnum in range(2): ret = readadc(adcnum, SPICLK, SPIMOSI, SPIMISO, SPICS) print adcnum, ": ",ret print "------------"