fsmMLK / inkscapeCircuitSymbols

Inkscape extension to assist creating circuit symbols.
GNU General Public License v3.0
199 stars 28 forks source link

Added MOSFET support #1

Closed kst-ttt closed 6 years ago

kst-ttt commented 6 years ago

Hi

I added MOSFET support and thought maybe you want the code to include it in you plugin...

regards KST

  #---------------------------------------------
  #metal oxyde transistors (N and P channel)
  def drawTransistorMOS(self,parent,position=[0, 0],value='T',angleDeg=0,label='MOSFET',mirrorEC=False,
                       drawBCEtags=False,
                       drawEnvelope=False,
                       transistorType='NCH',
                       drawVCE=False,
                       drawVCB=False,
                       drawVBE=False,
                       drawICarrow=False,
                       drawIBarrow=False,
                       drawIEarrow=False,
                       VCEname='V_{DS}',
                       VCBname='V_{DG}',
                       VBEname='V_{GS}',
                       ICname='i_D',
                       IBname='i_G',
                       IEname='i_S'):

    """ draws a general MOSFET

    parent: parent object
    position: position [x,y]
    label: label of the object (it can be repeated)
    mirrorInput: invert + and - inputs (default: positive above, negative below)
    opampDrawVin: write v+ and v- besides the inputs (default: False)
    opampDrawVd: write vd besides the input terminals
    flagDrawSupply: draw supply terminals
    """

    if transistorType == 'NCH':
      isNCH=True
    else:
      isNCH=False

    group = self.createGroup(parent,label)
    elem = self.createGroup(group,label)
    colorBlack=inkDraw.color.defined('black')

    L_arrow=2.5
    markerMOS=inkDraw.marker.createMarker(self, 'MOSArrow', 'M 0,0 l -%f,%f l 0,-%f z'% (L_arrow*1.2, L_arrow/2.0,L_arrow), RenameMode=1, strokeColor=colorBlack, fillColor=colorBlack, lineWidth=0.6)
    lineStyleArrow = inkDraw.lineStyle.set(lineWidth=1, lineColor=colorBlack, markerEnd=markerMOS)

    if mirrorEC:   
        if transistorType == 'NCH':
            inkDraw.line.relCoords(elem, [[-27,0]],[position[0]+17,position[1]-7])   #gate

            inkDraw.line.relCoords(elem, [[0,-25]],[position[0]+24,position[1]]) # source line
            inkDraw.line.relCoords(elem, [[-9,0]],[position[0]+28,position[1]+5.25]) # horizontal source line

            inkDraw.line.relCoords(elem, [[-4.75,0]],[position[0]+24,position[1]+0],lineStyle=lineStyleArrow) # horizontal arrow line 
            inkDraw.line.relCoords(elem, [[0,19.75]],[position[0]+24,position[1]+5.25]) # drain line
            inkDraw.line.relCoords(elem, [[-9,0]],[position[0]+28,position[1]-5.25]) # horizontal drain line

            inkDraw.line.relCoords(elem, [[0,-3.25]],[position[0]+28,position[1]-2]) # diode
            inkDraw.line.relCoords(elem, [[0,+3.25]],[position[0]+28,position[1]+2]) # diode
            inkDraw.line.relCoords(elem, [[4,0]],[position[0]+26,position[1]+2]) # diode
            inkDraw.line.relCoords(elem, [[-4,0],[2,4],[2,-4]],[position[0]+30,position[1]-2]) # diode

            pos_Gtag=[position[0]+10,position[1]-4]

        else:
            inkDraw.line.relCoords(elem, [[-27,0]],[position[0]+17,position[1]+7])   #gate

            inkDraw.line.relCoords(elem, [[0,-19.75]],[position[0]+24,position[1]-5.25]) # drain line
            inkDraw.line.relCoords(elem, [[-9,0]],[position[0]+28,position[1]+5.25]) # horizontal line

            inkDraw.line.relCoords(elem, [[0,25]],[position[0]+24,position[1]]) # source line
            inkDraw.line.relCoords(elem, [[4.75,0]],[position[0]+19,position[1]+0],lineStyle=lineStyleArrow) # horizontal arrow line 
            inkDraw.line.relCoords(elem, [[-9,0]],[position[0]+28,position[1]-5.25]) # horizontal line

            inkDraw.line.relCoords(elem, [[0,-3.25]],[position[0]+28,position[1]-2]) # diode
            inkDraw.line.relCoords(elem, [[0,+3.25]],[position[0]+28,position[1]+2]) # diode
            inkDraw.line.relCoords(elem, [[4,0]],[position[0]+26,position[1]-2]) # diode
            inkDraw.line.relCoords(elem, [[-4,0],[2,-4],[2,4]],[position[0]+30,position[1]+2]) # diode

            pos_Gtag=[position[0]+10,position[1]+4]

        pos_Etag=[position[0]+26.5,position[1]-12.5]
        pos_Ctag=[position[0]+26.5,position[1]+12.5]

    else:
        if transistorType == 'NCH':
            inkDraw.line.relCoords(elem, [[-27,0]],[position[0]+17,position[1]+7])   #gate

            inkDraw.line.relCoords(elem, [[0,25]],[position[0]+24,position[1]]) # source line
            inkDraw.line.relCoords(elem, [[-9,0]],[position[0]+28,position[1]+5.25]) # horizontal source line
            inkDraw.line.relCoords(elem, [[-4.75,0]],[position[0]+24,position[1]+0],lineStyle=lineStyleArrow) # horizontal arrow line 

            inkDraw.line.relCoords(elem, [[0,-19.75]],[position[0]+24,position[1]-5.25]) # drain line
            inkDraw.line.relCoords(elem, [[-9,0]],[position[0]+28,position[1]-5.25]) # horizontal drain line

            inkDraw.line.relCoords(elem, [[0,-3.25]],[position[0]+28,position[1]-2]) # diode
            inkDraw.line.relCoords(elem, [[0,+3.25]],[position[0]+28,position[1]+2]) # diode
            inkDraw.line.relCoords(elem, [[4,0]],[position[0]+26,position[1]-2]) # diode
            inkDraw.line.relCoords(elem, [[-4,0],[2,-4],[2,4]],[position[0]+30,position[1]+2]) # diode

            pos_Gtag=[position[0]+10,position[1]+4]

        else:
            inkDraw.line.relCoords(elem, [[-27,0]],[position[0]+17,position[1]-7])   #gate

            inkDraw.line.relCoords(elem, [[0,19.75]],[position[0]+24,position[1]+5.25]) # drain line
            inkDraw.line.relCoords(elem, [[-9,0]],[position[0]+28,position[1]+5.25]) # horizontal line

            inkDraw.line.relCoords(elem, [[0,-25]],[position[0]+24,position[1]]) # source line
            inkDraw.line.relCoords(elem, [[4.75,0]],[position[0]+19,position[1]+0],lineStyle=lineStyleArrow) # horizontal arrow line 
            inkDraw.line.relCoords(elem, [[-9,0]],[position[0]+28,position[1]-5.25]) # horizontal line

            inkDraw.line.relCoords(elem, [[0,-3.25]],[position[0]+28,position[1]-2]) # diode
            inkDraw.line.relCoords(elem, [[0,+3.25]],[position[0]+28,position[1]+2]) # diode
            inkDraw.line.relCoords(elem, [[4,0]],[position[0]+26,position[1]+2]) # diode
            inkDraw.line.relCoords(elem, [[-4,0],[2,4],[2,-4]],[position[0]+30,position[1]-2]) # diode

            pos_Gtag=[position[0]+10,position[1]-4]

        pos_Ctag=[position[0]+26.5,position[1]-12.5]
        pos_Etag=[position[0]+26.5,position[1]+12.5]

    inkDraw.line.relCoords(elem, [[0,14]],[position[0]+17,position[1]-7]) #vertical gate line
    inkDraw.line.relCoords(elem, [[0,3.5]],[position[0]+19,position[1]-7]) #vertical gate line
    inkDraw.line.relCoords(elem, [[0,3.5]],[position[0]+19,position[1]-1.75]) #vertical gate line
    inkDraw.line.relCoords(elem, [[0,3.5]],[position[0]+19,position[1]+3.5]) #vertical gate line

    if drawEnvelope:
      inkDraw.circle.centerRadius(elem, centerPoint=[position[0]+22,position[1]], radius=10, offset=[0, 0], label='circle')

    if drawBCEtags:
      tB=inkDraw.text.latex(self,group,'G',position=pos_Gtag,fontSize=self.fontSizeSmall/1.5,refPoint='cc',preambleFile=self.preambleFile,angleDeg=-angleDeg)
      tC=inkDraw.text.latex(self,group,'D',position=pos_Ctag,fontSize=self.fontSizeSmall/1.5,refPoint='cc',preambleFile=self.preambleFile,angleDeg=-angleDeg)
      tE=inkDraw.text.latex(self,group,'S',position=pos_Etag,fontSize=self.fontSizeSmall/1.5,refPoint='cc',preambleFile=self.preambleFile,angleDeg=-angleDeg)

    if angleDeg!=0:
      self.rotateElement(group,position,angleDeg)

    if inkDraw.useLatex:
      VCEname='$'+VCEname+'$'
      VCBname='$'+VCBname+'$'
      VBEname='$'+VBEname+'$'
      ICname='$'+ICname+'$'
      IBname='$'+IBname+'$'
      IEname='$'+IEname+'$'

    #draw voltage drops
    if drawVCE:
      pos=[position[0]+25+10 ,position[1]]
      self.drawVoltArrowSimple(group,pos,name=VCEname,color=self.voltageColor,angleDeg=90,invertArrows=not mirrorEC ,size=20.0,invertCurvatureDirection=False,extraAngleText=angleDeg)

    if drawVCB:
        if transistorType == 'NCH':
            if mirrorEC:
                pos = [position[0]+13,position[1]+6]
                ang = -45
            else:
                pos = [position[0]+13,position[1]-6]
                ang = 45
            self.drawVoltArrowSimple(group,pos,name=VCBname,color=self.voltageColor,angleDeg=ang,invertArrows= isNCH,size=25.0,invertCurvatureDirection=not mirrorEC,extraAngleText=angleDeg)
        else:
            if mirrorEC:
                pos = [position[0]+15,position[1]+15]
                ang = -45
            else:
                pos = [position[0]+15,position[1]-15]
                ang = +45
            self.drawVoltArrowSimple(group,pos,name=VCBname,color=self.voltageColor,angleDeg=ang,invertArrows=not isNCH,size=10.0,invertCurvatureDirection=not mirrorEC,extraAngleText=angleDeg)

    if drawVBE:
        if transistorType == 'NCH':
            if mirrorEC:
                pos = [position[0]+15,position[1]-15]
                ang = 45
            else:
                pos = [position[0]+15,position[1]+15]
                ang = -45
            self.drawVoltArrowSimple(group,pos,name=VBEname,color=self.voltageColor,angleDeg= ang,invertArrows=not isNCH,size=10.0,invertCurvatureDirection= mirrorEC,extraAngleText=angleDeg)
        else:
            if mirrorEC:
                pos = [position[0]+13,position[1]-6]
                ang = 45
            else:
                pos = [position[0]+13,position[1]+6]
                ang = -45
            self.drawVoltArrowSimple(group,pos,name=VBEname,color=self.voltageColor,angleDeg= ang,invertArrows= isNCH,size=25.0,invertCurvatureDirection= mirrorEC,extraAngleText=angleDeg)

    # draw terminal currents
    if drawICarrow:
      if mirrorEC:
        self.drawCurrArrowSimple(group,[position[0]+30 ,position[1]+17.5],name=ICname,color=self.currentColor,
                                angleDeg=90,invertArrows=not isNCH,size=7.5,invertTextSide=True,extraAngleText=angleDeg)
      else:
        self.drawCurrArrowSimple(group,[position[0]+30 ,position[1]-17.5],name=ICname,color=self.currentColor,
                                angleDeg=90,invertArrows=isNCH,size=7.5,invertTextSide=True,extraAngleText=angleDeg)

    if drawIBarrow:
        if mirrorEC:
            self.drawCurrArrowSimple(group,[position[0]+7.5-10 ,position[1]+3],name=IBname,color=self.currentColor,
                               angleDeg=0,invertArrows=not isNCH,size=7.5,invertTextSide=False,extraAngleText=angleDeg) 
        else:
            self.drawCurrArrowSimple(group,[position[0]+7.5-10 ,position[1]+2],name=IBname,color=self.currentColor,
                               angleDeg=0,invertArrows=not isNCH,size=7.5,invertTextSide=False,extraAngleText=angleDeg) 

    if drawIEarrow:
      if mirrorEC:
        self.drawCurrArrowSimple(group,[position[0]+30 ,position[1]-17.5],name=IEname,color=self.currentColor,
                                 angleDeg=90,invertArrows=not isNCH,size=7.5,invertTextSide=True,extraAngleText=angleDeg) 
      else:
        self.drawCurrArrowSimple(group,[position[0]+30 ,position[1]+17.5],name=IEname,color=self.currentColor,
                                angleDeg=90,invertArrows=isNCH,size=7.5,invertTextSide=True,extraAngleText=angleDeg)
    return group;
