Skip to content

Optocoupler CTR, SRAM reset restore, voltage-limited current source, macOS paste#241

Closed
esaruoho wants to merge 2 commits intopfalstad:v3-devfrom
esaruoho:v3-four-more-fixes
Closed

Optocoupler CTR, SRAM reset restore, voltage-limited current source, macOS paste#241
esaruoho wants to merge 2 commits intopfalstad:v3-devfrom
esaruoho:v3-four-more-fixes

Conversation

@esaruoho
Copy link
Copy Markdown

@esaruoho esaruoho commented Mar 2, 2026

Summary

Rebased onto v3-dev (replaces #223 which targeted master).

  • Adds adjustable CTR (current transfer ratio) for OptocouplerElm
  • Adds "Restore Contents on Reset" option for SRAMElm (snapshots initial state)
  • Adds voltage-limited current source (FLAG_VOLTAGE_LIMIT on CurrentElm)
  • Fixes macOS Cmd+V paste in Electron app

Fixes #150, #184, #149, #138.

Changes from master version

  • Extended v3-dev's dumpXml()/undumpXml() in CurrentElm and SRAMElm to serialize new fields
  • SRAMElm integrated with v3-dev's parseContentsString() helper

Test plan

  • Place Optocoupler → edit → verify CTR adjustment works
  • Place SRAM → load data → enable Restore on Reset → reset → verify data restored
  • Place current source → enable voltage limiting → verify current reduces at voltage limit
  • In Electron on macOS → Cmd+V → verify paste works

🤖 Generated with Claude Code

esaruoho and others added 2 commits March 6, 2026 08:21
…urce, macOS paste fix

- Configurable optocoupler CTR (pfalstad#150): Add CTR % parameter to edit dialog,
  scale CCCS transfer expression by CTR multiplier. Default 100%.
- SRAM restore on reset (pfalstad#184): Add "Restore Contents on Reset" checkbox.
  Stores initial map snapshot, restores it on simulation reset.
- Voltage-limited current source (pfalstad#149): Add compliance voltage mode.
  When enabled, current source becomes open circuit beyond max voltage.
- macOS Electron paste fix (pfalstad#138): Replace Menu.setApplicationMenu(false)
  with proper Edit menu so Cmd+C/V/X/A work in text fields.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When loading SRAM contents from a binary file, the filename is now
captured and displayed next to the Load button as "Loaded: filename.bin".
This helps users with multiple SRAMs identify which file was loaded into
each one, addressing feedback from @MatNieuw on issue pfalstad#184.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@esaruoho esaruoho force-pushed the v3-four-more-fixes branch from 5d6f4bb to c4d25b8 Compare March 6, 2026 06:23
@esaruoho
Copy link
Copy Markdown
Author

@pfalstad any takes on this?

@pfalstad
Copy link
Copy Markdown
Owner

I tried to do the limited current source thing once and got constant convergence failures. Looks like your version has the same issue. Try opening all the switches. Also I wouldn't have a separate checkbox for the voltage limiting. I would just use a default of 0 meaning unlimited.

<cir f="1" ts="0.000005" ic="10.20027730826997" cb="50" pb="50" vr="5" mts="5e-11">
  <w x="112 32 208 32" f="2"/>
  <w x="208 32 304 32"/>
  <w x="304 32 400 32"/>
  <s x="208 32 208 112" p="1"/>
  <s x="304 32 304 112"/>
  <r x="208 112 208 176" r="100"/>
  <r x="304 112 304 176" r="400"/>
  <r x="400 112 400 176" r="4000"/>
  <w x="208 176 304 176"/>
  <w x="304 176 400 176"/>
  <w x="304 208 304 176"/>
  <w x="304 208 400 208"/>
  <w x="304 208 208 208"/>
  <s x="304 208 304 288"/>
  <r x="208 288 208 352" r="600"/>
  <r x="304 288 304 352" r="200"/>
  <s x="400 208 400 352"/>
  <w x="112 352 208 352"/>
  <w x="208 352 304 352"/>
  <w x="304 352 400 352"/>
  <i x="112 352 112 32" f="1" cu="0.01" mv="5"/>
  <g x="112 352 112 384"/>
  <w x="400 32 400 112"/>
  <w x="208 208 208 288"/>
  <o en="20" sp="32" f="x3" p="0">
    <p v="0" sc="20"/>
    <p v="3" sc="0.05"/>
  </o>
</cir>

@pfalstad
Copy link
Copy Markdown
Owner

the sram thing is good

@pfalstad
Copy link
Copy Markdown
Owner

The optocoupler thing looks good. I would maybe just rename "CTR (%)" to "CTR Scale" because it doesn't look like the CTR is exactly 100... At least in my test case it wasn't.

@pfalstad
Copy link
Copy Markdown
Owner

the mac thing is good

@MatNieuw
Copy link
Copy Markdown

An optocoupler's CTR depends also on the current. There is usually a peak CTR between 5 and 20 mA diode drive current, and the peak varies per type. In the datasheets it is given as a percentage (like 80%), or absolute value like 0.8 . I think being able to specify a peak CTR at a certain diode current would be nice. As an example, the CTR specs from a CYN80N.
CQY80N

esaruoho added a commit to esaruoho/circuitjs1 that referenced this pull request Apr 15, 2026
Adds a configurable CTR scale factor to the optocoupler element. The
underlying base CCCS expression already models a ~100% CTR baseline
device; the new ctr field multiplies that response so users can model
parts with different transfer ratios.

Per @pfalstad feedback on pfalstad#241: the dialog field is labelled "CTR
Scale" rather than "CTR (%)" because the actual transfer ratio of the
base curve is not exactly 100%, so calling the input a percentage
would be misleading. The value now reads as a dimensionless multiplier
(e.g. 1.0 = baseline, 0.5 = half, 1.5 = 150% of baseline). Existing
circuits keep working because the dump format already stored ctr
directly, not as a percentage.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
esaruoho added a commit to esaruoho/circuitjs1 that referenced this pull request Apr 15, 2026
Adds an optional compliance voltage to CurrentElm. The redesign
addresses both pieces of @pfalstad feedback on PR pfalstad#241:

- No checkbox. Default maxVoltage = 0 means unlimited (ideal current
  source); a positive value enables compliance. The dialog field is
  labelled "Max Voltage (V, 0=unlimited)".
- Convergence with switches open. The original implementation
  hard-stepped between "stamp ideal source" and "stamp open" once
  |vd| crossed maxVoltage. Newton-Raphson then ping-ponged between
  the two stamps with no fixed point, especially with high-impedance
  loads (open switches, large resistors). Replaced with a smooth
  tanh-shaped saturation:

      i(vd) = currentValue * 0.5 * (1 - tanh((|vd| - maxVoltage)/vt))

  with vt = 5% of maxVoltage. The Norton companion model stamps the
  exact analytic Jacobian (di/dvd = -currentValue * 0.5 * sech^2(arg)
  / vt * sign(vd)) plus a small gmin so the matrix never goes
  singular when sech^2 is near zero.

Result: the source rolls off smoothly to zero current as |vd|
approaches maxVoltage rather than slamming between full-on and
full-off, which is what was killing convergence in the test circuit
@pfalstad shared on pfalstad#241.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@esaruoho
Copy link
Copy Markdown
Author

Closing in favor of four narrower PRs, one per change, with your feedback applied to each:

Sorry for bundling four separate things originally. Each new PR is reviewable on its own.

@MatNieuw's CTR-vs-current-curve request from this thread isn't in #336 — the polynomial would need to be reshaped rather than just scaled. Happy to do that as a follow-up if Paul wants it.

@esaruoho esaruoho closed this Apr 15, 2026
esaruoho added a commit to esaruoho/circuitjs1 that referenced this pull request Apr 15, 2026
Adds a configurable CTR scale factor to the optocoupler element. The
underlying base CCCS expression already models a ~100% CTR baseline
device; the new ctr field multiplies that response so users can model
parts with different transfer ratios.

Per @pfalstad feedback on pfalstad#241: the dialog field is labelled "CTR
Scale" rather than "CTR (%)" because the actual transfer ratio of the
base curve is not exactly 100%, so calling the input a percentage
would be misleading. The value now reads as a dimensionless multiplier
(e.g. 1.0 = baseline, 0.5 = half, 1.5 = 150% of baseline). Existing
circuits keep working because the dump format already stored ctr
directly, not as a percentage.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
esaruoho added a commit to esaruoho/circuitjs1 that referenced this pull request Apr 15, 2026
Adds an optional compliance voltage to CurrentElm. The redesign
addresses both pieces of @pfalstad feedback on PR pfalstad#241:

- No checkbox. Default maxVoltage = 0 means unlimited (ideal current
  source); a positive value enables compliance. The dialog field is
  labelled "Max Voltage (V, 0=unlimited)".
- Convergence with switches open. The original implementation
  hard-stepped between "stamp ideal source" and "stamp open" once
  |vd| crossed maxVoltage. Newton-Raphson then ping-ponged between
  the two stamps with no fixed point, especially with high-impedance
  loads (open switches, large resistors). Replaced with a smooth
  tanh-shaped saturation:

      i(vd) = currentValue * 0.5 * (1 - tanh((|vd| - maxVoltage)/vt))

  with vt = 5% of maxVoltage. The Norton companion model stamps the
  exact analytic Jacobian (di/dvd = -currentValue * 0.5 * sech^2(arg)
  / vt * sign(vd)) plus a small gmin so the matrix never goes
  singular when sech^2 is near zero.

Result: the source rolls off smoothly to zero current as |vd|
approaches maxVoltage rather than slamming between full-on and
full-off, which is what was killing convergence in the test circuit
@pfalstad shared on pfalstad#241.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
esaruoho added a commit to esaruoho/circuitjs1 that referenced this pull request Apr 20, 2026
Paul's pfalstad#241 test circuit with multiple open switches was still failing.
Root cause: vt was 5% of maxVoltage (0.25V for a 5V limit), giving a
near-discontinuous Jacobian. g jumps by ~1e7 across a few tens of mV
near the compliance threshold, so Newton pings between the linear and
saturated regimes.

Changes:
- vt = max(0.2 * maxVoltage, 0.1V) spreads the knee so sech^2 varies
  smoothly across ~1V instead of ~0.25V.
- Gmin floor raised from 1e-9 to 1e-6 to keep the Norton resistor well
  below the matrix stiffness scale in open-circuit topologies.
- Removed the explicit converged=false trigger; the solver's own
  convergence criteria are sufficient once the Jacobian is well-shaped.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants