Shop OBEX P1 Docs P2 Docs Learn Events
induction heating — Parallax Forums

induction heating

I'm trying to build a selective soldering machine. The difficult parts, CNC kinematics and liquid tin pump, are alredy solved. However, the seemingly easy part, heating the tin to melt it, is not so easy as it first seems. Lead free soldering tin dissolves even stainless steel relatively quickly and I didn't want to machine the whole pot from titanium. So I decided to use an enamel coated pot and heated it with a standard electrical hotplate.

This works basically but the temperature of the tin is difficult to control. Because of the large thermal inertia of the cast iron hotplate the temperature tends to overshot a lot if a simple on/off thermostat is used. A PID control is difficult to tune. So I decided to use an induction hotplate instead which offers instant power control. However, a standard off the shelf induction plate can't be used because you can't control the power with a simple interface but instead have to push several buttons. Safety features like pot removal detection and soft start causes delays...

But it's not very hard to build the whole power electronics for the plate from scratch. I've bought a standard induction plate from Amazon and ripped the electronics apart. This application note gives some useful information how the thing works. The coil of the plate is put together with a film capacitor (or actually two) to form a series resonant circuit which is driven by an IGBT or MOSFET half bridge.

The half bridge is always driven with 50% duty cycle but variable frequency. Higher frequency (above the resonant frequency) means lower current and less power, lower frequency (closer to resonant) means more power. I recycled a servo supply PFC module I had lying around which already contained most of the required circuitry: rectifier, capacitors, half bridge and MOSFET drivers. I've added some optocouplers and a curent transformer (actually a toroid inductor plus one winding of thick stranded wire).



The pieces of sheet iron on the plate are used as dummy loads. A first test with a 48V SMPS was successful but I didn't dare to power it directly from mains voltage, so far.

The next thing is to get current feedback from the secondary winding of the current transformer to an ADC input of the P2. As the signal is AC coupled anyway high gain modes can be used. The transformer has a 1:167 winding ratio so 50A primary current corresponds to 0.3A secondary current or 0.3V at a 1 ohm shunt resistor.

