SPI digital pot control MCP4151-502

The official pyboard running MicroPython.
This is the reference design and main target board for MicroPython.
You can buy one at the store.
Target audience: Users with a pyboard.
Post Reply
PeterA
Posts: 7
Joined: Thu May 24, 2018 9:00 am

SPI digital pot control MCP4151-502

Post by PeterA » Thu May 24, 2018 9:28 am

I have a 5k digital pot (MCP4151-502 - ww1.microchip.com/downloads/en/DeviceDoc/22060a.pdf) that I would like to control via the pyboard. This is my second time using SPI so I'm not particularly good at it at all.

I've used this pot before on the Raspberry Pi. It's really simple to set up and get going as is shown in this tutorial: http://www.takaitra.com/posts/503

I wired the CS pin on the chip to the SS pin on the pyboard, the SCK pin to SCK and the SDI/SDO pin to MOSI.

Basically what I need to do is to send two bytes (MSb and FSb), the first having a value of 00 and the second, a value that will set the resistance of the pot, for instance FF.

It boils down to this:

[code]
import pyb

from pyb import SPI

spi = SPI(2, SPI.MASTER, baudrate=1000000, polarity=1, phase=1, bits=16, firstbit=SPI.MSB)
spi.send(b'\x00\xFF')
[/code]

I cannot get it to work for the life of me, I've tried numerous variations and permutations. I'm not sure what kind of baudrate to set, also I’m not sure about the "bits" argument,

Any help would be deeply appreciated.

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: SPI digital pot control MCP4151-502

Post by pythoncoder » Thu May 24, 2018 4:23 pm

Your SPI setup looks OK except I think bits should be 8 to match the buffer which is a bytes object.

It's rather an odd device with the chip's SDI and SDO multiplexed. If you look at the datasheet fig. 6.1 it looks like a 200KΩ resistor should be used to protect the Pyboard output pin - the host controller uses hardware SPI so the middle diagram is relevant. I wouldn't worry about the exact resistor value. It won't go bang if you use 100KΩ. However the takaitra reference claims that the resistor is not needed as he never issues a read command. This may be true but you might want to fit one especially if you want to experiment with reading the device.

I have a doubt about takaitra's code: he's writing values of upto 0x1ff to the chip. From my reading of the datasheet the maximum for the 8-bit versions is 0x100. It supports 257 possible values, hence the 9 bit data word, but unless I'm missing something values should be constrained to the range 0 to 0x100.
Peter Hinch
Index to my micropython libraries.

PeterA
Posts: 7
Joined: Thu May 24, 2018 9:00 am

Re: SPI digital pot control MCP4151-502

Post by PeterA » Tue May 29, 2018 1:13 pm

Hello Peter, thank you for your reply.

I added a 150KΩ just to be on the safe side. Otherwise I haven't been having the best of luck with the SPI communication. I tried using the machine library, it also didn't work. Also tried every possible variation of argument values for initiating the SPI bus (wrote a script, didn't do it by hand) none of them worked.

I'm starting to think there might be something wrong with the way I send the bytes.

Regarding Takaitra's code, I am also not too sure about it, but what I do know is that on the Raspberry PI, I can set the resistance by sending x00, and another byte which determines the resistance (xFF sets the highest or lowest resistance - depends on how you wire it up, and the inverse happens if you send x00).

It's unfortunate, since I really wanted to use the pyboard for this project, do you think I would have more luck with an ESP32 or a wipy board?

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: SPI digital pot control MCP4151-502

Post by pythoncoder » Wed May 30, 2018 5:35 am

In my view the Pyboard is the gold standard for hardware interfacing. It was the first MicroPython target. The interfaces have been heavily used by a lot of people and have been pretty thoroughly debugged. If something doesn't work on a Pyboard it's unlikely to work on another platform.

You might consider using a logic analyser to find out what's happening at a hardware level. You can buy a Saleae clone from China very cheaply (or you can support the Saleae guys by getting a real one). Highly recommended.
Peter Hinch
Index to my micropython libraries.

PeterA
Posts: 7
Joined: Thu May 24, 2018 9:00 am

Re: SPI digital pot control MCP4151-502

Post by PeterA » Wed May 30, 2018 10:18 pm

The logic analyser is a great idea, but I really don't have time to wait for one, so I hooked the pyboard and the Raspberry pi to an oscilloscope, and the results are interesting.

https://imgur.com/a/qGiEzBX

Channel 1 was hooked up with MOSI and channel 2 to the clock. The initialisation parameters are on the left, and the bites written on the top. What strikes me is how different the SPI output is between the devices.

The gap between the bites is interesting and also the duty cycle is different, but the latter shouldn't be too much of a problem. If a bit has a value of 0 on the RPI the voltage doesn't drop to 0, it drops to about half of the voltage of what it was at value 1, while on the pyboard it does drop to 0 volts.

Anyone know how to make heads and tails of this? :)

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: SPI digital pot control MCP4151-502

