Using the principle of capacitor charging and discharging to realize one IO realizes two buttons
A few years ago, I visited a friend and mentioned that the cost of customers has become extremely high, especially in the toy industry, where even a single cent is carefully calculated. My friend was surprised to hear that, in order to reduce costs, solution providers are brainstorming various implementation methods. He was particularly shocked when I told him about a case where someone tried to use a single microcontroller IO pin to simulate the function of two buttons, which seemed quite novel to me at the time. I had never really thought about how that could be done before, but since others were able to achieve it, I felt determined to figure it out myself.
I have a habit of trying to solve problems before going to bed. If I can't find the answer, I usually fall asleep anyway. But if I'm stuck, I'll keep thinking until I find a solution. I knew that using an IO pin to implement multiple buttons was possible, and most methods rely on ADC functionality. By using a resistor divider, you can read different voltage levels to determine which button is pressed. However, if the IO doesn’t support ADC, there's still a way—by using capacitor charging and discharging, you can measure the time it takes for the capacitor to charge or discharge through the IO pin. (You can check my previous article on keyboard scanning for more details.)
The first idea I had was to use the principle of capacitor charging and discharging with two IO pins to simulate two buttons. After some research and testing, I found a working method.
Looking at the left side of the diagram, suppose MCU_IO1 is a bidirectional IO port. Let’s walk through the process step by step:
- Set MCU_IO1 as output and drive it high for a period of time. During this time, capacitor C1 charges up to nearly the supply voltage.
- Switch MCU_IO1 to input mode. If J1 and J2 are not pressed, the IO will behave like a high-impedance resistor. The charge on C1 will slowly leak away through this resistor, causing the voltage on C1 to drop over time. If we read the state of MCU_IO1 immediately after switching to input, we would see a high level (1).
- Set MCU_IO1 back to output and drive it low for a while. This will discharge the capacitor completely, bringing its voltage close to zero.
- Switch MCU_IO1 to input again. If neither J1 nor J2 is pressed, the reading should be low (0). However, if J1 is pressed, during step 2, the voltage remains high, but in step 4, it changes to high again. Similarly, if J2 is pressed, during step 2, the reading becomes low, but in step 4, it stays high. From these readings, we can determine whether J1 or J2 is pressed.
Once I had a working method, I needed to test it thoroughly. One major concern was that if J1 or J2 were pressed while the IO was in the wrong state, it could potentially short the power supply or ground, leading to damage. For example, if J1 is pressed while MCU_IO1 is set to low, it would create a direct short between the power supply and ground, which could burn out the MCU. The same risk applies when J2 is pressed while the IO is high.
To avoid this, the right half of the circuit includes a 220-ohm resistor connected to each switch (J3 and J4). This prevents any direct short between power and ground, regardless of which switch is pressed. Using this setup, we can still detect which switch is pressed based on the four-step process. However, if both J3 and J4 are pressed simultaneously, the system might not be able to distinguish between them, so additional logic may be needed for such cases.
Differential Mode Inductors,I type Inductors,Common Mode Inductors,Differential Mode Choke Inductor
Xuzhou Jiuli Electronics Co., Ltd , https://www.xzjiulielectronic.com