Hardware Test Infrastructure with TofuPilot
Test infrastructure is everything between the engineer's test script and the data that drives quality decisions. Instruments, fixtures, stations, software frameworks, data pipelines. TofuPilot sits at the center as the data backbone, connecting your test stations to dashboards, analytics, and traceability.
What Hardware Test Infrastructure Looks Like
A production test setup has multiple layers:
┌────────────────────────────────────────────┐
│ TofuPilot (Cloud) │
│ Dashboards · Analytics · Traceability │
├────────────────────────────────────────────┤
│ Test Framework Layer │
│ OpenHTF · pytest · Custom Python │
├────────────────────────────────────────────┤
│ Instrument Layer │
│ DMMs · Oscilloscopes · Power Supplies │
│ DAQs · Spectrum Analyzers · Load Banks │
├────────────────────────────────────────────┤
│ Fixture Layer │
│ Pogo pin fixtures · Cable harnesses │
│ Pneumatic actuators · Thermal chambers │
├────────────────────────────────────────────┤
│ DUT (Device Under Test) │
└────────────────────────────────────────────┘
Each layer has its own concerns. TofuPilot handles the top layer: collecting, storing, and analyzing the data that flows up from the test stack.
Station Architecture
A well-designed test station separates concerns:
| Component | Responsibility | Tools |
|---|---|---|
| Test logic | What to test and in what order | OpenHTF, pytest, custom Python |
| Instrument control | Communicating with test equipment | PyVISA, python-ivi, vendor drivers |
| Fixture control | Engaging/disengaging the DUT | GPIO, serial, pneumatic controllers |
| Data capture | Recording measurements | TofuPilot client |
| Operator interface | Scan serial, display results | OpenHTF UI, custom GUI |
Minimal Station Setup
from tofupilot import TofuPilotClient
import pyvisa
# Instrument layer
rm = pyvisa.ResourceManager()
dmm = rm.open_resource("TCPIP::192.168.1.10::INSTR")
psu = rm.open_resource("TCPIP::192.168.1.11::INSTR")
# Test logic
def run_functional_test(serial_number):
psu.write("OUTP ON")
vcc = float(dmm.query("MEAS:VOLT:DC?"))
current = float(dmm.query("MEAS:CURR:DC?"))
psu.write("OUTP OFF")
passed = 3.25 <= vcc <= 3.35 and 30 <= current <= 60
# Data capture
client = TofuPilotClient()
client.create_run(
procedure_id="BOARD-FUNCTIONAL",
unit_under_test={"serial_number": serial_number},
run_passed=passed,
steps=[{
"name": "Power Rails",
"step_type": "measurement",
"status": 3.25 <= vcc <= 3.35,
"measurements": [
{"name": "vcc_3v3", "value": vcc, "unit": "V", "limit_low": 3.25, "limit_high": 3.35},
{"name": "idle_current_ma", "value": current * 1000, "unit": "mA", "limit_low": 30, "limit_high": 60},
],
}],
)
return passed
# Operator interface
while True:
serial = input("Scan serial (or 'q' to quit): ")
if serial.lower() == "q":
break
result = run_functional_test(serial)
print(f"{'PASS' if result else 'FAIL'}")Scaling from One Station to Many
Identical Stations
When you add stations for the same test, keep the test code identical across all stations. Use the same procedure ID. TofuPilot distinguishes stations automatically.
import socket
# Station identification
STATION_ID = socket.gethostname() # Each station PC has a unique hostname
# Same test code, same procedure, different station
client.create_run(
procedure_id="BOARD-FUNCTIONAL",
unit_under_test={"serial_number": serial},
run_passed=passed,
steps=steps,
)
# TofuPilot tracks which station ran each testDifferent Test Stages
Production flows typically have multiple test stages. Each stage gets its own procedure.
Assembly Line:
Station 1-4: ICT (In-Circuit Test) → procedure: "ICT-V2"
Station 5-6: Functional Test → procedure: "FUNC-TEST-V3"
Station 7: Burn-In → procedure: "BURN-IN-24H"
Station 8-10: Final Test → procedure: "FINAL-TEST-V2"
TofuPilot links all test stages for a given serial number, creating a complete manufacturing test history.
Instrument Management
Common Instrument Types
| Instrument | What it measures | Interface |
|---|---|---|
| DMM (Digital Multimeter) | Voltage, current, resistance | GPIB, LAN, USB |
| Oscilloscope | Waveforms, timing | LAN, USB |
| Power Supply | (Provides power, measures output) | GPIB, LAN, USB |
| DAQ (Data Acquisition) | Multi-channel analog/digital | USB, PCIe |
| Spectrum Analyzer | Frequency content | GPIB, LAN |
| Load Bank | (Simulates load conditions) | Serial, LAN |
| Environmental Chamber | Temperature, humidity | Serial, LAN |
Instrument Connection Patterns
import pyvisa
class InstrumentPool:
"""Manage instrument connections for a test station."""
def __init__(self):
self.rm = pyvisa.ResourceManager()
self._instruments = {}
def get(self, name, address):
if name not in self._instruments:
self._instruments[name] = self.rm.open_resource(address)
return self._instruments[name]
def close_all(self):
for inst in self._instruments.values():
inst.close()
# Usage
pool = InstrumentPool()
dmm = pool.get("dmm", "TCPIP::192.168.1.10::INSTR")
psu = pool.get("psu", "TCPIP::192.168.1.11::INSTR")Infrastructure Monitoring
Your test infrastructure is itself something that needs monitoring. TofuPilot's dashboards reveal infrastructure health:
| Metric | What it indicates |
|---|---|
| FPY per station | Station hardware health |
| Cycle time per station | Instrument/fixture performance |
| Measurement variance per station | Fixture contact quality |
| Uptime per station | Reliability of test PC/software |
When one station's FPY drops while others stay stable, the problem is the station, not the product. Investigate the fixture, instruments, and cabling.
Infrastructure Best Practices
| Practice | Why |
|---|---|
| Version your test code | Know exactly what test ran on each unit |
| Use the same procedure ID across identical stations | Enables cross-station comparison |
| Store instrument calibration dates | Know when calibration might affect results |
| Keep fixtures as simple as possible | Fewer moving parts = fewer failure modes |
| Monitor cycle time | It's a free health indicator |
| Separate test logic from instrument drivers | Swap instruments without rewriting tests |
| Use IP-based instrument connections | More reliable than USB for production |
What TofuPilot Handles vs. What You Handle
| TofuPilot handles | You handle |
|---|---|
| Data storage and indexing | Test code and logic |
| Dashboards and analytics | Instrument drivers |
| Traceability and search | Fixture design and maintenance |
| Yield calculations | Station hardware setup |
| Measurement trending | Network connectivity |
| Cross-station comparison | Operator training |
TofuPilot is the data layer. You bring the test layer. Together they form a complete test infrastructure.