Embedded Systems and Power Electronics

Total Pageviews

About Me

My photo
I am currently a PhD student at UC Berkeley, following a 6-year journey working at Apple after my undergrad years at Cornell University. I grew up in Dhaka, Bangladesh where my interest in electronics was cultivated, resulting in the creation of this blog.

BTemplates.com

Powered by Blogger.

Jul 10, 2024

A low-cost high-side current sense amplifier: design considering non-idealities


Current-sensing is commonly used in power electronics and embedded systems, both for system monitoring, as well as to take decisions. Examples of common use cases for the latter are:
  1. Monitoring inductor current for current-mode control in power converters
  2. Monitoring converter current for overcurrent protection
  3. Reading battery charge current to inform the charging process
  4. Reading output current to compute output power to inform how to proceed in an MPPT charge controller
Use cases 1 and 2 require high-speed current measurements since they need to operate at either the converter's control frequency or based on a desired response time. Use cases 3 and 4, however, only require measuring "DC" current and so don't require high-speed current sense. The high-speed aspect ties to notions of slew rate and bandwidth for the amplifier. Other non-idealities, which I will describe here, affect even the DC behavior of the amplifier.

High-Side vs Low-Side Current Sensing

This article gives a good overview of the differences between high-side and low-side current sensing. Shown below are what they look like.

(a): High-side current sense
(b): Low-side current sense

Sense Resistor Selection

In both cases, the sense element is the series resistor Rs. By monitoring the voltage drop across Rs, you can compute the corresponding current from Ohm's Law: V=IR.

Tradeoffs for resistor selection include considerations for power and minimum sense voltage.
  • Power dissipation in the resistor is given by Irms2Rs. A larger resistor will correspond to larger power dissipation for the same current.
  • Using a small resistor corresponds to a smaller sense voltage. When using a small sense resistor, you will use a current sense amplifier (CSA) to amplify the small sensed voltage to feed the corresponding circuit, which is often an ADC. A smaller resistor will correspond to requiring a larger gain in the amplifier or a greater ADC resolution.

High-side vs low-side

High-side current sense refers to placing the sense resistor in the "power" side without disrupting the power return or ground, enabling  the use of a common ground overall circuit scheme. Low-side current sense refers to placing the sense resistor in the "ground" side, thereby disrupting the power return/ground. If common-ground is not desired for your application, you can use the low-side sense scheme. 

In this article, we're looking at applications where you prefer high-side current sense!

Non-idealities Considerations and Circuit Design

In this application, I'm focusing on using a standard ultra-cheap op-amp instead of a dedicated current sense amplifier (such as INA180).

The op-amp I'm picking for this is the TL082 which I have on hand. The amplifier design is based on a standard differential amplifier configuration as shown in this article. The datasheet for the TL082 can be found on the TI website [1] [2]. LCSC shows the ultra-low cost of < $0.20 at volume!

The schematic for the current-sense amplifier (CSA) is shown below.

CSA implementation circuit (click to enlarge schematic)
R1=R2=2.2kΩ, R3=R4=5.6kΩ, Rs=0.5Ω, C1=C2=4.7uF, C3=0.1uF
VSNS+ = 12V


There are 3 parts to the output to consider:
  1. VREF biases the output to 5V. Errors in the 5V reference will propagate to the output.
  2. The diffamp gain is given by R3/R1 assuming R1=R2 and R3=R4. The input to the diffamp is given by the voltage across the sense resistor, which is the product of the current through it and its resistance.
  3. The slope of the output voltage against current is negative due to the diffamp having negative gain. This is by design. See below.

