jordan314
Posts: 15
Joined: Fri Feb 08, 2013 10:06 pm

Trouble connecting to the MCP4131

Sat Feb 04, 2017 7:54 am

Hi,
I'm having a heck of a time connecting to a MCP4131 via SPI with a raspberry pi 3. I can connect to it fine with an arduino, the code is simple:

Code: Select all

digitalWrite(CSPIN, LOW);
SPI.transfer(0x00);
SPI.transfer(50); //number between 0 and 127
digitalWrite(CSPIN, HIGH);
The MCP4131 expects 16 bytes: 6 bytes of 0s: 0000 for the address of the wiper, 00 for the write command, and then 10 bytes of data.
I've tried the wiringPi library in C, the broadcom C library, and the spidev python library, but whenever I run them, the wiper pin to ground on the MCP4131 stays at 2.4V no matter what value I send. I'm providing 5V to the chip but using a 3.3V to 5V logic level converter to connect to the SPI pins and the pi.
Here is the python code:

Code: Select all

import spidev
import time

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

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

I can provide the broadcom or wiringPi code I'm using too. But given that all three aren't working, I think I have either the wiring set up wrong or something wrong in the pi. I don't have SPI disabled in /etc/modprobe.d/raspi-blacklist.conf and I have SPI enabled in the raspberry pi config. If I run lsmod | grep spi I see: spi_bcm2835 6678 0 . I can't run 'gpio load spi' because of a device tree error, but I've read that's ok, that it's already loaded. ls /dev/*spi* shows me /dev/spidev0.0 /dev/spidev0.1.

When I run my code and test the CS0 pin with my multimeter, it seems to stay at 3.3v. So I'm not sure if the SPI driver's not working or if my multimeter is too slow to see it go low and then high.
Also, the MCP4131 has a multiplexed SDO/SDIN pin, which I've tried connecting only to MOSI and to both MOSI and MISO. It doesn't seem to make a difference.
Does anyone have any ideas on how to get this working?

User avatar
joan
Posts: 14093
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: Trouble connecting to the MCP4131

Sat Feb 04, 2017 8:57 am

I guess your wiring is wrong. See viewtopic.php?p=595165#p595165

Here is some code which reads and writes the chip. It also monitors the output by feeding it into an ADC. It's an example only.

Code: Select all

#!/usr/bin/env python

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

import time
import pigpio # http://abyz.co.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 ")

jordan314
Posts: 15
Joined: Fri Feb 08, 2013 10:06 pm

Re: Trouble connecting to the MCP4131

Sat Feb 04, 2017 10:46 am

Thanks! I'll give that a shot. It's not the length of my wires is it? I'm using 6" female to female connected to 6" male to male jumper wires to get to the LLC, and then another 6" to get to the chip, so 18" total. The voltage drops from 5V to 4.7V at the chip, but that should still be enough to power it.

User avatar
joan
Posts: 14093
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: Trouble connecting to the MCP4131

Sat Feb 04, 2017 11:02 am

I doubt it's the length of the wires. A photo of your connections would be useful.

jordan314
Posts: 15
Joined: Fri Feb 08, 2013 10:06 pm

Re: Trouble connecting to the MCP4131

Sat Feb 04, 2017 12:26 pm

Thanks Joan!
Ok it must be my wiring because I tried your code, I see it cycling through but the voltage on the wiper output is still always 2.4.
Here are some photos, but it's a mess:
http://imgur.com/a/CTlsz
Here is my circuit, I have two MCP4131s and two Sparkfun BOB-12009 logic level converters: https://www.sparkfun.com/products/12009

