So I think it's time for me to scale down my ambitions a bit.
Physically, of course. In the upper left we can see my security TV auto on/off circuit as it stood so far, with the blue rectangle in the middle being the microcontroller board. On the bottom right we can see the start of the new circuit I'm cooking up, with the silver square at the bottom being the microcontroller board.
The new board is a "Seeeduino Xiao", which is a fancy name for a SAMD21 chip on a 14-pin breakout board.
I didn't bother putting the sticker on mine, since the sticker is spectacularly tiny and also not printed at very high resolution, so it's a bit blurry and pointless.
I made this change for two reasons. The first is that the Nano board I was using previously had way more IO lines than I actually needed for this project, and the second is that the ATMega328p chip it uses was designed by a lunatic. The AVR architecture has really peculiar external interrupt handling, a surprising shortage of timer/counters, and a shockingly slow CPU core compared to the SAMD21. I'm sure there's other differences as well but these are the main points that convinced me to switch.
For reference, this is how small the new board is.
One of the other changes I decided to make was adding an OLED display, given that they're only about $2 each. I figure it'll be nice to have a little status indication, and drawing little glowing pictures is gonna be more fun than just making single LEDs blink.
Of course it's also very tiny, so I'll need to make sure I don't get too carried away with how much I try to cram onto the display.
So now begins the task of transplanting the supporting circuitry from the old board to the new, starting with the 556 debouncing circuit for the switch input.
This was the most complex bit in terms of part count, though the principle of operation is fairly straightforward. It's just a pair of one-shot timers, after all.
But transplanting this circuit also came with some new challenges. The old board ran on a 5v supply and was happy to take 5v inputs as a result. The new board runs on a 3.3v supply because it's not stuck in the stone age. The NE556, however, is stuck in the stone age and has a minimum supply voltage of 4.5v, essentially restricting it to 5v (and up) operation.
Now just powering up the 556 wasn't going to be a problem because the board comes with a 5v supply pin, but getting those 5v signals into the board meant I'd need to level shift them down to 3.3 volts.
I decided to do this by inverting each of the signals through a common-source open-drain BS170 mosfet, using the internal pull-up resistors on the microcontroller to terminate them.
Why a mosfet though? Why not a resistor divider or a bipolar transistor?
The answer is failure modes. Suppose we hook a resistor divider up so that the pin input voltage is taken part way between the 556 output and ground. Everything goes fine, unless the ground connection comes loose, at which point the full 5v gets blasted into the microcontroller and fries the chip. Not failsafe.
The same story happens with a bipolar transistor: everything is fine and dandy so long as the emitter is tied to ground, but if the ground connection is cut then the base-collector junction will become forward biased and the microcontroller again gets fried with (a bit less than) 5v.
The mosfet solution is safe from this, though, as its gate pin is electrically isolated from the source and drain. If the source pin becomes disconnected, then the drain simply floats. There's no possibility of the gate voltage passing through the device unless the transistor itself is destroyed and shorted out internally.
Also I just happen to like mosfets, I think they're kind of under appreciated.
Now with that said I will most likely be sticking with a bipolar transistor for driving the IR LED. Since the LED is modulated at a relatively high carrier frequency, the gate capacitance of a logic level mosfet like the BS170 might load the microcontroller's output pin excessively, and while there's certainly plenty of ways to get around that I don't really feel like adding extra components to compensate when I can just avoid the problem altogether by using a BJT.