We need to consider the amplifier non-idealities when designing the part. The ones we are considering, along with their impacts is shown below.

  1. Input offset voltage
    • This is a mismatch in the input voltage of the op-amp, due to the input-side design of the op-amp itself. This gets amplified and shows up as an error on the output. The TL082 is specced at 5mV typically. With our amplifier's gain of 5.6/2.2=2.54, this means that this offset shows up at the output as ~12.7mV. Given that our system's current gain magnitude is 1.27V/A, this corresponds to a 10mA error in current reading.
    • Note that the offset can be positive or negative.
    • Additionally, the offset varies over part tolerances and temperature, going up to as much as 20mV, which will correspond to closer to 40mA of error.
    • Whether this is a problem or not depends on your application and desired current sense accuracy. You can perform an offset calibration to try to get rid of the steady-state error and only have to worry about the smaller temperature-dependent offset error. Alternately, you can use an opamp such as the TL081 which has additional pins to allow for offset nulling.
    • Better opamps with lower offset can be used if the offset is an issue and cannot be solved by calibration.
  2. Input bias and offset current
    • A large input bias current will correspond to voltages dropped across R1 and R2, which will correspond to errors in the sensed voltage. The TL082 has bias currents in the 50pA-8nA range. Since this shows up on both inputs on this amplifier, the impact will depend on the mismatch between the input resistors. This will not be an issue in this particular application. In a low-side current-sense amplifier, the bias will show up differentially since one side will likely be grounded, so you will need to be more careful there.
    • A large input offset current will correspond to mismatch in this voltage dropped across the input resistors, which will get amplified and show up as an error on the output. The TL082 has an input offset current spec between 25pA-4nA. The impact of this is the same as for the input offset voltage. Given that the input offset voltage spec is worse than this corresponding offset, this can be ignored for this application.
    • The design will tend to get more sensitive to bias/offset current if you use larger input resistors, so you should be careful about that.
  3. Input common-mode voltage range
    • Rail-to-rail opamps allow the input voltages to go as high as the supply voltage and as low as the supply return. However, the TL082 is not a rail-to-rail opamp, so you need to be careful about making sure that the input voltage is within the desired spec. The datasheet outlines that the input voltage can go as high as the supply rail but can only go as low as 4V above supply return. That means that in our single-rail application, the input voltage cannot go below 4V.
    • Note that this limit also means that you should not use the TL082 to buffer voltages below 4V!
    • With the 5.6k and 2.2k resistors, as well as the 5V VREF, this is not a concern in our application! However, this is something to keep in mind!
  4. Output voltage range
    • You can notice that I flipped the + and - inputs on the op-amp relative to a non-inverting configuration. This gives negative gain, but why did I do this? By using VREF=5V, this then means that as current goes up, the output voltage will go down but will nominally be 5V. If I used VREF=0V and used a non-inverting configuration, that would result in the desired 0A output to be 0V. However, the TL082 cannot drive its output to within 200mV of the supply rail or return (or even worse if you have too low an output resistance!).
    • This means that if the output sits at 200mV with no input, we cannot resolve currents below 158mA. However, if we sit at 5V, we don't have this issue since 5V is far out from either supply rail or GND!
    • With a large enough current, the output still can't swing low enough, so the max current we can resolve is about (5V-0.2V)/1.27[V/A]=3.8A. Note that this would result in a large power in the sense resistor, so this is another constraint to consider!

Some additional considerations:
  • VSNS+ is bounded between 4V and 14.75V. The lower bound maintains the op-amp's input common mode voltage range. The upper bound is given by the op-amp's supply voltage (=12V here). VSNS+ can go higher than 12V as long as the input to the op-amp pins is maintained to be at most 12V. The op-amp voltage at its non-inverting input is given by the equation below. With the circuit components implemented, this sets the upper bound of VSNS+ to 14.75V.

  • Errors in the reference voltage VREF (=5V here) will propagate to the output. These can be accounted for with an initial calibration step. For best performance, use a voltage ref chip such as the LM4040. This will give better accuracy for the voltage reference.
  • You can set the VREF to a higher voltage and increase the gain.
  • You can use a voltage divider at the output to rescale the output to a lower range.
  • You should add a low-pass anti-aliasing filter between the current-sense amplifier's output and the next-stage ADC.

