Electronics

Adafruit ST7735R TFT display minimal text example for PlatformIO

This example builds on the hardware & software setup outlined in Minimal ESP32 PlatformIO TFT display example using Adafruit ST7735. See there for the PlatformIO example & hardware setup.

Our code displays a counter on the display that is updated every second. Only the rectangle from the last text draw is cleared, facilitating much faster screen updates than if clearing the entire screen. Also, this technique allows you to flexibly update only part of the screen instead of having to re-draw all other segments on update.

#include <Arduino.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ST7735.h>
#include <string>

constexpr int Pin_LCD_CS = 27;
constexpr int Pin_LCD_DC = 23;
constexpr int Pin_LCD_RST = 22;
constexpr int Pin_LCD_SCLK = 14;
constexpr int Pin_LCD_MISO = 12;
constexpr int Pin_LCD_MOSI = 13;

Adafruit_ST7735 lcd(Pin_LCD_CS, Pin_LCD_DC, Pin_LCD_MOSI, Pin_LCD_SCLK,
                                 Pin_LCD_RST);

uint16_t backgroundColor = ST7735_WHITE;
uint16_t textColor = ST7735_RED;

void setup() {
  lcd.initR(INITR_BLACKTAB);      // Init ST7735S chip, black tab
  lcd.enableDisplay(true);        // Enable display
  // Fill screen with background color
  lcd.fillScreen(backgroundColor);
}

uint32_t counter = 0;

/**
 * The rectangle to clear the previous text
 * This is computed
 * 
 * @return int 
 */
struct Rect {
  int16_t x1;
  int16_t y1;
  uint16_t w;
  uint16_t h;
};
Rect lastTextRect;

void loop() {
  // The text we'll draw
  std::string text = "#" + std::to_string(counter);

  // Clear previous text
  if(!lastTextRect.w == 0 || !lastTextRect.h == 0) {
    lcd.fillRect(
      lastTextRect.x1,
      lastTextRect.y1,
      lastTextRect.w,
      lastTextRect.h,
      backgroundColor
    );
  }

  // Set position & parameters
  lcd.setCursor(0, 0);
  lcd.setTextColor(textColor);
  lcd.setTextWrap(true);
  lcd.setTextSize(5);

  // Compute bounding box of text text we'll draw
  // (so we can clear it later)
  lcd.getTextBounds(
    text.c_str(),
    lcd.getCursorX(),
    lcd.getCursorY(),
    &lastTextRect.x1,
    &lastTextRect.y1,
    &lastTextRect.w,
    &lastTextRect.h
  );
  
  lcd.print(text.c_str());
  delay(1000);
  counter++;
}

 

Posted by Uli Köhler in Arduino, PlatformIO

Minimal ESP32 PlatformIO TFT display example using Adafruit ST7735

This example code is for the KMR-1.8 SPI display (128x160px) and provides a minimal example using the Adafruit-ST7735 library that toggles the screen from black to white repeatedly. You can use this as a check if your hardware works correctly.

Hardware connection

Note that you can use any pin number on the ESP32 ; if you use other pins, ensure to change them in the code

  • Connect A0 or DC (whichever one exists on your board) to D23 on the ESP32 board.
  • Connect SCL (which is actually SPI SCK – the pin labeled SCK is just connected to the SD card!) to D14 on the ESP32 board.
  • Connect SDA (which is actually MOSI – the pin labeled MOSI is just connected to the SD card!) to D12 on the ESP32 board.
  • Connect CS to D27 on the ESP32 board.
  • ConnectRESET to D22 on the ESP32 board.
  • Connect LED- to GND on the ESP32 board.
  • Connect VCC to 3V3 on the ESP32 board.
  • Connect LED+ to 3V3 on the ESP32 board.
  • Connect Vcc to 3V3 on the ESP32 board.

Do not connect any pin to VIn or 5V. This can easily damage your display!

PlatformIO source code

#include <Arduino.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ST7735.h>

constexpr int Pin_LCD_CS = 27;
constexpr int Pin_LCD_DC = 23;
constexpr int Pin_LCD_RST = 22;
constexpr int Pin_LCD_SCLK = 14;
constexpr int Pin_LCD_MISO = 12;
constexpr int Pin_LCD_MOSI = 13;

Adafruit_ST7735 lcd(Pin_LCD_CS, Pin_LCD_DC, Pin_LCD_MOSI, Pin_LCD_SCLK,
                                 Pin_LCD_RST);

void setup() {
  lcd.initR();      // Init ST7735S chip, black tab
  lcd.enableDisplay(true);        // Enable display
}

void loop() {
  delay(500);
  lcd.fillScreen(ST7735_BLACK);
  delay(500);
  lcd.fillScreen(ST7735_WHITE);
}
[env:esp32dev]
platform = espressif32
board = esp32dev
framework = arduino
lib_deps =
    adafruit/Adafruit GFX Library@^1.11.5
    adafruit/Adafruit ST7735 and ST7789 Library@^1.10.0

 

Posted by Uli Köhler in Arduino, PlatformIO

JLCPCB Which Via plating thickness?

JLCPCB’s standard via plating thickness is 18μm

Source: My support request on 2023-05-23

Posted by Uli Köhler in Electronics

What are the part numbers for JST VH crimp contacts?

The part number for JST VH crimp contacts is SVH-21T-P1.1.

You can source them, for example, at LCSC.

Posted by Uli Köhler in Electronics

How I export KiCAD pick&place CSVs using kicad-cli

Since KiCAD 7.0, you can use the kicad-cli command line tool to export a pick & place position CSV file from a KiCAD project. You can also export an ASCII format, depending on what software you’ll use to process the data.

My standard export command uses the drill origin as a pick&place origin since you can place it anywhere you like:

kicad-cli pcb export pos MyPCB.kicad_pcb --format csv --use-drill-file-origin --units mm -o MyPCB.positions.csv

 

 

Posted by Uli Köhler in KiCAD

How to read KiCAD XML BOM using Python

This script reads an XML BOM (also called python-bom in kicad-cli) using beautifulsoup4 and – as an usage example, generates a RefDes to footprint name dictionary:

from bs4 import BeautifulSoup

def extract_footprints_by_ref_from_xml(filename):
    footprints_by_ref = {} # e.g. "C3" => "Capacitor_SMD:C_0603_1608Metric"
    
    with open(filename, "r") as infile:
        soup = BeautifulSoup(infile, features="xml")
        
    for component in soup.export.components.findChildren("comp"):
        refdes = component.attrs["ref"]
        footprints_by_ref[refdes] = component.footprint.text
    
    return footprints_by_ref

 

Posted by Uli Köhler in KiCAD, Python

How to export KiCAD XML BOM using kicad-cli

kicad-cli sch export python-bom MyBoard.kicad_sch -o BOM.xml

 

Posted by Uli Köhler in KiCAD

How to export KiCAD PCB as PDF using kicad-cli

This command will create a PDF printout of the PCB. The following example prints the front side in front of the back side:

kicad-cli pcb export pdf MyPCB.kicad_pcb -l "F.Cu,F.Mask,F.Silkscreen,F.Courtyard,Edge.Cuts,B.Cu,B.Mask,B.Silkscreen,B.Courtyard" -o MyPCB.front.pdf

This is the corresponding command to print just the back side, so that it isn’t occluded by the front side.

kicad-cli pcb export pdf MyPCB.kicad_pcb -l "B.Cu,B.Mask,B.Silkscreen,B.Courtyard,Edge.Cuts" -o MyPCB.back.pdf

 

Posted by Uli Köhler in KiCAD

How to iterate footprint pads using KiCAD pcbnew plugin Python API

Iterate the pads of a given pcbnew.FOOTPRINT object using

for pad in list(footprint.Pads()):
    # Example of what to do with [pad]
    print(f"{footprint.GetReference()} {pad.GetNetname()}")

Example of how to print all pads for every footprint on the board:

for footprint in list(pcbnew.GetBoard().GetFootprints()):
    for pad in list(footprint.Pads()):
        # Example of what to do with [pad]
        print(f"{footprint.GetReference()} {pad.GetNetname()}")

This will print, for example:

D1 Net-(D1-K)

 

Posted by Uli Köhler in KiCAD, Python

How to get all footprints on board using KiCAD plugin Python API

Use the following for loop to iterate all footprints in the current board:

for footprint in list(pcbnew.GetBoard().GetFootprints()):
    # Example of what to do with [footprint]
    print(footprint.GetReference())

 

Posted by Uli Köhler in KiCAD, Python

How to get all selected zones using KiCAD pcbnew plugin Python API

In our previous post, we showed how to get all selected objects using the KiCAD python API using

pcbnew.GetCurrentSelection()

You can simply filter these entries to obtain just a list of selected zones using either a for loop with inline filtering:

for selected_object in pcbnew.GetCurrentSelection():
    if type(selected_object).__name__ == 'ZONE':
        print(selected_object.GetReference())

or using a list comprehension:

selected_footprints: list[pcbnew.FOOTPRINT] = [
    zone for zone in pcbnew.GetCurrentSelection() if type(zone).__name__ == 'ZONE'
]

Complete plugin example:

#!/usr/bin/env python
import pcbnew
import os

class SimplePlugin(pcbnew.ActionPlugin):
    def defaults(self):
        self.name = "Plugin Name as shown in Pcbnew: Tools->External Plugins"
        self.category = "A descriptive category name"
        self.description = "A description of the plugin and what it does"
        self.show_toolbar_button = False # Optional, defaults to False
        self.icon_file_name = os.path.join(os.path.dirname(__file__), 'simple_plugin.png') # Optional, defaults to ""

    def Run(self):
        board: pcbnew.BOARD = pcbnew.GetBoard()
        footprints: list[pcbnew.FOOTPRINT] = board.GetFootprints()
        
        # TODO Do something useful with [board]
        for selected_object in pcbnew.GetCurrentSelection():
            print(selected_object)

SimplePlugin().register() # Instantiate and register to Pcbnew

Example output (excerpt):

D39
D32
D23
D37
D18
D34
D11
D15

 

Posted by Uli Köhler in KiCAD, Python

KiCAD minimal pcbnew plugin example

The following python script is more or less the minimal example of a KiCAD pcbnew plugin from our previous post How to show wx dialog message in KiCAD pcbnew plugin.

#!/usr/bin/env python
import pcbnew
import wx

class DialogExamplePlugin(pcbnew.ActionPlugin):
    def defaults(self):
        self.name = "Show dialog example"
        self.category = "A descriptive category name"
        self.description = "A description of the plugin and what it does"
        self.show_toolbar_button = False # Optional, defaults to False

    def Run(self):
        dlg = wx.MessageDialog(None, "Please select one or multiple footprints!\n...or use Ctrl+A to select everything.", "No footprints selected", wx.OK | wx.ICON_ERROR)
        dlg.ShowModal()
        dlg.Destroy()

DialogExamplePlugin().register() # Instantiate and register to Pcbnew

You can place this plugin, for example, in

~/.local/share/kicad/7.0/scripting/plugins/DialogExamplePlugin.py

Don’t forget to refresh the plugins from the pcbnew menu.

Posted by Uli Köhler in KiCAD, Python

How to show wx dialog message in KiCAD pcbnew plugin

When using KiCAD’s Python API for pcbnew, you can show a dialog by using the following snippet

# Show info dialog
dlg = wx.MessageDialog(None, "Please select one or multiple footprints!\n...or use Ctrl+A to select everything.", "No footprints selected", wx.OK | wx.ICON_ERROR)
dlg.ShowModal()
dlg.Destroy()

Note that you need to

import wx

at the top of your plugin.

This code will show the following dialog:

 

Complete plugin example:

#!/usr/bin/env python
import pcbnew
import wx

class DialogExamplePlugin(pcbnew.ActionPlugin):
    def defaults(self):
        self.name = "Show dialog example"
        self.category = "A descriptive category name"
        self.description = "A description of the plugin and what it does"
        self.show_toolbar_button = False # Optional, defaults to False

    def Run(self):
        dlg = wx.MessageDialog(None, "Please select one or multiple footprints!\n...or use Ctrl+A to select everything.", "No footprints selected", wx.OK | wx.ICON_ERROR)
        dlg.ShowModal()
        dlg.Destroy()