fsmMLK commented 6 years ago

Thank you! I will incorporate it as soon as possible!

kst-ttt commented 6 years ago

Thanks for the fast response.

For the sake of completeness I further have to suggest following two minor changes:

regards KST

circuitSymbols_semiconductors.inx:

Line 104:

      <param name="FET_VGSname" type="string" _gui-text="v_GS label (no $...$ needed)">v_{cb}</param>
      <param name="FET_VDSname" type="string" _gui-text="v_DS label (no $...$ needed)">v_{ce}</param>
      <param name="FET_VDGname" type="string" _gui-text="v_DG label (no $...$ needed)">v_{be}</param>
      <param name="FET_IDname" type="string" _gui-text="i_d label (no $...$ needed)">i_e</param>
      <param name="FET_ISname" type="string" _gui-text="i_s label (no $...$ needed)">i_c</param>
      <param name="FET_IGname" type="string" _gui-text="i_g label (no $...$ needed)">i_b</param>

change default values to:

     <param name="FET_VGSname" type="string" _gui-text="v_GS label (no $...$ needed)">v_{gs}</param>
      <param name="FET_VDSname" type="string" _gui-text="v_DS label (no $...$ needed)">v_{ds}</param>
      <param name="FET_VDGname" type="string" _gui-text="v_DG label (no $...$ needed)">v_{dg}</param>
      <param name="FET_IDname" type="string" _gui-text="i_d label (no $...$ needed)">i_d</param>
      <param name="FET_ISname" type="string" _gui-text="i_s label (no $...$ needed)">i_s</param>
      <param name="FET_IGname" type="string" _gui-text="i_g label (no $...$ needed)">i_g</param>

