Page 5 of 5 FirstFirst 12345
Results 41 to 49 of 49

Thread: Scooty-Puff

  1. #41
    Join Date
    Sep 2010
    Location
    ಠ_ಠ
    Posts
    2,152
    Images
    27
    Rep Power
    265

    Re: Scooty-Puff

    QUAD-nought is approaching the point that I really want to order a batch of PCBs from Seeed. Currently a stack of two 50mm x 100mm boards: one Power with plated holes for press-in connectors/plugs and one Logic board with larger unplated holes to let the plugs pass through the board and DIY current sensors. Both boards are laid out on a single 100mm x 100mm PCB project with central v-score to keep everything easily aligned and named, and they get mounted together with four M2 screws/standoffs on 35mm x 94mm rectangle and electrically connected with 2x10 header (2mm pitch; PTH pins on Power; pass-through SMD sockets on Logic). MOSFETs (FDBL86366_F085) and drivers (IRS21867) are on Power board along with phase and virtual ground sense resistor dividers, so only ever have low voltage, low current signals passing on the header. K20 with KL02 (Teensy-3.2) on Logic board with DRV5053 sensors, USB header, CAN header (JST PH-4: GND, ~13.8V, CANL, CANH) (MCP2542 with 5V buss and 3.3V I/O), and a piezo buzzer driven by DAC0 at ~13.8V. UART0 (as D0 and D1) is broken out to a pair of 0.35mm vias along the board edge because of lack of space and not being intended as primary interface.

    Did not add any external gate resistors and would require reworking the Power board yet again, but have only very short, fat traces from drivers to gates (0.5mm width; 3.5mm and 19.2mm lengths for low and high gates, respectively) with pull-down resistor and TVS at each gate pin, so hopefully the drivers will not overdrive/detonate the MOSFETs. Managed to get all of the components on the Power board in each package in the same orientation (all 0402 N/S and all 0805 E/W) for easier placing. The Logic board has four deviations of the 0402 E/W orientation (USB data lines, CAN termination, and buzzer load) and no deviations of the 0805 N/S orientation.

    Click image for larger version. 

Name:	quad_v0.6.1_logic.jpg 
Views:	21 
Size:	141.4 KB 
ID:	6722Click image for larger version. 

Name:	quad_v0.6.1_power.jpg 
Views:	18 
Size:	133.2 KB 
ID:	6723Click image for larger version. 

Name:	quad_v0.6.1_k20.jpg 
Views:	18 
Size:	93.2 KB 
ID:	6724Click image for larger version. 