DialogExamplePlugin().register() # Instantiate and register to Pcbnew

You can place this plugin, for example, in

~/.local/share/kicad/7.0/scripting/plugins/DialogExamplePlugin.py

Don’t forget to refresh the plugins from the pcbnew menu.

Posted by Uli Köhler in KiCAD, Python

Where to place custom KiCAD plugins on Linux?

In order to create a custom simple KiCAD plugin, save it as NAME.py in the following folder (where NAME is any filename such as MyTestPlugin):

~/.local/share/kicad/7.0/scripting/plugins

For example, you could place a plugin in

~/.local/share/kicad/7.0/scripting/plugins/MyPlugin.py

or in

~/.local/share/kicad/7.0/scripting/plugins/AddMyStuff.py

Note that you don’t need to restat pcbnew to load the plugins, you can just reload all plugins from the menu!

Posted by Uli Köhler in KiCAD

How to read KiCAD pick&place position file using pandas in Python

If you’ve exported a KiCAD pick & place position file using the GUI or the command line:

kicad-cli pcb export pos MyPCB.kicad_pcb --units mm -o MyPCB.pos

you can read it from within your Python script using pandas.read_table(...) like this:

import pandas as pd

pos = pd.read_table('KKS-Microcontroller-Board-R2.2.pos', delim_whitespace=True, names=["Ref", "Val", "Package", "PosX", "PosY", "Rot","Side"], comment="#")

Optionally, you can also index pos by the Ref column (which contains values such as C12D1 or U5):

pos.set_index("Ref", inplace=True)

You can also pack all that into a function:

def read_kicad_pos_file(filename):
    pos = pd.read_table(filename, delim_whitespace=True, names=["Ref", "Val", "Package", "PosX", "PosY", "Rot","Side"], comment="#")
    pos.set_index("Ref", inplace=True)
    return pos

If you’ve used .set_index(), you can access a component such as C13 using

pos.loc["C13"]

Example output:

Val                100nF_25V
Package    C_0603_1608Metric
PosX                187.1472
PosY               -101.8243
Rot                    180.0
Side                     top
Name: C1, dtype: object

 

Posted by Uli Köhler in KiCAD, pandas, Python

How to export KiCAD pick&place position file using kicad-cli

Since KiCAD 7.0, you can use the kicad-cli command line tool to export a pick & place position TSV file from a KiCAD project.

First, find out what the filename of the PCB file is. Typically, if your project is named MyPCB.kicad_pro, your main schematic file is named MyPCB.kicad_pcb.

Now you can export the position file using

kicad-cli pcb export pos MyPCB.kicad_pcb --units mm

This will output, for example

Loading board

If the PCB file is named MyPCB.kicad_pcb, the position file will be called MyPCB.pos.

You can also set a custom output file name such as out.pos using the -o option.

kicad-cli pcb export pos MyPCB.kicad_pcb -o out.pos --units mm

 

 

Posted by Uli Köhler in KiCAD

How to export KiCAD schematic PDF using kicad-cli

Since KiCAD 7.0, you can use the kicad-cli command line tool to export a colored schematic PDF from a KiCAD project.

First, find out what the filename of the main schematic file is. Typically, if your project is named MyPCB.kicad_pro, your main schematic file is named MyPCB.kicad_sch.

Now you can export the schematic PDF using

kicad-cli sch export pdf MyPCB.kicad_sch

This will output, for example

Plotted to '/home/uli/MyPCB/MyPCB.pdf'.

Done.

The PDF file from the output contains your schematic PDF.

Posted by Uli Köhler in KiCAD

Where to find cheap PCB-mount SMA connectors?

As for most parts, if you order more than just a few pcs, LCSC is the cheapest source of these components (however, you need to consider the rather expensive shipping costs).

Here’s some SMA connectors I’ve used:

Note that I don’t use them in typical RF applications, so I don’t have any information on impedance matching or accuracy etc.

 

Posted by Uli Köhler in Components, Electronics

What current rating do JST VH connectors have?

JST VH connectors such as the 6-pin B6P-VH male header have a current rating of 10 A per pin.

Source: JST VH datasheet

Posted by Uli Köhler in Electronics