feat(components): Regulated Power Supply with per-instance current limit
Adds a new picker entry 'Regulated Power Supply' under the analog
category. Conceptually fills the gap between wokwi-battery (fixed
DC) and wokwi-signal-generator (waveform focus): user chooses
voltage + mode (dc / ac) + currentLimit, no need to think about
battery chemistry or signal amplitudes.
Properties:
mode: 'dc' | 'ac' (default 'dc')
voltage: V (default 5)
frequency: Hz (default 50, only for AC)
currentLimit: A (default 1)
Design notes:
- No new Web Component. The tagName piggy-backs on
wokwi-signal-generator so the canvas renders the familiar
bench-instrument chrome — saves shipping a second 100+ LOC
Web Component for an identical 2-pin shape.
- SPICE: ideal V-source + ESR sized so a near-short reads
I ≈ 1.5·limit. ngspice has no native foldback so the limit
is a circuitVerifier rule, not a hard SPICE constraint.
- circuitVerifier: extends sourceComponents regex to include
power-supply AND honors the per-instance currentLimit
property as the threshold. Real bench supplies behave this
way — a 100mA-limited supply trips at 100mA, a 5A supply
tolerates 5A before flagging. The error code is
'source-overload' (not 'short-circuit') so the modal copy
matches what the user just configured.
The board GND / VCC pins of Arduino / ESP32 / etc. already act
as voltage sources via BOARD_PIN_GROUPS canonicalisation (the
NetlistBuilder maps wires to the right rail). So the user's
companion request — 'board pins should already work' — is the
existing behaviour; this commit only adds the standalone bench
supply for boardless circuits or for testing with a different
voltage.
This commit is contained in:
parent
3b527f3dce
commit
305170aeb9
|
|
@ -517,6 +517,66 @@
|
|||
"category": "analog",
|
||||
"description": "Single-channel optocoupler. CTR 80–600% (typ. 100%). Higher drive than 4N25, commonly used for MCU-to-mains isolation."
|
||||
},
|
||||
{
|
||||
"thumbnail": "<svg width=\"64\" height=\"64\" xmlns=\"http://www.w3.org/2000/svg\">\n <rect width=\"64\" height=\"64\" fill=\"#1a2332\" rx=\"4\"/>\n <rect x=\"10\" y=\"14\" width=\"44\" height=\"30\" fill=\"#2a3548\" rx=\"3\" stroke=\"#4a5878\"/>\n <text x=\"32\" y=\"30\" text-anchor=\"middle\" font-size=\"9\" font-family=\"monospace\" fill=\"#4ade80\" font-weight=\"bold\">5.00V</text>\n <text x=\"32\" y=\"40\" text-anchor=\"middle\" font-size=\"7\" font-family=\"monospace\" fill=\"#fbbf24\">1.00A</text>\n <circle cx=\"18\" cy=\"52\" r=\"3\" fill=\"#dc2626\"/>\n <circle cx=\"46\" cy=\"52\" r=\"3\" fill=\"#0f172a\" stroke=\"#64748b\"/>\n <text x=\"32\" y=\"60\" text-anchor=\"middle\" font-size=\"6\" fill=\"#9d9d9d\">PSU</text>\n </svg>",
|
||||
"tags": [
|
||||
"power-supply",
|
||||
"regulated",
|
||||
"source",
|
||||
"psu",
|
||||
"bench",
|
||||
"lab",
|
||||
"dc",
|
||||
"ac",
|
||||
"analog"
|
||||
],
|
||||
"properties": [
|
||||
{
|
||||
"name": "mode",
|
||||
"type": "string",
|
||||
"defaultValue": "dc",
|
||||
"control": "select",
|
||||
"options": [
|
||||
"dc",
|
||||
"ac"
|
||||
],
|
||||
"description": "DC for fixed rails, AC for sine waveform output"
|
||||
},
|
||||
{
|
||||
"name": "voltage",
|
||||
"type": "number",
|
||||
"defaultValue": 5,
|
||||
"control": "text",
|
||||
"description": "Output voltage in V (DC mode) or peak amplitude (AC mode)"
|
||||
},
|
||||
{
|
||||
"name": "frequency",
|
||||
"type": "number",
|
||||
"defaultValue": 50,
|
||||
"control": "text",
|
||||
"description": "Frequency in Hz (AC mode only)"
|
||||
},
|
||||
{
|
||||
"name": "currentLimit",
|
||||
"type": "number",
|
||||
"defaultValue": 1,
|
||||
"control": "text",
|
||||
"description": "Maximum sourced current in A. The verifier warns when exceeded."
|
||||
}
|
||||
],
|
||||
"defaultValues": {
|
||||
"mode": "dc",
|
||||
"voltage": 5,
|
||||
"frequency": 50,
|
||||
"currentLimit": 1
|
||||
},
|
||||
"pinCount": 2,
|
||||
"id": "power-supply",
|
||||
"tagName": "wokwi-signal-generator",
|
||||
"name": "Regulated Power Supply",
|
||||
"category": "analog",
|
||||
"description": "Bench DC/AC power supply with optional current limit. DC mode for fixed rails; AC mode for sine. Verifier enforces the current limit per instance."
|
||||
},
|
||||
{
|
||||
"thumbnail": "<svg width=\"64\" height=\"64\" xmlns=\"http://www.w3.org/2000/svg\">\n <rect width=\"64\" height=\"64\" fill=\"#e0e0e0\" rx=\"4\"/>\n <text x=\"50%\" y=\"50%\" text-anchor=\"middle\" dy=\".3em\" font-size=\"10\" fill=\"#666\">\n SIGNAL-GENERATOR\n </text>\n </svg>",
|
||||
"tags": [
|
||||
|
|
|
|||
|
|
@ -548,6 +548,41 @@ const MAPPERS: Record<string, Mapper> = {
|
|||
};
|
||||
},
|
||||
|
||||
// ── Regulated power supply (DC / AC, current-limit aware) ───────────────
|
||||
// Properties:
|
||||
// mode: 'dc' | 'ac' (default 'dc')
|
||||
// voltage: V (default 5)
|
||||
// frequency: Hz (default 50, only used in AC mode)
|
||||
// currentLimit: A (default 1; enforced by circuitVerifier,
|
||||
// NOT SPICE — ngspice has no native
|
||||
// foldback limiter)
|
||||
// The visual element reuses wokwi-signal-generator (no new Web Component
|
||||
// needed). ESR is derived from the currentLimit so a near-short reads
|
||||
// as I ≈ 1.5·limit, which the verifier then flags as source-overload.
|
||||
'power-supply': (comp, netLookup) => {
|
||||
const pos = netLookup('+') ?? netLookup('SIG') ?? netLookup('VCC');
|
||||
const neg = netLookup('−') ?? netLookup('-') ?? netLookup('GND');
|
||||
if (!pos || !neg) return null;
|
||||
const mode = String(comp.properties.mode ?? 'dc').toLowerCase();
|
||||
const voltage = Number(comp.properties.voltage ?? 5);
|
||||
const currentLimit = Math.max(0.01, Number(comp.properties.currentLimit ?? 1));
|
||||
const esr = Math.max(0.01, voltage / (currentLimit * 1.5));
|
||||
let source: string;
|
||||
if (mode === 'ac') {
|
||||
const freq = Number(comp.properties.frequency ?? 50);
|
||||
source = `SIN(0 ${voltage} ${freq})`;
|
||||
} else {
|
||||
source = `DC ${voltage}`;
|
||||
}
|
||||
return {
|
||||
cards: [
|
||||
`V_${comp.id} ${pos} ${comp.id}_int ${source}`,
|
||||
`R_${comp.id}_esr ${comp.id}_int ${neg} ${esr}`,
|
||||
],
|
||||
modelsUsed: new Set(),
|
||||
};
|
||||
},
|
||||
|
||||
// ── Signal generator (AC / pulse / DC) ───────────────────────────────────
|
||||
// Properties:
|
||||
// waveform: 'sine' | 'square' | 'dc' (default 'sine')
|
||||
|
|
|
|||
|
|
@ -128,22 +128,36 @@ export async function verifyCircuit(
|
|||
const branchCurrents = solve.branchCurrents;
|
||||
|
||||
// ── Rule 1: short circuit / power source overload ──────────────────────
|
||||
// Every voltage source (battery / signal-generator) emits a branch current
|
||||
// `i(v_<id>)`. SPICE convention: V-source's current is measured + → −
|
||||
// INTERNALLY, so external current draw is the absolute value.
|
||||
// Every voltage source (battery / signal-generator / power-supply) emits
|
||||
// a branch current `i(v_<id>)`. SPICE convention: V-source's current is
|
||||
// measured + → − INTERNALLY, so external current draw is the absolute
|
||||
// value.
|
||||
//
|
||||
// power-supply components carry a per-instance `currentLimit` property
|
||||
// that overrides the global short-circuit threshold — that matches what
|
||||
// a real bench supply does: a 100mA-limited supply trips at 100mA, a
|
||||
// 5A-limited supply tolerates up to 5A before flagging fault.
|
||||
const sourceComponents = input.components.filter((c) =>
|
||||
/^(battery|signal-generator)/.test(c.metadataId),
|
||||
/^(battery|signal-generator|power-supply)/.test(c.metadataId),
|
||||
);
|
||||
for (const src of sourceComponents) {
|
||||
const i = Math.abs(branchCurrents[`v_${src.id}`] ?? 0);
|
||||
if (i >= config.shortCircuitAmps) {
|
||||
const perInstanceLimit =
|
||||
src.metadataId === 'power-supply'
|
||||
? Number(src.properties?.currentLimit ?? config.shortCircuitAmps)
|
||||
: config.shortCircuitAmps;
|
||||
const threshold = Number.isFinite(perInstanceLimit) && perInstanceLimit > 0
|
||||
? perInstanceLimit
|
||||
: config.shortCircuitAmps;
|
||||
if (i >= threshold) {
|
||||
const isPsu = src.metadataId === 'power-supply';
|
||||
errors.push({
|
||||
severity: 'error',
|
||||
code: 'short-circuit',
|
||||
code: isPsu ? 'source-overload' : 'short-circuit',
|
||||
componentId: src.id,
|
||||
message: `Possible short circuit — ${src.metadataId} ${src.id} is delivering ${formatAmps(
|
||||
i,
|
||||
)} (threshold ${formatAmps(config.shortCircuitAmps)}). Check for 5 V tied directly to GND.`,
|
||||
message: isPsu
|
||||
? `Power supply ${src.id} is being asked for ${formatAmps(i)} — past its ${formatAmps(threshold)} current limit. A real bench supply would foldback or cut out. Raise the currentLimit or add more series resistance to the load.`
|
||||
: `Possible short circuit — ${src.metadataId} ${src.id} is delivering ${formatAmps(i)} (threshold ${formatAmps(threshold)}). Check for power tied directly to GND.`,
|
||||
metric: i,
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1044,6 +1044,65 @@
|
|||
"analog"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "power-supply",
|
||||
"tagName": "wokwi-signal-generator",
|
||||
"name": "Regulated Power Supply",
|
||||
"category": "analog",
|
||||
"description": "Bench DC/AC power supply with optional current limit. DC mode for fixed rails (5V, 12V, etc.); AC mode for sine sources. Visually shares the signal-generator chassis so no new Web Component is needed. The current limit is enforced by the circuit verifier — if any load pulls more than the configured amperage, Run is blocked with a 'source-overload' warning, mimicking a real bench supply's foldback behavior.",
|
||||
"properties": [
|
||||
{
|
||||
"name": "mode",
|
||||
"type": "string",
|
||||
"defaultValue": "dc",
|
||||
"control": "select",
|
||||
"options": [
|
||||
"dc",
|
||||
"ac"
|
||||
],
|
||||
"description": "DC for fixed rails, AC for sine waveform output"
|
||||
},
|
||||
{
|
||||
"name": "voltage",
|
||||
"type": "number",
|
||||
"defaultValue": 5,
|
||||
"control": "text",
|
||||
"description": "Output voltage in V (DC mode) or peak amplitude (AC mode)"
|
||||
},
|
||||
{
|
||||
"name": "frequency",
|
||||
"type": "number",
|
||||
"defaultValue": 50,
|
||||
"control": "text",
|
||||
"description": "Frequency in Hz (AC mode only)"
|
||||
},
|
||||
{
|
||||
"name": "currentLimit",
|
||||
"type": "number",
|
||||
"defaultValue": 1,
|
||||
"control": "text",
|
||||
"description": "Maximum sourced current in A. The verifier warns when exceeded."
|
||||
}
|
||||
],
|
||||
"defaultValues": {
|
||||
"mode": "dc",
|
||||
"voltage": 5,
|
||||
"frequency": 50,
|
||||
"currentLimit": 1
|
||||
},
|
||||
"pinCount": 2,
|
||||
"tags": [
|
||||
"power-supply",
|
||||
"regulated",
|
||||
"source",
|
||||
"psu",
|
||||
"bench",
|
||||
"lab",
|
||||
"dc",
|
||||
"ac",
|
||||
"analog"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "signal-generator",
|
||||
"tagName": "wokwi-signal-generator",
|
||||
|
|
|
|||
Loading…
Reference in New Issue