Multiplexing 32 Buttons and 32 Leds? - Page 1
Forum section: electronics / projects

author: luvini
author_rank: Contributor
timestamp: February 28, 2016, 12:35:07 am
content: i did 7-Segment display multiplexing before, thats the only experience with multiplexing i havenow i want to multiplex 32 Leds and 32 Buttons!is there a better way to desing this, maybe using less pins? or is this the only way to do that?also, how do i read multiplexed inputs?

author: uncle_bob
author_rank: Unknown
timestamp: February 28, 2016, 12:46:12 am
content: HiTo read the inputs you pull the switch high and look at a resistor to ground on the other side. If it's logic high, your swtich is closed. If it is logic low the switch is open.There are an enormous number of ways to do this. The easy way is to scan rows and read columns (organize 32 as 6x6 with 4 blanks). You pull a row high and look at what happens on the common outputs. That works without diodes if only one switch closes at a time. If you can have multiple closures, you need a diode in series with each switch.Bob

author: Psi
author_rank: Super Contributor
timestamp: February 28, 2016, 01:12:06 am
content: Perhaps you can take advantage of the fact that LEDs are polarized and double up some of the button/led lines.eg, If you scan for button press with a polarity that won't illuminate LEDs.of cause, it means you have restrictions on what LEDs you can illuminate while buttons are down.The other way to reduce pin count is to use an external decoder. So for example, 4 outputs could control 16 different lines.

