[DOCs][Added] More information about rotation and offsets

This commit is contained in:
Salvador E. Tropea 2023-11-22 12:48:50 -03:00
parent cbc196f37a
commit aedabbeb9c
4 changed files with 351 additions and 150 deletions

View File

@ -44,6 +44,11 @@ source/configuration/sup_variants.rst: ../kibot/var_*.py ../kibot/config_reader.
source/configuration/sup_globals.rst: ../kibot/globals.py ../kibot/config_reader.py
../src/kibot --rst --help-global-options > $@
source/rotations.rst: ../kibot/misc.py ../kibot/config_reader.py
../src/kibot --help-list-rotations > $@
source/offsets.rst: ../kibot/misc.py ../kibot/config_reader.py
../src/kibot --help-list-offsets > $@
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
@ -51,7 +56,8 @@ help:
# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
$(SPHINXTARGETS): Makefile source/configuration/sup_outputs.rst source/dependencies.rst source/usage.txt source/configuration/sup_preflights.rst \
source/configuration/sup_filters.rst source/configuration/sup_variants.rst source/configuration/sup_globals.rst source/errors.rst
source/configuration/sup_filters.rst source/configuration/sup_variants.rst source/configuration/sup_globals.rst source/errors.rst \
source/rotations.rst source/offsets.rst
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

View File

@ -134,7 +134,7 @@ Supported filters
- ``comment`` :index:`: <pair: filter - rot_footprint; comment>` [string=''] A comment for documentation purposes.
- ``extend`` :index:`: <pair: filter - rot_footprint; extend>` [boolean=true] Extends the internal list of rotations with the one provided.
Otherwise just use the provided list.
Note that the provided list has more precendence than the internal list.
Note that the provided list has more precedence than the internal list.
- ``invert_bottom`` :index:`: <pair: filter - rot_footprint; invert_bottom>` [boolean=false] Rotation for bottom components is negated, resulting in either: `(- component rot - angle)`
or when combined with `negative_bottom`, `(angle - component rot)`.
- ``mirror_bottom`` :index:`: <pair: filter - rot_footprint; mirror_bottom>` [boolean=false] The original component rotation for components in the bottom is mirrored before applying

View File