Measurements

With steady state currents, the following output voltages were measured.
  • 0.33A : 4.70V measured vs 4.58V expected : +2.6% error
  • 0.94A : 3.73V measured vs 3.81V expected : -2.0% error

The input offset contributes output error - with no input, you can measure the output and find the offset. The component tolerances also contribute additional error.

For the purposes of this demonstrative application, this is deemed sufficient! In a wide range of applications, this could also be sufficient, especially in cases where the application is very cost-sensitive! I wanted to share some of the non-ideality considerations through this application and would love to hear if this has helped you understand them!

Jul 3, 2024

Generating complementary PWM with adjustable deadtime for the RP2040


I have previously discussed the benefits of using the Raspberry Pi Pico, leveraging the easy-to-program Micropython along with the capable hardware peripherals: 2023 Updates: PhD; Pi Pico and Quick and dirty PIC16F72 programmer with the Pico

Several articles in the blog have previously described applications of PWM in embedded systems, such as Stereo audio player using the PIC32, MCP4822, microSD card and the MDDFS libraryDC motor control with PIC16F877A - Practical example of PIC PWM and Generation of sine wave using SPWM in PIC16F684.

Complementary PWM signals with 500ns deadtime

The underlying RP2040 in the Pi Pico provides an easy-to-use and still powerful and flexible set of PWM peripherals that can enable a wide range of applications. A common requirement in power electronics is the generation of complementary PWM signals. For example, the complementary PWM signals are used in a synchronous buck converter, shown below, to drive the switches S1 and S2.

Synchronous Buck Converter
Image source: https://commons.wikimedia.org/wiki/File:300px-Synch_buck.PNG

To prevent shoot-through, a deadtime is employed. Shoot-through is the event when both S1 and S2 are turned on, causing a large current through them due to shorting across the supply voltage. Even if the generated PWM signals are non-overlapping (ie S1 and S2 are never turned on together), delays in the circuitry - through the gate drivers and the power switches themselves - can still result in shoot-through conditions. In a severe case, the shoot-through can cause damage to the switches, blowing them out. In a more moderate case, small overlap times can result in reduced efficiency due to wasted power, but not necessarily damage to the switches. To combat this issue, a deadtime is inserted between the S1 and S2 driving signals. This is an amount of time when both switch control signals are zero allowing for system transients to settle out. How large it should be depends on the circuit parameters and behavior.

In many cases, gate drivers can have built-in features to insert dead-times, such as the LM5106. However, the ability to generate this in the microcontroller itself gives greater flexibility in the selection of gate driver. Further, it allows tuning the time easily in software rather than needing to change hardware components to change deadtimes.

Fortunately, the Pi Pico makes it fairly straightforward to do this!

The details of the PWM peripheral are outlined in the RP2040 datasheet section 4.5. You can find the code sample here: https://github.com/SyedTahmidMahbub/comppwm_rp2040

The corresponding source code is copied below for convenience:


The RP2040 has 8x PWM slices, each with 2 channels. The complementary PWM waveforms are produced on these 2 channels (A and B) on a given slice. The slice to GPIO mapping is shown below.
PWM slice+channel mapping to GPIO pins
Image source: RP2040 datasheet section 4.5.2

The key aspects of the code are:
  • Use Micropython to init PWM for the associated GPIO pins (A and B).
  • Alter RP2040 registers to configure for complementary PWM. This consists of two settings being changed.
    • Invert channel B relative to channel A.
    • Use center-aligned (phase-correct) PWM instead of edge-aligned. This ensures that the deadtime is applied to both rising and falling edges of channel A. If edge-aligned PWM was used, the channels would be set high together and the deadtime would only be applied on the falling edge of channel A.
  • The deadtime is applied to channel B such that channel A's duty cycle corresponds to the desired/set duty cycle.
  • The duty cycles corresponding to both channels A and B are updated with one register write.
  • The frequency of the output PWM using center-aligned/phase-correct mode is half that when using the default edge-aligned mode.
