hcooper@es.com wrote: >he used a 555 Actually, you don't need a 555. It can be done using the bit-bashing A/D converter from the Microchip AN??? that uses the 3-state feature of the pin to charge a capacitor and then discharge it through the resistor ladder and measure the trip point. There is an AN in the Embedded Control Handbook on this, but I've never seen it being used for switches, except by me ;) Switch chatter and component tolerance is a problem though, and you have to be able to afford the time to take several measurements. I used the well-known direct empirical approach (3 years ago ;) instead of playing with simulators. See below for details. The wiring looks like this: | v-- This is plit in 2x 4k7 for remote kbd. PIC | 470 ohm 10k 10k 10k 10k digital +<>----/\/\/\--+--/\/\/\--+--/\/\/\--+--/\/\/\--+--/\/\/\--+ IO pin | | | | | | | C --- | | | | --- SW1 \ SW2 \ SW3 \ SW4 \ | | | | | === === === === === Gnd I think that the highest no. of switches is of 8 for some reason I don't remember anymore, and only 1 can be closed at any one time. SW1 has priority over SW2 etc. I never went over 4 switches. The program that drives this, follows the following pseudoprogram: set pin to output drive '1' out wait for fixed time for C to charge to Vdd set pin to input zero an 8-bit counter do count down // gives 256 instead of 255 steps if counter rolls over return ok: no key was pressed endif while pin is '1' // Now, process counter contents to obtain key pressed // the test program used to gather data empirically returns here with // the counter in W, to be sent to the host as hex data in ASCII // The following code depends on how you solve the problem: subtract constant K1 from counter (***) shift counter right by 1 bit K2 times or AND with mask to remove unsign. LSBs (***) do table lookup of code using the counter as index, or compare with known boundary values for each key domain, to be determined. return pressed key code: which key. This code is called 3 times in a row and the result is accepted if it is a 2:3 success, else it is invalid, and if 2 invalid reads occur 1 after the other (i.e. the loop is called 2 times 3 times), the error is flagged on the display without disabling the unit completely. The user can then call service or clean the switches himself depending on his qualifications. K1, K2 and the lookup table must be determined individually for each application. See below. Notes: The wire to the switches can also be used to trace faults in board assembly. The idea is, to have the 470 ohms and the C close to the PIC, but then a long and winding trace that goes everywhere, before it reaches the 1st R (4k7 or 10k) and especially near pads known to spread solder when passed through a soldering system (and with holes in the solder-stop mask for this sense wire near them obviously). The 1st 10kOhm resistor is split into two 4k7 ohm ones if the kbd is remote, with one on the keyboard plate (or foil) and the other near the PIC. This protects both in case of serious oopses in the system (should be flameproof res.) and keeps EMI radiation at a minimum. The wire can be very long, but should be shielded in many cases. It behaves well with a lot of RF around. 3 meters are no problem. The system does NOT like ground fault currents. I will have warned you. Do not economize the ground wire to the keyboard away if there are Amperes in the chassis. (***): The constants K1 and K2 are determined empirically, by building the circuit and having the test program signal the values back to a PC through RS232, as Hex counter contents, represented in ASCII (two chars). This is used to determine the K1, K2 and the lookup table, which are later written into the final version of the code. C is determined such, that the discharge time gives the best spread of the counter read-out values, with the given Vdd and crystal frequency. It can also be determined empirically with the described test setup (I did this with graphite+rubber buttons - they vary in resistance with the force applied - the conclusion was: don't use graphited rubber buttons with this application ;). The charge/discharge delay is set to 1.2 * Trc to reach Vss + 0.2 V from Vdd and vice versa. I have given a thought to the collection of statistical data like this, using a parallel printer port to drive 8 relays (1:8 randomly) instead of the switches, and a serial link to collect data, and find out about how it behaves over long times (1 week ?). Temperature did not affect the operation seriously in the 8-50 deg. C range that I could test (warning: not metered). One of the things I'd like to try when I'll have some time (why do I keep saying this ?!), is to use a SMT 12C5XX W/O AD as ultra-miniature IR/RF remote control transmitter with this kind of setup. I should be able to manage 40 keys with 47 printed resistors and 6 SMT caps only, plus a SMT VFET and an IR LED, and a visible SMT LED for operation indication ;), and that with my codes. Watch out Japanese miniatures, here I come . (If someone wants to try this remote control idea out, by all means do and let me know. 40 keys are 8 keys per resistor array, 5 resistor ladders for 5 digital IO pins used for A/D, each with 8 resistors, plus the 5 470 ohm limiting resistors, one more for the gate of the FET, 5 SMT caps for A/D, one across Vdd/Vss, and finally a limiting resistor in series with the IR LED). Note that this circuit was born for the 16C54, the 12C5XX already has A/D on chip, but it also has Interrupts, which can cause the measuring loop above to fail. They must be disabled while in the loop. By adjusting the resistors in the ladder a linear response can be obtained, in terms of counter contents after conversion, and simply masking out bits may be enough to get the output value. There is a simpler version of the program, that removes the tests for shorts, and relies on the permanently connected resistor at the end of the ladder and on the lookup table to detect a key, a failed kdb, and a short ;) There is an even simpler version, that uses the internal A/D converter, with the same schematic, plus a two pin constant current source (CR ??) from Vdd, but that is a little beyond the mark imho, after all I was trying to do it the HARD way ;) Peter (plp@nospam.actcom.co.il) You know what to remove to send me email.