Netduino home hardware projects downloads community

Jump to content


The Netduino forums have been replaced by new forums at community.wildernesslabs.co. This site has been preserved for archival purposes only and the ability to make new accounts or posts has been turned off.
Photo

Driver for MCP23S08/MCP23S17 I/O Expander

Driver I/O Expander Port Expander MCP23S08 MCP23S17 SPI GPIO Expander

  • Please log in to reply
No replies to this topic

#1 ShVerni

ShVerni

    Advanced Member

  • Members
  • PipPipPip
  • 138 posts
  • LocationNew York, New York

Posted 14 June 2014 - 04:41 PM

Hello,
 
Have you ever wanted to--or needed to--add ridiculous numbers of GPIOs to your project? Did you want those ports to be as flexible as native ports, including features like pull-up resistors and interrupt support? Well then hopefully this driver will fit your needs.
 
This driver provides Netduino support for MCP23S08/MCP23S17 I/O expanders through SPI. You can, theoretically, add up to 128 GPIOs per chip select pin used. Each port on each expander can be configured as an input or output, and supports pull-up resistors on output ports and interrupts on input ports.
 
This driver makes use of Stefan Thoolen's excellent MultiSPI class to support multiple expanders.
 
This driver provides two means of interaction: All the ports on an expander can be written to or read from simultaneously, or a port on an expander can be setup and used as a drop-in replacement for a native GPIO.
 
Below is an example of using the driver with the latter method of interaction:

    public class Program
    {
        // Create some standard Netduino variables and ports
        static int count = 0;
        static InputPort foo = new InputPort(Pins.GPIO_PIN_D0, false, Port.ResistorMode.Disabled);
        static InputPort bar = new InputPort(Pins.GPIO_PIN_D1, false, Port.ResistorMode.Disabled);
        static InterruptPort button = new InterruptPort(Pins.ONBOARD_BTN, true, Port.ResistorMode.PullUp, Port.InterruptMode.InterruptEdgeLow);
 
        // Create the two expander objects
        static MCP23S17 expander1 = new MCP23S17(Pins.GPIO_PIN_D10, 0x00);
        static MCP23S17 expander2 = new MCP23S17(Pins.GPIO_PIN_D10, 0x01);

        // Create one output on each expander 
        static ExpandedOuputPort output1 = new ExpandedOuputPort(MCP23S17.ports.GP9, false, expander1);
        static ExpandedOuputPort output2 = new ExpandedOuputPort(MCP23S17.ports.GP7, false, expander2);

        // Create one input on each expander
        static ExpandedInputPort input1 = new ExpandedInputPort(MCP23S17.ports.GP2, Port.ResistorMode.PullUp, expander1);
        static ExpandedInputPort input2 = new ExpandedInputPort(MCP23S17.ports.GP12, Port.ResistorMode.PullUp, expander2);

        public static void Main()
        {
            button.OnInterrupt += button_OnInterrupt;

            while (true)
            {
                // Check the states of the expanders' outputs using the Netduino inputs
                Debug.Print("One output: " + foo.Read().ToString());
                Debug.Print("Two output: " + bar.Read().ToString() + "\n");

                // Check the states of the expanders' inputs
                Debug.Print("One input: " + input1.Read().ToString());
                Debug.Print("Two input: " + input2.Read().ToString() + "\n\n");

                Thread.Sleep(1000);
            }
        }

        /// <summary>
        /// When the Netduino's button is pushed this will alternate between toggling each
        /// expander's output port, e.g. the first push will toggle the output on expander1, 
        /// the second push will toggle the output on expander2, etc...
        /// </summary>
        /// <param name="pin">The pin triggering the interrupt</param>
        /// <param name="state">The pin state</param>
        /// <param name="time">The time of the interrupt</param>
        static void button_OnInterrupt(uint pin, uint state, DateTime time)
        {
            if (count == 0)
            {
                output1.Write(!output1.Read());
                count++;
            }
            else
            {
                output2.Write(!output2.Read());
                count = 0;
            }
            Debug.Print("Toggled");
        }
    }

A few notes:

 

This driver does not prevent multiple assignments: e.g. one could assign a port as an output port, and later assign it as an input port and no error would be thrown. So it's important to take care when assigning ports.

 

Writing/reading to/from the all the ports simultaneously can be done while using the ExpandedInputPort or ExpandedOutputPort classes, however the two methods will overwrite each other, i.e whichever method is used last will be the one that is in effect.

 

I have not implemented an ExpandedInterruptPort class. However, the interrupt functions can still be used with the checkInterrupt() method, which will return the contents of the INTF and INTCAP registers.

 

This driver is still a draft, so any feedback or suggestions are more than welcome!

Attached Files







Also tagged with one or more of these keywords: Driver, I/O Expander, Port Expander, MCP23S08, MCP23S17, SPI, GPIO Expander

0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users

home    hardware    projects    downloads    community    where to buy    contact Copyright © 2016 Wilderness Labs Inc.  |  Legal   |   CC BY-SA
This webpage is licensed under a Creative Commons Attribution-ShareAlike License.