A battery-powered, touch-controlled LED lamp built with an Arduino (ATmega328P). Tap to toggle the lamp on/off, hold to smoothly dim. Brightness is saved to EEPROM and the microcontroller enters deep sleep when the lamp is off for minimal power consumption.
- Touch on/off - Quick tap toggles the lamp
- Smooth dimming - Hold to adjust brightness continuously
- Direction memory - Dimming direction alternates each hold (up then down, etc.)
- Brightness persistence - Last brightness level saved to EEPROM and restored on power-up
- Deep sleep - MCU enters
SLEEP_MODE_PWR_DOWNwhen lamp is off, waking on touch via interrupt - Ultrasonic PWM - Timer1 set to ~31 kHz to eliminate audible coil whine from the boost converter
- Power optimization - Unused peripherals (ADC, SPI, TWI, USART, Timer2) disabled to reduce current draw
3D printed design for desk lamp: https://makerworld.com/en/models/2407165
Short assemble video and demonstration:

| Component | Purpose |
|---|---|
| Arduino Nano / ATmega328P | Microcontroller |
| TTP223 | Capacitive touch sensor |
| TP4056 | Li-Ion battery charger module |
| Boost converter (set to 12 V) | Steps up battery voltage for LED strip |
| IRLZ44N N-channel MOSFET | Switches the 12 V LED strip via PWM |
| 10 kΩ resistor | Gate pull-down on IRLZ44N (ensures LED off when MCU is unpowered) |
| 100 Ω resistor | Gate series resistor (limits ringing / inrush) |
| 12 V LED strip | Light output |
| Li-Ion 18650 battery | Power source |
| Jumper | Setting | Effect |
|---|---|---|
| A | OPEN | Active HIGH output |
| B | OPEN | Momentary mode |
TTP223 OUT ──> Arduino Pin 2 (INT0, wake interrupt)
Arduino Pin 9 ──> 100 Ohm ──> IRLZ44N Gate
│
10k Ohm
│
GND
IRLZ44N Drain ──> LED Strip (−)
IRLZ44N Source ──> GND
Boost Converter 12 V OUT ──> LED Strip (+)
Battery (+) ──> TP4056 B+ ──> Boost Converter IN
-
Startup - PWM frequency is set to ~31 kHz (ultrasonic). The saved brightness is loaded from EEPROM. The lamp starts in the OFF state and immediately enters deep sleep.
-
Touch to wake - A rising edge on Pin 2 fires an interrupt that wakes the MCU from sleep, toggles the lamp ON at the saved brightness.
-
Tap (< 300 ms) - Toggles the lamp on or off.
-
Hold (>= 300 ms) - While the lamp is on, brightness ramps up or down. On release, the direction reverses for the next hold. The new brightness is saved to EEPROM after a 2-second debounce delay.
-
Sleep - When the lamp is off and the touch pin is idle, the MCU enters
SLEEP_MODE_PWR_DOWN, drawing minimal current until the next touch.
Key constants in the sketch:
| Constant | Default | Description |
|---|---|---|
HOLD_THRESHOLD |
300 ms | Tap vs hold detection threshold |
DIM_STEP_INTERVAL |
20 ms | Speed of brightness ramping |
DIM_STEP |
3 | Brightness change per step (0-255 range) |
MIN_BRIGHTNESS |
10 | Lowest dimming level |
MAX_BRIGHTNESS |
255 | Full brightness |
DEFAULT_BRIGHTNESS |
128 | Initial brightness on first boot |
SAVE_DELAY |
2000 ms | Delay before writing brightness to EEPROM |
- Open
LedLamp-withTouchButton.inoin the Arduino IDE - Select your board (e.g. Arduino Nano, ATmega328P)
- Select the correct COM port
- Click Upload
This project is open source. Feel free to use and modify.