author: luvini
author_rank: Contributor
timestamp: February 28, 2016, 01:22:18 am
content: Quote from: uncle_bob on February 28, 2016, 12:46:12 ammaybe... that would work? for this, i wont be pressing more tham 1 button at the same time (but it would be interesting to learn that diode method anyways)Code:output_high(ButtonLine1);if(Button1){//do this}//... up to button 8if(Button8){//do this}output_low(ButtonLine1);output_high(ButtonLine2);//... continue repeating this process to get all buttons-----Quote from: Psi on February 28, 2016, 01:12:06 amtell me more about using the LEDs for that?

author: Psi
author_rank: Super Contributor
timestamp: February 28, 2016, 01:38:10 am
content: Consider this, If you only had a multiplex of buttons and you put one LED across each button. Then, providing the polarity was correct, as you scanned the buttons looking for any pressed ones you would also light up the LEDs.Since you're scanning the buttons really fast all LEDs would appear to be on.Now, if you wire the thing up so that the high and low used to scan can also be inverted in software you can scan in reverse polarity to check for button press and the LEDs wont light up.Should work, i've not actually tried doing it myself though.Something like this,When you want to light LEDs, scan rows high and pull cols low for leds you want on.When you want to check buttons, scan with rows low and cols all as inputs with internal pullups enabled. (Any low input means button pressed)There are disadvantages to this approach though,- While a button is pressed you lose the ability to light up leds on the same row and column- Since there is only one resistor per row of leds in my example you really need to scan them one at a time, If you enable a row and try to illuminate all leds on the column at once the more you enable the dimmer they will get. However you could fix this with more resistors (2 per led/switch element. Remember the switch also needs a resistor or you will short out the power when it tries to illuminate the led and the switch is currently down)

author: station240
author_rank: Unknown
timestamp: February 28, 2016, 09:47:16 am
content: What voltage are your IO pins ?As if it's below 3V you don't need to consider resistors for the LEDs.Also ensure the output can drive the 20mA of a typical LED.

author: uncle_bob
author_rank: Unknown
timestamp: February 28, 2016, 03:40:01 pm
content: Quote from: station240 on February 28, 2016, 09:47:16 amHiobThat can be dangerous.Often there is a "max current per bank" limit on the drive current. They each can do 20ma by themselves. Down in the fine print there is a note about 50 / 100 / 200 ma max current out of all pins combined ...Bob

author: Fungus
author_rank: Super Contributor
timestamp: February 28, 2016, 08:02:41 pm
content: Quote from: Psi on February 28, 2016, 01:38:10 am...apart from the LED turning off when you press the button.

author: Someone
author_rank: Super Contributor
timestamp: February 29, 2016, 12:42:22 am
content: Quote from: Fungus on February 28, 2016, 08:02:41 pmThere is a similar arrangement of multiplexing where pressing the button will light up the LED, an ok solution for many illuminated button UIs. Have used it but the strobing can be distracting.

author: luvini
author_rank: Contributor
timestamp: February 29, 2016, 03:17:13 am
content: Quote from: uncle_bob on February 28, 2016, 03:40:01 pmthe outputs are 5V and can only deliver 20ma, the LEDs can be directly driven without resistors, however, if i invert the connection, a output_low will give the LED the full current and kill it so a resistor is needed, while a output_high would turn it offQuote from: Fungus on February 28, 2016, 08:02:41 pmfor this project, there is no problem with the led turning off, as the led will be changing state when said button is pressedQuote from: Someone on February 29, 2016, 12:42:22 amso it works the opposite as the other idea? what strobing?

author: promacjoe
author_rank: Regular Contributor
timestamp: February 29, 2016, 05:04:30 am
content: I don't know how many bits you have available on your microprocessor, but, You can use a 4 by 8 bits array, to turn on the LEDs.and you can use an additional 4 bits for your switch inputs. You can supply the +/- From either the 4 bit or the 8 bit Lines. The switches will go through a resistor to keep from turning off the LEDs . All you need to know is which input is receiving voltage from which output. Once you know that you can determine which switch has been selected.

author: philh
author_rank: Newbie
timestamp: February 29, 2016, 05:22:19 am
content: You can always use Charlieplexing for the LED's.http://makezine.com/projects/charlieplexing-leds-with-an-avr-atmega328-or-arduino/If you have a ADC input on your MCU then you can sample 20 switches with just one pin.http://electronics-diy.com/electronic_schematic.php?id=720

author: luvini
author_rank: Contributor
timestamp: March 09, 2016, 01:53:04 am
content: i don't understand how Charlieplexing work, explain?

author: uncle_bob
author_rank: Unknown
timestamp: March 09, 2016, 02:00:09 am
content: Quote from: luvini on March 09, 2016, 01:53:04 amHiYou construct an R2R ladder ADC with the buttons as the switches in the DAC. You then read out the voltage of the DAC with an ADC.If you have resistors that are good to 0.00000001% and a 32 bit ADC, it will handle your 32 switches on a single ADC. You also would need zero ohm switches ...So not to practical done all on one port.More practically, You can get 6 or so switches on an ADC with fairly normal resistors. To handle your 32 switches, you wold need 5 or 6 ADC inputs. The resistor tolerance issue (and switch voltage drop) gets you before the ADC resolution.Bob

author: luvini
author_rank: Contributor
timestamp: March 09, 2016, 02:05:20 am
content: Quote from: uncle_bob on March 09, 2016, 02:00:09 ammy chip doesn't have ADC... but i asked about charlieplexing

author: uncle_bob
author_rank: Unknown
timestamp: March 09, 2016, 02:19:22 am
content: Quote from: luvini on March 09, 2016, 02:05:20 amHiWith the LED's the assumption is that the output pins are all in the "right" voltage range and current limit at a level the LED's are happy with. The three lines step off a very normal binary code and all the codes but 000, 010, 101, and 111 will light a single LED. To get the two outside LED's to work, you tri-state the middle pin and depend on the voltage drops to keep the "other" LED's from lighting up.Bob

author: luvini
author_rank: Contributor
timestamp: March 09, 2016, 03:19:54 am
content: hmm.. like that? so i would have to PWM the 3 pins to get the led i want to light up? (or use I/O pins with resistors to get the right voltage without PWM, because the chips i have have only 1 or 2 PWM outputs)

author: batteksystem
author_rank: Regular Contributor
timestamp: March 09, 2016, 03:43:57 am
content: Quote from: luvini on February 28, 2016, 12:35:07 amYou can also try other method other than multiplexing, say using ADC with resistor network to read the key press, which would help simplify the wiring greatly.

author: luvini
author_rank: Contributor
timestamp: March 09, 2016, 03:55:02 am
content: Quote from: batteksystem on March 09, 2016, 03:43:57 ammy chip doesnot have ADC(have 2 analog comparators), andno PWM output, its a PIC16F628A, i want to know how many LEDs i can control with it, by using either multiplexing or charlieplexing, then i also want to use a lot of buttons, so also need to find a way to do that and find the maximum amount i would get, and then combine the two.i'll then try the same with a PIC16F877A wich has a lot more pins, and see whats the maximum i could get with itthat one does have 2 PWM outputs and 8 ADC inputs============i could control 6 LEDs... by using 6 pins... what am i doing wrong?

author: SL4P
author_rank: Super Contributor
timestamp: March 09, 2016, 08:12:41 am
content: Stick with simple XY multiplexing - less confusing to debug / repair.LEDs and switches on the same matrix - BUT - use one extra bit to select which matrix is active (use a bus buffer). The scanning/refresh speed will hide any gaps or flicker.Personally, I'd use one of the earlier suggestions - reverse biasing the LEDs during key-matrix scans, but the separated matrix will help you learn before going that direction.I've done both with PIC16F628A - no problems

author: uncle_bob
author_rank: Unknown
timestamp: March 09, 2016, 11:15:30 pm
content: Quote from: luvini on March 09, 2016, 03:19:54 amHiThe most common way to do it is to just bit bang the outputs. Since you need to play with tri-states and odd combos, it is much easier to do that way.Bob

author: philh
author_rank: Newbie
timestamp: March 10, 2016, 12:54:35 am
content: Quote from: luvini on March 09, 2016, 01:53:04 amI included a link in my original reply just click it and Charlieplexing will be explained with videos and sample code.Here is the link again:http://makezine.com/projects/charlieplexing-leds-with-an-avr-atmega328-or-arduino/

author: PointyOintment
author_rank: Frequent Contributor
timestamp: March 10, 2016, 01:44:33 am
content: SX1509 can probably do this

author: luvini
author_rank: Contributor
timestamp: March 10, 2016, 04:50:35 am
content: ok, so i got to control 6 LEDs using only 3 pinsCode:#include <16F628A.h>#fuses NOWDT//Disable Watchdog Timer#fuses NOPROTECT//Disable Read/Write Protect#FUSES NOCPD//Disable EE protection#fuses NOLVP//Disable Low Voltage Programming (ICSP) ==keep low during operation if enabled to prevent entering ICSP mode==#fuses INTRC_IO//Set CLK pins as I/O#fuses NOMCLR//Disable Master Clear#FUSES NOBROWNOUT//Disable Reseting On Power Loss//#FUSES HS//Crystal With More than 4Mhz#use delay(clock=4000000)int speed;void ledD2(){output_float(pin_a1);output_high(pin_a2);output_low(pin_a3);}void ledD5(){output_high(pin_a1);output_float(pin_a2);output_low(pin_a3);}void ledD3(){output_float(pin_a1);output_low(pin_a2);output_high(pin_a3);}void ledD6(){output_low(pin_a1);output_float(pin_a2);output_high(pin_a3);}void ledD1(){output_high(pin_a1);output_low(pin_a2);output_float(pin_a3);}void ledD4(){output_low(pin_a1);output_high(pin_a2);output_float(pin_a3);}void ledOFF(){output_float(pin_a1);output_float(pin_a1);output_float(pin_a1);}void main(){speed=500;while(1){ledD1();delay_ms(speed);ledD2();delay_ms(speed);ledD3();delay_ms(speed);ledD4();delay_ms(speed);ledD5();delay_ms(speed);ledD6();delay_ms(speed);}}see the GIF attached of it workingso what i am doing is putting one pin as HIGH, other as LOW and other as FLOAT(high impedance)now how would i increase the amount of LEDs?

author: mubes
author_rank: Regular Contributor
timestamp: March 10, 2016, 09:41:18 am
content: Checkout MAX7219 family. They're commonly used on 8 digit 7 segment displays but there are no rules to say you can't just drive regular LEDs with them. Heck of a lot of resistors and other crud saved, and there's probably even a way you can use the row strobes as your scan lines for the switches, although you perhaps wouldn't save much.RegardsDAVE

author: uncle_bob
author_rank: Unknown
timestamp: March 10, 2016, 11:01:53 pm
content: Quote from: luvini on March 10, 2016, 04:50:35 amHiTo increase the LED's use more pins. Each set of 3 pins gets you 6 more LED's if the pin sets are independent. Each pair of pins adds 6 LED's if you have them part of a common array.Keep in mind that as you add more LED's the current drops. You get to a point that the LED's do not have much light at all fairly quickly.BobBbo

author: luvini
author_rank: Contributor
timestamp: March 11, 2016, 04:21:56 am
content: Quote from: uncle_bob on March 10, 2016, 11:01:53 pmhow do i make a common array of charlieplexing to add more leds on it?also, i tried multiplexing with LEDs tooCode:#include <16F628A.h>#fuses NOWDT//Disable Watchdog Timer#fuses NOPROTECT//Disable Read/Write Protect#FUSES NOCPD//Disable EE protection#fuses NOLVP//Disable Low Voltage Programming (ICSP) ==keep low during operation if enabled to prevent entering ICSP mode==#fuses INTRC_IO//Set CLK pins as I/O#fuses NOMCLR//Disable Master Clear#FUSES NOBROWNOUT//Disable Reseting On Power Loss//#FUSES HS//Crystal With More than 4Mhz#use delay(clock=4000000)int speed;//=====================================void led01(){output_high(pin_a1);//line 1output_low(pin_a2);output_low(pin_a3);output_low(pin_b1);//column 1output_high(pin_b2);output_high(pin_b3);}void led02(){output_high(pin_a1);//line 1output_low(pin_a2);output_low(pin_a3);output_high(pin_b1);output_low(pin_b2);//column 2output_high(pin_b3);}void led03(){output_high(pin_a1);//line 1output_low(pin_a2);output_low(pin_a3);output_high(pin_b1);output_high(pin_b2);output_low(pin_b3);//column 3}void led04(){output_low(pin_a1);output_high(pin_a2);//line 2output_low(pin_a3);output_low(pin_b1);//column 1output_high(pin_b2);output_high(pin_b3);}void led05(){output_low(pin_a1);output_high(pin_a2);//line 2output_low(pin_a3);output_high(pin_b1);output_low(pin_b2);//column 2output_high(pin_b3);}void led06(){output_low(pin_a1);output_high(pin_a2);//line 2output_low(pin_a3);output_high(pin_b1);output_high(pin_b2);output_low(pin_b3);//column 3}void led07(){output_low(pin_a1);output_low(pin_a2);output_high(pin_a3);//line 3output_low(pin_b1);//column 1output_high(pin_b2);output_high(pin_b3);}void led08(){output_low(pin_a1);output_low(pin_a2);output_high(pin_a3);//line 3output_high(pin_b1);output_low(pin_b2);//column 2output_high(pin_b3);}void led09(){output_low(pin_a1);output_low(pin_a2);output_high(pin_a3);//line 3output_high(pin_b1);output_high(pin_b2);output_low(pin_b3);//column 3}//=====================================void main(){speed=250;while(1){led01();delay_ms(speed);led02();delay_ms(speed);led03();delay_ms(speed);led04();delay_ms(speed);led05();delay_ms(speed);led06();delay_ms(speed);led07();delay_ms(speed);led08();delay_ms(speed);led09();delay_ms(speed);}}GIF of it working attached

author: dannyf
author_rank: Super Contributor
timestamp: March 11, 2016, 12:06:12 pm
content: QuotePut the switches parallel with the leds and read the switches by reverse-biasing the leds.

author: mariush
author_rank: Super Contributor
timestamp: March 11, 2016, 03:21:10 pm
content: It would be a serious pain in the ass, but you could multiplex 32 leds (actually up to 42 in theory) with only 7 i/o :from Microchip's compiled tips & tricks :http://ww1.microchip.com/downloads/en/DeviceDoc/01146B.pdfAs for 32 buttons, you should really think about debouncing and then there's also the issue of what happens if you press two buttons at the same time, if your projects needs to consider that or not.If you have to allow and accept multiple buttons at the same time, the cheapest and simplest way would probably be to use one or two or more shift register chips likeSN74LV165APWRfor example ... even with just one shift register chip, you'd need 2 (maybe 3) wires to read the 8 bits from the shift register and 4 wires to send power to the 4 rows of 8 buttons... send power to each row at a time, if one or more of the 8 buttons is pressed the shift register chip detects a 1 on that input pin, and your microcontroller reads the 8 bits through spi or i2c or whatever. If you chain two shift registers you would still need only two (or 3) pins to read the 16 bits from the shift register, and only 2 pins to send power to 16 buttons at a time.If you don't care about two buttons being pushed at the same time, you could use a cheap and simple ADC chip (or a couple of them) to detect pressed buttons. For example, get two of theseMCP3021 i2c 10 bit ADCsand connect them to your mcu using just two wirestip #7 from same pdf

author: philh
author_rank: Newbie
timestamp: March 11, 2016, 05:23:01 pm
content: how do i make a common array of charlieplexing to add more leds on it?here is a schematic for 20 LED's using 5 Pins.

author: uncle_bob
author_rank: Unknown
timestamp: March 12, 2016, 12:24:48 am
content: Quote from: philh on March 11, 2016, 05:23:01 pmHiDo you want to be able to see the LED's when you light them?How many LED's will be illuminated at any one time?In most cases the number of LED's turned on can be anywhere from none to all. Is that the case in your application?That was the limit when I first did this back in 1973. It's still the limit today ...Bob

author: luvini
author_rank: Contributor
timestamp: March 12, 2016, 01:02:04 am
content: Quote from: uncle_bob on March 12, 2016, 12:24:48 ami want to be able to turn on from 0 to 32, i guess with charlieplexing i could just change from one LED to another very fast and it wouldnt be noticeble, same for multiplexing?

author: uncle_bob
author_rank: Unknown
timestamp: March 12, 2016, 01:15:14 am
content: Quote from: luvini on March 12, 2016, 01:02:04 amHiIf you want to turn on all 32 at one time, the next question is: How bright do they need to be? That gets you to some current level (call it 10 ma). The next question is: what is the max current (either the drivers or the LED)? If the max current is 20 ma, you can multiplex (at most) two LED's. Anything past that and they are not bright enough. You will need to plug in your numbers for an exact 2.357 LED's sort of number. The answer is rarely more than 10 based on max LED current. With drivers like MCU pins sourcing the current, the answer is rarely more than 5 LED's.Bob