An example of phase-correct/center-aligned PWM operation is shown in the figure below, taken from the RP2040 datasheet.

Image source: RP2040 datasheet section 4.5.2.1

To generate the complementary signal on channel B, the duty cycle is computed as the sum of the pulse count corresponding to the desired duty cycle and the desired deadtime ticks. With a 125MHz clock for the RP2040 and default clock/divider settings, this corresponds to 8ns per tick. The inversion of channel B then ensures the production of the desired complementary setting.

Shown below are waveforms for GP16 (PWM 0A) and GP17 (PWM0B) for 100kHz PWM, 25% duty cycle and a 504ns deadtime. The deadtime can be verified by recognizing that it corresponds to one horizontal division, which is set to 500ns.

Complementary PWM signals with 500ns deadtime

Taking a zoomed out view of the waveform highlights the 100kHz frequency and illustrates the complementary PWM generation over multiple cycles, as shown below.

3 cycles of 100kHz PWM complementary signals

A natural use case for this generated complementary PWM signal is to control a synchronous buck converter to achieve high efficiency step down operation. Since Micropython will limit the design of a fast control loop, applications where the high frequency PWM is coupled with a low-bandwidth controller make for a natural home for this use case. A solar MPPT battery charger would make for an ideal usage scenario. Alternately, if the same configuration technique is applied in C, fast control loops can then be designed and implemented.

Mar 23, 2024

Electrolytic caps over frequency: why is my 470uF actually 20uF?


While using an LCR meter to measure a 470uF cap in lab, the meter read the expected values at low frequency (100 Hz). But when measured at 100 kHz, the meter read 19uF. While I expected a capacitance drop due to parasitic inductance, I was still surprised at this sharp of a drop. I decided to dig further.

Simplistically, we can model a real capacitor as the following circuit:

Simplistic capacitor model including parasitic elements

C is the main capacitor and the other terms represent parasitic elements: Rs and Ls are the series resistances and inductances, whereas Rp is the parallel (leakage) resistance.

When using ceramic capacitors, datasheets often provided impedance charts over frequency and clearly highlight the self-resonant frequency. Let's consider the C3216X5R1V226M160AC. The impedance chart for the part is shown below. The drop in the impedance magnitude below ~1MHz follows the expected shape of a capacitor. Past ~1MHz, the inductance starts rising again, following the expected shape of an inductor. The minimum point is the self-resonant frequency (SRF) where the capacitance and inductance reactances "cancel" and the impedance is driven by the series resistor. Since the impedance rises again past the self-resonant frequency, the effective capacitance is lower.

C3216X5R1V226M160AC impedance vs frequency

Let's consider a point past the SRF now:
C3216X5R1V226M160AC impedance highlighted at 8.684MHz

The cap is nominally 22uF. At 8.648MHz, the expected impedance would be given by:

Expected impedance would therefore be 0.84 mΩ. However, the chart indicates that the impedance is 56 mΩ. Based on that, the effective capacitance can be back-worked to be 0.33uF for this 22uF cap!

Now you could say that, this frequency is pretty high and way past the SRF so of course the cap isn't behaving as we expect it to. However, this ties directly to the electrolytic cap I was trying to use too.

When looking at the electrolytic part's datasheet, I noticed no equivalent SRF or impedance information. Electrolytic capacitors are known to have lower SRF than ceramic capacitors, but how bad is it actually?

As an aside, what causes the parasitic inductance and why is it better than the ceramic caps? A good reference to understand this is Improved Spice Models of Aluminum Electrolytic Capacitors for Inverter Applications 

In summary, consider the construction of a typical electrolytic capacitor where the contact foils are rolled within the package. The images below are taken from the paper linked above.
 