@ -13,6 +13,10 @@ But some conventions can make them tricky. Some manufacturers, like
`JLCPCB <https://jlcpcb.com/>`__, uses conventions that are incompatible
with KiCad.
Simple pick and place rotation correction
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The `following
blog <https://dubiouscreations.com/2019/10/21/using-kicad-with-jlcpcb-assembly-service/>`__
explains how to adapt the position files generated by KiCad to what
@ -23,6 +27,40 @@ You can achieve the same using KiBot. Here is a configuration example
that generates the BoM and position files in the same way JLCKicadTools
does:
.. code:: yaml
kibot:
version: 1
import:
- file: JLCPCB
The ``JLCPCB`` templates creates files compatible with JLCPB, including adjusts
for the most common components rotations.
This assumes KiBot can figure out which field was used to indicate the part number
used by LCSC (JLC uses `LCSC <https://lcsc.com/>`__ as supplier).
If you need to force the field name you can use something like:
.. code:: yaml
kibot:
version: 1
globals:
# Make it match the name used by your project
field_lcsc_part: LCSC
import:
- file: JLCPCB
This example is very simple, but also very specific for a particular manufacturer.
For this reason we will see how the ``JLCPCB`` template is implemented, so you can
adapt it. A similar result can be obtained using:
.. code:: yaml
kibot:
@ -33,22 +71,15 @@ does:
comment: 'Only parts with JLC code'
type: generic
include_only:
- column: 'LCSC#'
- column: _field_lcsc_part
regex: '^C\d+'
variants:
- name: rotated
comment: 'Just a place holder for the rotation filter'
type: kibom
variant: rotated
pre_transform: _rot_footprint
outputs:
- name: 'position'
comment: "Pick and place file, JLC style"
type: position
options:
variant: rotated
pre_transform: _rot_footprint_jlcpcb
output: '%f_cpl_jlc.%x'
format: CSV
units: millimeters
@ -81,25 +112,137 @@ does:
- field: References
name: Designator
- Footprint
- field: 'LCSC#'
- field: _field_lcsc_part
name: 'LCSC Part #'
csv:
hide_pcb_info: true
hide_stats_info: true
quote_all: true
The ``only_jlc_parts`` filter is used to generate the BoM and assumes
you put the JLC component code in a field named ``LCSC#`` (JLC uses
`LCSC <https://lcsc.com/>`__ as supplier). Note that the author of the
blog simply used ``Field4`` for this and his script searches for any
field containing the ``^C\d+`` pattern. I think this isnt a good idea
and I suggest using a defined name, like in this example.
The ``only_jlc_parts`` filter is used to generate the BoM.
The special field name ``_field_lcsc_part``is the result of KiBot autodetection.
You can force a value using the global option ``field_lcsc_part``, like in:
The ``rotated`` variant is used only to apply the ``_rot_footprint``
transformation filter. This filter is an internal filter of type
.. code:: yaml
globals:
# Make it match the name used by your project
field_lcsc_part: LCSC
Note that the author of the blog simply used ``Field4`` for this and his script
searches for any field containing the ``^C\d+`` pattern. KiBot can also autodetect
the field name, but I think this isnt a good idea and I suggest using a defined
name, using the above definition.
The ``_rot_footprint_jlcpcb`` is an internal filter of type
``rot_footprint``. Here is the same configuration file making explicit
use of the rotation filter:
.. code:: yaml
kibot:
version: 1
globals:
field_lcsc_part: LCSC
filters:
- name: only_jlc_parts
comment: 'Only parts with JLC code'
type: generic
include_only:
- column: _field_lcsc_part
regex: '^C\d+'
- name: fix_rotation
comment: 'Adjust rotation for JLC'
type: rot_footprint
negative_bottom: false
mirror_bottom: false
outputs:
- name: 'position'
comment: "Pick and place file, JLC style"
type: position
options:
pre_transform: fix_rotation
output: '%f_cpl_jlc.%x'
format: CSV
units: millimeters
separate_files_for_front_and_back: false
only_smd: true
columns:
- id: Ref
name: Designator
- Val
- Package
- id: PosX
name: "Mid X"
- id: PosY
name: "Mid Y"
- id: Rot
name: Rotation
- id: Side
name: Layer
- name: 'bom'
comment: "BoM for JLC"
type: bom
options:
output: '%f_%i_jlc.%x'
exclude_filter: 'only_jlc_parts'
ref_separator: ','
columns:
- field: Value
name: Comment
- field: References
name: Designator
- Footprint
- field: _field_lcsc_part
name: 'LCSC Part #'
csv:
hide_pcb_info: true
hide_stats_info: true
quote_all: true
As you can see we now create a filter named ``fix_rotation`` of type
``rot_footprint``:
.. code:: yaml
- name: fix_rotation
comment: 'Adjust rotation for JLC'
type: rot_footprint
negative_bottom: false
mirror_bottom: false
Using it, instead of the internal filter named ``_rot_footprint_jlcpcb``, is
the same here. But you can then customize the filter.
In order to add a new rotation or just change an existing one you just
need to use the ``rotations`` option. As an example: the internal list
of rotations rotates QFN packages by 270 degrees, now suppose you want to
rotate them just 90 degrees. The filter will look like this:
.. code:: yaml
- name: fix_rotation
comment: 'Adjust rotation for JLC'
type: rot_footprint
negative_bottom: false
mirror_bottom: false
rotations:
- ["^QFN-", 90.0]
This regular expression will match any footprint starting with ``QFN-``
and rotate it 90 degrees.
Note that the order in this list is relevant. The first match will be applied.
You can also use a customized filter using the internal template, here is an
example:
.. code:: yaml
kibot:
@ -109,141 +252,116 @@ use of the rotation filter:
- name: fix_rotation
comment: 'Adjust rotation for JLC'
type: rot_footprint
- name: only_jlc_parts
comment: 'Only parts with JLC code'
type: generic
include_only:
- column: 'LCSC#'
regex: '^C\d+'
variants:
- name: rotated
comment: 'Just a place holder for the rotation filter'
type: kibom
variant: rotated
pre_transform: fix_rotation
outputs:
- name: 'position'
comment: "Pick and place file, JLC style"
type: position
options:
variant: rotated
output: '%f_cpl_jlc.%x'
format: CSV
units: millimeters
separate_files_for_front_and_back: false
only_smd: true
columns:
- id: Ref
name: Designator
- Val
- Package
- id: PosX
name: "Mid X"
- id: PosY
name: "Mid Y"
- id: Rot
name: Rotation
- id: Side
name: Layer
- name: 'bom'
comment: "BoM for JLC"
type: bom
options:
output: '%f_%i_jlc.%x'
exclude_filter: 'only_jlc_parts'
ref_separator: ','
columns:
- field: Value
name: Comment
- field: References
name: Designator
- Footprint
- field: 'LCSC#'
name: 'LCSC Part #'
csv:
hide_pcb_info: true
hide_stats_info: true
quote_all: true
As you can see we now create a filter named ``fix_rotation`` of type
``rot_footprint``:
.. code:: yaml
- name: fix_rotation
comment: 'Adjust rotation for JLC'
type: rot_footprint
Using it, instead of the internal filter named ``_rot_footprint``, is
the same here. But you can then customize the filter.
The filter supports the following options:
- ``extend``: [boolean=true] Extends the internal list of rotations
with the one provided. Otherwise just use the provided list.
- ``negative_bottom``: [boolean=true] Rotation for bottom components is
computed via subtraction as ``(component rot - angle)``. Note that
this should be coherent with the ``bottom_negative_x`` of the
position output.
- ``invert_bottom``: [boolean=false] Rotation for bottom components is
negated, resulting in either: ``(- component rot - angle)`` or when
combined with ``negative_bottom``, ``(angle - component rot)``.
- ``rotations``: [list(list(string))] A list of pairs regular
expression/rotation. Components matching the regular expression will
be rotated the indicated angle. Special names ``_top`` and
``_bottom`` will match all components on that side of the board.
In order to add a new rotation or just change an existing one you just
need to use the ``rotations`` option. As an example: the internal list
of rotations rotates QFN packages by 270 degrees, no suppose you want to
rotate them just 90 degrees. The filter will look like this:
.. code:: yaml
- name: fix_rotation
comment: 'Adjust rotation for JLC'
type: rot_footprint
negative_bottom: false
mirror_bottom: false
rotations:
- ["^QFN-", 90.0]
This regular expression will match any footprint starting with ``QFN-``
and rotate it 90 degrees.
import:
- file: JLCPCB
definitions:
_KIBOT_POS_PRE_TRANSFORM: fix_rotation
The internal list of rotations is:
====================================================== ========
Footprint Rotation
====================================================== ========
``^Bosch_LGA-8_2x2.5mm_P0.65mm_ClockwisePinNumbering`` 90.0
``^R_Array_Convex_`` 90.0
``^R_Array_Concave_`` 90.0
``^SOT-223`` 180.0
``^SOT-23`` 180.0
``^TSOT-23`` 180.0
``^SOT-353`` 180.0
``^QFN-`` 270.0
``^LQFP-`` 270.0
``^TQFP-`` 270.0
``^SOP-(?!18_)`` 270.0
``^TSSOP-`` 270.0
``^DFN-`` 270.0
``^SOIC-`` 270.0
``^VSSOP-10_`` 270.0
``^CP_EIA-3216-18_`` 180.0
``^CP_EIA-3528-15_AVX-H`` 180.0
``^CP_EIA-3528-21_Kemet-B`` 180.0
``^CP_Elec_8x10.5`` 180.0
``^CP_Elec_6.3x7.7`` 180.0
``^CP_Elec_8x6.7`` 180.0
``^CP_Elec_8x10`` 180.0
``^(.*?_\|V)?QFN-(16\|20\|24\|28\|40)(-\|_\|$)`` 270.0
``^PowerPAK_SO-8_Single`` 270.0
``^HTSSOP-28-1EP_4.4x9.7mm*`` 270.0
====================================================== ========
You can create filters for different assembly houses and generate independent
position files for each manufacturer. The next sections explains more details
related to this.
Fixing offsets in position files
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The same mechanism used to change rotations can be applied to offsets in the positions.
You just need to add new offsets to the ``offsets`` option, like in the following example:
.. code:: yaml
- name: fix_rotation
comment: 'Adjust rotation for JLC'
type: rot_footprint
negative_bottom: false
mirror_bottom: false
offsets:
- ["^QFN-20", "1,0.5"]
This will shift the component center of QFN-20 footprints 1 mm in the X axis and 0.5 mm in the Y axis.
The signs of this correction depends on many options, in general they are compatible with the JLCKicadTools tool.
Understanding the rotations problem
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The rotation you get in the position file depends on the following factors:
1. How KiCad footprints are oriented. In general KiCad footprints has their pin 1 at the top left corner.
2. How the manufacturer machine software interprets the angle. KiCad mirrors components on the bottom side, but JLCPCB doesn't (november 2023)
3. How chips are oriented in the tape reel. Some manufacturers even support multiple orientations for the same component.
This means the problem isn't that simple to solve. The internal database of rotations is just a list of common cases, but can't solve any
problem. In fact you can have two components with the same footprint and different rotations in the same project.
To solve this problem you can:
- Provide a list of rotations and offsets using the ``rotations_and_offsets`` option
- Use special fields to specify the rotations and offsets
Fine grained rotation and/or offset adjusts
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Using the configuration file
============================
The ``rotations`` and ``offsets`` options of the `rot_footprint` filter can apply adjusts to components based on their footprint.
This covers the most common cases. But if you have two components with the same footprint and different rotation adjusts you can't
solve the problem. Of course you could use different names for the footprints, even when they are the same, just to allow matching
them using different regular expressions. But you can also use the ``rotations_and_offsets`` option. Another case is when you need
to provide adjusts for different manufacturers and the rotations for the same footprint depends on the manufacturer.
When using the ``rotations_and_offsets`` option you can specify which field is used to match the component. So you can use any
field you want, not just the footprint. This gives you freedom to match components using customized fields. The following example
will adjust U103 rotation by 180 degrees:
.. code:: yaml
filters:
- name: fix_rotation
comment: 'Adjust rotation for JLC'
type: rot_footprint
negative_bottom: false
mirror_bottom: false
rotations_and_offsets:
- field: Reference
regex: U103
angle: 180.0
Note that this rotation will have more precedence than the rotations database. Also note that you can eliminate the rotations
database using the ``extends`` option. So you can create different filters with different mechanisms to adjust the rotations and
offsets for different manufacturers.
Note that after matching a rule in the ``rotations_and_offsets`` list the values are applied and no farther search is done for
this component. If you need to adjust the rotation, but keep searching for an offset, you can use the ``apply_angle``.
The ``apply_offset`` option is the counterpart for the offset.
Using the schematic
===================
If you want to have more metadata inside the project you can use fields to specify the rotations and offsets.
The `JLC-Plugin-for-KiCad <https://github.com/bennymeg/JLC-Plugin-for-KiCad/>`__ implements corrections embedding the adjusts
in the schematic fields. You can apply it using KiBot filters. The ``rot_fields`` and ``offset_fields`` options can be used
to specify a list of field names that contains such adjusts. Note that you can create different filters for different
manufacturers specifying different field names.
The way asjusts are applied is compatible with the `JLC-Plugin-for-KiCad` plugin. If you want to apply adjusts computed like
in the ``rotations_and_offsets``, ``rotations`` and ``offsets`` options just disable the ``bennymeg_mode`` option. Also note
that `JLC-Plugin-for-KiCad` v3.1.0 computes the adjusts for the bottom layer in a way that isn't compatible with JLCPCB,
at least on november 2023.
Using the default options a rotation filter will look for fields named ``JLCPCB Rotation Offset`` and/or ``JLCRotOffset`` for
rotations and ``JLCPCB Position Offset`` and/or ``JLCPosOffset`` for offsets. The search isn't case sensitive, so using things
like ``jlcrotoffset`` is accepted.
.. index::
@ -273,3 +391,21 @@ Additionally we support:
Important: These files doesnt support manual panelization with repeated
reference names, youll get the coordinates for just one component
because this is a BoM.
.. index::
pair: rotations; supported
Internal list of rotations
~~~~~~~~~~~~~~~~~~~~~~~~~~
.. include:: rotations.rst
.. index::
pair: offsets; supported
Internal list of offsets
~~~~~~~~~~~~~~~~~~~~~~~~
.. include:: offsets.rst

