1

I started to try to read an MCP3008 ADC using SPI bit banging with pigpio. I wrote the unattractive little script below, starting from the example in the pigpio documentation and here is a screenshot of my output.

I believe that this should read the lowest four channels of the ADC and print the output. Channels 0 to 3 are connected to +5V, GND, +5V, floating, so I expected to see values like 1023, 0, 1023, xxx where the last would be noise.

Instead I see all 1023's.

Have I done something terribly wrong?

enter image description here

import pigpio
import time

CE1  = 2
MISO = 3
MOSI = 4
SCLK = 17

pi = pigpio.pi()

pi.bb_spi_open(CE1, MISO, MOSI, SCLK, 10000, 3)

nums = [128 + n for n in (16, 32, 48, 64)]
while True:
    print "wow!"
    for num in nums:
        print "num! ", num
        count, data = pi.bb_spi_xfer(CE1, [1, num, 0])

        print "count = ", count, data = [byte for byte in data]

        value = ((data[1]&3)<<8) | data[2]
        print "value = ", value
        time.sleep(1)

enter image description here

  • 1
    Try sending [1, 128+num, 0]. You might be in differential mode. – joan Jan 9 '18 at 9:11
  • @joan thanks, I'll give it a try in a bit (not near my pi at the moment). num already has a 128 in it already; nums = [128 + n for n in (16, 32, 48, 64)] so would the 2nd 128 wrap it back to zero, or cause a problem because it would then be greater than 256? I don't understand what "mode" actually means. I see that it is mentioned in the pigpio documentation. Maybe I should ask a separate question on that? – uhoh Jan 9 '18 at 9:40
  • 1
    My bad, I didn't notice nums, I read what I assumed to be there. For channels 0 to 3 you should use nums = [128 + n for n in (0, 1, 2, 3)]. Personally I'd just use for num in range(4): and [1, 128+num, 0] as I think it looks clearer. – joan Jan 9 '18 at 10:47
  • 1
    My bad again. I have just looked at my Python code and I use [1, (8+channel)<<4, 0]. Where channel is 0 to 3 for the channels you use. – joan Jan 9 '18 at 16:15
  • 1
    I also use value = ((data[1] << 8) | data[2]) & 0x3FF to calculate the returned value. – joan Jan 9 '18 at 16:18
1

Comments by @Joan (above) were extremely helpful! MCP3008 does indeed use mode=0, where I had it erroneously set to 3.

The following works very nicely!

import pigpio
import time

CS   = 2
MISO = 3
MOSI = 4
SCLK = 17
MODE = 0

pi = pigpio.pi()

pi.bb_spi_close(CS)  # because I use ctrl-C to break each time

pi.bb_spi_open(CS, MISO, MOSI, SCLK, 10000, MODE)

while True:
    for n in range(4):

        ct, data = pi.bb_spi_xfer(CS, [1, (8+n)<<4, 0])

        val  = ((data[1]<<8) | data[2]) & 0x3FF

        print (n, ct, val, "data=", [byte for byte in data] )

    time.sleep(1)
  • @joan works like a charm, yippee! – uhoh Jan 9 '18 at 23:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.