DIY 14kW Induction Heater
by Learning on Demand in Circuits > Electronics
2348 Views, 4 Favorites, 0 Comments
DIY 14kW Induction Heater
Hello there! A while ago, I made a 4 kW induction heater capable of melting copper, steel, brass, and aluminium. Since then, I've rebuilt almost all of it, and this version has been pushed to 14 kW from three-phase mains. It melts steel, and it has made calcium carbide at well over 2000 °C. For more info and footage, watch my YouTube videos on the topic here. The biggest lesson from the upgrade: making the power stage bigger is the easy part. What kills big inverters is mostly transformer core saturation. My first version of this Instructable didn't cover it at all, because I hadn't run into it yet. At 4 kW I got away with it. At 14 kW I didn't. So a large part of this guide is about that.
I've written this so you can build one at whatever power level you want. The architecture is the same at 2 kW and at 14 kW; what changes is the switches, the bus voltage, the turns ratio and the capacitor ratings, and I'll show you how to size those. I have only pushed mine to 14 kW, so that's the number I can vouch for.
What's new compared to the 4 kW version:
- IGBT full bridge (2× Infineon FF200R12KS4) on a ~400 V three-phase bus, instead of four MOSFETs on 230 V single-phase
- Two gate drive transformers, so the bridge gets real dead time
- NPN/PNP clamps on the gate drivers, so the gates always start from −12 V
- Core saturation protection: DC-blocking capacitor, half-width first pulse, bleeder and restart lockout
- A rewritten controller (V3) that approaches resonance from the safe side and has a hardware safety supervisor and watchdog
This isn't a project for complete beginners in electronics, and the 14 kW version is even less so than the old one. That being said, I hope it motivates you to learn everything you need to understand and build it yourself. There's an endless supply of electronics knowledge on the internet; start with smaller and easier projects, and once you feel ready, come back to this one. You've got this!
In this Instructable, I just show you the way I built it; you're free to make your own changes as you see fit.
Video (Part 3, the 14 kW upgrade): https://youtu.be/7b1zsku5o-A.
Code and schematic: https://github.com/Zocum/induction-heater (use the V3 folder). You should also be able to find a PDF of the schematic somewhere in this Instructable.
⚠️ Safety first
This machine rectifies mains to ~580 V DC, which is lethal, and the DC link stays charged after you switch it off. The tank rings at several hundred volts and hundreds of amps, even at low input voltage. Molten metal near a water-cooled coil is a steam-explosion risk if a crucible cracks. Never work on it energised, always check with a meter that the bus has discharged, and bring it up at low voltage from an isolated supply first (see the bring-up step).
Downloads
Supplies
Supplies
These are the components I'm using. Feel free to use different ones if you need to and if you know what you're doing. The next step explains what to change for a different power level.
This is not a cheap project. The old 4 kW version cost me $400–600 on top of the tools, mostly for the power capacitors and the MOSFETs. The 14kW added another ~$600 on top. If you don't have them yet, factor in another $200–600 for a decent oscilloscope and $100–200 for a soldering station and a DC bench supply. Try to get the most expensive parts second-hand, especially the resonant capacitors and the IGBT modules.
Tools
- Oscilloscope, at least 2 channels. Handheld ones are cheaper.
- A decent soldering station. Don't buy the cheapest crap, or you'll go bald before you finish the build.
- ST-Link V2 programmer to flash the STM32.
- A DC bench supply, and ideally an isolated high-voltage DC supply for the first power tests (I used a 3 kW / 250 V Mean Well).
Controller
- STM32F103C8T6 "Blue Pill" (x1). If you use a different one, the timer code will need adapting. Avoid microcontrollers with a WiFi antenna; they pick up EMI from the power stage and crash, potentially mid-melt, which isn't very healthy for your transistors.
- 12 V power supply, at least 100 W, for the PCB, fans and pumps, plus a 12 V → 3.3 V buck converter for the STM32 and the OLED.
- LM339 comparator (x1), with a 300 kΩ hysteresis resistor. It turns the feedback signal into a clean square wave. It's slow, but it works; a TLV3501 would be the faster upgrade.
- I2C OLED 128×64 (SH1106), DS18B20 water temperature sensor, 2 push buttons (frequency up/down), 2 switches (PWM enable and lock), a potentiometer (run timer), a relay.
- A solderable prototype PCB, big enough for everything.
Gate drive
- MIC4422 (non-inverting) and MIC4421 (inverting), 2 of each (grab spares). The STM32's pins are far too weak to drive a gate drive transformer, so these chips take the signal and make it strong. Each GDT gets one of each, on the two ends of its primary.
- EPCOS B64290-L40-X830 N30 ferrite rings (x2), one per GDT. If you use a different core, it needs a high inductance per turn (A_L above ~2000 nH).
- 2× 2N2219 NPN, 2× PNP (forgot what part number...), 1 kΩ and 4.7 kΩ resistors, 10 kΩ pull-up/pull-down resistors (for the clamps).
- Capacitors: 6.8 µF / 50 V film and 100 nF ceramic at each driver's supply, 22 nF at each driver output, 1 µF / 50 V ceramic DC-blocking cap on each GDT primary.
Inverter
- Infineon FF200R12KS4 IGBT half-bridge modules (x2), 1200 V / 200 A. Two modules = one full H-bridge.
- Per gate: 2 Ω resistor with a 1N4148 across it, 5.6 kΩ gate-emitter resistor, two back-to-back 15 V zeners, and a small (~20 µH) common-mode choke.
- DC link film capacitors right at the modules: 4x (2 per IGBT brick) Vishay MKP1848620094P5 (20 µF / 900 V). These are as important as the transistors themselves. Also 2x WIMA FKP 1 0,022 uF, one in parallel with each Vishay MKP1848620094P5 pair.
- Heatsink (water-cooled aluminum block in my case) and thermal interface material (20W/mK thermal pads).
Coupling transformer
- Magnetics ZP48613TC ferrite rings (x5), P material, stacked. Either 42-turn primary with 2-turn secondary, or 21-turn primary with 1-turn secondary; Make the decision based on what frequency range you plan to operate at. More on that later.
- 12 AWG flexible wire, or Litz wire if you can (a pain in the backside to make, but better).
- DC-blocking capacitor in series with the primary: I reused a CELEM C500T (1.4 µF / 1100 V / 600 A) from my old resonant tank, but other film capacitors will work too; for example, one Vishay MKP1848620094P5 would work here too.
- Bleeder across the DC-blocking capacitor in order to discharge it before starting up the inverter again: 3× 100 kΩ / 5 W resistors in series.
Tank and cooling
- Resonant capacitors: 2× 10 µF / 700 Vrms / 1000 A (Anxon) in series, giving 5 µF / 1400 Vrms. Celem and Illinois Capacitor also make good ones. They must be water-cooled and have a high kVAr rating.
- Soft copper tube, at least 8 mm OD, for the work coil. Bigger = less resistive loss, but harder to bend without it collapsing.
- Copper bus bars (at least 3 mm thick), flare fittings, silicone hoses.
- 12 V water pumps (x2, ~0.5 bar, 10 L/min), radiators with fans (at least 2: one loop for the tank, one for the inverter), 12 V fans for the PCB.
Feedback
- Ferrite ring FT240-77 (x1) and ~20 m of 0.22 mm (31 AWG) enamelled wire for the current transformer (100 turns), with a 20-100 Ω burden resistor.
- Back-to-back zeners to clip the CT signal before the comparator.
To power the inverter
Pick one; the next step helps you decide.
- A DC power supply. The safest option, since you don't have to mess with mains. My 3 kW Mean Well (250 V / 12 A) is what I started with, and it's still what I use for the first low-voltage test of any change.
- Rectified single-phase mains (~325 V DC). Full-bridge rectifier (I used a GBPC5006, it also needs a water-cooled aluminum heatsink), smoothing capacitors, a choke, and a precharge circuit (a lightbulb through which the current flows when charging up the capacitor bank. It is necessary because an empty capacitor is basically a short circuit). This is what my 4 kW version ran on.
- Rectified three-phase mains (~565–580 V DC). What the 14 kW version runs on: 3-phase rectifier (VS-70MT160PAPBF, it also needs a water-cooled aluminum heatsink), Hammond 195R10 choke (50 mH), 420 µF / 1100 V MKP bus capacitor (EPCOS B25620C1427A101), precharge resistor/NTC with a bypass contactor, 400 kΩ bleeder, RC snubber (407 nF + 10 Ω), DSEP60-12AR freewheel diode, MOVs, 3-pole breaker.
I hope I didn't forget anything. If so, let me know in the comments or by email (gesuendergeist@gmail.com).
How It Works, and Choosing Your Power Level
The chain
The heating happens in the resonant tank: the work coil plus a capacitor bank. At the resonant frequency, since we have a series LC tank, the coil's inductance and the capacitors cancel each other out, so a small voltage pushes a huge current through the coil. That current makes a rapidly alternating magnetic field, which induces eddy currents in whatever metal (or graphite) sits inside, and those heat it up.
The tank needs hundreds of amps at a few tens of volts, but the mains gives hundreds of volts at a few tens of amps. The coupling transformer converts one into the other. Its secondary is the tank loop itself, so the transformer's secondary, the coil and the capacitors are all in series: a series resonant tank. Mine is 42:2, a 21:1 ratio, so ~27 A in the primary becomes ~560 A in the tank.
The H-bridge chops the DC bus into a square wave. The STM32 measures the timing of the tank current with a current transformer and keeps adjusting the frequency so the bridge always switches just above resonance. The gate drive transformers carry the switching signals from the low-voltage controller to the IGBT gates, which float between 250 VDC and 580 VDC, depending on what power source I'm using (Either a DC bench power supply, mains 1-phase rectified, or mains 3-phase rectified).
Choosing your power level
Four decisions set how big your heater is.
1. The bus voltage. Rectified 230 V single-phase gives ~325 V DC; rectified 400 V three-phase gives ~565–580 V DC. That sets the voltage class of your switches: 600–650 V parts for single-phase (I used IXFN56N90P MOSFETs in the 4 kW version, which are 900 V and had plenty of headroom), 1200 V parts for three-phase. Leave at least 1.5–2× headroom for spikes.
2. The turns ratio. This is your main power knob. A full bridge's square wave has a fundamental of about 0.9 × V_bus (RMS), and at resonance the tank looks like a small resistor R. So roughly:
P ≈ (0.9 × V_bus / a)² / R, with a = N_primary / N_secondary
You can't really measure R (it changes with the load, the temperature, and the coil), but you don't need to. The formula tells you that power grows with the square of the bus voltage and falls with the square of the turns ratio. Halve the ratio and you roughly quadruple the power. That's why, in the old version, I used fewer primary turns for graphite: it's so resistive that it needs more voltage across the tank to take the same power. Start with a high ratio (low power) and work your way down.
3. The tank capacitors. Once you know your power, check your capacitors. With my numbers at 14 kW, the tank drive voltage is 0.9 × 580 / 21 ≈ 25 V, so the tank current is about 14,000 / 25 ≈ 560 A. The voltage across the capacitors is that current times their reactance:
V_C = I / (2π × f × C)
At 25 kHz and 5 µF that's about 720 V RMS, which is why I put two 700 Vrms caps in series, so I then have 1400Vrms of headroom. Alternatively, I could use a 10uF capacitor instead to lower the capacitive reactance. This is also the reason why these power resonant capacitors are rated for different frequency ranges; you must respect these ranges to avoid catastrophic damage to the capacitor. Check both voltage and current ratings, and always start with something in the coil: an empty coil has a very high Q, and the capacitor voltage can climb far higher than it is rated for.
4. The coupling transformer core. More power at a lower frequency means more volt-seconds on the core, and that's where saturation comes from. Step 7 shows you how to calculate the minimum number of turns for your bus voltage and frequency. Do that calculation before you wind anything, or else you're at high risk of destroying your power transistors.
Set Up Microcontroller & Gate Drivers
**How to interpret the images in the right order: (1) first breadboard version, (2) first working design hand-soldered onto a PCB and placed inside the red enclosure, seen in the first 2 videos of the series, (3) & (4) show how I moved the same PCB into the new enclosure for the 14kW version and then added more stuff to fix previously existing problems which I explain and show how I fixed in the third video of the series.**
It all begins with the microcontroller. The V3 firmware is a PlatformIO project in VS Code (the old version was a single Arduino IDE sketch; it's still in the repo as V1, but please use V3). Install PlatformIO in VS Code, open the V3 folder, connect the ST-Link for communication between the STM32 and your computer, and upload. Everything you'll ever need to tune is in one file: include/config.h.
Pins used:
PA8 -> PWM → gate drivers for GDT B (TIM1_CH1)
PB13 -> Complementary PWM → gate drivers for GDT A (TIM1_CH1N)
PB8 / PB9 -> GDT_EN / GDT_NEN — clamp control (Step 4)
PA0 -> Tank current zero-crossing from the LM339
PA1 -> DS18B20 temperature sensor
PA2 -> Run-timer potentiometer
PB0 -> Relay (follows the PWM state)
PB1 -> PWM enable switch
PB12 -> Lock switch
PB14 / PB15 -> Frequency up / down buttons
PB6 / PB7 -> OLED I2C (SCL / SDA) --Important: keep both wires physically away from each other to avoid interference that could crash your MCU; better yet, twist SCL & GND wires together, and also twist SDA & VCC wires together. I also mention it in the schematic; also don't forget the low-pass RC filters right at the MCU pins.--
In the old version, one PWM signal from PA8 went to a MIC4422 and a MIC4421. The two chips drive the two ends of the GDT primary: the MIC4422 passes the signal as it is; the MIC4421 flips it upside down. So when one end is at +12 V, the other is at 0 V, and vice versa, which puts a full ±12 V swing across the primary. That trick is still here, but now there are two such driver pairs, one per GDT, fed by two different timer outputs. The next step explains why.
As before: the PCB looks horrible, but if you can follow the schematic, wire it up on a breadboard first and you'll see it isn't that complicated.
Two Gate Drive Transformers (GDTs) = Real Dead Time
**How to interpret the images in the right order: some images show the old, single GDT topology I was using, then other, newer images show the current topology where I use 2 GDTs **
A GDT is a small transformer that carries the gate signals across to the IGBTs while keeping the power stage galvanically isolated from the controller: no direct current path between the high-voltage side and the PCB.
Why dead time matters
In each leg of the bridge, the top and bottom transistor must never be on at the same time. If they are, even briefly, the bus is shorted straight through them. That's shoot-through, and at 580 V it destroys a module instantly.
IGBTs make this harder than MOSFETs, because they don't turn off cleanly. After the gate goes low, a tail current keeps flowing for a while as the charge inside the silicon recombines. You can't pull it out faster through the gate; you can only wait it out. So we need a dead time: a gap after one switch turns off before the other one turns on. For the FF200R12KS4 I use at least 800 ns.
Why one GDT can't do it
My old build had a single GDT with four secondaries, one per MOSFET, fed by one square wave. The problem: a single square wave flips all four gates at the same instant. When one secondary goes positive, the opposite one goes negative at exactly the same moment. There's no gap between the top transistor turning off and the bottom one turning on, except whatever the gate resistors and delays happen to give you. With fast MOSFETs at 300 V I got away with it; with slow-tailed IGBTs at 580 V you can't.
How two GDTs fix it
I now use one GDT per diagonal. GDT A drives the top switch of leg A and the bottom switch of leg B; GDT B drives the other two.
The STM32's advanced timer (TIM1) makes two complementary signals, CH1 and CH1N, with a hardware dead-time generator. When one signal falls, the timer waits the programmed dead time before raising the other. During that gap, both signals are low.
Each GDT gets one of those signals through its own MIC4422/MIC4421 pair. Input high → +12 V across the primary; input low → −12 V.
A nice bonus: during the dead time, all four gates sit at −12 V, not at zero. Negative gate bias is what keeps an "off" IGBT off while its partner switches; otherwise, the Miller capacitance could force it on, creating a short circuit.
Winding them
Each GDT is 14 turns on a B64290-L40 N30 ring with five identical wires twisted together: one primary and 2 secondaries. I twist the three wires with a drill before winding. Beware the phases! Mark the start of every wire, because swapping one secondary's polarity turns a switch on when it should be off. Every GDT primary has a 1 µF ceramic DC-blocking capacitor in series.
The GDTs are transformers too, so they can saturate. At ±12 V with 14 turns on this core, they'd only saturate below about 4–6 kHz, far below anything the heater does, so the only real risk for them is the start-up problem in the next step.
There is a fantastic video on how to wind a GDT by Kaizer Power Electronics on YouTube. Watch it.
Downloads
The NPN/PNP Clamps — Always Starting From −12 V
This was a bug that made my bridge fail randomly at start-up at 580 V but never at 250 V.
The problem
Originally, both drivers of each GDT shared one input, pulled to ground through a resistor when PWM was off. With the input low, the MIC4422 outputs 0 V, but the inverting MIC4421 outputs +12 V (because it inverts the negative rail into the positive one, so to say). So while the machine sat idle, apparently doing nothing, 12 V of DC sat across the GDT primary and slowly charged its DC-blocking capacitor.
When I pressed start, that stored charge came out as a DC offset. Instead of a clean ±12 V square wave, the first gate pulses went up to about +20 V and down to only about −1 V. Over the next few cycles the whole envelope walked down until it finally settled at ±12 V (see oscilloscope image attached).
The +20 V wasn't the problem (the zeners clamp it anyway). The missing −12 V was. When one IGBT in a leg turns on, the midpoint swings by hundreds of volts in a couple hundred nanoseconds. That fast dV/dt pushes current through the Miller capacitance of the other IGBT, straight into its gate. The negative bias is the only thing holding that gate below its threshold. Without it, the "off" IGBT gets nudged on, and you have shoot-through.
It also explains why it only happened at high voltage: the Miller current scales with dV/dt, and dV/dt scales with the bus voltage. At 580 V the kick is more than twice as strong as at 250 V.
The fix
Make sure both driver outputs sit at 0 V while idle, so the GDT capacitor stays empty and the very first pulse is a proper ±12 V swing. (also see oscilloscope image)
My solution was to split the driver inputs, each fed from the PWM signal through its own 1 kΩ resistor, and add two transistors per GDT:
- An NPN (2N2219) from the MIC4422 input to ground. When on, it pulls that input low, so the MIC4422 outputs 0 V.
- A PNP from 3.3 V to the MIC4421 input. When on, it pulls that input high, so the MIC4421 also outputs 0 V.
Two STM32 pins control them: GDT_EN (PB8) drives the PNP bases and GDT_NEN (PB9) drives the NPN bases, each through 4.7 kΩ. When the clamp is engaged (EN low, /EN high), both transistors conduct and override the PWM signal; that's what the 1 kΩ resistors are for, so the transistor always wins against the MCU pin. When the clamp is released (EN high, /EN low), the transistors are off and the PWM passes straight through.
A 10 kΩ pull-down on EN and a 10 kΩ pull-up on /EN keep the clamp engaged even while the STM32 is resetting and its pins are floating. The safe state is the default state.
Together with the half-width first pulse (Step 7), the first gate pulse is now always a clean swing, and the start-up failures stopped completely.
(If you prefer logic chips to transistors, a 74HCT08 AND gate on the MIC4422 input and a 74HCT32 OR gate on the MIC4421 input do the same job.)
Inverter/H-bridge
**Again, here is a mixture of images from the old V2 version together with the final V3 build**
The GDT secondaries drive the gates of the four transistors of the full bridge, which, through the coupling transformer, drives the resonant tank.
In the old version, those transistors were four IXFN56N90P MOSFETs. Now it's two FF200R12KS4 IGBT modules. Each module is a half-bridge (two IGBTs in one package), so two of them make one full H-bridge. The bridge is driven diagonally, which is why each GDT drives one IGBT in each module.
Each gate gets the same little network:
- 2 Ω gate resistor (plus the 2.5 Ω inside the module) sets the switching speed.
- 1N4148 across the gate resistor for a faster turn-off path.
- 5.6 kΩ gate-to-emitter holds the gate off if the drive ever disappears.
- Back-to-back 15 V zeners clamp any spike below the gate's rating.
- A small common-mode choke on each gate/emitter pair keeps switching noise out of the drive. (This is actually not necessary, only recommended)
The DC link capacitors are still as important as the transistors themselves; trust me, you don't want to mess these up. Mount them right at the modules. The loop from the capacitors through a leg and back should be as small as physically possible, because every bit of stray inductance in that loop becomes a voltage spike at turn-off.
Cooling: the transistors need to be water-cooled. In the old build I mounted the MOSFETs on water-cooled aluminium blocks with 20 W/m·K, 2 mm thermal pads (at least 16 W/m·K, and the thinner the better), held down with zip ties, because my attempt at tapping the aluminium block was a total disaster. Now I've mounted the IGBTs to 2 water-cooled aluminum heatsinks, using the same thermal pads as before. The inverter loses much less energy than the tank, so its cooling loop can be small, but keep it separate from the tank loop. You don't want to stress-heat your transistors with water the coil has already warmed up; they have enough to do already.
Powering the Inverter
How it evolved
I first used a 3 kW DC supply (250 V / 12 A) from Mean Well. I still recommend it if you don't feel comfortable handling mains. Then I switched to rectified 230 V single-phase for more power: a GBPC5006 bridge on a water-cooled block, 3 mF of electrolytics, and a 5 mH / 20 A choke in the AC line to improve the power factor. It helped, but the voltage sagged from ~330 V at light load to ~250 V at 15 A, and the breaker still tripped at ~5.2 kW. For soft-charging the 3 mF capacitor bank (so it does not trip the breaker), I use a halogen lamp; when it goes out, it means the capacitors are almost full, and then I can close the main switch (see Falstad 1-phase simulation in the images).
The 14 kW version runs on three-phase. Three phases overlap, so the rectified bus is much smoother and higher (~565–580 V), and the current is spread over three wires.
The 14 kW supply
3-phase ~400VAC goes direct into 70A, 1.2kV rectifier. The rectifier feeds a choke-input LC filter: the 50 mH Hammond 195R10 choke followed by the 420 µF MKP bus capacitor. Film instead of electrolytics here, because the bus is high-voltage and the ripple current is large. Without the bus capacitor, my bus sagged to about 480 V on average under load; with it, it never drops below about 550 V.
A few things to keep in mind:
- Soft-charge. An empty capacitor bank is basically a short circuit. In the old, 4kW version, I charged it through a halogen lamp and then switched to the main path with a second breaker. Now the 420 µF MKP bus capacitor for the 580V version charges through a resistor/NTC, and a contactor bypasses it once the bus is up. Actually, I now have both versions in the same box: if I only have 1-phase available, I draw the power through the single-phase rectifier + 3mF electrolytic cap bank and 5mH choke inductor for PF, and then use it with the new H-bridge (including the extra 420uF MKP cap and 50mH choke, since they're now a fixed part of the DC bus). So I may run the same H-bridge at different voltage and power levels, depending on what I have at hand.
- The freewheeling diode gives the choke current somewhere to go when the load changes suddenly.
- Spikes. An RC snubber (407 nF + 10 Ω) across the rectifier output. My first power-up at 588 V destroyed a cheap DC panel meter and took the rectifier with it; the snubber came after that. A small fuse would make sense here too.
- Bleeder. 400 kΩ across the bus slowly discharges it after shutdown. Still, always measure before touching anything.
The Coupling Transformer and Core Saturation
This could arguably be the most important step of the whole guide. Many of my transistors have died to this.
The core material is still of utmost importance: P material (a manganese-zinc ferrite) is what I found to be the best, in five ZP48613TC rings stacked together. In the old version, I had two transformers, one with fewer primary turns for graphite and one with more for less resistive loads. Now there's a single one, 42:2, and this step explains why.
What saturation is
A transformer core cares about flux, measured in volt-seconds (V*s) or webers (W), although here I prefer to use volt-seconds directly (since 1 Weber = 1 V*s anyway). Too much of it and it will saturate. Think of the core as a magnet: every time you put a voltage across the winding, you magnetize it, either from south pole to north pole, or from north pole to south pole, or from neutral (if the machine hasn't been turned on yet and the transformer isn't operating) to south pole...you get it. Reverse the voltage for the same time, and you magnetize it the same amount in the opposite direction. There is a point at which the transformer won't take any more flux - or, to keep our analogy alive, you won't be able to 'magnetize' it any further. But as long as the flux level stays within the boundaries, everything's fine.
If the level reaches the rim, the core saturates. The primary inductance collapses, the winding stops being a transformer and becomes a piece of wire, and the H-bridge is suddenly switching into a short circuit across the bus. The current goes vertical in microseconds, and your transistors die.
The flux budget (the one formula you need)
How much a core can take in one direction:
λ_sat = N × Ae × B_sat
N is the number of primary turns, Ae the core's cross-section (found in the datasheet of the ferrite cores), B_sat the saturation flux density of the ferrite.
For mine: 42 turns, five stacked rings with 944 mm² total. P material saturates at about 0.5 T cold, but ferrite loses capacity as it heats up; at a realistic 100 °C it's about 0.39 T. Always use the hot number.
λ_sat = 42 × 0.000944 m² × 0.39 T ≈ 15.5 mV·s
That's the whole budget.
Each half-cycle, we pour in the bus voltage times half a period. But that's the full swing from one side to the other; if the flux is centred, it only goes half of that above the middle. So the steady-state peak is:
λ_peak = V_bus / (4 × f)
At 580 V and 25 kHz, that's 5.8 mV·s, about 37% of the budget. Healthy.
Cause 1: Running too low in frequency
Frequency is in the denominator. Lower frequency means longer pulses, more volt-seconds, less margin. A transformer doesn't have a maximum frequency; it has a minimum one. For mine, the absolute limit is:
f_min = V_bus / (4 × N × Ae × B_sat) --> f_min = 560 / (4 × 42 × 0.00090926 × 0.39) ≈ 9.4 kHz
This is exactly why I rewound it. With a 21-turn primary, the budget was only 7.7 mV·s and the minimum frequency ~19 kHz. When I moved to a bigger coil and a 5 µF tank resonating around 25 kHz (using my biggest coil), 21 turns would have run the core at 75% of saturation in steady state. So I doubled both windings to 42:2; same 21:1 ratio, same power, twice the flux budget. No new cores needed.
To size your own: decide the maximum bus voltage and lowest frequency you'll ever run at, and keep the steady-state peak below about half the hot saturation flux (about 0.2 T for P material). Then:
N_min = V_bus / (4 × f_min × Ae × 0.2 T)
For my core at 580 V and 25 kHz that gives about 31 turns; I have 42. The extra margin is for the start-up transients below.
Cause 2: Flux walking
Now imagine the positive half-cycle is slightly longer than the negative one. One transistor turns off 30ns later than its partner. Their on-state voltages differ by a fraction of a volt. The timer period is an odd number of clock ticks, so one half is 13.9 nanoseconds longer. Any of that, and every cycle you pour in a few more drops than you take out. The core never forgets. At 25,000 cycles per second, the level creeps up until it hits the rim. That's flux walking.
Fix: a DC-blocking capacitor in series with the primary. A capacitor can't pass DC, so any imbalance charges the capacitor a little instead of walking the core, and the flux stays centred.
This capacitor carries the full primary current, so it must be a real high-current film capacitor: at 14 kW and 25 kHz, mine drops about 120 V RMS. I reused a CELEM C500T from my old tank. Choose the value so it resonates with the transformer's leakage inductance well above your operating range (mine is around 126 kHz), not inside it.
Cause 3: The very first pulse
Everything so far is the steady state. My real problem was pressing start.
When the bridge is off, the flux sits at zero, not in the middle of a swing. If the first pulse is full width, it pours in a full swing starting from zero, so the first peak is double the normal one. At 25 kHz that's 11.6 mV·s, 75% of the budget on the very first stroke. At 20 kHz it would be 94%.
Fix: make the first pulse half width. Half a pulse lands the flux exactly where it would have been in steady state, and every pulse after that swings symmetrically around the middle. In the firmware, this is just a few lines (Step 10).
Cause 4: The DC-blocking capacitor itself
Here's the twist. The DC-blocking capacitor keeps the flux centered while running. But when you stop the bridge, the last pulse gets cut off mid-stroke, and the capacitor can be left parked at a random voltage. Press start again, and that voltage dumps into the transformer as a DC offset and saturates it. The part you installed to prevent saturation now causes it. On one occasion, I tripped the breaker at startup because the transformer saturated, short-circuiting the H-bridge.
It doesn't take much. The parked voltage rings slowly (~870 Hz for mine) against the transformer's magnetising inductance (about 24 mH), and every volt left on the cap eats about V × √(L × C) ≈ 0.18 mV·s of the budget. With the half-width first pulse, about 50 V left on the capacitor is enough to saturate my core on restart; with a full-width first pulse, about 20 V. On a 580 V bus, those are frighteningly small numbers.
Fix: a bleeder and a restart lockout. Three 100 kΩ / 5 W resistors in series (300 kΩ) across the capacitor drain it with a time constant of about 0.4 s. The firmware refuses to restart until 3 seconds after the last stop (about 7 time constants), so the cap is always essentially empty when the next start begins.
Cause 5: Heat
Ferrite's saturation flux drops as it heats up (roughly 0.5 T cold → 0.39 T at 100 °C for P material). A design that's fine cold can saturate after ten minutes at full power. Design with the hot value, give the transformer airflow, and keep an eye on its temperature during long runs.
Cause 6: The other transformers
The GDTs and the feedback CT are transformers too. The GDTs had exactly the same start-up disease (a charged DC-blocking cap in series with the output of the inverting gate driver), which the clamps in Step 4 cure. The feedback CT overheated during my 11 kW runs; lowering its burden resistor from 100 Ω to 18 Ω lowered the voltage, and with it the flux, on its core. However, 18 Ω of burden is too low for the transformer to pick up the current signal appropriately at < ~40 V, so when you are testing the bridge at lower voltages (10V, 12V, 15V, 20V, etc.), keep a higher burden resistor like 100 Ω (which will give you an easy time measuring the current on the oscilloscope since the current transformer has 100 turns). Although you could also go lower with the turns of the CT (current transformer), I found that 47 turns with a 47 Ω burden will work just as fine.
Summary
- Frequency too low -> Long pulses overflow the core. Fix: Enough primary turns for your lowest frequency (42:2 instead of 21:1).
- Flux walking -> Tiny asymmetries add up every cycle. Fix: DC-blocking capacitor in series with the primary.
- Full-width first pulse -> First flux buildup is double the normal. Fix: Half-width first pulse in firmware.
- Parked DC-block cap -> Leftover voltage adds a DC offset at restart. Fix: 300 kΩ bleeder + 3 s restart lockout.
- Hot ferrite -> Saturation flux drops ~20%. Fix: Design with hot B_sat, cool the core.
- GDT cap charged while idle -> Gates start without negative bias. Fix: NPN/PNP clamps (Step 4)
- CT burden too high -> CT core overheats. Fix: Lower burden resistor.
LC Tank
The resonant tank gets its power from the coupling transformer, which acts as a step-down transformer. It consists of the copper-tube work coil in series with the capacitor bank, mounted on thick copper bus bars.
It needs to be copper tube because water cooling is non-negotiable here; it will literally melt otherwise. Colder copper also has lower resistance than hot copper. The capacitors must be water-cooled as well, with a high kVAr rating, because the reactive voltages and currents are huge. My current bank is two 10 µF / 700 Vrms / 1000 A capacitors in series (5 µF, 1400 Vrms; for a couple of days, I also tried just one 10uF capacitor, but the resonant frequencies with the different coils it gave me were too low for comfort, which prompted me to return to 2, 10uF caps in series.), with aluminium heatsinks and thermal pads on the cooling water loop. Alternatively, you can use 10 or 20 smaller film capacitors in parallel. Film, please. Here electrolytics are forbidden by law, God, and the universe!
The coil. Fewer turns let you push more current into the workpiece, and vice versa. Make the coil only as big as you need to; mine is sized so my crucible, plus its insulation, fits nicely inside. The tighter you pack the turns (without them touching), the stronger and more concentrated the field in the workpiece.
Flare fittings make swapping coils easy. Tighten them properly: twice I had a fitting that wasn't making good contact, and it got incredibly hot, wasting energy into the cooling water and limiting the current I could push.
Resonant frequency. The coil's inductance and the capacitance set the resonant frequency. A magnetic workpiece pulls it down until it passes its Curie point and stops being magnetic, after which the frequency goes back up. Resistive loads push it up; the more resistive, the higher. With my current coils and 5 µF, the heater runs anywhere between 25 and 42 kHz depending on the coil and the load. The controller follows it automatically.
Cooling. Give the tank its own cooling loop, separate from the inverter. It heats up a lot. That is one 12V water pump for each of the 2 cooling loops. Before the water returns to the bucket reservoir, it goes through fan-cooled aluminum heat sinks (12V for the fans). This helps slow down the rise of temperature, and can even halt it if you're melting outside in winter. Unfortunately, unless you're mainly heating graphite and are operating outside with really low air temperatures, the puny 12V computer fans won't cut it: you will need to either periodically refill the buckets with fresh, cool water, or get yourself a heavy-duty water chiller like those Vevor sells. Especially when melting metals, since a lot of the power you're drawing will be dissipated as heat inside the work coil instead of the workpiece, because metals have much poorer coupling efficiency compared to graphite (although steel, if you can get it to fill most of the inner diameter of the work coil, shows a decent coupling efficiency too, but still bad compared to graphite or silicon carbide crucibles with a high graphite content).
Resonance Feedback
The feedback tells the microcontroller how far from resonance we are. It's a current transformer (CT): an FT240-77 ferrite ring with 100 turns of 31 AWG wire and a burden resistor, threaded over one of the leads of the coupling transformer's primary. Because the transformer is tightly coupled, that current is essentially the tank current scaled down, so its timing tells us where the tank is.
In the old version the burden resistor was 100 Ω; at 11 kW the CT core started overheating, and dropping to 18 Ω fixed it (but a bit higher will do too; keep it at 100 Ω whenever you are testing the bridge at low power (from 10V to 30V or so, otherwise the signal won't be strong enough for the STM32 microcontroller to detect. The CT signal is clipped by back-to-back zeners and then goes into the LM339 comparator, which turns it into a clean square wave for pin PA0. A 300 kΩ hysteresis resistor on the comparator stops it chattering around the zero crossing; adding it made the whole phase measurement much cleaner. The LM339's open-collector output is pulled up to 3.3 V, so the STM32 is never exposed to anything higher.
If the lock hunts in the wrong direction: your feedback is upside down (180° off). Swap the two CT wires (the one going to ground and the one going to the comparator), or swap the GDT primary connections, and that should do the trick.
The Code
The firmware is on GitHub in the V3 folder. You tune everything in include/config.h. This step explains what it does in plain words; if you want the register-level details, see the box at the end.
1. The metronome: TIM1 makes the square wave
TIM1, the STM32's advanced timer, counts at 72 MHz and switches its outputs halfway through each cycle, so:
f = 72 MHz / (ARR + 1)
ARR is the number the timer counts up to. At 50 kHz that's 1440 counts per cycle, so ARR = 1439 (the count starts at zero). To change frequency, the code just writes a new ARR. TIM1 also has the dead-time generator from Step 3, so CH1 and CH1N come out complementary with the gap built in. The CPU never toggles a pin itself; the timer does it all in hardware, even when the code is busy.
2. The stopwatch: TIM2 measures the phase
The question the controller keeps asking is: how long after I switch does the tank current cross zero?
TIM2 is a stopwatch that TIM1 resets to zero at the start of every PWM cycle. When the comparator's edge arrives on PA0, TIM2 latches its count in hardware, with zero software delay. That count as a fraction of the period, times 360, is the phase:
c
Edges that land right on top of a switching edge are thrown away as noise.
3. The steering: now much simpler
The old version used a full PID with gain scheduling and separate tracking and locked modes. It turned out that isn't needed. Frequency is already the running sum of all the corrections, so a single proportional gain is enough to drive the error to zero. V3 just does this, every 20 ms:
c
Inside a ±2° deadband it stops correcting, so it doesn't dither.
Don't be surprised that my target (TARGET_PHASE_DEG) is −122° and not something near zero. The measured phase includes the CT, the comparator delay, the dead time and the wiring, so the number that means "just above resonance" is different for every build. You find yours during calibration (Step 11).
4. Always approach from above
In the old version I ran right at resonance "because… YOLO". Not anymore. Above resonance, the tank behaves like an inductor and the transistors switch softly (ZVS). Below resonance, it behaves like a capacitor and they hard-switch, with nasty spikes. At 14 kW, that difference is the difference between a machine and a firework.
So when you flip the lock switch, the code starts 6 kHz above the last known resonance and walks down until it locks. If it ever falls through resonance, the phase suddenly jumps by more than 120°; the code sees that and starts again from above. If it loses the signal completely, it slowly creeps upward, the safe direction.
5. Dead time that adapts
At resonance the dead time sits at its 800 ns floor, and it grows by 100 ns per kHz as you go above resonance (up to 1.5 µs), because the current at the switching moment is larger there. A longer dead time shifts the measured phase, so the code adjusts the target to match. That way one TARGET_PHASE_DEG works across coils and loads.
6. Starting and stopping safely
This is where the saturation fixes from Step 7 live, in bridge.cpp:
c
The trick is the fourth line: starting the counter halfway through the first "high" phase makes the first pulse exactly half width. The clamps are released before that, so nothing slow sits between setting the counter and switching the outputs on.
When stopping, the outputs go off and the clamps engage immediately after. Then a 3 second lockout prevents a restart until the bleeder has emptied the DC-blocking capacitor.
Every normal stop is a soft stop: the code first ramps the frequency 7 kHz above resonance over about a second, then cuts the gates. That keeps the switching soft on the way out. The run timer (the pot, 0–5 minutes) does the same when it expires, but parks above resonance with the gates still running.
7. The safety net
The frequency tracking runs in the main loop. If the loop ever froze (a crashed display, EMI, a bug), the bridge would keep switching with nobody steering. V3 adds three layers:
- A dead-man supervisor (TIM4, 1 kHz interrupt). The main loop checks in constantly. If it's silent for 200 ms while PWM is on, the interrupt takes over, performs the soft stop, cuts the gates and latches a fault.
- The hardware watchdog (~800 ms). If everything else fails, it resets the STM32. After a watchdog reset, the controller refuses to start until you've switched PWM off and on again.
- An I2C guard for the OLED, so a display glitch can't freeze the loop in the first place.
All the buttons and switches also have a 30 ms glitch filter, because at 14 kW the switching noise is strong enough to fake button presses.
Controls
- PWM enable switch: master switch. Nothing switches at power-up; charge the bus first, then flip this.
- Lock switch: turns on the frequency tracking and starts the run timer. With it off, the bridge runs at the manual frequency.
- Up/down buttons: manual frequency.
- Pot: run time, 0–5 minutes.
- OLED: frequency (L = locked, F = free), temperature, phase and error, uptime, timer and safety state.
Under the hood (optional): what a register line looks like
If you've never seen this kind of code, a register is a block of bits inside the microcontroller that controls some hardware function. For example, GPIOA's CRH register is 32 bits wide and configures pins A8 to A15, four bits each. This line configures only pin A8:
c
0xF is binary 1111, one 4-bit field. The ~ flips it, so ANDing with it clears just A8's field and leaves the other pins alone. Then 0xB (binary 1011) is written in, which means "alternate function, push-pull, 50 MHz": it hands pin A8 over to the timer so the timer can drive it. The duty cycle is set the same way, with TIM1->CCR1 = (arr + 1) / 2, the halfway point of the count, which gives a 50% square wave.
Bringing Up and Calibration
General checkpoints as you build/rebuild/make changes:
- STM32 + oscilloscope. Once the code is uploaded for the first time, scope the PWM signals that will then go on to the gate drivers. Make sure they look okay (including correct dead time; my V3 code on GitHub should work right off the bat though) before you hook them up to the gate driver ICs. This will give you certainty that this first step is working, which will give you one less place to look for a potential error you might be hunting further down the line. Moreover, I advise you to internalize this mantra of thoroughly testing everything every step of the way, no matter how small, so you can catch bugs right when they happen and you don't take them with you to the next step(s) of the build and then you find yourself agonizingly searching for the bug all over the place or, even worse, incorrectly diagnose the problem and go down a completely erroneous rabbit hole.
- Scope the gates. Connect the GDTs to the IGBTs, bus unpowered. Every gate should show a clean ±12 V from the very first pulse, and a real both-off gap at each transition. This is just to make sure the H-bridge is properly working/switching before you put any power through it.
- Low voltage, isolated supply. Power the bridge from an isolated DC supply at low voltage first. I ran mine up to about 250 V this way before ever connecting it to both rectified single-phase and rectified three-phase.
- Set the phase target. Important! The phase target will not be correct for your build. I am certain of this because every time I have slightly made changes to the hardware, the phase target has changed every single time. Admittedly, this is a part of the software I am not so proud of, since you have to tune it to your build, but at least the solution is an easy one as long as you can do a quick low-power bench test with the oscilloscope. So, this is how I do it: I scope the output of the H-bridge (this is the voltage waveform), and then I simultaneously scope across the CT (current transformer) to see the current waveform; then what I do is search for the resonant frequency with the frequency-up and frequency-down buttons (resonance is when the voltage and current waveforms we are measuring are in phase). Once we have found the correct frequency, you will see the phase target you want displayed on the display; read it and write it into TARGET_PHASE_DEG. Then write the frequency you measured that at to F_TUNE_HZ. For my current build, as you can see in the code, I measured -122 (degrees) at 40500Hz.
- Dead time. The dead time in this code is tuned for the FF200R12KS4 IGBT bricks that I have: 800ns when locked to the resonant frequency and 1500ns when detuned (frequency above the resonant frequency, where current lags the voltage). If you use other transistors, calculate the minimum dead time you need and replace the values in the code.
- Then go up in steps, always with a load in the coil. Test at 30V DC bus, then 70V, then 120V then 200V, then 330V, and so on. This is how I did it.
The Final Product
The finished product looks a lot like one of those commercial units you can buy online, and it works fantastically well. I've melted and poured kilos of steel, brass, copper, and aluminum, and also managed to go up above 2000°C to make calcium carbide from unburnt lime and charcoal.
It is up to you and your creativity to package/house your own version as you like. Have fun!
In the future, I will release a fourth video in the series talking about crucibles and coupling efficiency because these make a noticeable difference. But, in short, use graphite or SiC crucibles with a high graphite content for anything other than iron/steels, and ceramic or SiC with low graphite content, or your own crucibles when melting iron/steel, while making sure the metal fills up as much as possible of the inside of the work coil (or course after the layer of ceramic insulation and the crucible walls).
Thanks for reading this tutorial, and good luck with your own builds. See you around!