My partner has a little battery-operated table lamp I got her on a trip abroad. You push a button, and it lights up. Push it again, and it dims to half intensity. Push a third time, and it turns off.
She asked me if I could put a timer inside it to turn itself off after 20 minutes, so she didn't have to worry about falling asleep with it on and draining the batteries.
The lamp has one IC, unmarked, but the PCB traces were easy to follow, and some poking and prodding with a scope and some jumper wires revealed how the lamp works:
Ideally, the timer would run off the LED supply, not the battery, so when the lamp turns off, the timer naturally stops and consumes no current. Time precision isn't critical, so some kind of RC delay suffices. Pulling the IC switch pin low is all that's needed, but the timer needs to be able run at full voltage, half voltage, and toggle the switch twice to get from full intensity to off.
So we need a timer and a bistable oscillator and some way to pull a pin to ground. This is clearly a job for the usual NE555 timer chip, but it needs 4.5v minimum to work. Instead, I stumbled upon the TLC551, which is the same kind of chip, but has CMOS inputs and can operate down to 1V. That's perfect. The CMOS inputs won't mess too much with the micro-amps needed for the long RC time constant, and it will tolerate working at half-voltage, even when the batteries get weak.
The supply to the TLC551 chips needs filtering so they can operate off the half-intensity square wave LED supply. The TLC551 needs so little current this was not difficult. A bit of trial and error gave a simple supply filter that kept the voltage high enough in all conditions.
The first TLC551, the Timer, is configured as monostable (one-shot) and monitors the rising voltage on the largest capacitor I could fit in the enclosure (1200 uF) and when the voltage reaches 2/3rds of the LED supply, the Discharge pin goes open-drain to GND (pin 1). I manually tweaked the resistance until the delay was very close to 20 minutes. There's no point in calculating it: with a charge current in the range of 4 to 5 micro-amps, input pin current, capacitor leakage, and any surface contaminant leakage would make any model inaccurate.
The second TLC551, the Toggle, is configured as astable (oscillator), and has its Discharge pin connected to the top leg (BAT+) side. Once powered on, it oscillates at 1.5 Hz, pulling the IC switch pin low repeatedly (and slowly enough to not be rejected by the debouncing circuitry) until the LED supply turns off, stopping all supply to the Timer, the Toggle, and the LEDs.
The unorthodox bit here, is how the Toggle power is switched on: its GND pin is connected to the Discharge pin of the Timer. Until the Timer triggers, the entire Toggle circuit is floating at BAT+ and does not draw any current. This prevents both interfering with the button pull-down, and having any leakage currents slowly charge the timing capacitor.
I built the Timer and Toggle dead-bug style on the PDIP ICs themselves, wrapped them in tape, stuffed them in whichever little crevice would hold them (the lamp is small, fits in your hand), and soldered jumper wires to connect it all up. I also printed out the schematic and squeezed it into another space. Should someone in the future (including me!) open up this lamp, they will know what and why. :)
The lamp re-assembled without any external changes, and now, you can turn it on, half or full, and after 20 minutes, it turns off. A nice side-effect is that when it shuts off from full intensity, it first switches to half intensity for a little over a second, then switches off, giving a nice transition.