KiBot variants example

A test/example of how to use KiBot assembly variants

KiBot variants example

KiBot variants

This is an example of how to use variants with KiBot.

Index

Definition

In the KiBot context a variant is what is usually known as an assembly variant. So the idea is that you have one PCB, but various different variants (flavors) of the product. The difference between them is which components are used.

Typical applications are:

Currently KiBot can handle not only which components are soldered, but also different values. The support for different values is complex and only used by a minority. So please be patient if some use case isn’t well covered, just report it.

Implementation

To create a variant you must add specific fields to the components in the schematic. Currently KiBot supports three methodes:

Example

The best way to explain how to use it is using an example. We start with an hypothetic design: the programmer section of the Arduino UNO R3. The schematic is the following:

Schematic

This is basically an ATMega8U2 used as a bridge between USB and the Arduino UNO serial port. So we will assume this board is useful. We’ll also assume we have three possible uses:

Additionally:

The first step is to choose a variant mechanism. For this example we will use the KiBoM style. This style puts more information inside the schematic, so you need to provide less information from outside.

Now that we chose a format we must add the corresponding tags. We can identify four groups of components here:

To mark components that will be added to the board only for certain variant KiBoM uses +VARIANT. And when we want to exclude a component from a variant we use -VARIANT.

We’ll use the default Config field. So lets see what we’ll use for each group.

Now that we know what to use we’ll add the Config field to the mentioned components. To make it faster we can add it to one component, lets say to J4, and then use the Tools -> Edit symbol fields menu option. Here is what we should have in the Config field:

Symbol fields dialog

This is all we need to add to the schematic. Now is time to configure KiBot.

If you don’t know about the KiBot file format you could be interested in reading the following explanation. YAML files are self explanatory, so perhaps you can go on even without knowing about the format.

Ok, now we have to define the three variants we mentioned before: USB, XTAL and default. All variants will be put in a section named variants. So we’ll create a list of items, each item is a variant definition. Lets start with the simplest: default. Here is what we use:

variants:
  - name: 'default'
    comment: 'Minimal PCB no USB'
    type: kibom

This is the section variants and its first item. The name is default and we added a comment to remmember what this variant is. We also define the type as kibom, what we called style.

Now lets go for the second, here we add:

  - name: 'USB'
    comment: 'Full board'
    type: kibom
    file_id: _USB
    variant: USB

You’ll notice two new attributes: file_id and variant. The first is what we’ll add to the names of the files in order to distinguish from the default. And the second … well this is just the tag we used to mark USB components.

You should be able to figure out how to define the third variant, here we go:

  - name: 'XTAL'
    comment: 'No USB, but crystal included'
    type: kibom
    file_id: _XTAL
    variant: XTAL

A little bit long, but simple. Here is all together:

variants:
  - name: 'default'
    comment: 'Minimal PCB no USB'
    type: kibom

  - name: 'USB'
    comment: 'Full board'
    type: kibom
    file_id: _USB
    variant: USB

  - name: 'XTAL'
    comment: 'No USB, but crystal included'
    type: kibom
    file_id: _XTAL
    variant: XTAL

This is all we need to define the variants. Of course our config file must define what to do with the variants. But this document is about the variants, we won’t focuse on the rest. You can see the whole configuration file here.

What now? How can we tell KiBot what variant to use? There are three methodes:

  1. Use the variant option for an specific output.
  2. Select a default variant to be used by all outputs that doesn’t specify a variant.
  3. Same as above but from the command line.

The simplest way is the third. In this case we just need to add -g variant=NAME to the command line. Lets say we have a copy of the repo containing this example and we want to generate the BoM. In our example the HTML BoM output is named bom_html so we can just run:

kibot -s run_erc,run_drc -d Result bom_html

This will create Result/BoM/t1-bom.html. To generate the BoM for the USB variant we can use:

kibot -s run_erc,run_drc -d USB -g variant=USB bom_html

And we’ll get a different BoM in USB/BoM/t1-bom_USB.html.

The CI/CD workflow for this repo runs the ERC and DRC checks and then generates all the configured outputs for the three variants. The commands used are approximately these:

kibot -d Generated -s run_drc -i
kibot -d Generated -s run_erc -i
kibot -d Generated/default -g variant=default -s run_erc,run_drc
kibot -d Generated/USB -g variant=USB -s run_erc,run_drc
kibot -d Generated/XTAL -g variant=XTAL -s run_erc,run_drc

The first two are the checks, no output generated. The other three skips the checks and generates all outputs for each variant. All files are stored in the Generated folder.

Results

Here is what we get, you can download the results obtained on GitHub CI/CD Actions from here. Click on the images to get a larger image or the generated document.

Schematic PDF

Excluded components are marked with a cross:

Default variant

XTAL variant

USB variant

Bill of Materials

Excluded components are listed as DNF in a separated list. Note we could also remove them.

Default variant

Default variant

Default variant

The XLSX files contain the same information, arranged a little bit different, here is the USB variant:

Default variant

PCB PDF

Excluded components are marked with a cross in the *.Fab layer. Their solder paste and adhesive glue is removed from *.Paste and *.Adhes. The following PDFs were gnerated including F.Fab, F.Paste, F.Adhes and Dwgs.User:

Default variant

Default variant

Default variant

Gerbers

Excluded components are marked with a cross in the *.Fab layer. Their solder paste and adhesive glue is removed from *.Paste and *.Adhes:

Default variant

Default variant

Default variant

Position

Here only the fitted components are included in the pick and place file:

3D Model

Excluded components are removed from the 3D model (STEP file, 3D Viewer render and Blender export):

Default variant

Default variant

Default variant

Changing values

Variants can also affect any of the component fields. In order to overwrite one field value when a variant is selected you must define a field named VARIANT:FIELD. The value for this field will replace the value of the regular FIELD when the VARIANT is in use.

Here is an example, if you have a resistor with a value of 1k and you want this value to change to 2k2 when the test variant is in use you just need to define a field named test:value and assign 2k2 to this field.

To enable it you just need to add a pre_transform filter of the type var_rename to the variant performing the transformation. Suppose you have the following variants:

variants:
  - name: 'production'
    comment: 'Production variant'
    type: kibom
    file_id: '_(PROD)'
    variant: PROD

  - name: 'development'
    comment: 'Development variant'
    type: kibom
    file_id: '_(DEV)'
    variant: DEV

And you want to both apply such a transformation you can define:

filters:
  - name: 'Variant rename'
    type: var_rename
    separator: ':'
    variant_to_value: true

variants:
  - name: 'production'
    comment: 'Production variant'
    type: kibom
    file_id: '_(PROD)'
    variant: PROD
    pre_transform: 'Variant rename'

  - name: 'development'
    comment: 'Development variant'
    type: kibom
    file_id: '_(DEV)'
    variant: DEV
    pre_transform: 'Variant rename'

The separator option controls which character is used to separate the VARIANT and the FIELD in the field name.

The variant_to_value enables the conversion from fields named VARIANT to the component value when the variant is in use.

To make things simpler you can use an internally defined filter called _var_rename. This is a var_rename filter with : as separator and variant_to_value disabled. Using it the configuration is simpler:

variants:
  - name: 'production'
    comment: 'Production variant'
    type: kibom
    file_id: '_(PROD)'
    variant: PROD
    pre_transform: '_var_rename'

  - name: 'development'
    comment: 'Development variant'
    type: kibom
    file_id: '_(DEV)'
    variant: DEV
    pre_transform: '_var_rename'

A complete example

The configuration file used in this example can be found here.