Skip to the content
PCBKitNew board
2 layers60 × 40 mmCanary, the printed circuit board in 3D

Open hardware from OffGrid Devices. One folder per board. CERN-OHL-S.

Size
60 × 40 mm
Copper layers
2
Thickness
1.6 mm
Parts
52
Nets
38
Pads
182
Tracks, vias
360, 82
Pours
5
Routed
Yes
KiCad
KiCad 10.0 (file 20260206)
Created
26 Aug 2026
Updated
6 Nov 2026

Overview

Canary is an open-source printed circuit board by offgridevices, from the offgridevices/offgrid-hardware repository on GitHub, published under the CERN-OHL-S-2.0 licence. It is a 2-layer board of 60 × 40 mm with 52 parts on 38 nets, routed with 360 tracks and 82 vias.

It is built around the ATMEGA328P-AU, SGP40-D-R4 and SHT40-AD1B-R2, with the AP2112K-3.3TRG1, SCD41-D-R2 and CL21A106KAYNNNE among its other parts. Its parts include 14 resistors, 13 capacitors, 5 ICs, 5 diodes and 3 connectors. It belongs with the AVR (ATmega, ATtiny) boards of this library.

Main components

12

README

products/canary/README.md

Canary — first-vent detector for lithium batteries

Canary v1

Status: designed and verified in simulation, not yet built. Every gate below passes on this revision; no board has been assembled or powered yet.

Revisions

This folder always holds the latest revision; an ordered revision stays at its order tag (docs/versioning.md).

RevisionWhat changedStatusOrder tag
1.0first design: SGP40 + SCD41 + SHT40 + NTC tab, ATmega328P, 100 dB sounder, 60 × 40 mm, 2 layersdesigned and simulation-verified, not yet built—

What it is

A 60 × 40 mm board you put next to (or on) an e-bike or scooter battery while it charges. It watches for the first vent — the moment a failing cell boils off electrolyte as solvent vapour and CO₂ — which comes before self-heating, thermal runaway and smoke. A smoke alarm reacts at the end of that chain; Canary is built to react near its start.

Grid storage and EV packs already carry off-gas detectors (Honeywell BES, Li-ion Tamer). The battery charging in a hallway has nothing. Canary is that detector as an open, cheap, USB-powered board you can order fully assembled.

It fuses three kinds of evidence and needs two at once to alarm:

EvidenceSensorFires onAlone it means
GasSensirion SGP40 MOX (on the isolated sensor head)raw signal ≥ 700 ticks below its learned clean-air baseline (strong ≥ 2500)WARN (cleaning spray, solvents)
CO₂Sensirion SCD41 photoacousticrise ≥ 250 ppm/min or ≥ 1500 ppm over baseline (strong ≥ 1200 ppm/min or ≥ 4000 ppm)WARN (someone breathing on it)
HeatNTC on the thermal tab (or remote probe)≥ 50 °C, or ≥ 1 °C/min above 35 °C (strong: ≥ 65 °C, or ≥ 3 °C/min above 30 °C)WARN; strong heat alone → ALARM

ALARM = gas and CO₂ (one strong), or heat and any gas evidence, or strong heat alone; held 3 s before it sounds, latched for at least 60 s. Outputs: green breathing (watching), amber (one kind of evidence), red flashing + 100 dB 4 kHz sounder in the smoke-alarm T3 pattern. The button self-tests in normal state and hushes for 2 minutes in alarm — the hush ends early if the evidence gets worse.

Product video: a narrated 4-minute explainer, built by video/ and published rather than committed (video/README.md).

The real firmware, on a simulated ATmega328P with virtual sensors, catching a vent at 400 s (alarm 7.6 s later) — sim/hil/:

vent scenario

Requirements, and whether they are met

RequirementHow it is checkedMet?
Order from PCBWay, arrive assembled and workingGerbers + PCBWay BOM + CPL + firmware HEX in production/; all parts on top; every part has an MPNYes (files); hardware not yet built
Parts in production todayDistributor check 2026-10-14, docs/sourcing-2026-10-14.mdYes — one NRND part replaced (NTC)
Latest KiCadKiCad 10.0.6 (kicad/kicad:10.0.6-full), current stableYes
Schematic cleankicad-cli sch erc: 0 violationsYes
Board clean, fab's limitskicad-cli pcb drc --schematic-parity --severity-all: 0 errors, 0 warnings, 0 unconnected against PCBWay 2-layer limits (with margin)Yes
Clean copper, wide enough for its currentcheck_geometry.py: no corner sharper than 45° (the router's six right angles mitered by miter.py); every power track ≥ 2.4× its IPC-2221 width at a 10 °C riseYes
Schematic = circuit = board = firmwarecheck_netlist.py (27 nets, 0 mismatches), DRC parity, check_pins.py (11 pins, 0 mismatches)Yes
Detects a vent within seconds, ignores single-cause eventsHIL simulation of the real firmware: vent → ALARM in 7.6 s; spray, breath → no alarm; still detecting after 100 min of charging; 65/65 checks across 9 scenariosYes, in simulation
Sounder driver safengspice: drain clamped at 5.4 V on 5 V, clamp diode ≤ 0.34 A, VBUS dip ≥ 4.95 V, for 0.5–4 mH coilsYes
Pack temperature good enough at the thresholdsTolerance stack-up: ≤ 1.24 °C worst case at 65 °C; rate quantum 0.2 °C/minYes
Runs from any USB charger23.5 mA watching, ~520 mA worst-case peak in alarmYes (≤ 900 mA)

How to order (PCBWay, fully assembled)

  1. PCB: upload production/canary-gerbers.zip.
    • 2 layers, FR-4, 1.6 mm, 60 × 40 mm, 1 design
    • Min track/spacing 6/6 mil (the design's tightest gap is 0.2 mm), min hole 0.3 mm
    • Solder mask yellow, silkscreen black (white is fine if black is not offered on yellow)
    • Surface finish ENIG (fine-pitch DFN sensors)
    • The board has three internal routed slots (1.0 mm wide): they are intended, not errors.
  2. Assembly: turnkey, top side only, 43 placements / 27 unique parts.
    • BOM: production/canary-bom-pcbway.csv (MPN, maker, LCSC # for reference, notes)
    • Centroid: production/canary-cpl.csv; drawing: production/canary-assembly.pdf
    • J1 (USB-C) has four plated shell slots — pin-in-paste/hand-solder as PCBWay prefers.
    • Sensirion parts (U3 SGP40, U4 SHT40, U5 SCD41): no washing, no conformal coating.
  3. Programming (PCBWay offers it; ask in the order notes): flash production/canary.hex to U2 (ATmega328P) through the Tag-Connect TC2030 pads (J2, standard 6-pin AVR ISP pinout), with fuses lfuse 0xE2, hfuse 0xD9, efuse 0xFD (internal 8 MHz, no clock divider, brown-out 2.7 V). To do it yourself: a USBasp + TC2030-IDC-NL cable, then make -C firmware flash.

Case

enclosure/print/canary-v1-bumper.stl is an optional printed frame (PLA/PETG, no supports, 64 × 44 × 5 mm). The board presses in from below; its underside stays flush with the frame's so the thermal tab still lies on the pack, and the USB-C, probe connector and the sensor head's air path stay open.

bumper

Bring-up

  1. Plug a USB-C cable from any phone charger. Green blinks for 90 s (gas sensor warm-up), then breathes slowly.
  2. Press TEST/HUSH: green, amber, red sweep, a short beep, and the SGP40 self-test runs. A fault shows as an amber double blink with a chirp every minute.
  3. Telemetry: TXD pad, 3.3 V, 38400 8N1, one line a second (t= st= tp= ... sraw= co2= rate= dtdt= e= f=).
  4. Use: lay the board on the pack with the thermal tab touching it (or plug a 10 kΩ B3950 NTC probe into the JST-PH and tape it to the pack), the sensor head ("AIR IN") facing the air above the pack.

Limits — read these

  • Not a certified safety device. Keep your smoke alarm.
  • The thresholds are not yet validated against a real venting cell. The simulated worlds use stated assumptions (SGP40 drop of thousands of ticks, CO₂ rising by thousands of ppm within a minute, accelerating self-heating), based on how first vent is described for commercial off-gas detectors. A real abuse test (a cell vented beside the board, in a safe facility) is the next step, and the thresholds in firmware/src/detect.h may move.
  • No battery backup: if the outlet loses power, Canary is off.
  • Placement matters: the gas and CO₂ sensors need the vent plume to reach them; inside a closed bag or a frame with no airflow, use the probe and expect slower gas detection.
  • The ATmega328P has no USB: firmware updates need an ISP programmer.
  • 3D models for SGP40, SHT40, SCD41, the sounder and the JST connector are simple dimensioned boxes made by src/models3d.py (KiCad 10.0.6 ships none).

Files

PathWhat
production/Gerber zip, PCBWay BOM, CPL, netlist, assembly + schematic PDFs, firmware HEX
canary.kicad_sch, canary.kicad_pcb, canary.kicad_proKiCad 10 design (generated)
src/the design source: circuit.py (every part and net), schematic.py, board.py, miter.py, finish.py, fab.py, checks
firmware/AVR C firmware (detect.c is the detector logic)
sim/hil/simavr hardware-in-the-loop harness + scenarios
sim/spice/, sim/analysis/sounder driver SPICE, NTC/power/I²C analyses
video/the scripts that build the narrated product video (the MP4 is published, not committed)
web/the interactive bench page (build_page.py → one HTML file); its detector is a port of detect.c checked equal to the firmware second by second
mechanical/STEP model (zipped)
enclosure/3D-printable bumper: bumper.scad, and print/canary-v1-bumper.stl
TESTS.md, docs/decisions.mdevery test with results; the trade-offs

How to build

Needs docker (kicad/kicad:10.0.6-full), Java + xvfb (Freerouting 1.9.0 at /opt/fr/freerouting-1.9.0.jar or FREEROUTING_JAR), avr-gcc, Python 3.

sh
python3 src/make.py                 # schematic, ERC, netlist gate, place, route, DRC gate, fab
python3 src/make.py sch finish fab  # without re-routing (the routed board in out/ is reused)
make -C firmware                    # firmware only
cd sim/hil && gcc -O2 -I<simavr>/simavr/sim ... && python3 scenarios.py   # see sim/hil/README.md

Routing is done by Freerouting and is not bit-for-bit repeatable, so the committed canary.kicad_pcb is the design of record: CI rebuilds the fab outputs from it and checks they match what is committed.

Parts

52
QtyValueFootprintReferences
8100nCapacitor_SMD:C_0603_1608MetricC3, C4, C5, C6, C8, C10, C11, C12
410uCapacitor_SMD:C_0805_2012MetricC1, C2, C9, C13
31kResistor_SMD:R_0603_1608MetricR8, R11, R12
3FiducialFiducial:Fiducial_1mm_Mask2mmFID1, FID2, FID3
210kResistor_SMD:R_0603_1608MetricR3, R14
210k 0.1%Resistor_SMD:R_0603_1608MetricR6, R7
24.7kResistor_SMD:R_0603_1608MetricR4, R5
25.1kResistor_SMD:R_0603_1608MetricR1, R2
2M2MountingHole:MountingHole_2.2mm_M2H1, H2
1100Resistor_SMD:R_0603_1608MetricR9
1100kResistor_SMD:R_0603_1608MetricR10
110k B3380Resistor_SMD:R_0603_1608MetricTH1
11uCapacitor_SMD:C_0603_1608MetricC7
1470Resistor_SMD:R_0603_1608MetricR13
1AO3400APackage_TO_SOT_SMD:SOT-23Q1
1AP2112K-3.3Package_TO_SOT_SMD:SOT-23-5U1
1ATmega328P-AUPackage_QFP:TQFP-32_7x7mm_P0.8mmU2
1AmberLED_SMD:LED_0603_1608MetricD4
1B5819WDiode_SMD:D_SOD-123D2
1CMT-8504Buzzer_Beeper:MagneticBuzzer_CUI_CMT-8504-100-SMTBZ1
1GNDTestPoint:TestPoint_Pad_D1.0mmTP3
1GreenLED_SMD:LED_0603_1608MetricD3
1ISP (Tag-Connect)Connector:Tag-Connect_TC2030-IDC-NL_2x03_P1.27mm_VerticalJ2
1ProbeConnector_JST:JST_PH_S2B-PH-SM4-TB_1x02-1MP_P2.00mm_HorizontalJ3
1RXDTestPoint:TestPoint_Pad_D1.0mmTP2
1RedLED_SMD:LED_0603_1608MetricD5
1SCD41Sensor:Sensirion_SCD4x-1EP_10.1x10.1mm_P1.25mm_EP4.8x4.8mmU5
1SGP40canary:Sensirion_DFN-6_2.44x2.44mm_P0.8mm_SGP40U3
1SHT40Sensor_Humidity:Sensirion_DFN-4_1.5x1.5mm_P0.8mm_SHT4x_NoCentralPadU4
1SMF5.0ADiode_SMD:D_SMFD1
1TEST / HUSHButton_Switch_SMD:SW_SPST_TL3342SW1
1TXDTestPoint:TestPoint_Pad_D1.0mmTP1
1USB-C powerConnector_USB:USB_C_Receptacle_GCT_USB4125-xx-x-0190_6P_TopMnt_HorizontalJ1

Questions

How big is the Canary PCB?

It measures 60 × 40 mm and has 2 copper layers, 1.6 mm thick.

What parts does the Canary use?

52 parts, built around the ATMEGA328P-AU, SGP40-D-R4, SHT40-AD1B-R2 and AP2112K-3.3TRG1. 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 Canary KiCad files?

From the offgridevices/offgrid-hardware repository on GitHub, at the commit this page was made from: the board is products/canary/canary.kicad_pcb and its schematic products/canary/canary.kicad_sch. PCBKit opens the board in the browser, with nothing to install.

Can I use the Canary design in my own project?

Its repository publishes it under the CERN-OHL-S-2.0 licence: you may reuse it on that licence's terms (keep the author's notice, and for a copyleft licence share your changes alike).

More from offgridevices/offgrid-hardware

10
  • 8 layers38 × 38 mmRidge3-lite, the printed circuit board in 3D

    Ridge3-lite

    offgridevices/offgrid-hardware

    Open hardware from OffGrid Devices. One folder per board. CERN-OHL-S.

    260 partsCERN-OHL-S-2.0
  • 6 layers91.6 × 50.6 mmSmokebreak, the printed circuit board in 3D

    Smokebreak

    offgridevices/offgrid-hardware

    Open hardware from OffGrid Devices. One folder per board. CERN-OHL-S.

    208 partsCERN-OHL-S-2.0
  • 8 layers36 × 36 mmRidge3-esc, the printed circuit board in 3D

    Ridge3-esc

    offgridevices/offgrid-hardware

    Open hardware from OffGrid Devices. One folder per board. CERN-OHL-S.

    193 partsCERN-OHL-S-2.0
  • 6 layers65.3 × 57.8 mmLayercam pro, the printed circuit board in 3D

    Layercam pro

    offgridevices/offgrid-hardware

    Open hardware from OffGrid Devices. One folder per board. CERN-OHL-S.

    189 partsCERN-OHL-S-2.0
  • 6 layers38 × 53.6 mmLayercam main, the printed circuit board in 3D

    Layercam main

    offgridevices/offgrid-hardware

    Open hardware from OffGrid Devices. One folder per board. CERN-OHL-S.

    168 partsCERN-OHL-S-2.0
  • 4 layers86 × 50 mmPrint hub, the printed circuit board in 3D

    Print hub

    offgridevices/offgrid-hardware

    Open hardware from OffGrid Devices. One folder per board. CERN-OHL-S.

    137 partsCERN-OHL-S-2.0
  • 6 layers36 × 36 mmRidge3-fc, the printed circuit board in 3D

    Ridge3-fc

    offgridevices/offgrid-hardware

    Open hardware from OffGrid Devices. One folder per board. CERN-OHL-S.

    124 partsCERN-OHL-S-2.0
  • 2 layers86 × 58 mmPacket logger carrier, the printed circuit board in 3D

    Packet logger carrier

    offgridevices/offgrid-hardware

    Open hardware from OffGrid Devices. One folder per board. CERN-OHL-S.

    22 partsCERN-OHL-S-2.0
  • 2 layers27.2 × 20.3 mmLayercam ring, the printed circuit board in 3D

    Layercam ring

    offgridevices/offgrid-hardware

    Open hardware from OffGrid Devices. One folder per board. CERN-OHL-S.

    11 partsCERN-OHL-S-2.0
  • 2 layers22 × 16 mmLayercam usb, the printed circuit board in 3D

    Layercam usb

    offgridevices/offgrid-hardware

    Open hardware from OffGrid Devices. One folder per board. CERN-OHL-S.

    7 partsCERN-OHL-S-2.0

Similar boards

  • 2 layers40 × 40 mmDrone fc, the printed circuit board in 3D

    Drone fc

    TakaI2/Drone_simulate

    ドローンの挙動と設計をシミュレートする

    52 parts
  • 6 layers133 × 102 mmIasis, the printed circuit board in 3D

    Iasis

    hydazz/iasis

    An optional Raspberry Pi Compute Module 5 carrier for Iasis. It plugs into the main board's HubPD population and carries Ethernet, NVMe storage, an accessory USB-C port and a service USB-C port.

    723 partsApache-2.0
  • 4 layers50.8 × 22.9 mmWeather Feather Wing, the printed circuit board in 3D

    Weather Feather Wing

    benjamincrockett/Weather-Feather-Wing

    A circuit board incorporating temperature, humidity, atmospheric pressure, and CO2 sensors into an Adafruit Feather Wing form factor with Stemma QT connectors.

    35 parts
  • 2 layers18.6 × 27.4 mmScd sensor, the printed circuit board in 3D

    Scd sensor

    rblaze/erust-weather-station

    10 parts
  • 4 layers60.7 × 27.2 mmKyberBoard, the printed circuit board in 3D

    KyberBoard

    lowdrant/kyber

    Extending/Retracting Lightsaber CAD/FW/EDA

    71 parts2AGPL-3.0
  • 2 layers229.6 × 158.2 mmSpace banana, the printed circuit board in 3D

    Space banana

    obra/space-banana

    https://twitter.com/erinbeess/status/1503424797224677376?s=20&t=_vethJano1TXJZ3IsSkWwQ

    129 parts2
  • 2 layers458.2 × 116.3 mmSpacecadet, the printed circuit board in 3D

    Spacecadet

    keyboardio/pcbs

    Some keyboard PCB designs

    287 parts1
  • 2 layers320.7 × 130.2 mmKeyboardocb, the printed circuit board in 3D

    Keyboardocb

    bertalesko/pcb-repo

    180 parts