← Ensayos de fusibles automatizados con un Raspberry PLC
Banco de ensayo de fusiblesRaspberry PLC 19RGPIOControl
Ensayos de fusibles automatizados con un Raspberry PLC — ejemplo completo
Ensayos de fusibles normalizados en Python sobre Raspberry PLC: secuencias PD, no fusión y fusión, relés selectores, muestreo cada 500 ms y veredicto.
Programa completo y ejecutable para el Raspberry PLC 19R (fuse-test-sequences.py): incluye cabecera de conexionado, requisitos y notas de integración.
Descarga el pack completo del proyecto — gratisEste ejemplo + los relacionados + lista de materiales
Vista de solo lectura.
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
COMPLETE EXAMPLE — Fuse test sequences (PD, non-fusing, fusing)
Equipment: Raspberry PLC 19R (Industrial Shields)
Based on: fuse test bench project
Wiring:
- Sorensen XG supply over SCPI/serial (/dev/ttyUSB0)
- ADS1015 over I2C: current through 60 mOhm shunt (A0-A1)
- PLC relays R0.3..R0.6: fuse holder base selection
- Inputs I0.0/I0.2/I0.3: safety interlocks
Requirements:
pip3 install pyserial adafruit-circuitpython-ads1x15 python3-librpiplc
Standardized test types:
PD — dissipation measurement: rated current, record Vdrop
NON_FUSING — 1.13·In for 1 h: the fuse must NOT blow
FUSING — 1.45·In: the fuse MUST blow before the time limit
Integration with the catalog:
- Supply: sorensen-scpi-power-supply-control.py
- Measurement: ads1015-differential-adc-autogain.py
- Loop: closed-loop-current-calibration.py
- Safety: safety-interlocks-emergency-stop.py
- Report: txt-test-reports.py
"""
import time
from rpiplc_lib import rpiplc
# Relay that connects each fuse holder base to the power circuit
BASE_RELAY = {"22x58": "R0.3", "14x51": "R0.4", "10x38": "R0.5", "NH00": "R0.6"}
MONITOR_PERIOD_S = 0.5 # monitoring every 500 ms
FUSING_CRITERION = 0.5 # blown if I_measured < 0.5 * I_setpoint
# Automatic mode: setpoints per test type loaded from a reference
# file (embedded here so the example is self-contained)
TEST_TABLE = {
"PD": {"in_factor": 1.00, "duration_s": 180, "must_blow": False},
"NON_FUSING": {"in_factor": 1.13, "duration_s": 3600, "must_blow": False},
"FUSING": {"in_factor": 1.45, "duration_s": 3600, "must_blow": True},
}
def select_base(base):
"""Energize only the relay of the chosen base (the rest stay open)."""
for name, relay in BASE_RELAY.items():
rpiplc.pin_mode(relay, rpiplc.OUTPUT)
state = rpiplc.HIGH if name == base else rpiplc.LOW
rpiplc.digital_write(relay, state)
def run_test(supply, read_current, check_interlocks,
test_type, fuse_in, base):
"""Run a test and return a dict with the result."""
cfg = TEST_TABLE[test_type]
setpoint = fuse_in * cfg["in_factor"]
samples = []
print("Test %s | base %s | In=%.0f A -> setpoint %.1f A"
% (test_type, base, fuse_in, setpoint))
select_base(base)
supply.set_current(setpoint) # after closed-loop calibration
supply.output(True)
t0 = time.time()
verdict = "NOT_BLOWN"
while time.time() - t0 < cfg["duration_s"]:
# 1) safety ALWAYS first
reason = check_interlocks()
if reason is not None:
supply.output(False)
return {"type": test_type, "result": "ABORTED", "reason": reason}
# 2) measurement and fusing criterion
i_measured = read_current()
samples.append(i_measured)
if i_measured < FUSING_CRITERION * setpoint:
verdict = "BLOWN"
break
time.sleep(MONITOR_PERIOD_S)
supply.output(False)
passed = (verdict == "BLOWN") == cfg["must_blow"]
return {"type": test_type, "result": verdict,
"passed": passed, "t_s": round(time.time() - t0, 1),
"i_avg": round(sum(samples) / max(len(samples), 1), 2)}
def main():
rpiplc.init("RPIPLC_19R")
# Stubs to run the example without hardware: on the real bench the
# catalog modules cited in the header are imported instead.
class DemoSupply:
def set_current(self, a): print(" [SCPI] SOUR:CURR %.2f" % a)
def output(self, on): print(" [SCPI] OUTP %s" % ("ON" if on else "OFF"))
demo_setpoint = [28.3]
def read_current_demo():
demo_setpoint[0] *= 0.93 # simulates a fuse gradually blowing
return demo_setpoint[0]
result = run_test(
supply=DemoSupply(),
read_current=read_current_demo,
check_interlocks=lambda: None,
test_type="FUSING", fuse_in=20.0, base="10x38")
print("\nResult:", result)
# The 'result' dict is the input of the TXT report generator
if __name__ == "__main__":
main()
Descarga el pack completo del proyecto — gratisEste ejemplo + los relacionados + lista de materiales