.. index:: pair: notes; position files pair: notes; pick and place pair: position; rotate Notes about the position file ----------------------------- Position files are quite simple. You can generate them as plain text (ASCII) or as a spreadsheet (CSV). But some conventions can make them tricky. Some manufacturers, like `JLCPCB `__, uses conventions that are incompatible with KiCad. Simple pick and place rotation correction ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The `following blog `__ explains how to adapt the position files generated by KiCad to what JLCPCB needs. To achieve it the author uses a script called `JLCKicadTools `__. 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 `__ 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: version: 1 filters: - name: only_jlc_parts comment: 'Only parts with JLC code' type: generic include_only: - column: _field_lcsc_part regex: '^C\d+' outputs: - name: 'position' comment: "Pick and place file, JLC style" type: position options: pre_transform: _rot_footprint_jlcpcb 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 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: .. 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 isn’t 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: version: 1 filters: - name: fix_rotation comment: 'Adjust rotation for JLC' type: rot_footprint negative_bottom: false mirror_bottom: false rotations: - ["^QFN-", 90.0] import: - file: JLCPCB definitions: _KIBOT_POS_PRE_TRANSFORM: fix_rotation 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 `__ 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. Including through-hole components ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The default behavior is to only include SMD components in the position files. This is because in most cases is expensive to automatically solder them. But with some manufacturers offering simple assembly at no cost you could want to include them. For a ``position`` output you just need to disable the ``only_smd`` option. When using the ``JLCPCB`` template you can just use: .. code:: yaml kibot: version: 1 import: - file: JLCPCB definitions: _KIBOT_POS_ONLY_SMD: false Including fiducials and similar stuff ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Position files are intended to be used by pick and place machines. So things like reference position marks are excluded. You can include them enabling the ``include_virtual`` option. But this could include other things you don't want. As an example we will show how to include fiducials, but exclude mounting holes: .. code:: yaml kibot: version: 1 filters: - name: remove_extra comment: 'Remove mounting holes' type: generic exclude_any: - column: References regex: "^H\\d+" outputs: - name: 'position' type: position dir: positiondir options: dnf_filter: remove_extra format: CSV # CSV or ASCII format units: millimeters # millimeters or inches separate_files_for_front_and_back: false only_smd: false include_virtual: true Here the `remove_extra` filter removes references starting with `H` and followed by a number, which are used for mounting holes. You could also filter them using a regular expression for the footprint. The following example will generate a positions file only with the fiducials: .. code:: yaml kibot: version: 1 filters: - name: remove_extra comment: 'Keep only fiducials' type: generic include_only: - column: References regex: "^FID\\d+" outputs: - name: 'position' type: position dir: positiondir options: dnf_filter: remove_extra format: CSV # CSV or ASCII format units: millimeters # millimeters or inches separate_files_for_front_and_back: false only_smd: false include_virtual: true Note that this needs synchronized schematics and PCBs. This means that all important objects in the PCB must be related to a symbol in the schematic and that you must ask KiCad to sync both. In particular the above example assumes fiducials are also in the schematic. If the PCB contains footprints not found in the schematic, like in the case of a KiKit panel, you'll need KiBot 1.6.4 or newer. .. index:: pair: position; XYRS files pair: pick and place; XYRS files XYRS files ~~~~~~~~~~ XYRS files are just BoM files in CSV format that includes pick and place data (**X** position, **Y** position, **R**\ otation and **S**\ ide). You can generate them using the internal BoM generator (``bom`` output). The following fields contains the needed information: - ``Footprint X`` - ``Footprint Y`` - ``Footprint Rot`` - ``Footprint Side`` Additionally we support: - ``Footprint Type`` (SMD, THT, VIRTUAL) - ``Footprint X-Size`` - ``Footprint Y-Size`` - ``Footprint Populate`` Important: These files doesn’t support manual panelization with repeated reference names, you’ll 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