DigiPot MCP413X/415X/423X/425X

A lot of people have needed a digital potentiometer. I’ve had a few laying around, so decided to make a digipot library for the kind I have. They are MCP413X/415X/423X/425X, and I have specifically the MCP4131. They are SPI communication; however, you can use any digital pin for the CS (chip select).

Here’s the library link
https://xod.io/libs/xodballxod/digipot-mcp-spi/

Also, here’s an online tutorial on how to wire the chip to an LED, and some sample code to test in Arduino IDE.

Enjoy!
~xodballxod~

3 Likes

Updated Library to allow both wipers on Models that have two wiper. I pulled out the SPI object, and allows to save space while hooking up to two digitpot nodes with either different ChipSelect or different Address… I don’t have the bigger chip, yet. So, I don’t have any of the “read” functionality. But, at least we have a way to just write to the potentiometers. The 2nd Wiper should be address 01h? There’s more details in the spec sheet that I don’t understand, yet. I may update the library, again, after I get the bigger chip and get all the functionality working… Though, the Address is essential for changing the 2nd wiper on those models that have a second wiper, like MCP42x1.
Also, it was unclear if I need to send 16-bit command, or 8-bit command. Both work, but I think some functions that are not programmed may require the 16-bit command, so that’s what is use, now.
I also couldn’t figure out how to check if the SPI was ready. I have it doing “begin” in the setup.
Seems to work just fine, though.

I got the dual wiper chip, MCP4251, and made significant improvements to the library. Now, you can use the boolean to select which Wiper, and also Increment and Decrement. There is still more functionality I will program, in the next version. (*Learning a lot about SPI).

I could use some help in Custom Types. Inside the library are some nodes with my attempt at the Custom Class for a DigiPot to hold the maxSteps, CS port, and max Kohms, but I couldn’t get it to work. Some better examples on the XOD documents would be helpful, or someone just post one here?

Here is a screenshot of the main showing the improvements.

Cheers!
~xbx~

1 Like

Hi @xodballxod,

Great to see another device made accessible to xoders!

I’ve attached a xodball that shows you one way of creating a custom type for your library:
digipot.xodball (7.2 KB)

I don’t have a digital potentiometer, so my testing is limited to checking that the code compiles.

My first step was to create a new node, which I’ve named digipot, with inputs of all the types you would like to combine in your custom type. The only output is an output-self representing your custom type.
Screenshot 2022-02-08 at 21.38.40

The not-implemented-in-xod node contains the following code:

node {

     meta {
        struct Type {
            SPIClass* spi;
            uint8_t cs;
            bool bits8;
            Number MOhm;
            uint8_t maxStep;
            
            void writeStep (uint8_t step) {
                ::digitalWrite(cs, false);
                uint8_t address = bits8 ? 0x10 : 0x00 ; // Choose which wiper address (8-bit format)
                spi->transfer(address);
                spi->transfer(step);
                ::digitalWrite(cs, true);
            } 
        };
    } 
    
    void evaluate(Context ctx) {
        if (isSettingUp()){
            Type digipot;
            digipot.spi = getValue<input_SPI>(ctx);
            static_assert(isValidDigitalPort(constant_input_CS), "must be a valid digital port");
            ::pinMode(constant_input_CS, OUTPUT); // set pinmode output for Chip Select;
            digipot.cs = constant_input_CS;
            digipot.bits8 = getValue<input_bits8>(ctx);
            digipot.MOhm = getValue<input_MOhm>(ctx);
            digipot.maxStep = digipot.bits8 ? 255 : 128;
            emitValue<output_digipot>(ctx, digipot);
        }
        
    }
}

I’ve defined your custom type as a struct. Inside the struct is a variable for each of the inputs to the digipot node. I’ve also created one member function, writeStep, for demonstration purposes. A full implementation would include functions for all the actions you require (increment, decrement, etc.).

I modified your digipot-write-step node to have only three inputs:

  1. the digipot custom type
  2. number of steps
  3. update

Screenshot 2022-02-08 at 21.59.34

The not-implement-in-XOD node calls the writeStep function defined above:

node {
    void evaluate(Context ctx) {
        if (!isInputDirty<input_UPD>(ctx))
            return;
        auto digipot = getValue<input_digipot>(ctx);
        digipot.writeStep(getValue<input_STEP>(ctx));
        emitValue<output_DONE>(ctx, 1);
    }
}

I was able to compile the following example patch:
Screenshot 2022-02-08 at 22.19.57

You mention your plan to create a library with richer functionality. The quickest and easiest route might be to wrap an existing Arduino library, such as https://github.com/kulbhushanchand/MCP4251

Wow! Super cool! I didn’t know how to use the struct Type in the meta definition for Properties. Plus, You showed how to implement Methods, too! This example of Custom Types is super helpful! We’re learning a ton from this library project! And, we can apply these SPI library techniques to a bunch of new projects!

I’m looking forward to implementing this inside the library.

BIG THANKS!!!

1 Like