Skip to the content
4 layers160 × 100 mmRobust io, the printed circuit board in 3D

Rugged industrial I/O board in KiCad — ATmega1284P, CAN, isolated I/O, high-side switches, and motor drivers. Schematic complete, PCB routing in progress.

Size
160 × 100 mm
Copper layers
4
Thickness
1.6 mm
Parts
304
Nets
205
Pads
862
Tracks, vias
1,992, 343
Pours
10
Routed
Yes
KiCad
KiCad 10.0 (file 20260206)
Created
14 Sep 2026
Updated
8 Nov 2026

Overview

Robust io is an open-source printed circuit board by lusher00, from the lusher00/Robust-IO repository on GitHub. It is a 4-layer board of 160 × 100 mm with 304 parts on 205 nets, routed with 1,992 tracks and 343 vias.

It is built around the ATMEGA1284P-AU, DRV8876PWP and B560C, with the 1N4148W, BAT54C and B340 among its other parts. Its parts include 97 resistors, 73 capacitors, 46 diodes, 11 connectors and 9 ICs. It belongs with the robots and motor control boards and the AVR (ATmega, ATtiny) boards of this library.

Main components

9

README

README.md

Robust IO

A rugged industrial I/O board designed in KiCad 10.

Robust IO rev A, assembled board

Status

  • Rev A: fabricated and assembled by JLCPCB (5 bare boards, 2 assembled), ordered 2026-10-05. Board 1 is under bring-up: power rails, MCU, UART console and MCP2515 CAN controller are verified; the MC33978 input interface does not yet answer on SPI (see Bring-up log). Board 2 is partly disassembled from the reverse-polarity incident and needs C44/C45, U5, U1, U14 and one BTS7008 refitted.
  • Rev B: change list collected below, not started.
  • Schematic: complete across four hierarchical sheets. ERC clean.
  • PCB layout: fully routed. DRC reports 0 errors and 4 library-mismatch warnings (J20, U1, U14, U7), which are intentional local footprint edits.

Board

ItemValue
Size160 x 100 mm, four M3 mounting holes
Layers4: F.Cu signal, In1 GND plane, In2 +24V plane, B.Cu signal
Copper2 oz outer, 1 oz inner
Minimum drill0.3 mm
Supply24 V nominal through a blade fuse (F1) and SMDJ24A TVS
AssemblySMD parts on top side only; through-hole connectors and fuse holder hand-fitted

Architecture

SheetContents
powerTwo TPS560430 buck regulators (+5V, +3.3V), input fuse, TVS, bulk capacitors
processorATmega1284P, MCP2515 + MCP2562 (CAN), crystals, ISP header (J1), UART header (J20), reset button
inputsMC33978 22-channel switch detect with fused, filtered inputs and status LEDs
outputs2Four BTS7008-2EPA dual high-side switches (8 outputs), two DRV8876 motor drivers

Connectors

  • J1: 2x3 2.54 mm SMD header, AVR ISP (SPI is also on test points).
  • J20: 1x6 2.54 mm SMD header, 3.3 V TTL UART in FTDI cable pinout. RX and TX have series resistors and a TVS array.
  • J14, J19, J18, J16, J9, J10 (top edge): 3.5 mm pluggable terminal headers for the switch inputs, each with a fused supply pin and ground.
  • J15 (bottom edge): 24 V supply input and ground.
  • J3, J5 (bottom edge): high-side outputs OUT_0 to OUT_7, with +24V and ground.
  • J6 (bottom edge): two motor driver outputs, with +24V and ground.
  • J4 (left edge): CAN bus, +5V and ground. SW1 is next to it.

Test points

41 test points (35 top, 6 bottom) cover the supply rails, SPI, UART, CAN interrupt, driver control and sense lines, and ground. Positions and nets are listed in fab/robust-io-testpoints.csv.

Known limits of rev A

  • Supply polarity is not marked on the board. J15 pins 1 and 2 (the square pad end, nearest F1) are +24V; pins 3 and 4 are GND. There is no reverse-polarity protection, so a reversed supply forward-biases D6 and the substrate diodes of every part on the rail. Both rev A boards were powered reversed during bring-up; see the Bring-up log.

  • MC33978 input LEDs read "input at ground". Each input LED sits between +24V (2.2k) and the IC pin, so it lights when the input is pulled low. That is correct for switch-to-ground sensing, which is all rev A supports; switch-to-battery on an SP channel needs that channel's LED removed, because the 2.2k sources more current than the IC can sink.

  • BTS7008 GND pins have no series resistor. The datasheet calls for 47 ohm in the GND pin (RGND) and limits GND pin current to 50 mA.

  • CS_CAN has no pull-up. With the MCU in reset (during ISP) the MCP2515 can drive MISO; programming is unreliable unless the board is power-cycled first. Fit 10k from TP8 to TP1 if it keeps failing.

  • UART activity LEDs load the lines. C69/C70 (10 nF) with the 1k series resistors give a 10 us edge, too slow for 115200 baud. The console runs at 38400 on rev A.

  • C57 to C60 use a polarized symbol in the schematic; the fitted parts are 50 V MLCCs and have no polarity.

  • The BTS7008-2EPA is rated for a 28 V maximum supply. Use a regulated 24 V supply; do not connect directly to a charging battery system.

  • Reverse polarity protection is the fuse and TVS only. There is no series reverse-blocking stage.

  • The input polyfuses are rated 30 V, which is a small margin over 24 V.

  • Y1 load capacitors (22 pF) have not been matched to the crystal's specified load capacitance.

  • Regulator output tracks are 0.2 mm wide.

Bring-up log (rev A)

  • Both boards were first powered with the supply reversed. The symptom was a rail that read like a diode (0.5 V both ways, about 2 Ohm at 1 A), with whichever part had the lowest forward drop getting warm: D6, then U5, then the BTS7008 switches and DRV8876 drivers as parts were removed. With the supply in current limit at about 1 V nothing was damaged except C44 and C45 on board 2, which vented after conducting in reverse for a long time. D6 was correctly placed on both boards; the earlier CPL change for it has been reverted.
  • Board 1 after correct power: 5 V and 3.3 V present, fuses written (JTAG off), firmware flashed from a Raspberry Pi over J1, console at 38400 8N1 on J20, MCP2515 answers. MC33978 does not answer the SPI check: continuity from the MCU to U7 pins 2, 3, 4, 16, 31 and 32 is good, VBATP and VDDQ are present, all four SPI modes were tried. The MISO pull-up test in firmware 0.3 (MC33978 check frames line in the banner) is the next step: 0xFFFFFFFF means the chip never drives MISO, 0x00000000 means it is selected but not shifting.
  • With JTAG enabled (fresh chip) outputs 2 to 5 switch on by themselves. They go off once the fuses are written.
  • On a Pi 4, avrdude leaves GPIO25 (reset) driven low after it exits. Run pinctrl set 25 ip pu (or raspi-gpio set 25 ip pu) after programming, or unplug J1 pin 5, before expecting the board to run.
  • The Pi's mini UART (/dev/ttyS0) is unreliable for the console even at 38400. Use an FTDI cable on J20 for the console and the Pi only for programming, or switch the Pi to the PL011 (dtoverlay=disable-bt).

Rev B change list

  • Mark + and - on the silkscreen at J15; add a reverse-polarity stage at the input (P-FET or ideal-diode controller) so a reversed supply does nothing.
  • Input indicator LEDs: two-lead bicolour LED (red/green) in series with each input, replacing the 2.2k pull-ups R62 to R83, so the LED shows current in either direction and switch-to-battery works on the SP channels. Check the MC33978 comparator thresholds against the LED drop before committing.
  • 47 ohm in series with each BTS7008 GND pin (U8 to U11).
  • 10k pull-up on CS_CAN.
  • C69/C70 to 220 pF, or drive the UART LEDs from the MCU.
  • C57 to C60: non-polarized capacitor symbol.
  • Test points: Keystone 5015 SMT loops on the rails, SPI, UART, interrupt, fault and analog sense lines; the four corner mounting holes are GND and take a ring lug, which covers the ground clips.
  • Rev A fab outputs move to fab/revA/ and docs/revA/ before any rev B output is generated.

Files

  • robust-io.kicad_pro - project file
  • robust-io.kicad_sch - root sheet
  • power.kicad_sch, processor.kicad_sch, inputs.kicad_sch, outputs2.kicad_sch - schematic sheets
  • robust-io.kicad_pcb - PCB layout
  • robust-io.kicad_sym, sym-lib-table - project symbol library
  • robust-io.kicad_dru - custom design rules
  • DRC.rpt, ERC.rpt - latest check reports

Documentation (docs/)

FileContent
robust-io-schematic.pdfSchematic, all sheets
layout-top.pdf, layout-bottom.pdfCopper and silkscreen per side
assembly-top.pdfAssembly drawing with reference designators
board-top.png, board-bottom.png, board-angle.png3D renders
robust-io-revA-top.jpg, robust-io-revA-top-board-only.jpgPhotos of the assembled rev A board (composite of several exposures, rectified to the board outline)

Regenerate with bash docs/make_docs.sh after saving the schematic and board.

Firmware (firmware/)

ATmega1284P firmware 0.3: UART service console (38400 8N1), CAN protocol with host timeout, output current trip, motor control, EEPROM settings and a self-test. Runs on rev A hardware; the MC33978 driver is unverified until the chip answers (see Bring-up log). Build with make in firmware/ (avr-gcc); make fuses and make flash program the board from a Raspberry Pi wired to J1. See firmware/DESIGN.md for the pin map, console commands, CAN frame layouts and settings.

Host tools (tools/)

Everything for talking to the board over CAN from a Pi, laptop or robot: a DBC file, a Python package with the robustio command-line tool, a terminal dashboard, a browser dashboard, a bring-up and end-of-line test runner that writes a report per board, and a ROS 2 driver node. All of them also run against the firmware simulator, so they can be used before hardware exists. See tools/README.md.

Fabrication outputs (fab/)

FilePurpose
make_gerbers.shPlots Gerbers, drill files and the position file with kicad-cli, then zips the Gerbers
gerbers/, robust-io-gerbers.zipGerber and Excellon drill files
robust-io-BOM-JLC-smd.csvJLCPCB assembly BOM, 50 lines, LCSC part number on every line
robust-io-CPL-JLC.csvJLCPCB placement file
cpl_rotation_offsets.jsonPer-part rotation corrections applied to the placement file
kicad-pos.csvRaw KiCad position export
robust-io-BOM-tht.csvThrough-hole parts to fit by hand (fuse holder, terminal headers)
robust-io-testpoints.csvTest point list with nets and positions
robust-io-fab-all.zipEverything above in one archive

To regenerate the Gerbers after a board change, save the board in KiCad and run:

text
bash fab/make_gerbers.sh

The placement file is not produced by the script. JLCPCB's rotation convention differs from KiCad's for some packages, so the rotation for each part in robust-io-CPL-JLC.csv is the KiCad rotation plus the offset in cpl_rotation_offsets.json. Regenerate it whenever parts move, and check the result in JLCPCB's placement preview before ordering.

Bring-up order

  1. Fit F1 and J15. Apply 24 V from a current-limited supply with nothing else connected.
  2. Check +5V (TP2) and +3.3V (TP1) against ground.
  3. Wire the Raspberry Pi to J1 (firmware/DESIGN.md section 4) and run make fuses, then make flash, in firmware/. Do this before connecting any load to J3 or J5: until the fuses disable JTAG, outputs 2 to 5 can switch on by themselves. Release the reset line afterward (pinctrl set 25 ip pu).
  4. On the J20 console (FTDI cable, 38400 8N1): ver, then selftest.
  5. Connect CAN and run robustio bringup --console /dev/serial0 --serial <n> from tools/, which writes a report for the board.
  6. Connect loads and enable the outputs and motor drivers one channel at a time (robustio bringup --loads once all are connected).