59
docs/source/rotations.rst Normal file
View File

@ -0,0 +1,59 @@
======================================================= ========
Footprint Rotation
======================================================= ========
``^(.*?_|V)?QFN-(16|20|24|28|40)(-|_|$)`` 270
``^BatteryHolder_Keystone_1060_1x2032`` -180
``^Bosch_LGA-`` 90
``^CP_EIA-`` 180
``^CP_Elec_`` 180
``^C_Elec_`` 180
``^DFN-`` 270
``^D_SOT-23`` 180
``^Diodes_PowerDI3333-8`` 270
``^ESP32-W`` 270
``^HTSSOP-`` 270
``^JST_GH_SM`` 180
``^JST_PH_S`` 180
``^LED_WS2812B-2020_PLCC4_2.0x2.0mm`` 90
``^LED_WS2812B_PLCC4`` 180
``^LQFP-`` 270
``^MSOP-`` 270
``^PUIAudio_SMT_0825_S_4_R*`` 270
``^PinHeader_2x03_P1\.27mm_Vertical`` 90
``^PinHeader_2x05_P1\.27mm_Vertical`` 90
``^PowerPAK_SO-8_Single`` 270
``^QFN-`` 270
``^Quectel_L80-R`` 270
``^RP2040-QFN-56`` 270
``^R_Array_Concave_`` 90
``^R_Array_Convex_`` 90
``^Relay_DPDT_Omron_G6K-2F-Y`` 270
``^SC-74-6`` 180
``^SO-`` 270
``^SOIC-`` 270
``^SOIC127P798X216-8N`` 270
``^SOP-(?!(18_|4_))`` 270
``^SOT-143`` 180
``^SOT-223`` 180
``^SOT-23`` 180
``^SOT-353`` 180
``^SOT-363`` 180
``^SOT-89`` 180
``^SSOP-`` 270
``^SW_DIP_SPSTx01_Slide_Copal_CHS-01B_W7.62mm_P1.27mm`` -180
``^SW_SPST_B3`` 90
``^TDSON-8-1`` 270
``^TO-277`` 90
``^TQFP-`` 270
``^TSOP-6`` 270
``^TSOT-23`` 180
``^TSSOP-`` 270
``^Transformer_Ethernet_Pulse_HX0068ANL`` 270
``^UDFN-10`` 270
``^USB_C_Receptacle_HRO_TYPE-C-31-M-12*`` 180
``^USON-10`` 270
``^VSON-8_`` 270
``^VSSOP-10_`` 270
``^VSSOP-8_`` 180
``^VSSOP-8_3.0x3.0mm_P0.65mm`` 270
======================================================= ========