Level shifting 3.3V to 12V without inversion

I'm working on a project using a Raspberry Pi 4 to send control pulses to an external circuit. The GPIO ports on the Pi are at 3.3V high. The external circuit expects high signals of 12V. I came across a thread on this forum of someone who also needed to level shift 3.3V logic to 12V:

The circuit is simple enough for me, but unfortunately, it inverts the signal. We'd like the output to be low, then send a high pulse of specified duration. But, from the animation in that thread, the signal would normally be high and then a short negative pulse would pass.

Is there a way I can level shift 3.3V to 12V without inverting? Could I attach the collector of the transistor to the base of another BJT to invert again?



You could invert the code logic in your sketch.

@LarryD couldn't this be achieved with a single MOSFET without the need for inverting?

What if you leave the collector and pullup as is, but connect the base to your 3.3V supply through the base resistor, and connect the emitter to your logic output? When your control output is high, the base and emitter are the same voltage, so no current will flow and the transistor will be off. When your control output is low, base current will flow and the transistor will turn on. That would give you non-inverting logic. However, that means if the output is normally low, the transistor would be normally on, and current will be flowing most of the time. If a battery is involved, you probably want the transistor to be off most of the time. So changing your code logic may be the better choice.

Ever the "XY Problem". :grin:

And indeed, the answer is to use the simplest circuit which inverts, and change your code to do the inversion.

That is the whole point of using a microcomputer! It does the work for you! :sunglasses:

Yes, you use an optocoupler. However the bandwidth is limited, without knowing what exactly you are trying to do its not clear if this will work for you. Please explain the pulse requirements of the external circuit.

I guess you could use a single-supply comparator in non-inverting mode. The comparator's output will depend on its supply - use a 12V supply and at its signal input end, compare the 3.3V signal against a 1V reference (zero might result in false switching of the comparator).

Thank you all for your advice. I decided to take the advice of switching the logic in my code to start high and send low for the pulse, which when inverted after shifting to 12V, sends the desired signal, using the 2N222 circuit I linked above. I had thought about just switching the logic around, but being a novice, was worried that we might accidentally send a high signal before the rest of the experiment was ready.

So, we're trying to use an external trigger mechanism for an energy beam to turn on (rising edge) and off (falling edge). I had imagined that we'd get the beam ready for trigger, then run the script. The Pi circuit would send a trigger pulse and the beam would turn on and then off. But with the logic reversed, I was afraid that if we got the beam ready, the Pi circuit, inverted, would start off with high output (since the GPIO is normally low) and the beam would just be triggered immediately.

Again, being a novice, it took me a minute to realize I could add a pause in the script. So basically, inverting the logic, we run the script, it sets GPIO to high (inverted output to low), pauses and waits for any key input. Then we get the external beam ready to go. Then just hit any key to continue the script as before.

Still, I'd like to learn more and will read about MOSFETs, opto-couplers and the op-amp comparator as a way to level shift. I know each must have limits on delays, rising and falling edge times, etc.

I'm not terribly sure yet what the precision needs of our experiment is yet. We're testing the beam's external triggering system - basically, how long does it take to ramp up or shut off when we trigger it to? We have commercial, high-frequency equipment for measuring. But for control signal, we just need something that can trigger the beam for varying lengths of time. The pulse length will be on the order of 1s. The vendor guarantees beam off (what we're primarily interested in) within 100ms. I asked a vendor engineer how much better does the system perform than the guarantee and didn't know but was curious to find out. We might try to shorten the interval width as much as possible, or lengthening it, or if sending a series of pulses (beam gating), changing the interval between pulses. The vendor says there's no constraint between on and off. And at least 31 seconds between off and on, to guarantee no delay with beam on. So, I'm guessing our bandwidth needs aren't high?

So far, I've only tested the circuit against my hobby oscilloscope, and playing with the precision of beam on time, it seems like I can get something like ~10 ms variation on beam on time reliably. Since following advice here and inverting the logic, I've delivered the circuit to the lab and demo'd it using just my scope. Next week, we'll test it against the commercial scopes and try it on the beam system.

10 ms? That is super slow! You should have no problem with any of the proposed circuits. If it were 10 us it could require some thought. If you get into trouble I would suspect the Pi - AFAIK unless you are using RTOS or something similar the OS may decide your application is not important at the moment and freeze it for many long milliseconds. I have little experience with Pi but it is said for timing critical tasks it is better to use Arduino (or other simple MCU) controlled from the Pi.