Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 8 of 8

Thread: 16-channel mux or switch register for reading keyswitches

  1. #1
    Junior Member
    Join Date
    Oct 2019
    Posts
    16

    16-channel mux or switch register for reading keyswitches

    Hi, I'd like to design a simple circuit board that holds 16 switches and some way to read them, preferably without needing 16 wires to Teensy pins. In previous prototyping I used a keyboard matrix with one diode per switch, but I'm thinking it might be easier to solder if I used a 16-channel mux or maybe a switch register, to avoid soldering all the diodes.

    I remember reading a web page on the Teensy website about using a mux to read buttons, but can't find it now. Anyone know where it is?

    Alternately, I'm wondering how I select a good chip for this. When narrowing things down using Digikey or Mouser, there seem to be few 16 channel through-hole mux chips and they're pretty expensive? Maybe my search query narrowed things too far.

  2. #2
    Senior Member+ MichaelMeissner's Avatar
    Join Date
    Nov 2012
    Location
    Ayer Massachussetts
    Posts
    3,448
    Assuming the switches are just on/off switches, one way be to use an i2c device like the MCP23017, such as Adafruit sells:


    You will likely need to add 2 pull-up resistors (2.2K is typical) in order to get I2C to work on Teensy (unless you have something like the prop shield or audio shield that already provides the resistors). Wiring would be:
    • Teensy 3.3v -> MCP23017 VDD
    • Teensy Ground -> MCP23017 VSS
    • Teensy Pin 19 -> two connections: 1 to MCP23017 SCL, and the other to a 2.2K resistor that is connected to 3.3v;
    • Teensy Pin 18 -> two connections: 1 to MCP23017 SDA, and the other to a 2.2K resistor that is connected to 3.3v.


    The switches would be connected on one end to the MCP23017 GP pin and on the other end ground (or 3.3v, depending on how you setup the MCP23017 device).

  3. #3
    Junior Member
    Join Date
    Oct 2019
    Posts
    16
    Update: I found the writeup I was thinking of. It's at the bottom of the midi page, search for "connecting many buttons". Those are 8-bit. I guess 8-bit multiplexers are much cheaper?

    https://www.pjrc.com/teensy/td_midi.html

  4. #4
    Senior Member
    Join Date
    Feb 2015
    Location
    Finland
    Posts
    136
    The Teensy MIDI page shows how to use 74HC4051 (8:1 multiplexer); the 74HC4067 (16:1 multiplexer) is otherwise similar, but uses four address lines instead of three. Both seem to be available at typical stores (Digikey, Mouser, LCSC) at less than a dollar/euro apiece.

    However, the MCP23017 MichaelMeissner suggested is in many ways superior, because you only need to connect four pins (I2C SCL, I2C SDA, 3.3V, and GND) for up to 128 buttons (8 MCP23017 chips). It too seems to be available at those same stores, at about a dollar/euro apiece, or slightly over.

    The idea is that instead of using digitalReadFast() to obtain the button states, you communicate with the MCP23017 chips using I2C, using the Wire library. Essentially, after you setup the Wire and initialize the chip, to check the button states you do
    Code:
    uint8_t b0to7, b8to15;
    
    Wire.begintransmission(32 + address); /* address = 0..7, depending on MCP23017 A0,A1,A2 pins */
    Wire.write(0x12);
    Wire.requestfrom(32 + address, 2); /* Same as above! */
    if (Wire.available() > 0) {
        b0to7 = Wire.read();
        if (Wire.available() > 0)
            b8to15 = Wire.read();
    }
    Wire.endtransmission();
    for each chip, to get the first 8 button states in b0to7, and the second 8 button states in b8to15, for that particular chip.

    There is also a SPI version of the same chip, MCP23S17, which is used in a very similar way, except with the SPI bus (and SPI library). (I didn't know this chip existed, only found out about it in the MCP23017 datasheet!)
    This chip is interesting in that if one wants to isolate the button circuits, it is rather easy to do with say an ADuM1401 and an isolated DC-DC converter (to supply current to the button circuits). I don't know why anyone would need to isolate the button circuits from the microcontroller, but with this chip it is quite cheap (< $10) and simple. (Each MCP23s17 needs their own chip select pin, so to use multiple chips, you need more isolated channels. With a Si8661, you can use three MCP23s17 chips, for a total of 48 isolated buttons/digital inputs.)

    Depending on your use case, you may also wish to debounce the buttons in software.

  5. #5
    Junior Member
    Join Date
    Oct 2019
    Posts
    16
    Yeah, that will do. Thanks!

  6. #6
    Senior Member+ MichaelMeissner's Avatar
    Join Date
    Nov 2012
    Location
    Ayer Massachussetts
    Posts
    3,448
    In terms of optimization note that there are various speed levels for I2C, and it defaults to the slowest speed (100Khz), you might be able to boost it up to a higher speed, depending on the device you are talking to, how many devices you have on the I2C bus, and the length of the entire I2C bus.

    There are two interrupt pins that can be attached to Teensy pins,and you can use that to skip a group of buttons that weren't pressed in the last cycle.

    While the Adafruit MCP23017 library gives you access to each individual button, you probably should get 8 buttons at once to minimize the I2C traffic.

    If you are using the Teensy LC, 3.2, 3.5, or 3.6 (but not the Teensy 4.0 or 2.x) there is a library 'i2c_t3.h' that has various advantages over the standard Wire library. The downside is it is incompatible with the standard Wire library, so you have to make sure every library you call does not include Wire.h (it it wants to do I2C, it should be using 'i2c_t3.h' as well). Another downside is at the present, it does not support the Teensy 4.0 processor.

  7. #7
    Junior Member
    Join Date
    Oct 2019
    Posts
    16
    Okay, good to know. I'm hoping I don't need to worry too much about that since it doesn't seem likely that I need to poll the keyboard more than 100 times a second, probably less. The MCP23017 will do higher speeds, though, according to the datasheet.

  8. #8
    Senior Member+ MichaelMeissner's Avatar
    Join Date
    Nov 2012
    Location
    Ayer Massachussetts
    Posts
    3,448
    Quote Originally Posted by skybrian View Post
    Okay, good to know. I'm hoping I don't need to worry too much about that since it doesn't seem likely that I need to poll the keyboard more than 100 times a second, probably less. The MCP23017 will do higher speeds, though, according to the datasheet.
    Yeah, human reaction times are fairly slow compared to computer times, but if you decide to go for more buttons, then the problem scales up.

    Note however, if you do go for higher number of buttons, then you have to pay more attention to proper wiring, and having things be modular can really help.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •