Skip to the content
2 layers50 × 35 mmFan switch, the printed circuit board in 3D

12V DC Fan switch based on ESP8266

Size
50 × 35 mm
Copper layers
2
Thickness
1.6 mm
Parts
23
Nets
23
Pads
66
Tracks, vias
91, 39
Pours
2
Routed
Yes
KiCad
KiCad 9.0 (file 20241229)
Created
18 Sep 2022
Updated
12 Oct 2026

Overview

Fan switch is an open-source printed circuit board by burgrp, from the burgrp/hw-fan-switch repository on GitHub. It is a 2-layer board of 50 × 35 mm with 23 parts on 23 nets, routed with 91 tracks and 39 vias.

It is built around the PAN2110P0AA, LM1117MP-3.3 and AO3400A, with the SK22 among its other parts. Its parts include 6 capacitors, 5 connectors, 3 resistors, 3 ICs and 2 diodes.

Main components

4

README

README.md

hw-fan-switch

A small, wirelessly-controlled 12 V DC fan switch. It drives a fan with a variable PWM duty cycle and is controlled over a BLE long-range radio link, making it part of the Bleriot node network.

PCB

The board is built around a Puya PY32F003 Cortex-M0+ microcontroller with a PAN211x radio, and the firmware is written in Go and compiled with TinyGo.

Features

  • Variable-speed fan control via hardware PWM (TIM14_CH1 on PB1).
  • 50 kHz PWM carrier, above the audible range to avoid switching noise.
  • Configurable low-speed handling:
    • Low-duty threshold — below this duty the fan is treated as stopped and the output is forced to 0.
    • Low-duty kickstart — a brief higher-duty pulse to overcome fan stiction when starting at low speed.
  • Wireless control and telemetry over the PAN211x BLE long-range link.
  • Yellow status LED is steadily on while the hub is online and flashes briefly once per second while offline.
  • Device identity, radio settings, and configuration are owned by the site inventory and baked into each firmware image at build time.

Repository layout

PathDescription
board/KiCad hardware design (schematic, PCB, BOM, production files).
fw/Importable TinyGo firmware and board-owned build profile.
fw/spec/Device specification: registers and runtime Config.
fw/cmd/dev/Optional local development inventory.
sub/hw-kicad/Shared KiCad symbol/footprint library (git submodule).

Hardware

FunctionPin
Yellow status LEDPB0
Fan PWM output (TIM14_CH1, AF0)PB1
Radio SPI clockPA2
Radio SPI dataPA1
Radio SPI chip selectPA4

The status LED is active high. A successfully decoded hub packet keeps the node online for five seconds. While online the LED remains on; after the timeout it follows BleRiot's 200 ms on, 800 ms off heartbeat until another packet arrives.

The KiCad project lives in board/, with fabrication outputs (Gerbers, BOM, positions) under board/production/.

Firmware

The firmware is the importable fanswitch package. Its TinyGo implementation exports Run, while fw/spec exposes Config, the register table, chip, and a typed build/flash profile. BleRiot generates a private external package main inside the deployment module and calls Run with that instance's baked identity and configuration. Nothing is generated in this repository for a deployment build.

Prerequisites

  • TinyGo
  • pyOCD for flashing and RTT logging
  • arm-none-eabi-objdump (optional, for disassembly)

Clone with submodules:

sh
git clone --recurse-submodules https://github.com/burgrp/hw-fan-switch.git

Build and flash

Build deployment firmware from the authoritative site inventory. For the AGC checkout and its basement.fan instance:

sh
cd /home/paul/git/agc/bleriot

# Inspect the generated entry point without writing it
go run . node gen --name basement.fan

# One-time: install the target CMSIS pack
go run . node install-pack --name basement.fan

# Generate the private entry point and build image.elf
go run . node build --name basement.fan

# Generate, build, flash, and open RTT
go run . node build --name basement.fan --flash --rtt

# Open RTT without flashing
go run . node rtt --name basement.fan

The bleriot node commands resolve the selected inventory instance. node build generates its identity and Config under that deployment's private .bleriot directory, then builds this module using the profile carried by spec.Type. The deployment pins the firmware version in go.mod; it does not carry fan-specific build flags. This repository's Makefile contains optional aliases for fw/cmd/dev.

Configuration

The inventory Config (see fw/spec/spec.go) controls runtime behaviour:

FieldMeaning
DefaultDutyFan duty cycle (0–100) applied at startup.
LowDutyThresholdDuty below which the fan is forced to 0. 0 disables the threshold.
LowDutyKickstartDuty briefly applied to spin up the fan from low speed. 0 disables the kickstart.

Control interface

The device exposes a single register over the Bleriot network:

RegisterTagTypeUnitDescription
duty1int%PWM duty cycle, 0–100.

Writing duty updates the fan speed; the hub's next scheduled GET observes the new value. A NULL write stops the fan. Reading returns the current duty.

Parts

23
QtyValueFootprintReferences
3100nCapacitor_SMD:C_0805_2012MetricC3, C5, C6
210uCapacitor_SMD:C_0805_2012MetricC1, C4
1100Resistor_SMD:R_0805_2012Metric_Pad1.20x1.40mm_HandSolderR2
110kResistor_SMD:R_0805_2012Metric_Pad1.20x1.40mm_HandSolderR1
112VConnector_Wire:SolderWire-1sqmm_1x01_D1.4mm_OD3.9mmJ1
116MHzCrystal:Crystal_SMD_3225-4Pin_3.2x2.5mmY1
11uCapacitor_SMD:C_0805_2012MetricC2
131mmDrake:Wire antena 2.4GHzA1
1330RResistor_SMD:R_0805_2012Metric_Pad1.20x1.40mm_HandSolderR3
1AO3400APackage_TO_SOT_SMD:SOT-23Q1
1GNDConnector_Wire:SolderWire-1sqmm_1x01_D1.4mm_OD3.9mmJ2
1LEDLED_SMD:LED_0805_2012Metric_Pad1.15x1.40mm_HandSolderD2
1LM1117MP-3.3Package_TO_SOT_SMD:SOT-223-3_TabPin2U1
1M+Connector_Wire:SolderWire-1sqmm_1x01_D1.4mm_OD3.9mmJ4
1M-Connector_Wire:SolderWire-1sqmm_1x01_D1.4mm_OD3.9mmJ5
1PAN2110P0AAPackage_SO:SOIC-8_3.9x4.9mm_P1.27mmU2
1PY32F003W1xSxPackage_SO:SOIC-16_3.9x9.9mm_P1.27mmU3
1SK22Diode_SMD:D_SMB_HandsolderingD1
1SWDDrake:SWDX1
1TXConnector_PinHeader_2.54mm:PinHeader_1x01_P2.54mm_VerticalJ3

Similar boards

  • 2 layers100 × 50 mmHw bms-48v, the printed circuit board in 3D

    Hw bms-48v

    burgrp/hw-bms-48v

    48V/200A battery monitoring system

    41 parts1
  • 2 layers40 × 42 mmBleriot rs485, the printed circuit board in 3D

    Bleriot rs485

    burgrp/bleriot-rs485

    DIN rail mounted RS485 to WiFi bridge

    21 parts1
  • 4 layers68 × 19 mmBob, the printed circuit board in 3D

    Bob

    burgrp/bleriot

    BleRiot is a compact request/response protocol for reading and writing named integer registers on low-power RF nodes. A Linux hub polls the nodes and bridges their registers to an external Registry service.

    25 parts
  • 2 layers314 × 27 mmBleriot REG6, the printed circuit board in 3D

    Bleriot REG6

    burgrp/bleriot-REG6

    REG6 is a six-channel solid-state-relay controller built around a PY32F030 and PAN2110. This repository contains the KiCad hardware and a standalone TinyGo/BleRiot module under fw/ that exposes one integer percentage…

    85 parts
  • 2 layers77 × 51 mmAt32f455-bob, the printed circuit board in 3D

    At32f455-bob

    burgrp/hw-at32f455-bob

    66 parts
  • 2 layers170.6 × 121.1 mmEIM, the printed circuit board in 3D

    EIM

    bhorst519/bluecar

    232 parts3
  • 2 layers175 × 120 mmNanook mb, the printed circuit board in 3D

    Nanook mb

    burgrp/nanook-mb

    NANOOK geothermal heat pump main board

    83 parts2

Questions

How big is the Fan switch PCB?

It measures 50 × 35 mm and has 2 copper layers, 1.6 mm thick.

What parts does the Fan switch use?

23 parts, built around the PAN2110P0AA, LM1117MP-3.3, AO3400A and SK22. The full list of its parts is on this page, with links to each part's symbol and footprint where PCBKit's library has them.

Where can I download the Fan switch KiCad files?

From the burgrp/hw-fan-switch repository on GitHub, at the commit this page was made from: the board is board/fan-switch.kicad_pcb and its schematic board/fan-switch.kicad_sch. PCBKit opens the board in the browser, with nothing to install.

Can I use the Fan switch design in my own project?

Its repository states no licence, so its author keeps all rights: ask burgrp before reusing the design.