mcp3008BitBang.py 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. #!/usr/bin/env python
  2. #
  3. # Bitbang'd SPI interface with an MCP3008 ADC device
  4. # MCP3008 is 8-channel 10-bit analog to digital converter
  5. # Connections are:
  6. # CLK => 18
  7. # DOUT => 23 (chip's data out, RPi's MISO)
  8. # DIN => 24 (chip's data in, RPi's MOSI)
  9. # CS => 25
  10. import RPi.GPIO as GPIO
  11. import time
  12. import sys
  13. CLK = 23
  14. MISO = 21
  15. MOSI = 19
  16. CS0 = 24
  17. CS1 = 26
  18. def setupSpiPins(clkPin, misoPin, mosiPin, csPin):
  19. ''' Set all pins as an output except MISO (Master Input, Slave Output)'''
  20. GPIO.setup(clkPin, GPIO.OUT)
  21. GPIO.setup(misoPin, GPIO.IN)
  22. GPIO.setup(mosiPin, GPIO.OUT)
  23. GPIO.setup(csPin, GPIO.OUT)
  24. def readAdc(channel, clkPin, misoPin, mosiPin, csPin):
  25. if (channel < 0) or (channel > 7):
  26. print("Invalid ADC Channel number, must be between [0,7]")
  27. return -1
  28. # Datasheet says chip select must be pulled high between conversions
  29. GPIO.output(csPin, GPIO.HIGH)
  30. # Start the read with both clock and chip select low
  31. GPIO.output(csPin, GPIO.LOW)
  32. GPIO.output(clkPin, GPIO.HIGH)
  33. # read command is:
  34. # start bit = 1
  35. # single-ended comparison = 1 (vs. pseudo-differential)
  36. # channel num bit 2
  37. # channel num bit 1
  38. # channel num bit 0 (LSB)
  39. read_command = 0x18
  40. read_command |= channel
  41. sendBits(read_command, 5, clkPin, mosiPin)
  42. adcValue = recvBits(12, clkPin, misoPin)
  43. # Set chip select high to end the read
  44. GPIO.output(csPin, GPIO.HIGH)
  45. return adcValue
  46. def sendBits(data, numBits, clkPin, mosiPin):
  47. ''' Sends 1 Byte or less of data'''
  48. data <<= (8 - numBits)
  49. for bit in range(numBits):
  50. # Set RPi's output bit high or low depending on highest bit of data field
  51. if data & 0x80:
  52. GPIO.output(mosiPin, GPIO.HIGH)
  53. else:
  54. GPIO.output(mosiPin, GPIO.LOW)
  55. # Advance data to the next bit
  56. data <<= 1
  57. # Pulse the clock pin HIGH then immediately low
  58. GPIO.output(clkPin, GPIO.HIGH)
  59. GPIO.output(clkPin, GPIO.LOW)
  60. def recvBits(numBits, clkPin, misoPin):
  61. '''Receives arbitrary number of bits'''
  62. retVal = 0
  63. for bit in range(numBits):
  64. # Pulse clock pin
  65. GPIO.output(clkPin, GPIO.HIGH)
  66. GPIO.output(clkPin, GPIO.LOW)
  67. # Read 1 data bit in
  68. if GPIO.input(misoPin):
  69. retVal |= 0x1
  70. # Advance input to next bit
  71. retVal <<= 1
  72. # Divide by two to drop the NULL bit
  73. return (retVal/2)
  74. if __name__ == '__main__':
  75. try:
  76. GPIO.setmode(GPIO.BOARD)
  77. setupSpiPins(CLK, MISO, MOSI, CS0)
  78. while True:
  79. val = readAdc(0, CLK, MISO, MOSI, CS0)
  80. print("ADC Result: ", str(val))
  81. time.sleep(.3)
  82. except KeyboardInterrupt:
  83. GPIO.cleanup()
  84. sys.exit(0)