Arduino Basics: KY-004 Key Switch Module
Abstract
Learn how to use the KY-004 Key Switch Module, which is essentially a push button on a breakout board. This tutorial focuses on configuring Arduino digital input pins to read button presses, distinguishing between an unpressed and a pressed state, and controlling an output based on user action.
1. Introduction
The KY-004 is one of the simplest input modules, featuring a momentary push button switch and typically a current-limiting resistor. It serves as an excellent starting point for learning digital input and the critical technique of debouncing, as mechanical switches naturally produce signal noise.
In this episode, you’ll learn:
- The principle of a pull-up resistor for digital input.
- How to use the INPUT_PULLUP mode in Arduino.
- How to read the button state using digitalRead().
- How to toggle an output state with a single press.
This project introduces direct user control over your circuit, a necessity for creating interactive projects.
2. Prerequisites
Make sure you have:
- An Arduino Uno or compatible board.
- One KY-004 Key Switch Module.
- Jumper Wires.
- Arduino IDE
3. Wiring and Setup for Arduino
The KY-004 module has three pins and is designed to operate easily with microcontrollers.
Step 1 – Identify Pins
The module has three pins: Signal (S), VCC (+), and Ground (− or GND).
Step 2 – Connect the Module (Using Internal Pull-up)
We will use the Arduino’s built-in internal pull-up resistors for cleaner, simpler wiring. This means the signal pin will be HIGH when unpressed and switch to LOW when pressed.
- Connect the – / GND pin of the KY-004 to the GND pin on the Arduino.
- Connect the + / VCC pin of the KY-004 (or leave it unconnected if your module is wired to short S to GND when pressed). Note: To be safe and utilize the internal pull-up, only connecting the S and GND pins is often sufficient, as the button typically connects S to GND when pressed.
- Connect the S / Signal pin of the KY-004 to Arduino Digital Pin 2.
This image was created with Fritzing
Step 3 – Initialize Pin Mode
In the setup() function, configure the button pin to use the internal pull-up resistor:
pinMode(2, INPUT_PULLUP);
We will use the on-board LED (Pin 13) as our output indicator, set as OUTPUT.
4. Writing Button Toggling Code
Open main.ino and implement the following code to toggle the state of the built-in LED (Pin 13) with each press of the button on Pin 2.
const int BUTTON_PIN = 2;
const int LED_PIN = 13; // Built-in LED
// Variables for state change detection and debouncing
int ledState = LOW; // Current state of the LED
int lastButtonState = HIGH; // Last recorded state of the button (unpressed)
long lastDebounceTime = 0; // Last time the button state was toggled
long debounceDelay = 50; // The debounce time (in milliseconds)
int buttonPressed;
void setup() {
pinMode(LED_PIN, OUTPUT);
// Configure the button pin with the internal pull-up resistor
pinMode(BUTTON_PIN, INPUT_PULLUP);
Serial.begin(9600);
Serial.println("KY-004 Key Switch Test Ready!");
}
void loop() {
// Read the current state of the button
int reading = digitalRead(BUTTON_PIN);
// --- 1. Debounce Logic ---
// Check if the state *has changed* from the last loop iteration
if (reading != lastButtonState) {
// Reset the debounce timer upon state change
lastDebounceTime = millis();
// Reset the action flag
buttonPressed = false;
}
// Check if the state change has persisted past the debounce delay
if ((millis() - lastDebounceTime) > debounceDelay) {
// --- 2. Action Logic ---
// ONLY check if the *debounced* state is LOW (pressed) AND
// if we haven't already acted on this press
if (reading == LOW && !buttonPressed) {
// Perform the action (Toggle the LED state)
ledState = (ledState == LOW) ? HIGH : LOW;
digitalWrite(LED_PIN, ledState);
Serial.print("LED Toggled. New State: ");
Serial.println(ledState == HIGH ? "ON" : "OFF");
// Mark the press as handled so it won't toggle again
// until the button is released and pressed again.
buttonPressed = true;
}
}
// Save the reading for the next loop iteration
lastButtonState = reading;
}
Code Explanation
- INPUT_PULLUP: Ensures the button pin is HIGH when untouched. Pressing the button pulls the pin LOW.
- State Change Detection: The code only checks for a toggle when the button state changes from its previous state (currentButtonState != lastButtonState).
- Software Debouncing: The millis() function is used to create a non-blocking delay, ensuring that a state change is only registered once every 50ms, effectively filtering out mechanical noise.
5. Compiling and Running the Project
Step 1 – Build
Click the Verify button (checkmark icon) in the Arduino IDE to compile the sketch.
Step 2 – Upload
- Connect your Arduino board via USB.
- Select the correct board and COM port.
- Click the Upload (arrow icon) button.
Step 3 – Test
- Open the Serial Monitor (Tools > Serial Monitor).
- Press the KY-004 button once. The built-in LED (Pin 13) should turn ON.
- Press the button again. The LED should turn OFF.
- The Serial Monitor should print the status change cleanly, without multiple “Toggled” messages per press, thanks to the debouncing code.
7. Hands-On Lab Recap
You’ve learned:
- How to use the Arduino’s internal pull-up resistor via INPUT_PULLUP.
- How to perform non-blocking debouncing using millis() to filter button noise.
- How to manage a digital state (toggling) with a momentary switch.
This skill is essential for using any form of user input in an embedded system.
8. Common Issues & Fixes
| Issue | Cause | Solution |
|---|---|---|
| LED toggles multiple times per press. | Debouncing issue. | Increase the debounceDelay value (e.g., from 50ms to 100ms). |
| LED is always ON and doesn't respond. | Wiring error or incorrect Pin Mode. | Ensure the S pin is connected to the digital input and the pinMode() is set to INPUT_PULLUP. |
| Button only works when held down. | Using simple if (currentButtonState == LOW) without state management. | Use the provided state change detection logic (Section 4) to ensure the LED state toggles only once per press event. |


