4

I'm trying to control a digital potentiometer using RPi's SPI interface but for some reason it is failing, and I can't figure out why.

I have successfully controled the potentiometer by manually setting the CS, SCK and DataOut pins in the chip, but I'm trying now to use the SPI interface that automates all this process.

This is the code I have written:

import spidev
import time

spi = spidev.SpiDev()
spi.open(0, 0)
spi.max_speed_hz = 100000
spi.cshigh = False
#spi.loop = True
#spi.threewire = True
spi.mode = 0b00

try:
    for i in range(0, 50, 10):
        print "Write " + str(i) + " - ",
        resp = spi.xfer2([0x00, i])
        print "Read: " + str(len(resp)) + " " + str(resp[0]) + " " + str(resp[1])
        time.sleep(1)
finally:
    spi.close()

The former program shows this output when running but the LED doesn't light:

$ sudo python DigitalPot-SPI.py
Write 0 -  Read: 2 0 0
Write 10 -  Read: 2 0 0
Write 20 -  Read: 2 0 0
Write 30 -  Read: 2 0 0
Write 40 -  Read: 2 0 0

And this is how my circuit looks like:

RPi-SPI-MCP4131

In the MCP4131's datasheet this is the pin order I'm using (and I've used it successfully controlling the potentiometer manually):

MCP pin configuration

When I uncomment the line that reads spi.threewire = True the following happens to the console output (I wanted to uncomment it as the MCP4131 multiplexes its inputs and outputs):

$ sudo python DigitalPot-SPI.py
Write 0 -  Read: 2 0 0
Traceback (most recent call last):
  File "DigitalPot-SPI.py", line 17, in <module>
    time.sleep(1)
IOError: [Errno 22] Invalid argument

Any help will be appreciated.

  • I know this is old, but this post uses spidev to control a potentiometer in this family. – Hendy Jan 5 '18 at 4:47
2

The standard Linux driver does not support SPI 3-wire operation.

My pigpio library implements a basic 3-wire mode on the main SPI device (the auxiliary SPI device does not support 3-wire).

I have used the following code to control a MCP4131 digital pot.

#!/usr/bin/env python

# mcp4131.py
# 2016-01-06
# Public Domain

import time
import pigpio # http://abyz.me.uk/rpi/pigpio/python.html

INCPOT=0x04
DECPOT=0x08

# 00h Volatile Wiper 0 
#   Write Data 0000 00nn nnnn nnnn
#   Read Data  0000 11nn nnnn nnnn
#   Increment  0000 0100
#   Decrement  0000 1000

# 01h Volatile Wiper 1
#   Write Data 0001 00nn nnnn nnnn
#   Read Data  0001 11nn nnnn nnnn
#   Increment  0001 0100
#   Decrement  0001 1000

# 02h-03h Reserved

# 04h TCON
#   Write Data 0100 00nn nnnn nnnn
#   Read Data  0100 11nn nnnn nnnn

# 05h Status
#   Read Data  0101 11nn nnnn nnnn

# 06h-0Fh Reserved

# SPI open flags

W3=(1<<9) # select 3-wire operation
W3N1=(1<<10) # switch to miso after one byte
U0=(1<<5) # don't set CE0
U1=(1<<6) # don't set CE1

pi = pigpio.pi() # Connect to local Pi.

digpot_write = pi.spi_open(1, 2000000, U0|U1) # first SPI open
digpot_read  = pi.spi_open(1,  50000, W3|W3N1|U0|U1) # 3-wire write 1 then read
adc          = pi.spi_open(0, 2000000, U0|U1)

inc = True

potpos = 0

try:

   while True:

      pi.spi_write(digpot_write, [0, potpos])

      (b, d) = pi.spi_xfer(digpot_read, [0x0C, 0])
      if b == 2:
         rpos = d[1]
      else:
         rpos = -1

      (b, d) = pi.spi_xfer(adc, [1, 0x80, 0])
      if b == 3:
         c1 = d[1] & 0x0F
         c2 = d[2]
         ch0 = (c1<<8)+c2
      else:
         ch0 = -1

      (b, d) = pi.spi_xfer(adc, [1, 0xC0, 0])
      if b == 3:
         c1 = d[1] & 0x0F
         c2 = d[2]
         ch1 = (c1<<8)+c2
      else:
         ch1 = -1

      print("0={:4d} 1={:4d} pot={} ({})".format(ch0, ch1, potpos, rpos))

      if inc:
         potpos += 1
         if potpos > 129:
            inc = False
            potpos = 129
      else:
         potpos -= 1
         if potpos < 0:
            inc = True
            potpos = 0

      """
      if inc:
         cmd = DECPOT
      else:
         cmd = INCPOT

      (b, d) = pi.spi_xfer(digpot, [cmd])
      if b == 1:
         dp = d[0]
      else:
         dp = -1

      if ch1 > 4090:
         inc = False
      elif ch1 < 10:
         inc = True
      """

      time.sleep(0.05)

except:
   pi.spi_close(digpot_read)
   pi.spi_close(digpot_write)
   pi.spi_close(adc)
   pi.stop()
   print("closed handle and stopped ")

Also see https://www.raspberrypi.org/forums/viewtopic.php?f=44&t=84081&p=595260&hilit=mcp4131#p595260

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.