Skip to content

Commit e9b7c75

Browse files
esaruohoclaude
andcommitted
Fix SCR oscillation: use latching trigger/hold logic like TriacElm
The previous combined formula (ig/triggerI + ia/holdingI > 1) re-evaluated the on/off state every timestep without hysteresis. With a series resistor, the anode current would hover near the threshold: the SCR would turn on, current would rise, then the voltage drop across the series resistor would reduce anode current below the threshold, turning it off again -- causing oscillation between two states. Replace with separate trigger and hold conditions: - Gate current exceeding triggerI latches the SCR on (state = true) - Anode current dropping below holdingI turns it off (state = false) This matches the latching behavior of a real SCR and the pattern already used by TriacElm. An SCR with a series resistor should latch on and remain on once triggered, which is what LTspice shows for the same circuit. Also reset state to false in reset() for proper initialization. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 1b0ea53 commit e9b7c75

File tree

1 file changed

+11
-5
lines changed

1 file changed

+11
-5
lines changed

src/com/lushprojects/circuitjs1/client/SCRElm.java

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ void reset() {
7676
volts[anode] = volts[cnode] = volts[gnode] = 0;
7777
diode.reset();
7878
lastvag = lastvac = curcount_a = curcount_c = curcount_g = 0;
79+
state = false;
7980
}
8081
int getDumpType() { return 177; }
8182

@@ -222,12 +223,17 @@ void stamp() {
222223
// iterations. Previously the state switching was inside doStep(), causing
223224
// the anode resistance to flip-flop between on (0.0105) and off (10e5) on
224225
// every sub-iteration when an external series resistance was present,
225-
// preventing convergence (issue #851). This matches the pattern used by
226-
// TriacElm and DiacElm.
226+
// preventing convergence (issue #851).
227+
//
228+
// Use separate trigger/hold conditions with latching, matching the pattern
229+
// used by TriacElm. Once the gate current exceeds triggerI the SCR latches
230+
// on, and stays on until the anode current drops below holdingI. The gate
231+
// only triggers; it does not need to remain driven to keep the SCR on.
227232
void startIteration() {
228-
double icmult = 1/triggerI;
229-
double iamult = 1/holdingI - icmult;
230-
state = (-icmult*ic + ia*iamult > 1);
233+
if (ia < holdingI)
234+
state = false;
235+
if (ig > triggerI)
236+
state = true;
231237
aresistance = state ? .0105 : 10e5;
232238
}
233239

0 commit comments

Comments
 (0)