# Rail to rail +12/-12 V square wave generation with microcontroller

I need to generate a +/-12 V square wave, +/-0.4 V tolerance is allowed. The purpose is to drive the pilot signal of an electric vehicle level 2 charger, for those curious.

EDIT (clarification): what I'm trying to design here is the EVSE controller depicted below (the part enclosed in red). As you can see, the output of the circuit is +/-12 V PWM signal in series with a 1 KΩ resistor that is normally open-ended if no car is connected, or pulled to ground through different resistance values by the car to signal different states when it's connected to said car.

END OF EDIT

This is both a hobby project and brain exercise for me, so I would like to use discrete components that I already own, namely BJTs and resistors, while avoiding opamps since the ones that can achieve rail-to-rail outputs within the desired specs are hard to source for me. I'm also aware that a simpler solution would be a MOSFET push-pull stage but as I mentioned before, this is also about trying to understand BJTs better.

This is the schematic I came up with:

simulate this circuit – Schematic created using CircuitLab

Note that I used a common-emitter push-pull output as opposed to the more usual common-collector because the 0.7 V dropout of the emitter followers would be out of the required specs (+/-0.4 V around rails)

Q1 takes its input signal (0..3.3 V) from a microcontroller and drives Q2 between cutoff/sat.

When IN is 3.3 V, Q2 is off and node A has ~11 V which saturates Q4 while keeping Q3 "almost" off. As a result, OUT has a voltage of -11.8 V, which is well within the desired +/-0.4 V tolerance.

When IN is 0 V, Q2 is on, A has around -11.8 V, which saturates Q3 while keeping Q4 off. In this case OUT shows +11.8 V, which is also good.

However I can see two minor problems:

1. As you can see in the plot below, V(OUT)'s high to low propagation delay is about ~4 µs longer than that from low to high, and I can't really grasp why. As a result, OUT's duty cycle is higher than that of IN so it needs to be compensated from software, which I'd rather not do.

2. There's some shoot-through current through Q3 and Q4, though not alarming, I'd prefer to not have it. An inductance + fly-back diode might be necessary, but I wonder if this problem is derived from the previous one and fixing it would also fix this.

## Simulation of various solutions provided below

For study and comparison purposes. Input is set to 200 KHz to better display propagation delay. Plotted:

• input and output voltages
• $$\I_{c}\$$ of the output BJTs.

### Jonk

This is the currently accepted answer because of its simplicity, low shoot-through and propagation delay symmetry.

simulate this circuit

This has the problem of both output BJTs being active when IN floats, which could be solved by feedback resistor R8 which latches the circuit in its last status and, additionally, replacing the output resistor R6 with two 1 KΩ between the output collectors.

Also, note: propagation delay symmetry in this circuit depends on the choice of NPN/PNP transistors and, more specifically, their junction capacitances. Try simulating with different transistors or sweeping their capacitances to see the effect.

simulate this circuit

### Hacktastic

simulate this circuit

### Kuba

simulate this circuit

### AnalogKid

simulate this circuit

• V4 is upside down Apr 27, 2022 at 22:10
• @jsotola: bottom rail is meant to be -12v Apr 27, 2022 at 22:24
• that is correct ... the positive side of the V4 power supply should be connected to ground Apr 27, 2022 at 22:44
• @jsotola: there's no functional difference between -12v with (+) pointing up and +12v with (-) pointing up unless I'm missing something very basic here Apr 28, 2022 at 8:46
• @fraxinus: I'm very open to learning different ways. A few answers provided shoot-through protections, please post yours if you have an alternative/better one. Apr 28, 2022 at 8:48

I'll keep it fairly simple. (And it is very similar to hacktastical's approach except that the input isn't DC-blocked and I've tied the input stage's emitters just slightly differently.) Consider the following:

simulate this circuit – Schematic created using CircuitLab

Personally, I'd put resistors in the emitters of the output BJTs to limit the output current. But I don't know what you are driving or care about, so I left them off for simplicity.

Just did a simulation to make sure I wasn't a complete idiot:

That includes a $$\60\:\Omega\$$ to $$\100\:\Omega\$$ source impedance, which is likely for any MCU pin drive, and also $$\10\:\Omega\$$ emitter resistors for the driver BJTs. (But a very light $$\10\:\text{k}\Omega\$$ load, as I'm just giving it a whirl for now.)

• Neato. I like it. +1. I’d be careful about biasing that lower pre-driver though. Instead of 3.3V I’d choose 2.5V or so to make sure that the input will turn it off. Apr 28, 2022 at 15:58
• Would you mind explaining how this prevents shoot-through current, and what the role of C1 is? Thank you! This looks great in ltspice, both propagation delays and shoot-through. Apr 28, 2022 at 16:40
• @jamarju I suggested in the text, using emitter resistors. I still recommend doing that. And there will be some shoot-though. (C1 helps remove charge from the driver BJTs and lower shoot-through, but will need adjustment for specific situation.) So that can be readily adjusted to a nice minimum. Did you check in your simulation to see what it was there? And if you really want hard current limits added, that can be done, but you'll pay about 450 mV for the privilege.
– jonk
Apr 28, 2022 at 16:45
• Thanks for the explanation. I added 200 Ω resistors between the emitters and their respective rails (without modifying anything else) and that caused the output to drop to around +/-9 V, which I can't afford as the specs state a maximum 0.4 V drop. Without the resistors, the shoot-through is below 1mA. The load should always be around 2 KΩ Apr 28, 2022 at 16:52
– jonk
Apr 28, 2022 at 16:57

Shoot-through current, the problem is that there is a current path through R5 and R6 in series with the two transistors (basically, diodes) whenever the Q2 collector voltage is between +11.4 and -11.4, which is most of the time during a transition.

Solution - two 15 V zener diodes, one in series with each base. Now the series string is

+12 V > 0.6 V drop > 15 V drop > 15 V drop > 0.6 V drop > -12 V.

Adding this up, it comes to 31.2 V, which is greater than 24 V. Thus, there is no time when both base-emitter junctions are forward biased at the same time.

Connect the junction of the two zener diodes to the Q2 collector with one resistor; it acts as the current limiter for both Q3 and Q4. Let's call that a re-purposed R5. Note that the voltage drop across this resistor is way less than before because of the additional 15 V drop. You probably will have to decrease the value of R5.

Time lag - A saturated transistor turns off more slowly than it turned on. This is caused by charge stored in the base. The capacitance charges up after the base current exceeds the level required for saturation, so you don't see the effect at turn on. However, at turn off the excess charge must be depleted before the transistor begins to turn off, so you do see a delay.

The common solution is to put a small capacitor in parallel with the base resistor. At turn off this capacitor acts as a charge pump to drive the base below (for an NPN) the emitter. The excess base charge is dumped into the added capacitor more quickly that it would be dissipated in the resistor.

Another method is to prevent "hard" saturation by clamping the base to the collector through a Schottky diode; this is called a Baker clamp, and is the basis of Schottky TTL logic components.

https://en.wikipedia.org/wiki/Baker_clamp

• "A saturated transistor turns off more slowly than it turned on". Thanks for explaining this. I tried to implement and simulate your solution but I was not able to see an improvement over other solutions. Apr 29, 2022 at 20:38

First, let's note that this circuit is never going to perform exceptionally well as-is. Without adding semiconductors, that is. I'll try and tweak it somewhat below, but it'd be much easier to use any of the fully symmetric architectures to achieve inherent symmetry. This circuit has asymmetry due to Q1 and Q2 having no complementary devices to work with.

The simulation was not set up correctly. Both the Offset and Ampltiude of V1 should be set to 3.3/2. Yes, such formulas can be used.

simulate this circuit – Schematic created using CircuitLab

Let's look at their base currents (timestep=10ns), with V(IN) and V(OUT) below them for timing reference:

Q3 never fully turns off - it has about 3uA flowing through the base in the off state. Q4 does turn off fully. But this isn't the problem.

Let's observe how those transistors are driven, then. Let's speed up the square wave a bit, and sweep R3 from 400ohm to 10kohm:

simulate this circuit

At 200kHz, R3 above about 5kohm makes the circuit too slow to switch. That's because Q2 is driven deep into saturation. So, to speed things up, generally R3 needs to be lower. The lower the value, the faster Q2 turns off, but also the slower it turns on. The asymmetry grows the deeper Q2 is driven into saturation. When Q2 operates in very light saturation, the turn-on and turn-off times become almost equal. Just below R3 of 500 ohms, Q2's turn-on and turn-off become equally quick at about 600ns.

We can now see if negative feedback might make things less sensitive. Let's set R3 to 1kohm, and add an emitter degeneration resistor.

simulate this circuit

We can see that for R3=1k, R8=120 gives a reasonable degree of symmetry without changing anything else. For R3=600, R8=40 is the limiting value:

We can also check the sensitivity to Q2's beta - it's insignificant across the range of beta=50 to 150.

Let's now add a bypass capacitor to Q2's input resistor R2:

simulate this circuit

The relationship is nonmonotonic: the minimal falling edge delay is for C1=100pF. Values lower or higher give higher delays. We're now solidly in the 0.3-0.5us propagation delay territory.

We can improve symmetry now by letting Q4 turn on faster, by lowering R6.

simulate this circuit

Best propagation delay symmetry is around R6=50k. We can now see if R5's value can be improved as well.

Let's choose R6=10k for fastest falling edge, and select R5 for equal rising edge delay:

Reasonable symmetry is achieved with R6=10k, R5=20k. We note that at lower R5/R6 values, there's a bit of a raised pedestal before the rising edge. We could get rid of it by slowing things down a bit.

We can also evaluate the performance when faced with varying capacitive loading, as expected in a more realistic model:

simulate this circuit

The behavior is reasonable across a range of load capacitances:

We can now guess that R1 will need a speed-up capacitor as well. Due to the time scales involved, we need to get the simulation time step down to 4ns to avoid numerical artifacts.

The optimized circuit looks as follows:

simulate this circuit

The propagation delay is below 0.1us, and is fairly symmetric:

The performance is quite acceptable at 100kHz, and should be well-suited for operation at 10kHz. The the rise/fall propagation delay will further vary up to 50ns due to Q3/Q4 beta mismatch. 50ns over 100us is about 0.05% duty cycle error due to mismatch, and it's relatively stable otherwise, so for any particular selection of components, it's a constant error term.

The load resistance can go a bit below 1kohm, but not much:

The various optimization steps are shown below:

• Thanks for the excellent analysis and explanation. But isn't the light saturation's sweet spot too dependent on Q2's beta? Apr 27, 2022 at 22:50
• This is an incredibly educative and detailed response, I'm learning a lot from it. Thanks again! Apr 28, 2022 at 9:00

Here's a version that uses a dual Sziklai driver (simulate it here):

This design will render the full duty cycle range and provide strong +/-12V drive.

How it works: the pre-driver pair emitters are biased to 3.3V/2. As the input swings above and below that threshold by +/- Vbe, it activates the upper or lower transistor. So the input signal requirement is 3.3V/2 +/- Vbe, or about 2.25V / 1.05V.

The 100pf cap provides some negative feedback to control the slew rate. The 100k resistor provides some hysteresis.

[A short postscript. The Level 2 charger pilot signal is 1kHz, 10-90% duty cycle. Design accordingly.]

• This circuit's symmetry is simply beautiful. I'm going to simulate the crossover distortion as it's actually a PWM signal where the duty cycle carries information. All of you guys' explanations are helping me a lot! Apr 27, 2022 at 23:32
• +1 Great solution. As the delay happens in both edges it works at much faster switching rates without affecting the PWM duty cycle. Apr 27, 2022 at 23:45
• Varying the duty cycle will vary the average DC offset seen at the first pair, so be forewarned. If your PWM can’t tolerate that then revert to using a level shifter. Apr 27, 2022 at 23:53
• If this is for a charger circuit, and there is some possibility of noise kick-back to the controller, one thought would be to use optocouplers for the predrivers. This would break up a potentially troublesome ground loop. Apr 28, 2022 at 16:02
• The AC-coupled version didn't work. SAE J1772 specifies a 10 - 90% duty cycle for the pilot signal. I know you didn't mention PWM, but the spec is clear about this. As for noise kickback, that's always a concern, especially given that very high currents are sent alongside the pilot signal. There's also the possibility of a defective cable, receptacle, etc. leading to a short. Apr 29, 2022 at 15:45

In fact, it can be done with MOSFET, and 2N7002 is often used for this kind of switching.

SIMPLIS SIMULATION FILE:

https://www.asuswebstorage.com/navigate/a/#/s/7FFB1261A2544EC4B2232911FBCE6EDCY