The current flow through the structure can be modelled as an RC ladder network with distributed resistances and capacitances. This translates to capacitances further down the ladder network (such as C5 shown below) have larger series resistances and the associated time constants are large compared to the period of the voltage across the cap. This results in a drop in capacitance with frequency, greater than that of just the contact and packaging inductances.

A side note of interest is that the opposing current directions through the foils can help cancel the parasitic inductances, asides from small mismatches in foil alignment, depending on device assembly.

Is there an easy way to verify this for the cap I have? And can I trust the 19uF reading from the LCR meter? That's why I proceeded to do. (The reason for the distrust was more due to the meter misbehaving in lab for other measurements but is good to check against.)

I have a Digilent Analog Discovery 2 at home, which I have found to be very handy! I recently learned I can use it as an impedance analyzer
Digilent Analog Discovery 2

The following is the required setup to get impedance measurements.
Impedance measurement setup: "Load" is the cap under test

Using this setup, I am now able to get some quick impedance measurements for my cap. A key aspect of this is to perform the short compensation to ensure that measurement parasitics are taken into account. Without performing this compensation at first, I saw very different results due to the ~50nH of additional parasitic inductance through my measurement setup.

The reactance measurement is shown below:
Reactance measurement from 1kHz to 1MHz

I exported the reactance measurements, and then found the values of C0 and L0. C0 is the capacitance at the lowest measurement frequency and L0 is the inductance at the highest measurement frequency. This allows me to simply model the capacitor as a constant C0 in series with constant L0 (and also a constant series resistor but that isn't factored into this reactance measurement).

For these measurements, the values of C0 and L0 are 407.6 uF and 34.5 nH. C0 is within 20% of the 470uF capacitance, as per the part's spec. Overlaying the reactance due to C0 and L0 on the measured reactances yields the following plot.
Parasitic L, C fit on reactance measurements

This shows that barring the area around the SRF, the reactance is very well modelled by the constant C0 and L0. Considering the reactance, then, the equivalent capacitance can be computed as shown below.
"Effective" capacitance fit on reactance measurements


At 100 kHz, the capacitance is about 80 uF and at 200 kHz, the capacitance is about 20 uF! That is a HUGE drop from the 470 uF rating of the part (and measured 408 uF at low frequency). The self resonant frequency is about 40 kHz, which is very low compared to the ceramic cap shown previously. Of course, this is a different part in a different larger package and so that is not a fair comparison.

Back to where I was trying to use this! This is the input cap for a buck converter operating in the 80-200 kHz range. With such a substantial drop in effective capacitance, the input current ripple will be substantially higher than that predicted/computed with a 408uF cap!

In this particular converter, the 408uF cap would lead to about 23 mVpp ripple. However, with a 20uF cap, this goes up to 463 mVpp. Interestingly, operating this converter at a slower 100 kHz with the same cap (80uF @ 100kHz) could result in a lower ripple!

Be careful which parts you use! And make sure you consider the frequency-dependent behavior! Once you're above the SRF, the capacitance value drops precipitously. If possible, operate below the SRF or make sure you understand what the impact will be if you don't. There's also the consideration of ESR but with electrolytic caps, that tends to decrease with resistance - which is why you'll see ripple current specs get better at higher frequencies for electrolytic caps.

Jan 2, 2024

Quick and dirty PIC16F72 programmer with the Pico


Accompanying Github repo: https://github.com/SyedTahmidMahbub/q-dpico_picprog72

Having come to Dhaka over winter break, I was able to scrounge through the 10+ year-old collection of electronics stuff my parents had in storage from when I would experiment with electronics during the initial days of this blog. Among the many parts, I stumbled upon a large number of PIC16F72 MCU's - the defacto 8-bit cheap MCU of choice for many (commercial) projects. However, I couldn't seem to find the corresponding PICKIT2/3 programmer from back then - or one of the clones I had made - within the storage cabinets. At the same time, I had been working on some projects with the Pi Pico (as mentioned in the blog previously: https://tahmidmc.blogspot.com/2023/08/2023-updates-phd-pi-pico.html). This seemed like the perfect use case for the Pico - a very quick and dirty programmer to flash the PIC16F72. With its 2MB onboard flash, a very easy-to-program Micropython interface and the PIC16F72's fairly timing insensitive ICSP protocol (http://ww1.microchip.com/downloads/en/devicedoc/39588a.pdf), I set out to build a programmer to flash some test code onto the PIC16F72. I made use of whatever parts I could scrounge from the parts bin to put the project together.

As expected, Micropython on the Pi Pico enabled a super-quick development time. To echo what I had previously quoted from the Raspberry Pi foundation:

Computing is just so cheap compared to what it has been historically. That then enables things that are maybe not super efficient, not super tight timing like Micropython but who cares at that point? A lot of people will come in and say things like 'in this benchmark, I found that MicroPython is 100x slower than C' but if your C code is 100x faster than you need, then it doesn't matter. You just write the code you need and you focus on the parts that add value to your project and then you move on to your next project.

And this is the perfect use case! It's not the highest performance result but it gets the job done and the project development was super quick!

The details for the PIC16F72 programming are covered in Microchip's documentation: http://ww1.microchip.com/downloads/en/devicedoc/39588a.pdf

A description of Microchip's HEX file format is provided here: https://microchipdeveloper.com/xwiki/bin/view/software-tools/ipe/sqtp-file-format-specification/intel-hex/

The hardware elements of the project have a few key aspects:

  1. A higher voltage power supply is required for programming. This is between 12.75V and 13.25V VPP. To achieve this, a boost converter is used to raise the 5V USB rail to about 13V. I didn't have any inductors on hand except one unmarked part I found, that measured around 1.8mH. The boost converter operates in discontinuous conduction mode with the minimal VPP required current. Because of the 3.3V IO level of the Pico, I used an NPN transistor instead of a logic level MOSFET I had on hand due to the MOSFET's relatively high threshold voltage.
  2. A VPP level shifter is required to drive the VPP pin up to 13V or hold it low. A PC817 optocoupler is used for this.
  3. Level shifters are not needed for the PGD and PGC programming lines since the 3.3V from the Pico is high enough (>2V) for the PIC to register, even though the PIC is powered off 5V.
One useful and interesting aspect of the project is that no separate programming interface is required to transfer the PIC's HEX file from the PC to the Pico. Since the PIC16F72's flash storage is so small compared to the Pico's onboard storage, and using the Micropython setup on the Pico exposes a filesystem, I can just copy the HEX file contents onto a file on the Pico using the Thonny editor. And then hit run in Thonny to program the PIC!

The software is effectively the following:
  1. Configure the IOs for their corresponding functions.
  2. Configure PWM for the boost converter, running at 50kHz.
    1. Adjust the duty cycle until the output is near 13.2V.
    2. The output voltage is sensed by an ADC channel.
  3. Hold this duty cycle for the output voltage - at this point, the feedback loop is stopped.
  4. Detect the target PIC.
  5. If detected, issue a bulk erase and then check that the part is blank.
  6. Upon success, flash the words read from the HEX file.
To modify for another similar (small) PIC, adjust the constants at the beginning of the code:
  • CODE_START_ADDR
  • CODE_END_ADDR
  • CONFIG_START_ADDR
  • CONFIG_END_ADDR
  • DEVID_PIC16F72
If you use a different inductor for the boost, you can play around with the switching frequency and loop time too.


The schematic for the setup is shown below:


The code can be found here on this github repo: https://github.com/SyedTahmidMahbub/q-dpico_picprog72

The repo also has 2 test hex files test.hex and testbig.hex where the latter has a large array in flash to program over a larger amount of the flash storage.

Shown below is an example output from Thonny when I set the target voltage to 13.15V and flashed the testbig.hex file:
The code and project are by no means optimized for speed or performance. They are, however, optimized for development time! The project could easily be adapted to support other MCUs, and to create an ultra-cheap programmer - something I had previously done with the PIC16F1459 but the Pico enables greater versatility. Due to the onboard stoarage, the Pico could also program a PIC with no interface to a computer for isolated industrial flashing settings.

Finally, a quick photo to truly highlight the quick and dirty build:


Dec 21, 2023

Sizing IR2110 high-side bootstrap capacitor


I have previously discussed the IR2110 gate driver on this blog: https://tahmidmc.blogspot.com/2013/01/using-high-low-side-driver-ir2110-with.html

A crucial part of the high-side gate driver is the sizing of the bootstrap cap. A common sizing strategy is to "use a large cap" and use a larger one for small frequencies. Here, I present a simple method to model the discharge of the cap in a simple LTSpice simulation to inform the capacitor sizing. Shown below is the simulation setup along with the functional block diagram of the IR2110.




A few key points regarding the setup:
  • S1 and S2 represent the high side gate drive FETs in the IR2110 that drive the HO pin.
  • S3 and S4 represent the low side gate drive FETs in the IR2110 that drive the LO pin.
  • Ibs represents the quiescent VBS current and the offset supply leakage current: Ibs = ILK + IQBS. From datasheet, that evaluates to a max of 50µA + 230µA = 280µA.
  • GDH and GDL have their threshold voltages set at +0.5V (refH) and -0.5V (refL) respectively. These, along with yH and yL generate the drive pulses for S1-S4 and correspondingly M1-M2.
  • C1 is the bootstrap cap here, specified at 1µF.
The logic for generating the drive signals for S1-S4 is shown in the diagrams below. Click on the images to expand.

Now, let's go on to the key discussion regarding the cap sizing.

Once the cap is charged, there are a few discharge paths:
  • Charge transferred to the gate of the MOSFET being driven
  • Current draw due to the gate-source resistor
  • Leakage paths - the largest one modeled here is Ibs
For the charge transfer, consider the gate charge of the MOSFET being driven. This can be gathered from the datasheet of the MOSFET. For the IRFZ44N in this simulation, this is around 40nC-50nC as can be seen from Fig 6 in the IRFZ44N datasheet:
The voltage droop due to charging the MOSFET gate (Qg) can be estimated as:
The voltage droop due to driving current through the gate-source resistor can be estimated as:

VD1 is the forward drop for the bootstrap diode D1. Ton is the on-time given by the product of the duty cycle and period.

Below is the voltage across the boostrap cap from the sim:

Observations from this waveform:
  • Between 440µs and 500µs, M2 is on, which charges the bootstrap cap C1 through D1. A larger charge resistance (D1 on-state resistance) or a larger bootstrap cap C1 would increase this charging time.
  • At 500µs, M1 is turned on. Note that this simulation doesn't model the deadtime, but since we're primarily interested in the boostrap cap's dynamics, that is fine.
  • The sharp vertical drop right after 500µs is the charge transfer to M1's gate.
  • The continued droop afterwards, to 540µs, is due to Ibs and the gate-source-resistance.
  • The voltage drops from 11.403V to 10.921V.
  • VGS for M1 tracks this voltage from 500µs to 540µs.

Below is a simple script to estimate the total droop with Python:
import numpy as np

D = 0.4
Tperiod = 100e-6
Ton = D * Tperiod
V0 = 11.403

Cboostrap = 1e-6
Qg_FET = 45e-9
Rg_on = 1031
Ibs = 280e-6

dV_Qg = -Qg_FET/Cboostrap
dV_Rg = -V0 * (1 - np.exp(-Ton/Rg_on/Cboostrap))
dV_Ibs = -Ibs/Cboostrap * Ton

V_final = V0 + dV_Qg + dV_Rg + dV_Ibs
print("Droop sources:")
print(f" Gate charge: {dV_Qg :.3f} V")
print(f" Gate resistor: {dV_Rg :.3f} V")
print(f" Ibs: {dV_Ibs :.3f} V")

print(f"Droops from {V0 :.3f} V to {V_final :.3f} V")


The output of the script is:

Droop sources:
  Gate charge: -0.045 V
  Gate resistor: -0.434 V
  Ibs: -0.011 V
Droops from 11.403 V to 10.913 V

The computed droop matches very well with the simulation!

Key observations:
  • The droop will get worse with reduced gate-source resistance. Using a larger resistance than 1k will reduce the droop.
  • The droop will get worse with a longer on-time. This is why a larger capacitance is needed when operating at lower frequencies such as 50Hz or 60Hz.
  • Using a super large cap will increase how long the cap will require being charged at startup. This may be dealt with by precharging the cap (by turning on M2) before M1 has to be turned on.
  • A 100% duty cycle can't be used since the bootstrap cap can't be recharged. How high the max possible duty cycle is depends on how long it takes to recharge the cap through the bootstrap diode.
  • Gate charge for the MOSFET is a weak function of applied voltage and a very strong function of gate voltage. A larger gate drive voltage will result in a greater droop. Note though that this may not matter if the gate-source resistor dominates the droop.
  • A good max allowable droop is given by the 9.7V figure for the IR2110's max VBS undervoltage threshold. Given that there are always additional leakage components, and the cap has an associated tolerance (in many cases >20%), you will want to build in lots of margin.

Hopefully, this was a useful introduction to sizing the bootstrap capacitance for the IR2110 (or other gate driver). Here is also a good reference to look at: AN-978

If you want further clarification on any aspect of this, do let me know in the comments!

Nov 10, 2023

SmartSinePy, and an example of GUI development with PySide6


Source code at: https://github.com/SyedTahmidMahbub/SmartSinePy

Quite a very long time ago, I had posted a Windows tool called Smart Sine to generate a sine table. See: https://tahmidmc.blogspot.com/2012/10/smart-sine-software-to-generate-sine.html

This was very useful for pre-generating the sine-table instead of in the main program itself, often useful to save space (and not have to perform trig operations) especially on 8-bit microcontrollers.

I was recently looking into developing quick GUIs for some test bench automation and was primarily looking for something where I could position and size GUI elements visually (a WYSIWYG editor, basically) and decided to dig into QT Designer and PySide6. I don't mind defining properties and event handlers programmatically (in fact I do prefer it) but what I really don't want to do is have to add every GUI element in code and define its location and size - this is where the QT Designer's visual editing really comes in helpful! Reminds me a lot of the Visual Studio GUI editor back in Visual Basic development days.

This provided a good opportunity to redo Smart Sine and have an example project for developing the GUI application. A few aspects explored on the GUI side of things:

  • Creating the layout in QT Designer
  • Getting inputs from a table
  • Working with GUI widget signals (events such as button pressed or slider value changed)
  • Updating text in labels and a text browser (textbox)
  • Generating a plot with matplotlib and embedded it on the GUI
This is a great reference for embedding matplotlib: https://david.roesel.cz/notes/posts/matplotlib-figure-embedded-in-qt/
Particularly about temporarily adding a text box within the widget to specify the layout.

For this particular project, I read in the .ui file (that QT Designer generates) straight in the main code without an intermediate conversion.

Here is a snapshot from QT Designer:

Here are a couple snapshots of the application running:
There are a fair few Python dependencies that you will have to install. A one-line command for installing them is:
python3 -m pip install pyside6 numpy pyperclip matplotlib

If there's interest in packaging this up into an executable, let me know!

The code is commented and should be self-explanatory. But if there are specific questions or anything that is unclear, let me know and I can clear it up!