License

See LICENSE. Free for personal, educational, and open-source use. For commercial licensing, contact ryan.lush@gmail.com.

Parts

304
QtyValueFootprintReferences
33.1uFCapacitor_SMD:C_0603_1608MetricC10, C13, C14, C15, C18, C20, C21, C22, C23, C24, C25, C26, C27, C28, C29, C30 +17
32LEDLED_SMD:LED_0603_1608MetricD14, D15, D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26, D27, D28, D29 +16
22100Resistor_SMD:R_0603_1608Metric_Pad0.98x0.95mm_HandSolderR31, R32, R33, R34, R35, R36, R37, R38, R39, R40, R41, R42, R43, R44, R45, R46 +6
222.2kResistor_SMD:R_1206_3216MetricR62, R63, R64, R65, R66, R67, R68, R69, R70, R71, R72, R73, R74, R75, R76, R77 +6
17.1uFCapacitor_SMD:C_0603_1608Metric_Pad1.08x0.95mm_HandSolderC4, C48, C49, C51, C57, C58, C59, C60, C61, C62, C63, C64, C65, C66, C67, C68 +1
174.7kResistor_SMD:R_0603_1608MetricR10, R11, R12, R13, R14, R15, R16, R17, R18, R19, R20, R21, R22, R23, R24, R26 +1
1310kResistor_SMD:R_0603_1608Metric_Pad0.98x0.95mm_HandSolderR1, R7, R28, R29, R53, R84, R85, R86, R87, R88, R89, R90, R91
8B560CDiode_SMD:D_SMCD2, D4, D8, D9, D10, D11, D12, D13
6PolyfuseFuse:Fuse_1206_3216MetricF2, F3, F4, F6, F7, F8
5Screw_Terminal_01x06Connector_Phoenix_MC:PhoenixContact_MC_1,5_6-G-3.5_1x06_P3.50mm_HorizontalJ9, J10, J16, J18, J19
422pFCapacitor_SMD:C_0603_1608MetricC1, C2, C11, C12
4BTS7008Package_SO:TSSOP-14-1EP_4.4x5mm_P0.65mmU8, U9, U10, U11
4GNDTestPoint:TestPoint_Pad_D1.0mmTP38, TP39, TP40, TP41
4MountingHole_PadMountingHole:MountingHole_3.2mm_M3_DIN965_Pad_TopBottomH1, H2, H3, H4
3330Resistor_SMD:R_0603_1608Metric_Pad0.98x0.95mm_HandSolderR8, R93, R97
3Screw_Terminal_01x06Connector_Phoenix_MSTB:PhoenixContact_MSTBA_2,5_6-G-5,08_1x06_P5.08mm_HorizontalJ3, J5, J6
20Resistor_SMD:R_0603_1608Metric_Pad0.98x0.95mm_HandSolderR59, R61
21.5k 1%Resistor_SMD:R_0603_1608Metric_Pad0.98x0.95mm_HandSolderR56, R57
2100kResistor_SMD:R_0603_1608Metric_Pad0.98x0.95mm_HandSolderR92, R95
2100nF 16VCapacitor_SMD:C_0603_1608Metric_Pad1.08x0.95mm_HandSolderC52, C54
2100nF 50VCapacitor_SMD:C_0603_1608Metric_Pad1.08x0.95mm_HandSolderC55, C56
2100uF 50VCapacitor_SMD:CP_Elec_8x10C44, C45
210nFCapacitor_SMD:C_0603_1608MetricC69, C70
21N4148WDiode_SMD:D_SOD-123D44, D46
21kResistor_SMD:R_0603_1608MetricR98, R99
22.2uFCapacitor_SMD:C_0805_2012Metric_Pad1.18x1.45mm_HandSolderC3, C6
222.1kResistor_SMD:R_0603_1608Metric_Pad0.98x0.95mm_HandSolderR4, R6
222nFCapacitor_SMD:C_0603_1608Metric_Pad1.08x0.95mm_HandSolderC50, C53
222uFCapacitor_SMD:C_0603_1608Metric_Pad1.08x0.95mm_HandSolderC5, C8
22N7002Package_TO_SOT_SMD:SOT-23Q3, Q4
2BAT54CPackage_TO_SOT_SMD:SOT-23D1, D3
2DRV8876rml:IC_DRV8876PWPRU1, U14
2NPResistor_SMD:R_0603_1608Metric_Pad0.98x0.95mm_HandSolderR58, R60
2Screw_Terminal_01x04Connector_Phoenix_MSTB:PhoenixContact_MSTBA_2,5_4-G-5,08_1x04_P5.08mm_HorizontalJ4, J15
2TPS5604Package_TO_SOT_SMD:SOT-23-6U4, U5
1+24VTestPoint:TestPoint_Pad_D1.0mmTP3
1+3.3VTestPoint:TestPoint_Pad_D1.0mmTP1
1+5VTestPoint:TestPoint_Pad_D1.0mmTP2
1.1uF 50VCapacitor_SMD:C_0805_2012Metric_Pad1.18x1.45mm_HandSolderC47
110-20AFuse:Fuseholder_Blade_Mini_Keystone_3568F1
110k 1%Resistor_SMD:R_0603_1608Metric_Pad0.98x0.95mm_HandSolderR55
110uF 50VCapacitor_SMD:C_0805_2012MetricC17
110uHCapacitor_SMD:C_0603_1608MetricL3
1120Resistor_SMD:R_0603_1608Metric_Pad0.98x0.95mm_HandSolderR2
112MHzrml:WE-XTAL_CFPX-180Y2
116.2k 1%Resistor_SMD:R_0603_1608Metric_Pad0.98x0.95mm_HandSolderR54
116MHzrml:WE-XTAL_CFPX-180Y1
118uHInductor_SMD:L_Sunlord_SWPA4030SL2
11kResistor_SMD:R_0603_1608Metric_Pad0.98x0.95mm_HandSolderR30
11nCapacitor_SMD:C_0603_1608MetricC19
11nFCapacitor_SMD:C_0603_1608MetricC16
12.2uF 50VCapacitor_SMD:C_0805_2012Metric_Pad1.18x1.45mm_HandSolderC46
14.7kResistor_SMD:R_0603_1608Metric_Pad0.98x0.95mm_HandSolderR27
151kResistor_SMD:R_0603_1608Metric_Pad0.98x0.95mm_HandSolderR3
16.8uHInductor_SMD:L_Sunlord_SWPA4030SL1
1750Resistor_SMD:R_0603_1608MetricR25
188.7kResistor_SMD:R_0603_1608Metric_Pad0.98x0.95mm_HandSolderR5
1AMUX0TestPoint:TestPoint_Pad_D1.0mmTP16
1ATmega1284P-APackage_QFP:TQFP-44_10x10mm_P0.8mmU2
1AVR-ISP-6Connector_PinHeader_2.54mm:PinHeader_2x03_P2.54mm_Vertical_SMDJ1
1B340Diode_SMD:D_SMCD7
1B3U-1000PButton_Switch_SMD:SW_SPST_B3U-1000PSW2
1BZX384C6V8Diode_SMD:D_SOD-323D5
1CHS-01TBButton_Switch_SMD:SW_DIP_SPSTx01_Slide_Copal_CHS-01B_W7.62mm_P1.27mmSW1
1CS_CANTestPoint:TestPoint_Pad_D1.0mmTP8
1CS_IN0TestPoint:TestPoint_Pad_D1.0mmTP7
1DEN0TestPoint:TestPoint_Pad_D1.0mmTP20
1DEN1TestPoint:TestPoint_Pad_D1.0mmTP21
1DEN2TestPoint:TestPoint_Pad_D1.0mmTP22
1DEN3TestPoint:TestPoint_Pad_D1.0mmTP23
1DRV_OUT0TestPoint:TestPoint_Pad_D1.0mmTP30
1DRV_OUT1TestPoint:TestPoint_Pad_D1.0mmTP31
1DRV_OUT2TestPoint:TestPoint_Pad_D1.0mmTP32
1DRV_OUT3TestPoint:TestPoint_Pad_D1.0mmTP33
1DRV_OUT4TestPoint:TestPoint_Pad_D1.0mmTP34
1DRV_OUT5TestPoint:TestPoint_Pad_D1.0mmTP35
1DRV_OUT6TestPoint:TestPoint_Pad_D1.0mmTP36
1DRV_OUT7TestPoint:TestPoint_Pad_D1.0mmTP37
1DSELnTestPoint:TestPoint_Pad_D1.0mmTP19
1EN_M0TestPoint:TestPoint_Pad_D1.0mmTP24