Name:	quad_v0.6.1_drv.jpg 
Views:	18 
Size:	101.0 KB 
ID:	6725


    Fluffenstein's Monster (sooo much hair) is apparently never going to join my older sibling and her bigger and better behaved cat in Seattle, so we have to continue caring for her until we find her a new home. ~19lbs cat that is great with dogs, but a bit too 'dominant' to get along with many other cats and does not like anything touching her belly (bites and claws in response). At least she does not object too much to getting her claws trimmed, unlike the newest addition: a stray that was abandoned as kitten then caught as feral by Trap/Neuter/Release program and finally dumped/wandered onto property.
    Please pardon the pedantry... and the profanity... and the convoluted speech pattern...
    "You have failed me, Brain!"
    bleh

  2. #42

    Re: Scooty-Puff

    If you're worried about the drivers, how about making the traces to the gates very narrow instead?
    I don't know how narrow Seeed can make them; you can probably only get down to perhaps 0.1 Ohms per inch.
    But, even so, that limits the current of the driver a little bit. And as long as your switching duty cycle is low, like 1:100 (which it should be for any MOSFET driver) you won't have noticeable heat build-up.

  3. #43
    Join Date
    Sep 2010
    Location
    ಠ_ಠ
    Posts
    2,152
    Images
    27
    Rep Power
    265

    Re: Scooty-Puff

    The potential problem is inductance of the gate drive traces causing poorly damped ringing/overshoot at the gate pin without a low value resistor in series to prevent excessively large current spikes. The short length and significant width of the traces should minimize the inductance, and the TVS should suppress any dangerously large overshoot should it occur (those MOSFETs are rated +/-20Vgs maximum). Figured it wasn't worth risking since those MOSFETs are pretty expensive, so just spent the last bit of time adding high-side and low-side gate resistors by shifting the driver layouts over 1mm to squeeze 0402 resistors in between the low-side gate pins and driver ICs. Also increased the exclusion zone around and underneath the driver ICs and gate drive traces since they will essentially become high current, high frequency transmitters. Do not get to exclude the ground fill in the space between the SOURCE and DRAIN pads under the MOSFET without adding more layers or squishing MOSFETs closer together vertically which will mess with the Logic board layout as well.

    The IRS21867 can sink/source up to 4A for very quick switching of large gate charge MOSFETs and the 13.8V auxiliary power buss is externally fused for 10A continuous, so should have no trouble with the drivers having brown-outs or incompletely turning on the MOSFETs - unlike cheap controllers that use weak charge pumps to provide the 10~15V for the gate drivers from the 5~6V input (or internal linear regulator for microcontroller).
    Please pardon the pedantry... and the profanity... and the convoluted speech pattern...
    "You have failed me, Brain!"
    bleh

  4. #44
    Join Date
    Sep 2010
    Location
    ಠ_ಠ
    Posts
    2,152
    Images
    27
    Rep Power
    265

    Re: Scooty-Puff

    Switching losses are primarily due to switching frequency and not duty cycle. Yes, pushing the duty cycle close to either extreme (0% or 100%) risks the MOSFETs not turning on/off completely, but frequency is the larger contributor since increasing frequency increases the number of on/off transitions and decreases the effective on/off time for all duty cycles. Higher driver source/sink current limits enable faster turn on/off by wasting less time in the linear region where Rds is relatively high, so less heat is produced.

    Zero Voltage Switching and Zero Current Switching can greatly reduce the switching losses and decrease stresses on the semiconductors by not turning on/off when both the voltage and current are large. ZVS involves turning off the switch with a small capacitor in parallel with it, so current through the switch almost immediately drops to zero and instead goes into charging the capacitor (resulting in low off-switching losses). A small inductor in series with the switch and capacitor results in a (quasi-)resonant circuit that eventually causes the voltage across the switch and capacitor to approach zero and/or become negative, which is when the switch is turned back on with very low to no on-switching losses (anti-parallel/freewheeling diode forward biased and freely conducting).

    Drivers without an isolated high-side supply (or internal charge pump) cannot have 100% duty cycle on the high-side because the bootstrap capacitor will eventually discharge.
    Please pardon the pedantry... and the profanity... and the convoluted speech pattern...
    "You have failed me, Brain!"
    bleh

  5. #45

    Re: Scooty-Puff

    Switching losses are primarily due to switching frequency and not duty cycle.
    Sorry -- by duty cycle, I meant the ratio "switching time" to "stable time." Not the PWM duty cycle.
    Because switching time doesn't shift, a faster switching frequency leads to a higher duty cycle for the "time in switch."

    Regarding switch current: 13V drive into 0.1 Ohms means 130A temporary current spike. If your driver is robust, it may last for a long time even under those conditions, but I added a small gate resistor for the Onyx Fire to make sure. (Then again, that uses low-gatecharge, low-gatevoltage MOSFETs, driven straight from the MCU, because the continuous current isn't that much ...)

    Drivers without an isolated high-side supply (or internal charge pump) cannot have 100% duty cycle on the high-side
    That's always annoyed me! I love the IR2101 for what it is, but if you're building a die, is it really that hard to just stick a few more transistors on it to separate the charge pump from the high side, and allow 100% PWM duty cycle? Really?

  6. #46
    Join Date
    Sep 2010
    Location
    ಠ_ಠ
    Posts
    2,152
    Images
    27
    Rep Power
    265

    Re: Scooty-Puff

    It is not the driver I am worried about. The drivers are limited to ~4A by the internal resistance of the transistor design in the driver's output stage. What potentially worries me is the ringing caused by the MOSFET gate and the gate drive trace forming a series LRC circuit. If the inductance of the trace is too large, or the resistance of the trace too low, then the damping factor will be too small to prevent significant overshoot/ringing at the gate pin of the MOSFET. Inductance and resistance both increase with decreasing trace width and increasing trace length, so can get trace with low inductance and low resistance, or high inductance and high resistance. Want a minimal inductance and 5~100 Ohm resistance (depending on gate capacitance), and that can only be guaranteed with a series gate resistor unless the MOSFET's gate resistance is already in that range. The MOSFET I'm planning to use has a gate resistance of ~2 Ohm at 1MHz, so too small to be certain it will overwhelm the inductance of the very short gate drive traces. If the gate driver ICs were on the Logic board and the gate drive traces were passing through the header connecting the Logic and Power boards, there would be absolutely no doubt that gate resistors would be required because of their length. But the Power board has the driver ICs sitting immediately beside the low-side MOSFET and within 25mm of the high-side MOSFET, so the inductance might possibly be small enough to work safely without added gate resistors.
    Please pardon the pedantry... and the profanity... and the convoluted speech pattern...
    "You have failed me, Brain!"
    bleh

  7. #47

    Re: Scooty-Puff

    The drivers are limited to ~4A by the internal resistance of the transistor design
    Oh, that's convenient! The spec is then not "max tolerable" but instead "max achievable" and as long as you don't overheat it with a high switching requency, you're good!
    As you say, ringing is bad. I've killed some Pololu DCDC converters before with that (long power leads, ceramic capacitors with almost no ESR.)
    I like TVS-es for gate protection; if you drive the gates with 12V, a 14V stand-off TVS is fine, and they generally saturate at < +4V, which leaves margin for a 20V Vgs rating (assuming they're fast enough -- and they actually add some capacitance to the circuit just to mess with you :-)

  8. #48
    Join Date
    Sep 2010
    Location
    ಠ_ಠ
    Posts
    2,152
    Images
    27
    Rep Power
    265

    Re: Scooty-Puff

    The data sheet for the IRS21867 does not list any current limits in the "Absolute Maximum Ratings" or "Recommended Operating Conditions". Under "Static Electrical Characteristics", it does list 4A as typical "output high/low short circuit pulsed current" when driving high by 15V while shorted to 0V, and driving low while shorted to 15V, respectively. Granted, that is only for a <=10us pulse width. Still, the outputs of the IRS21867 almost certainly have a significant Rds (probably in the range of 2~6 Ohm) when compared to most power MOSFETs with Rds of <<1 Ohm (FDBL86366_F085 has Rds of <6 mOhm at Vgs=10V and Tj=175C).
    Please pardon the pedantry... and the profanity... and the convoluted speech pattern...
    "You have failed me, Brain!"
    bleh

  9. #49
    Join Date
    Sep 2010
    Location
    ಠ_ಠ
    Posts
    2,152
    Images
    27
    Rep Power
    265

    Re: Scooty-Puff

    Just going to leave this here in case anyone else ever needs to turn a small PCB into a V-cut array. Would have made panelizing the quadnought power board a bit easier than repeatedly performing the 'offset, save, copy, undo offset, save again, paste' using gerbv.

    Code:
    #! /usr/bin/env python3.1
    
    '''
     *******************************************************************************
     * Panelizer script for optimized gerbers output by eagle-7.5.0
     *******************************************************************************
     * Copyright (c) 2017, Matthew Paulishen.
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions are met:
     *
     *     * Redistributions of source code must retain the above copyright
     *       notice, this list of conditions and the following disclaimer.
     *     * Redistributions in binary form must reproduce the above copyright
     *       notice, this list of conditions and the following disclaimer in the
     *       documentation and/or other materials provided with the distribution.
     *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
     * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
     * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     *******************************************************************************
    '''
    
    import re
    from optparse import OptionParser
    from datetime import datetime
    
    
    parser = OptionParser()
    parser.add_option(  '-p', '--project', dest='projectName',
                        help='Common name of project files (no extension)',
                        metavar='FILE',
                        action='store', type='string')
    parser.add_option(  '-a', dest='copies_x',
                        help='Copies in X-axis', metavar='int',
                        action='store', type='int')
    parser.add_option(  '-b', dest='copies_y',
                        help='Copies in Y-axis', metavar='int',
                        action='store', type='int')
    parser.add_option(  '-x', dest='offset_x',
                        help='X-axis offset in [mm]', metavar='int',
                        action='store', type='int')
    parser.add_option(  '-y', dest='offset_y',
                        help='Y-axis offset in [mm]', metavar='int',
                        action='store', type='int')
    
    (options, args) = parser.parse_args()
    project_name = options.projectName
    copies_x = options.copies_x
    copies_y = options.copies_y
    offset_x = options.offset_x
    offset_y = options.offset_y
    
    
    if (not project_name or len(project_name)<4):
        print('Minimum command-line options for proper usage is:\n python panelizer.py -p example_project_v0.0.0 -a 1 -b 2 -x 100 -y 50')
        exit()
    
    gerber_extensions = [
        '.toplayer.ger',
        '.bottomlayer.ger',
        '.topsoldermask.ger',
        '.bottomsoldermask.ger',
        '.topsilkscreen.ger',
        '.bottomsilkscreen.ger'
        ]
    
    
    # Excellon ("X%dY%d")
    # %
    # M48
    # M72
    # T01C0.0394
    # T02C0.0807
    # T03C0.1181
    # %
    # T01
    # X3642Y2756
    # ...
    # T02
    # ...
    # M30
    
    
    # project_name.drills.xln
    inFile = open(project_name+'.drills.xln', 'r')
    outFile = open('panel_'+project_name+'.drills.xln', 'w')
    
    count_this_tool = 0
    count_tools = -2
    temptoollist = []
    
    for line in inFile:
    
        # copy header
        if (count_tools < 0):
            outFile.write(line)
            if (re.match('%', line) != None):
                count_tools += 1
    
        # 'X...Y...' - next tool hit
        elif (re.match('X', line) != None):
            outFile.write(line)
            count_this_tool += 1
    
            xyd = re.split("\D", line)
            xyd_int = [int(xyd[1]), int(xyd[2])]
            temptoollist.append( xyd_int )
    
        # 'T...'/'M30' - tool change or end of file
        elif (re.match('[TM]', line) != None):
    
            # print collected mods for last tool (if any)
            for iter_x in range(copies_x):
                if (iter_x == 0):
                    range_y = range(1, copies_y)
                else:
                    range_y = range(copies_y)
                for iter_y in range_y:
                    for index_hit in range(len(temptoollist)):
                        outFile.write(
        'X{:d}Y{:d}\n'.format(
            int(temptoollist[index_hit][0]+( (iter_x)*(offset_x/0.00254) )),
            int(temptoollist[index_hit][1]+( (iter_y)*(offset_y/0.00254) )) ) )
    
            outFile.write(line)
    
            count_tools += 1
            count_this_tool = 0
            temptoollist.clear()
    
    outFile.close()
    inFile.close()
    
    
    
    
    
    
    
    # Gerber (optimized) ("X%07dY%07d%s")
    # G75*
    # %MOIN*%
    # %OFA0B0*%
    # %FSLAX25Y25*%
    # %IPPOS*%
    # %LPD*%
    # %AMOC8*
    # 5,1,8,0,0,1.08239X$1,22.5*
    # %
    # %ADD10C,0.00000*%
    # %ADD11C,0.01969*%
    # %ADD12C,0.01600*%
    # D10*
    # X...Y...D02*  (start point)
    # X...Y...D01*  (end point)
    # X...Y...D01*  (end point with last as start)
    # X...Y...D01*
    # X...Y...D01*
    # ...
    # X...Y...D01*
    # D11*
    # ...
    # M02*
    
    # project_name.*.ger
    for index_ext in range(len(gerber_extensions)):
    
        inFile = open(project_name+gerber_extensions[index_ext], 'r')
        outFile = open('panel_'+project_name+gerber_extensions[index_ext], 'w')
    
        count_this_tool = 0
        count_tools = -1
        temptoollist = []
    
        for line in inFile:
    
            # copy header
            if (count_tools < 0):
                outFile.write(line)
                if (re.match('D', line) != None):
                    count_tools += 1
    
            # 'X...Y...' - next tool hit
            elif (re.match('X', line) != None):
                outFile.write(line)
                count_this_tool += 1
    
                xyd = re.split("\D", line)
                xyd_int = [int(xyd[1]), int(xyd[2]), int(xyd[3])]
                temptoollist.append( xyd_int )
    
            # 'D...'/'M02' - tool change or end of file
            elif (re.match('[DM]', line) != None):
    
                # print collected mods for last tool (if any)
                for iter_x in range(copies_x):
                    if (iter_x == 0):
                        range_y = range(1, copies_y)
                    else:
                        range_y = range(copies_y)
                    for iter_y in range_y:
                        for index_hit in range(len(temptoollist)):
                            outFile.write(
            'X{:07d}Y{:07d}D{:02d}*\n'.format(
                int(temptoollist[index_hit][0]+( (iter_x)*(offset_x/0.000254) )),
                int(temptoollist[index_hit][1]+( (iter_y)*(offset_y/0.000254) )),
                int(temptoollist[index_hit][2]) ) )
    
                outFile.write(line)
    
                count_tools += 1
                count_this_tool = 0
                temptoollist.clear()
    
        outFile.close()
        inFile.close()
    
    
    exit()
    Please pardon the pedantry... and the profanity... and the convoluted speech pattern...
    "You have failed me, Brain!"
    bleh

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •