Part of setting up a microcontroller when writing a piece of firmware usually involves configuring its connections to the outside world. You define a mapping of physical pins to intenral peripherals to decide which is an input, output, analogue, or whatever other are available. In some cases though that choice isn’t available, and when you’ve used all the available output pins you’re done. But wait – can you use an input as an output? With [SCART VADER]’s lateral thinking, you can.
The whole thing takes advantage of the internal pull-up resistor that a microcontroller has among its internal kit of parts. Driving a transistor from an output pin usually requires a base resistor, so would it be possible to use the pullup as a base resistor? If the microcontroller can enable or disable the resistor on an input pin then yes it can, a transistor can be turned off and on with nary an output to be seen. In this case the chip is from ATmega parts bin so we’re not sure if the trick is possible on other manufacturers’ devices.
As part of our 2025 Component Abuse Challenge, this one embodies the finest principles of using a part in a way it was never intended to be used, and we love it. You’ve still got a few days to make an entry yourself at the time of writing this, so bring out your own hacks!


i don’t see the abuse. this looks like entirely normal use of a gpio.
Until someone forgets and set that pin to output and high, it will result in high current draw that can damage either the transistor or the AVR chip.
This should not happen: a) pullup is just enabled if pin is configured as input, b) yes, driving high now on output can damage pin!
Transistor holds the output voltage now at 0.8V… a high current for internal transistor. But often CMOS output pins are “safe” for an external short, limiting the max. current possible by its own resistance (but now burning power inside the chip)
I took the article text to mean that the pin in question is a dedicated input.
In fact it’s further improved if the pull-up is enabled, OUT set to 0, and DDR used to toggle (assuming it’s a software bit-bang application). The base turns off much faster (orders of magnitude!) when current is withdrawn from it — BJTs are in fact voltage-mode devices, they just draw a convenient (sometimes..) base current to tell you when it’s on. ;-)
Sorry, what a nonsense. A pull-down would keep it a “real” input. An output driving low could be considered also as an input. The only way to use this “trick” (whis it is not) is just the fact, that pull-ups can only be enabled, when configured as input.
The pull-up can be very weak (e.g. 100K), so the transistor should be one with very low base current.
With MCU VDD 1V2 it might not work anymore.
BTW: a need to enable pull-up or not, and the actual input becomes floating when not enabled. This can cause an EMC issue: if input pin gets now a high voltage, e.g. due to electrostatic charge or leakage out of base from transistor – the MCU pin could be damaged.
Internal pull-ups is for avoiding inputs pins floating, not for driving external loads or acting as pull-up for open-drain logic.
Another “problem”: if no pullup enabled = input floating or even pullup enabled and transistor pulls now input to 0.8V… – putting the input pin voltage into “forbidden” voltage range… the internal input pin logic can now start to “oscillate”, trying to see a low or high, always toggling internal logic very fast. It can create a high current consumption, even burning so much current in internal input logic, that MCU (at least this pin) will get fried.
Technically, this input pin is floating or gets an input voltage level remaining in the transition zone (not low neither high, opening two transistors inside and creating a short current in internal logic). Both conditions (input floating and/or hanging somewhere in between) are not “allowed conditions”.
Just touching the input pin with your finger could damage the pin (or the ESD protection kicks in).
Or: the input pin will be “latched up”. So, it might work just once (and you have to power cycle the MCU).
BTW: why do you need this transistor?
If your solenoid control logic has a CMOS input – as to see in drawing, and as CMOS input not drawing “any” current…
Just toggle between pullup and pulldown. It will do the same job, but without any issues for MCU pin.
Just: a voltage translation to 6V does not seem to be CMOS.
You could also use an external pullup (but way larger as internal pulldown) and just toggle internal pull-down.
Use an external CMOS level shifter instead of transistor, at best one with Schmitt-trigger input and it works better.
I do not see really where the “strange” use case should be? This input pin could be also an open-drain output, acting also as an input pin. Just: as pullup you use internal pullup (just weak).
If open-drain drives low – it becomes an “input” (current flow) and input should read low.