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:
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:
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:
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:
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:
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: true
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
:
- name: fix_rotation
comment: 'Adjust rotation for JLC'
type: rot_footprint
negative_bottom: false
mirror_bottom: true
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:
- name: fix_rotation
comment: 'Adjust rotation for JLC'
type: rot_footprint
negative_bottom: false
mirror_bottom: true
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:
kibot:
version: 1
filters:
- name: fix_rotation
comment: 'Adjust rotation for JLC'
type: rot_footprint
negative_bottom: false
mirror_bottom: true
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:
- name: fix_rotation
comment: 'Adjust rotation for JLC'
type: rot_footprint
negative_bottom: false
mirror_bottom: true
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:
How KiCad footprints are oriented. In general KiCad footprints has their pin 1 at the top left corner.
How the manufacturer machine software interprets the angle. KiCad mirrors components on the bottom side, but JLCPCB doesn’t (november 2023)
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
optionUse 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:
filters:
- name: fix_rotation
comment: 'Adjust rotation for JLC'
type: rot_footprint
negative_bottom: false
mirror_bottom: true
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:
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:
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:
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.
XYRS files
XYRS files are just BoM files in CSV format that includes pick and place
data (X position, Y position, Rotation and Side).
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.
Internal list of rotations
Footprint |
Rotation |
---|---|
|
270 |
|
-180 |
|
90 |
|
180 |
|
180 |
|
180 |
|
270 |
|
180 |
|
270 |
|
270 |
|
270 |
|
180 |
|
180 |
|
90 |
|
180 |
|
270 |
|
270 |
|
270 |
|
-90 |
|
-90 |
|
270 |
|
270 |
|
270 |
|
270 |
|
90 |
|
90 |
|
270 |
|
180 |
|
270 |
|
270 |
|
270 |
|
270 |
|
180 |
|
180 |
|
180 |
|
180 |
|
180 |
|
180 |
|
270 |
|
-180 |
|
90 |
|
270 |
|
90 |
|
270 |
|
270 |
|
180 |
|
270 |
|
270 |
|
270 |
|
180 |
|
270 |
|
270 |
|
270 |
|
180 |
|
270 |
Internal list of offsets
Footprint |
Offset X |
Offset Y |
---|---|---|
|
-1.27 |
-0.64 |
|
-2.54 |
-0.64 |
|
0.00 |
-1.44 |