In the freshman design class on Friday (2016 Feb 19), I did not cover any of the material I had queued up as things students might need. Instead, I responded to a question from one of the students working on the LED cube project about how pin multiplexing worked. I had covered this once before in the class, but in a rather hurried way, and the students did not appear to have investigated the designs on their own to figure it out. So I decided to take the time to go through the development of the idea from the initial problem to one of the many possible solutions.
The problem is fairly simple to state: in a 4×4×4 RGB LED cube, there are 192 LEDs that need to be separately controlled—we want to be able to have any combination of them be on or off (I’m not getting into PWM control for adjusting the brightness in this class, though the hardware is not really different). The problem is that there are not 192 output pins on the Teensy boards, so they have to pack more functionality into fewer pins.
I started out with the idea of time-multiplexing. We don’t really need every LED that is on to be on all the time—if we are willing to have the whole cube be dimmer, we can have each LED on only a fraction of the time. For example, if we are willing to have each LED on for only 1/16th of the time, we can make 16 time slots, assign each LED to one time slot, and only need to control 12 LEDs in each time slot. If we specify which time slot we are currently in with 4 pins (binary encoding of the 16 possible values), then we only need 12+4=16 pins to control the 192 LEDs.
I then drew a grid of 12 rows and 16 columns (actually, I only showed a couple of each, and used …) and put an LED in each grid position, connecting the row to the anode and the column to the cathode. I then showed that if we had exactly one of the columns low, we could control all the LEDs in the column with a high voltages on the rows for the LEDs in the column that should be lit.
We then looked at current-limiting resistors, deciding that it made more sense to put them on the rows than on the columns, because the number of LEDs lit on each row is either 0 or 1 at a time, but anywhere from 0 to 12 may be lit on a column. We can compute a resistor that provides the desired current for the row, but the column has very different current needs depending on the number of LEDs lit. We also discussed that all the LEDs on a row should be the same color, since the forward voltage for the LEDs is different for different colors, and the needed resistor size depends on the forward voltage at the desired current. (I reviewed how to do the calculation of the current-limiting resistor.) Note: choosing columns to have the cathodes and rows to have the anodes, combined with needing a single color on each row, puts a constraint on whether we use common-anode or common-cathode RGB LEDs. If the wrong type of RGB LED is bought, then the columns would have to have the anodes and the rows the cathodes.
I suggested the use of a decoder or demultiplexer chip to decode 4 output lines into 16 column lines, with exactly one column being active. There is a 4-to-16 decoder chip available as a through-hole part (CD74HC4515EN), but it is a bit pricey, and students would be better off with a pair of 3-to-8 decoders (SN74HC138N), using the enable inputs to decode the remaining bit. Note: theSN74HC138N has an active-low output, with only one output low at a time (or 0, if the chip is not enabled). The CD74HC238E has an active-high output, with only one output high at a time. I did not talk about the different logic families and the logic levels needed for them. The HCT family, which needs a 5V power supply and uses traditional TTL signal levels is not a good choice for being driven from the Teensy outputs—the HC family is a better choice.
We then looked at another problem. If we want 20mA in each LED, then we need up to 240mA for a column and 240mA combined from all the outputs. The Teensy boards can’t deliver that much power from the output pins! Even the decoder chip is only designed for about 6mA on the output. So we can’t drive the rows and columns from the Teensy or decoder outputs.
For that matter, we can’t get 240mA from the 3.3V regulator for a Teensy LC or Teensy 3.1 (though the Teensy 3.2 is specified fairly conservatively to allow up to 250mA, which is barely enough). I suggested that we might want to power the LEDs off of the USB 5V power, which can deliver 500mA—more than enough.
I then introduced field-effect transistors (specifically MOSFETs) as voltage-controlled switches. For the columns, we just need an nFET for each column, with a threshold voltage between 0V and 3.3V, so that it is off when the decoder output is low and on when the decoder output is high. The gate of a MOSFET takes essentially no current, and even the cheapest nFETs can work in this application. I showed the students how to use the DigiKey search page to find a through-hole nFET with a threshold voltage in a reasonable range and sort by price for buying 20.
We talked about including the on-resistance of the MOSFET as part of the current-limiting resistance. The 5LN01SP-AC had an on-resistance of 7.8Ω, which is a little high—it might be better to use a slightly better nFET with a lower on resistance, as the column current varies with the number of LEDs lit, and we don’t want the brightness to change much. For about 13¢ more per transistor,we can get NTD3055L104-1G, which have a 100mΩ resistance—though that is for a 5V Vgs, and we are planning a 3.3V Vgs, which appears to increase the on-resistance by about a factor of 5, based on the current-vs-Vgs curves on the data sheet.
We then looked at using a pFET to control the rows. The gate voltage would be 0V for an on pFET, and 3.3V for an off pFET, so with the source at 5V, Vgs is -5V for off, and -1.7V for on. We had a hard time finding many pFETs with a threshold guaranteed to be between -1.7V and -5V, so I added the idea of adding an inverter powered from the 5V supply, so that the gate voltage is 0V or 5V, and the threshold merely needs to between 0V and -5V, which is easy to meet (VP2106N3-G, for example, which has a 7Ω on-resistance for a 5V drive). We discussed the need to include this on-resistance in the current-limiting resistance calculation, but there is no need to seek a very low resistance, as only one LED is drawing current through the pFET at any time.
So the final design that we came up with by the end of class looked something like this:
We didn’t discuss it, but the decoder should probably also be powered from the 5V USB power, so that it can turn the nFETs on more completely, giving a lower on-resistance for the columns.