Post by pythoncoder » Thu May 31, 2018 8:36 am

The first observation is that, as I suggested above, bits should be set to 8. When you set it to 16, and send (say) 0 followed by 0xff, the Pyboard sends two 16 bit values. I think the chip wants two 8-bit values.

All the examples coming from the Pyboard are exactly as I would expect.

As for the Raspberry Pi there is surely some measurement problem here with the voltage on the data line. Also the driver deasserts the data line after each bit. This is unusual but shouldn't have any effect. The Pi is using polarity 0 and (I think) phase 0 but it's hard to be sure without expanding the timebase.
Peter Hinch
Index to my micropython libraries.

PeterA
Posts: 7
Joined: Thu May 24, 2018 9:00 am

Re: SPI digital pot control MCP4151-502

Post by PeterA » Sun Jun 03, 2018 7:19 pm

There indeed was a problem with the measurement. I still don't know what went wrong, but I redid it, and the problem was gone. Here is a comparison between the RPI and the PYB, where the polarity and phase were set to 0 and the bits to 8. The first three rows show MOSI activity on channel 1 and channel 2 shows the activity of the clock. The output on the PYB is very similar to the PPI's.

https://imgur.com/a/0wHJ0p6

Channel 2 in the last row shows the activity of CE0 on the RPI and SS on the PYB. Therein lies the difference. Did I forget to control SS in some way?

PeterA
Posts: 7
Joined: Thu May 24, 2018 9:00 am

Re: SPI digital pot control MCP4151-502

Post by PeterA » Tue Jun 05, 2018 9:23 am

So the problem appears to be the SS/CS pin, the pyb SPI driver doesn't use it (in the documentation: "At the moment, the NSS pin is not used by the SPI driver and is free for other use.") and is always set to low. The MCP4xxx digital pots require the CS pin to function at all (in the MCP4xxx documentation: To start a command, or sequence of commands, the CS signal must transition from the inactive state (VIH) to an active state (VIL or VIHH)). It apparently registers the transition and it seems that it doesn't work if the CS pin is set to low all the time. At least that's how I understood the short paragraph about the CS pin in the MCP4xxx documentation (https://imgur.com/a/GU9lClk).

On the other hand though when looking at the SPI timings in the documentation it says that the CS transition should take place at least 60ns before the clock input comes, but a maximum time is not given (https://imgur.com/lRqr5fy) , so theoretically it could be infinite and the CS pin being on LOW (VIL) continually wouldn't be a problem.

One way around this problem would be to use a digital pin to generate the CS signal and input delays using utime. Would utime be precise enough for the task?

PeterA
Posts: 7
Joined: Thu May 24, 2018 9:00 am

Re: SPI digital pot control MCP4151-502

Post by PeterA » Tue Jun 05, 2018 1:06 pm

Update: It worked! The lack of CS signal was the problem, substituted the CS pin with X1.

import utime
from pyb import SPI

spi = SPI(2, SPI.MASTER, baudrate=1000000, polarity=0, phase=0, bits=8, firstbit=SPI.MSB)
CS = pyb.Pin(pyb.Pin.board.X1, pyb.Pin.OUT_PP)

CS.value(1)
pyb.udelay(300)
CS.value(0)

spi.send(b'\x00\xFF')
CS.value(1)

The delay before and after the bytes are sent can't be precisely controlled, since the spi.send command takes up quite a bit of processing power I would imagine, you cannot shorten the delay and expending it doesn't really make much sense.

Peter thank you for all the valuable input, it helped a lot.

I hope the SPI drivers will get addressed soon and CS functionality added, CS is apparently not only needed to chain multiple SPI devices together but also critical just to control some of them.

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: SPI digital pot control MCP4151-502

Post by pythoncoder » Wed Jun 06, 2018 7:46 am

From the point of view of the SPI master there may be several slaves on the bus. The CS pin on the slave enables the master to determine which slave it is accessing: each slave CS is connected to a different pin on the master.

It seems to me there would be little point in the firmware controlling a single NSS pin. It's easiest for each device driver to control its own CS pin (with the pin in use being selected by the application). That way a single application can use multiple device drivers each controlling a single device on a common SPI bus.
Peter Hinch
Index to my micropython libraries.

Post Reply