The BOB LLCs need a 5V and 3.3V reference and ground to convert the signals.
Pi 3.3 VDC to 3.3v breadboard rail. 3.3v Breadboard rail to LV pin on both BOBs.
Pi 5 VDC to 5v breadboard rail. 5v breadboard rail to HV pin on both BOBs, also to pin 8 (VDD) on both MCPs and also to pin 5 (P0A) to supply voltage for the wiper to resist.
Pi Ground to breadboard ground rail on 3.3v side. Ground rail to 3.3v GND on both BOBs.
Pi MOSI to both BOBs channel 3 (LV3). Each BOB channel 3 (HV3) to pin 3 on MCP (SDI/SDO).
Pi MISO disconnected. (I've tried connecting it to LV3 too, no difference other than loopback echo readings in some scripts)
Pi SCLK to both BOBs channel 2 (LV2). Each BOB channel 2 (HV2) to pin 2 on each MCP (SCK).
Pi CE0 to first BOB channel 1 (LV1). BOB channel 1 (HV1) to pin 1 on first MCP (CS). Pi CE1 to second BOB channel 1 (LV1). Second BOB channel 1 (HV1) to pin 1 on second MCP (CS).
Both BOB HV GND to Pin 4 on both MCPs. Also connected to ground rail (so both MCP grounds are connected to each other). Also connected to pin 7 of both MCPs (P0B).
Do the grounds on both sides of the BOB need to be connected together? I've tried both and it doesn't seem to matter. I've tried connecting the pi directly to the MCP4131 using a 3.3v VDD as well, but couldn't get my code to work.
Many thanks,
Jordan

User avatar
joan
Posts: 14093
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: Trouble connecting to the MCP4131

Sat Feb 04, 2017 1:29 pm

I gave you a bad example. You shouldn't use U0 and U1 in the SPI opens as that prevents CS being toggled properly.

For what you try the following.

Code: Select all

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

jordan314
Posts: 15
Joined: Fri Feb 08, 2013 10:06 pm

Re: Trouble connecting to the MCP4131

Sat Feb 04, 2017 9:53 pm

Thanks Joan,
That's not working either, though interestingly now the wiper is stuck at 4.6V for all of my scripts including yours. Maybe I'll try just one MCP chip directly next. You just work with the chip at 3.3v and don't use a LLC correct?
Thanks again--

User avatar
joan
Posts: 14093
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: Trouble connecting to the MCP4131

Sat Feb 04, 2017 10:44 pm

jordan314 wrote:Thanks Joan,
That's not working either, though interestingly now the wiper is stuck at 4.6V for all of my scripts including yours. Maybe I'll try just one MCP chip directly next. You just work with the chip at 3.3v and don't use a LLC correct?
Thanks again--
I've probably only used the MCP4131 at 3V3 (I invariably use a voltage divider on the MISO line if I drive a chip from 5V and that wouldn't have worked with the MCP4131).

jordan314
Posts: 15
Joined: Fri Feb 08, 2013 10:06 pm

Re: Trouble connecting to the MCP4131

Mon Feb 06, 2017 7:32 am

Hi Joan,
I was able to get your code to work once I realized it was using CE1 and not CE0. Thanks, now I know my wiring is correct!

Now I'm having trouble connecting in c, which is what the rest of my project is in. Here is my wiringPi code, can anyone tell me what I'm doing wrong? The voltage never changes.

Code: Select all

#include <wiringPiSPI.h>
#include <stdio.h>

int main()
{

  if (wiringPiSPISetup (0, 500000) < 0){
      printf ("Unable to open SPI device 0\n");
      return(1);
  }
  unsigned char buffer[2];
  int i;
for(i = 1; i < 128; i++){
     buffer[0] = 0x00;
     buffer[1] = i;
     wiringPiSPIDataRW(0, buffer, 2);
     printf("\nWriting %d\n", i);
     usleep(300 * 1000);
     }
  return 0;
}

User avatar
joan
Posts: 14093
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: Trouble connecting to the MCP4131

Mon Feb 06, 2017 9:01 am

You seem to be using fd 0 which will normally be stdin rather than the file descriptor returned by the SPI open function wiringPiSPISetup(). I'm assuming wiringPiSPISetup() does return an fd.

jordan314
Posts: 15
Joined: Fri Feb 08, 2013 10:06 pm

Re: Trouble connecting to the MCP4131

Mon Feb 06, 2017 9:13 am

http://wiringpi.com/reference/spi-library/
0 Is the channel which I assume is CE0. Most of the examples I've seen (for wiringPi with other chips) just check the return value to see if the device could be opened, like this one:
https://gist.github.com/Jotschi/3659646

