The ATMega168 is a great general purpose 8-bit AVR microcontroller from Atmel. It has 23 GPIO pins, but sometimes (as I have found) you can run out of I/O pins as your design grows. This happened to me recently when, of the 23 GPIO pins available, 2 were taken up by an external ceramic resonator, 1 for the reset line, 3 for serial coms, 14 for the LCD, and 3 for RGB LED control. This used all 23 GPIO pins, with none left for the four buttons I needed. What to do? This Design Idea has the solution.
A close look at the ATMega168 data sheet revealed that the I/O pins available on the 28-pin DIP package and on the 32-pin TQFP package are not all the same. On the TQFP package, there are an additional pair of VCC & GND pins and an additional two ADC input pins on top of the
with these extra ADC inputs, all would be OK and the design would be saved.
Now, the user interface was fairly overloaded with functions, and various combination button pushes were used to call up different menus on the LCD. Also, the software was still under development and more combination button pushes might be called for. I wanted to be able to detect each button individually as well as all possible button push combinations, so for four buttons, I needed to detect a total of 24, or 16 possible button states.
OK I thought, that should not be hard. I just need a resistor network between my four buttons and one of the ADC inputs so each button pulls down a different amount and all 16 combinations are evenly spaced between VCC and GND (Figure 1). However when I tried to do this it turned out not to be as easy as it looked at first sight.
For more detail: Read multiple switches using ADC