Comments

  • evanhevanh Posts: 16,027

    Very cool project!

  • I suspect that submerging an incaloy calrod in the solder may very well be okay. I find it a bit hilarious that you found the exact same app note that I read years ago about inductive heating. I'll note, though, that the only inductive cooktop I've opened was (a) parallel resonant and (b) a class C output stage.

  • Sorry, what is an "incaloy calrod"? Google translator doesn't know theese words... Do you mean an immersion heater made from a coil of nickel base alloy pipe with heating wire inside?

    Yes, the original electronics of the plate also used a parallel resonant circuit with only a single IGBT. But I found the series resonant version of the app note easier to understand and to control. And I don't care about $5 extra cost as the PFC module was already there.

  • Yes. Calrod is a trademark of ge, but has come into common use in the USA. It's the word I think of when describing a standard electric stove. Incaloy is one of several possible metals on the outside of such a heater.

    I never really went through all the math to derive the function of the series vs parallel resonant circuit, and I personally find "high power" scary because of some big sparks when I was kindergarten aged...

  • Lastly, I would ask what stainless steels you've tried. I feel like 316 might be okay for your application where 304 isn't.

  • It works! Even with only 48V suply I can feel the pot heating up, well... getting warm a little bit. My clamp ampere meter reports 1.7A DC current from the supply so that's ~80W total power consumption at 20kHz PWM frequency. The P2 measures 5.5A RMS current at the coil output. The difference is because of the half bridge driving the coil only at around half the voltage and the total current ist the sum of active and reactive current.

    As we can expect the power to frequency function is highly non-linear. At 25kHz power drops to 30W and current to 3A. At 30kHz it's only 15W and 2A RMS.


    First (red) trace is the PWM/NCO output pin from the P2, second (green) trace is secondary voltage of the current transformer.

    I have to implement some safety features then I'll test with full mains voltage.

    It's impressive that there is almost no noise at the RMS readings while there is lots of noise visible on the scope. Only the last digit is dithering which means ~30mA noise. Unfortunatelly, it's difficult to calculate the actual output power. Phase shift between current and voltage is unknown because I can't monitor the voltage at the floating terminal of the induction coil. I also can't measure the DC input current without the help of the clamp ampere meter. But it doesn't matter much. Assuming that the power is proportional to the RMS current is only a rough guess. But the closed PID control loop with the thermocouple will balance out all errors of the power stage.

  • BTW, power is proportional to the square of voltage so I could expect something around 1.8kW max. at 230V. The MOSFETs are rated for 48A continous current at 20kHz which translates to ~35A RMS current at 100Hz rectified mains voltage.

    Here is the test code:

    '' InductionHeating.spin2
    '' Test program for induction hotplate with MOSFET half bridge
    
    {
    current transformer ratio 1:167, 50A peak primary -> 0.3A secondary
    2 ohm shunt resistor -> 0.6V peak input voltage, AC coupled
    
    ADC mode x3.16 gain, +/- 0.8V range, 12 bits resolution (signed)
    2048 LSBs = 66.66A, 30.72 LSBs = 1.0A
    }
    
    CON 
      _xtlfreq = 25_000_000
      _clkfreq = 180_000_000
      '_BAUD       = 230400 ' serial debug port
    
    ' Pins
      pinPwm  = 8  ' PWM output
      pinEna  = 10 ' power stage enable output
      pinAdc  = 12 ' current transformer ADC input
    
      modeAdc = P_ADC + P_ADC_3X
      modeSinc3 = %10_1000 ' SINC3 filtering 256 clocks
    
      modeNco = P_NCO_FREQ + P_OE
      ncoBase = $4000_0001 ' base period = 1 clock, phase = 90°
      nco1kHz = 23861 ' 2^32 * 1k / 180M
    
    OBJ  
      com : "jm_serial.spin2"
    
    VAR
      long  offset  ' average of 256 samples = center line for AC coupling
      long  rmsCurr ' measured RMS current 
      long  status  
    
      byte  cog
    
    PUB main | x, i
      com.start (_BAUD)
      StartAdc
      repeat ' endless loop
        com.str (string ("avg="))
        com.dec (offset)
        com.str (string (" curr="))
        com.dec (rmsCurr)
        com.str (string (" cnt="))
        com.dec (status)
        com.tx (10)
        waitx (_clkfreq / 10)
    
    PRI StartAdc
      cog:= cognew (@adcCode, @offset) + 1 ' address of VAR into PTRA
    
    
    DAT '' cog for PWM and ADC processing
    ORG
    
    adcCode ' pin and event initialisation
                fltl  #pinAdc
                fltl  #pinPwm
                wrpin ##modeAdc,#pinAdc
                wxpin #modeSinc3,#pinAdc
                drvl  #pinAdc
                wrpin #modeNco,#pinPwm
                wxPin ##ncoBase,#pinPwm
                wypin ##nco1kHz*30,#pinPwm
                drvl  #pinPwm
                drvh  #pinEna
                setse1 #1<<6 + pinAdc ' event #1 = ADC sample ready
                setse2 #1<<6 + pinPwm ' event #2 = NCO overflow
    getSample
                waitse1            
                rdpin x,#pinAdc ' get ADC sample
                sub   x,diff1   ' two stage differenciation
                add   diff1,x
                sub   x,diff2
                add   diff2,x
                shr   x,#12     ' reduce to 12 bits resolution
                zerox x,#11     ' clear invalid high bits
                mov   avg,filt
                shr   avg,#8
                sub   filt,avg  ' 255:1 low pass filter
                add   filt,x
                sub   x,avg     ' signed result = raw sample - average
                muls  x,x       ' square
                add   rsum,x
                add   rcnt,#1
                jnse2 #adcDone  ' calculate RMS after each PWM falling edge
    
                qdiv  rsum,rcnt ' average of squares
                akpin #pinPwm
                getqx x
                qsqrt x,#0      ' root of average -> RMS current
                mov   stat,rcnt
                mov   rcnt,#0
                mov   rsum,#0
                getqx curr
    adcDone            
                setq  #2
                wrlong avg,ptra
                jmp   #getSample
    
    x       long 0
    diff1   long 0
    diff2   long 0
    filt    long 0
    rsum    long 0
    rcnt    long 0
    
    avg     long 0
    curr    long 0
    stat    long 0
    
    
  • @Circuitsoft said:
    Lastly, I would ask what stainless steels you've tried.

    I have to admit that I haven't tried stainless steel at all. From the experience that we have to exchange the tips of the soldering irons every month or so with lead free solder while they have lasted for years with leaded tin I simply don't trust it and don't want to waste time and money. Modern machines for lead free solder all have pure titanium pots and I think that has a reason.

    I personally find "high power" scary because of some big sparks when I was kindergarten aged...

    Power electronics is my business. And although we have an electrolytic cap blowing up from time to time because it's soldered in with the wrong polarity I have produced big sparks and smoke only very rarely. Last thing I remember was a very old computer monitor (cathode ray tube) catching fire but that wasn't my fault. o:)

  • Yeah. I hooked 120vac up to a 3v buzzer and melted it into a barstool when I was in Kindergarten...

  • @Circuitsoft said:
    Yeah. I hooked 120vac up to a 3v buzzer and melted it into a barstool when I was in Kindergarten...

    I'm kinda more interested in hearing what you were doing in a bar at that age with a buzzer. :smiley:
    Sorry. Thread drift!

  • jmgjmg Posts: 15,175

    @ManAtWork said:
    The half bridge is always driven with 50% duty cycle but variable frequency. Higher frequency (above the resonant frequency) means lower current and less power, lower frequency (closer to resonant) means more power.

    Cool looking setup.
    What do these systems do for wider power ranges ?
    The graphs here https://www.onsemi.com/pub/Collateral/AND9166-D.PDF (fig 23) show a ~ 3:1 nicely smooth power range by frequency-slope effects alone.
    For lower powers, do they then reduce MOSFET ON times, or phase control at 50Hz, or do full mains cycle on-off ?

  • Hmm.. (head scratching) I thought that the current through the coil is approximately proportional to the inverse of frequency. That would give a 3:1 range for frequencies from 20 to 60kHz. Eddy current losses (and thus heat generated) should be proportional to the square of the current. This would result in a 9:1 range which would be perfect for a hotplate with 1..9 power levels.

    Of course, current vs. 1/f proportionality is not true near the resonant frequency but the Q factor (quality) of the resonant cirquit becomes very low at high power levels. From the numbers in post #7 the 1/f proportionality for current and 1/f² proportionality for power is a good approximation above the resonant frequency. At the resonant frequency there is a over-proportional power peak but that's all completely logical.

    I don't know how they came to the 3:1 result. They definitely have better equipment and a deeper view into theory than me. But I'm sure you have more than a 3:1 range. Of course, you can always switch to on/off control if you need less than the minimum power.

  • The power goes down as frequency increases because you're reducing the skin depth of the iron surface that's heating, effectively increasing the resistance. When frequency gets too high, you start to run into skin depth Issues on the strands of the litz wire that makes up the "heating" coil.

  • Today I ran the circuit from 200V AC from a transformer. with up to 5A current draw or 1000W output power I have heated up a pot of water to boiling within some minutes. However, my capacitors of the resonant circuit are not of very good quality. They get hotter than the MOSFETs. I think I have to get some new ones that are rated for the full 30A current at 20kHz. Standard X2 noise suppressor types are not suitable.

    I've added a potentiometer to set the nominal current and a closed loop frequency control that adjusts the NCO according to the power demand.

    '' InductionHeating.spin2
    '' Test program for induction hotplate with MOSFET half bridge
    
    {
    current transformer ratio 1:167, 50A peak primary -> 0.3A secondary
    2 ohm shunt resistor -> 0.6V peak input voltage, AC coupled
    
    ADC mode x3.16 gain, +/- 0.8V range, 12 bits resolution (signed)
    2048 LSBs = 66.66A, 30.72 LSBs = 1.0A
    RMS value is calculated once per NCO cycle (20kHz to 60kHz)
    
    Voltage and current varies during a power cycle (100 or 120Hz half sine wave)
    of rectified mains voltage because we don't use a big electrolytic cap
    on the DC bus. This would only result in a poor power factor. The required
    cap and PFC inductor would cost more than a bit oversized MOSFET to handle the
    higher peak current.
    
    To get constant current readings we have to average it over a (multiple of)
    full power cycles. A PID cycle of 20Hz is used to fit both European and USA 
    power grids.
    
    The so called PID control is acually a pure I control. Because the current 
    measurement and LC time constant is ~1000 times faster than the 20Hz cycle
    there is virtually no delay and the integrator produces no overshot.
    
    The I-gain is adapted to the frequency so the gain is lower close to
    the resonant frequency to compensate the non-linear frequency to power
    relation.
    
    }
    
    CON 
      _xtlfreq = 25_000_000
      _clkfreq = 180_000_000
      '_BAUD       = 230400 ' serial debug port
      pidPeriod  = _clkfreq / 20 ' common divisor of 100 and 120Hz
    
    ' Pins
      pinPwm  = 8  ' PWM output
      pinEna  = 10 ' power stage enable output
      pinAdc  = 12 ' current transformer ADC input
      pinPoti = 14 ' potentiometer for power command
    
      modeAdc   = P_ADC + P_ADC_3X
      modeSinc3 = %10_1000 ' SINC3 filtering 256 clocks
      modePoti  = P_ADC
      modeSinc2 = %00_1101 ' SINC2 sampling 8192 clocks
    
      modeNco = P_NCO_FREQ + P_OE
      ncoBase = $4000_0001 ' base period = 1 clock, phase = 90°
      nco1kHz = 23861 ' 2^32 * 1k / 180M
      minFreq = nco1kHz * 20
      maxFreq = nco1kHz * 60
    
    OBJ  
      com : "jm_serial.spin2"
    
    VAR
      long  offset  ' average of 256 samples = center line for AC coupling
      long  rmsCurr ' actual instanous RMS current (per NCO cycle)
      long  actCurr ' actual RMS current (averaged over multiple power cycles)
      long  status  ' 0=off, 1= enabled, -1= error
      long  nomCurr ' nominal RMS current
    
      long  potiLo
      long  potiHi
      byte  cog
    
    PUB main | x, i
      com.start (_BAUD)
      StartAdc
      repeat ' endless loop
        nomCurr:= GetPotiCalib * 30 / 133 ' 0..30A
        com.str (string ("avg="))
        com.dec (offset)
        com.str (string (" curr="))
        com.dec (actCurr)
        com.str (string (" stat="))
        com.dec (status)
        com.str (string (" nom="))
        com.dec (nomCurr)
        com.tx (10)
        waitx (_clkfreq / 10)
    
    PRI StartAdc
      cog:= cognew (@adcCode, @offset) + 1 ' address of VAR into PTRA
      pinstart (pinPoti, modePoti + P_ADC_GIO, modeSinc2, 8192)
      potiLo:= GetPotiRaw
      potiLo:= GetPotiRaw
      wrpin (pinPoti, modePoti + P_ADC_VIO)
      potiHi:= GetPotiRaw
      potiHi:= GetPotiRaw
      wrpin (pinPoti, modePoti + P_ADC_1X)
    
    PRI GetPotiRaw : p
      repeat until pinr (pinPoti) ' wait for sample ready
      return rdpin (pinPoti)
    
    PRI GetPotiCalib : p | x
      x:= GetPotiRaw
      return (x - potiLo #> 0) * 4096 / (potiHi - potiLo) <# 4095
    
    DAT '' cog for PWM and ADC processing
    ORG
    
    adcCode ' pin and event initialisation
                fltl  #pinAdc
                fltl  #pinPwm
                wrpin ##modeAdc,#pinAdc
                wxpin #modeSinc3,#pinAdc
                drvl  #pinAdc
                wrpin #modeNco,#pinPwm
                wxPin ##ncoBase,#pinPwm
                wypin ##maxFreq,#pinPwm
                drvl  #pinPwm
                drvh  #pinEna
                setse1 #1<<6 + pinAdc ' event #1 = ADC sample ready
                setse2 #1<<6 + pinPwm ' event #2 = NCO overflow
                call   #getDummy
                call   #getDummy
                call   #getDummy
                getct  pTime
                addct1 pTime,pCycle
    getSample
                waitse1            
                rdpin x,#pinAdc ' get ADC sample
                sub   x,diff1   ' two stage differenciation
                add   diff1,x
                sub   x,diff2
                add   diff2,x
                shr   x,#12     ' reduce to 12 bits resolution
                zerox x,#11     ' clear invalid high bits
                mov   avg,filt
                shr   avg,#8
                sub   filt,avg  ' 255:1 low pass filter
                add   filt,x
                sub   x,avg     ' signed result = raw sample - average
                abs   x
                cmp   x,maxCurr wc
          if_nc jmp   #overCurr ' shutdown on overcurrent
                mul   x,x       ' square
                add   rsum,x
                add   rcnt,#1
                jnse2 #noRms    ' calculate RMS after each PWM falling edge
    
                qdiv  rsum,rcnt ' average of squares
                akpin #pinPwm
                getqx x
                qsqrt x,#0      ' root of average -> RMS current
                'mov   stat,rcnt
                mov   rcnt,#0
                mov   rsum,#0
                getqx rms
    adcDone            
                setq  #3
                wrlong avg,ptra
                jmp   #getSample
    
    noRms
                cmp   rcnt,#1 wz
          if_nz jmp   #adcDone     ' right after RMS calculation...
                add   psum,rms     ' execute once per NCO cycle
                add   pcnt,#1
                jnct1 #adcDone
    pidCtrl                        ' execute once per 20Hz cycle
                qdiv  psum,pcnt
                addct1 pTime,pCycle
                mov   pcnt,#0
                mov   psum,#0
                rdlong nom,ptra[4] wz
         if_z   jmp   #powerOff
                sub   nom,act      ' deviation = nominal - actual
                mov   x,freq
                sub   x,subFreq    ' variable gain, closer to resonant -> lower gain
                shr   x,#6
                muls  x,nom        ' non-linearity corection
                sar   x,#2
                sub   freq,x
                fges  freq,##minFreq
                fle   freq,##maxFreq
                wypin freq,#pinPwm
                getqx act
                'mov   stat,x
                jmp   #adcDone
    
    powerOff
                getqx act
                drvl  #pinEna
                mov   rms,#0
                mov   act,#0
                mov   stat,#0
    waitOn      setq  #3
                wrlong avg,ptra
                rdlong nom,ptra[4] wz
          if_z  jmp   #waitOn
                mov   stat,#1   
                jmp   #adcCode ' restart        
    
    overCurr
                drvl  #pinEna
                wrpin #0,#pinPwm
                mov   act,x
                neg   stat,#1
                setq  #3
                wrlong avg,ptra
                jmp   #overCurr
    
    getDummy
                waitse1            
                rdpin x,#pinAdc ' get ADC sample
                sub   x,diff1   ' two stage differenciation
                add   diff1,x
                sub   x,diff2
      _ret_     add   diff2,x
    
    
    maxCurr long 1536 ' max. current = 50A 
    
    x       long 0
    diff1   long 0       ' sinc3 diff values
    diff2   long 0
    filt    long 2048<<8 ' offset filter
    rsum    long 0       ' sum of RMS input samples
    rcnt    long 0       ' count of samples per NCO cycle
    psum    long 0       ' sum of RMS output samples
    pcnt    long 0       ' count of samples per PID cycle
    pTime   long 0
    pCycle  long pidPeriod
    freq    long maxFreq ' current NCO frequency (control output)
    subFreq long nco1kHz * 15 ' offset for non-linearity correction
    
    avg     long 2048
    rms     long 0
    act     long 0
    stat    long 1
    nom     long 0
    
    

    @Circuitsoft said:
    The power goes down as frequency increases because you're reducing the skin depth of the iron surface that's heating, effectively increasing the resistance. When frequency gets too high, you start to run into skin depth Issues on the strands of the litz wire that makes up the "heating" coil.

    The coil in the plate is made of stranded wire with the strands coated with insulation varnish ("HF litz"). So I think the skin effect is not a problem. The decreasing current at higher frequencies is simply caused by the induction getting dominant over the capacitance of the resonant circuit. Of course, there is a remarkable skin effect in the pot bottom but this is self-regulating. As resistance of the pot core (secondary winding of a transformer) gets higher the Q factor of the resonant circuit increases causing higher voltage swing.

  • The induction hot plate I opened up, the individual stands looked like 24awg (.25mm^2). That gives an upper frequency of 68KHz before skin depth becomes an issue.

  • A solid copper wire of the size used in the hot plate would probably be (6awg) closer to 1.1KHz.

  • I've added bigger caps and a fan for cooling. Now it works really well.

  • @ManAtWork said:
    I've added bigger caps and a fan for cooling. Now it works really well.

    Nice work!

  • It not only cooks water but also melts a pot of soldering tin.

    The electronics stay quite cool (heatsink ~35°C, DC bus cap ~60°C, resonant caps ~40°C) but the wires to the induction coil get pretty hot. While the ampere meter shows only 4A AC input current before the rectifier the current through the induction coil is around 25A which is a bit high for an AWG15 wire.

    BTW, the thermocouple measurement displays 217°C when the tin starts to melt what is exactly the lower melting point of lead free tin (SAC307). Seems to be more accurate than in boiling water where it says 96°C.

  • @ManAtWork said:
    ...
    BTW, the thermocouple measurement displays 217°C when the tin starts to melt what is exactly the lower melting point of lead free tin (SAC307). Seems to be more accurate than in boiling water where it says 96°C.

    Actually, this should be no surprise as the tin evaporates much, much less than water does so the tin vapors do not cool off the thermocouple probe housing as much as water vapors do. If you used the same probe pictured above for both measurements, that is. And in the above picture the probe housing is surrounded by mostly hot air (tin vapors are practically negligible) Speculation ? Perhaps, but plausible. So maybe the direct thermocouple measurement isn't as inaccurate as you previously determined ? That would be good news if proved right.

  • Well, could be... But to tell something real about accuracy multiple instances of the circuit should be build and measured under different environment conditions and with a calibrated reference thermometers. I don't have the time for that. I'll build an alternate setup with a MAX31855 and decide which one does the job better. If I only build a single machine with a single thermocouple the $6 for the MAX chip can be neglected. But I don't like the fact that the temperature vs. voltage chart is hardwired into the chip. If you change the type of thermocouple you have to buy a new chip. I'd prefer a flexible solution which implements the calculations for the compensation in software.

    I don't think that vapors or air/gas flow in general does have a big influence on the results if at least 5mm of the the thermocouple tip is immersed in liquid. The thermal conductivity of the liquid is ~1000 times higher than that of the gas. Re-condensing vapor of course can carry a lot of thermal energy but it heats instead of cools. That's how vapor phase ovens work.

    BTW, I'll need some more temperature sensors for safety to detect possible overheating of the driver heatsink, the coil and the pump motor. But there, cheap NTC resistors should do as used in 3D printer extruders. They can be measured directly with the P2 ADCs in X1 mode without any calibration. 10° more or less doesn't make much difference, there.

  • Good points.
    Having calculations in software is way more flexible and cheaper in the long run. I'm very far from convincing you to make the test setup. That would be an overkill in this case. After all, you intend to melt solder tin and not boil water. Nor is it a scientific experiment but just a practical approach to a problem.

Sign In or Register to comment.