User avatar
joan
Posts: 14093
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: Trouble connecting to the MCP4131

Mon Feb 06, 2017 9:18 am

In that case your code looks okay to me.

For reference here's some code I have used.

Code: Select all

#include <stdio.h>

#include <pigpio.h>

int main(int argc, char *argv[])
{
   int i;

   int h_mcp3202;

   int h_mcp4131_w;
   int h_mcp4131_r;

   const int PV=129;

   char txBuf[3];
   char rxBuf[3];

   unsigned v, w;

   double start, duration;

   int speed, iters, maxsps, diags;

   uint32_t nt;
   unsigned micros;
   int tdiff;

   unsigned readings[4096];

   speed = 1000000;
   iters = 1000;
   maxsps = 100000;
   diags = 0;

   if (argc > 1) speed = atoi(argv[1]);
   if (argc > 2) iters = atoi(argv[2]);
   if (argc > 3) maxsps = atoi(argv[3]);
   if (argc > 4) diags = 1;

   micros = 1000000 / maxsps;

   if (gpioInitialise() < 0) return 1;

   h_mcp3202   = spiOpen(1, speed, 0x03); /* set mode 3, no reason */

   h_mcp4131_w = spiOpen(0, speed, 0x03); /* set mode 3, no reason */
   h_mcp4131_r = spiOpen(0,  250000, 0x1B); /* 3-wire after 1 byte */

   txBuf[0] = 1;
   txBuf[2] = 0;

   for (i=0; i<4096; i++) readings[i] = 0;

   start = time_time();

   for (i=0; i<iters; i++)
   {
      nt = gpioTick() + micros;

      txBuf[1] = 0x80; /* channel 0 */
      spiXfer(h_mcp3202, txBuf, rxBuf, 3);
      v = (rxBuf[1]&0x0F)*256 + rxBuf[2];

      readings[v/10]++;

      do /* rate limit to maxsps */
      {
         tdiff = nt - gpioTick();
      }
      while (tdiff > 0);

      if (diags) printf("ch0=%u\n", v);
   }

   duration = time_time() - start;

   for (i=0; i<4096; i++)
      if (readings[i]) printf("%d %d\n", i*10, readings[i]);

   printf("sps=%.0f duration=%.1f\n", (float)iters/duration, duration);

   /*
      Now check the digital pot, its output is connected to the mcp3202
      channel 1,
   */

   txBuf[2] = 0;

   for (i=0; i<1000; i++)
   {
      txBuf[0] = 0; /* write wiper 0 */
      txBuf[1] = i%PV; /* 0 - 128 */
      spiXfer(h_mcp4131_w, txBuf, rxBuf, 2);

      txBuf[0] = 1;
      txBuf[1] = 0xC0; /* channel 1 */
       
      spiXfer(h_mcp3202, txBuf, rxBuf, 3);
      v = (rxBuf[1]&0x0F)*256 + rxBuf[2];

      txBuf[0] = 0x0C; /* read wiper 0 */
      txBuf[1] = 0;

      rxBuf[1] = 0;

      spiXfer(h_mcp4131_r, txBuf, rxBuf, 2);
      w = rxBuf[1];

      if (diags) printf("set=%3u adc=%4u pot=%3u\n", i%PV, v, w);

      if ((i%PV) != w) printf("mismatch set=%d read=%d\n", i%PV, w);
   }
}

jordan314
Posts: 15
Joined: Fri Feb 08, 2013 10:06 pm

Re: Trouble connecting to the MCP4131

Mon Feb 06, 2017 3:34 pm

I reached out to Gordon Henderson, the developer of wiringPi, and he said this:
That code bit-bangs the SPI port rather than use the kernel driver. It will leave the pins in the wrong state, so if you run the C program using wiringPi AFTER the python one, then it won't work correctly.

Try rebooting the Pi then running the C program.
I had been testing another bitbanging python script without rebooting.
I tried rebooting and it worked!!
Thanks for your help!

Return to “Troubleshooting”