The 280 most common of 304 parts.

More from lusher00/Robust-IO

1
  • 4 layers159.1 × 101.4 mmRobust io.before sw2, the printed circuit board in 3D

    Robust io.before sw2

    lusher00/Robust-IO

    Rugged industrial I/O board in KiCad — ATmega1284P, CAN, isolated I/O, high-side switches, and motor drivers. Schematic complete, PCB routing in progress.

    258 parts

Similar boards

  • 6 layers80.8 × 65.2 mmPROC099A PCB, the printed circuit board in 3D

    PROC099A PCB

    kassemmkk/awr2243

    368 parts
  • 4 layers99 × 139 mmRCU, the printed circuit board in 3D

    RCU

    GhanGhan/SurvBot

    Remote controlled robot that surveys the environment it is travelling in

    148 parts
  • 4 layers100 × 100 mmPhmod, the printed circuit board in 3D

    Phmod

    gallicchio/AMOD-and-RFMOD

    The tutorial's 2x12 adapter (/mudd/133electronics/icepi-zero-dac-adc/adapterboard/) with a 2 x 6 right-angle Pmod socket on a 15 mm extension of its right-hand end, so an Icepi Zero can drive AMOD-A's and RF-MOD's Pmod…

    234 parts
  • 4 layers36 × 36 mmFc f405, the printed circuit board in 3D

    Fc f405

    fkontiebo/flight-controller

    Contrôleur de vol 4 layers basé sur STM32F405RGT6, conçu comme plateforme de navigation autonome avec bus CAN.

    97 partsMIT
  • 4 layers79 × 79 mmMinuet, the printed circuit board in 3D

    Minuet

    brown-studios/minuet

    Minuet upgrades your MAXXAIR Maxxfan with a brushless DC motor, home automation features, and accessories.

    103 parts67MIT
  • 2 layers100 × 44.4 mmMiniFeed, the printed circuit board in 3D

    MiniFeed

    SG-O/MiniFeedPCB

    Main PCB for automated SMT Feeder

    92 parts10CC-BY-4.0
  • 4 layers90.1 × 90.1 mmBoard1, the printed circuit board in 3D

    Board1

    iRobotics-Pacbot-2022-2023/Electrical

    Electrical

    24 parts
  • 4 layers80 × 85 mmPacboard2025 alt, the printed circuit board in 3D

    Pacboard2025 alt

    iRobotics-Pacbot/Electrical

    Electrical Projects

    32 parts

Questions

How big is the Robust io PCB?

It measures 160 × 100 mm and has 4 copper layers, 1.6 mm thick.

What parts does the Robust io use?

304 parts, built around the ATMEGA1284P-AU, DRV8876PWP, B560C and 1N4148W. 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 Robust io KiCad files?

From the lusher00/Robust-IO repository on GitHub, at the commit this page was made from: the board is robust-io.kicad_pcb and its schematic _claude_scratch/inputs.before-erc.kicad_sch. PCBKit opens the board in the browser, with nothing to install.

Can I use the Robust io design in my own project?

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