circuitSymbols.py:

Line 1649:

    if drawVGS:
      if mirrorEC:
        pos = [position[0]+15,position[1]-15]
        ang = +45
      else:
        pos = [position[0]+15,position[1]+15]
        ang = -45
      self.drawVoltArrowSimple(group,pos,name=VGSname,color=self.voltageColor,angleDeg=ang,
                               invertArrows=True, size=10.0,  invertCurvatureDirection=mirrorEC, extraAngleText=angleDeg)

change arrow position to

    if drawVGS:
      if mirrorEC:
        pos = [position[0]+15,position[1]-16]
        ang = +45
      else:
        pos = [position[0]+15,position[1]+16]
        ang = -45
      self.drawVoltArrowSimple(group,pos,name=VGSname,color=self.voltageColor,angleDeg=ang,
                               invertArrows=True, size=10.0,  invertCurvatureDirection=mirrorEC, extraAngleText=angleDeg)

line 1679:

    if drawIGarrow:
      if mirrorEC:
        pos = [position[0]-5 ,position[1]-11]
      else:
        pos = [position[0]-5 ,position[1]+11]

      self.drawCurrArrowSimple(group,pos,name=IGname,color=self.currentColor,
                               angleDeg=0,invertArrows=False,size=7.5,invertTextSide=not mirrorEC,extraAngleText=angleDeg) 

change arrow position to:

    if drawIGarrow:
      if mirrorEC:
        pos = [position[0]-5 ,position[1]-9]
      else:
        pos = [position[0]-5 ,position[1]+9]

      self.drawCurrArrowSimple(group,pos,name=IGname,color=self.currentColor,
                               angleDeg=0,invertArrows=False,size=7.5,invertTextSide=not mirrorEC,extraAngleText=angleDeg) 
fsmMLK commented 6 years ago

Thanks again!

Updated version has been uploaded. I decided to not change Ig position. It would be too close to the circuit line. However, I made changes on v{gs}. I changed the distance between the arrow and the text on function drawVoltArrow and changed the orientation from +-45 to +-20 degrees. Now I_g and V_gs are much more spaced apart than before. Unless you use a very long i_g name, I don't think they will overlap now.

Please let me know if the changes suits you.

kst-ttt commented 6 years ago

Yes, this looks much better now...

Thanks again for the fast response.

regards KST