Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature: analog multiplexer #76

Open
conversy opened this issue Mar 6, 2024 · 8 comments
Open

feature: analog multiplexer #76

conversy opened this issue Mar 6, 2024 · 8 comments

Comments

@conversy
Copy link

conversy commented Mar 6, 2024

Hello,

the currently available Multiplexer is digital-only: the output is the "High Logic Voltage" if the selected input pin's value is True.
It would be nice to have an analog option, that would basically transfer the selected input pin's voltage/current to the output.
Maybe something like this in MultiplexerElm.java, though I'm not sure how the internals of CircuitJS work:

class MultiplexerElm extends ChipElm {
	final int FLAG_INVERTED_OUTPUT = 1<<1;
	final int FLAG_STROBE = 1<<2;
	final int FLAG_ANALOG = 1<<3;
...
	int getSelectedValue() {
	    int selectedValue=0;
	    for (int i = 0; i != selectBitCount; i++)
		if (pins[outputCount+i].value)
		    selectedValue |= 1<<i;
		return selectedValue
	}

	void execute() {
	    int selectedValue = getSelectedValue();
	    if (hasFlag(FLAG_ANALOG)) {
		double current = pins[selectedValue].current;
		if (strobe != -1 && pins[strobe].value)
		    current = 0;
		pins[outputPin].current = current;
	    } else {
		boolean val = pins[selectedValue].value;
		if (strobe != -1 && pins[strobe].value)
		    val = false;
		pins[outputPin].value = val;
		if (hasFlag(FLAG_INVERTED_OUTPUT))
		    pins[outputPin+1].value = !val;
	   }
	}

I hope this makes sense!
(And congrats for this excellent software!)

@pfalstad
Copy link
Owner

pfalstad commented Mar 6, 2024

So it would be bidirectional, right?

That wouldn't be hard, although it's not as easy as this. pins[___].current is just for reporting purposes. Modifying it does not change the circuit behavior.

I'd have to get rid of the voltage source for the output (change getVoltageSourceCount()) and instead connect the output directly to the inputs, probably using stampResistor() with a small value for the "on" input and a large value for all the "off" inputs.

@conversy
Copy link
Author

conversy commented Mar 6, 2024

Thank you for answering!

Yes, it would be bidirectional, I guess.
I read somewhere that such chip has an internal resistance of about 60 ohms, for what it's worth.

[edit] added 'bi' before 'directional'

@AgainPsychoX
Copy link

AgainPsychoX commented Mar 25, 2024

Anyway could it be compatible with something like 74HC4052?
Maybe I can use sub-circuit to simulate something like this, using MOSFETS?

@AgainPsychoX
Copy link

AgainPsychoX commented Mar 26, 2024

Indeed I managed to make it with sub-circuits, Or at least I think I do, it seems to working for me, please notify me if something is wrong. 😄 The simulation performance wouldn't be the same as the using pre-programmed approach, but it's neglectable unless you have very large circuits (or slow computer).

Here circuit files (multiple versions due to VCC/logic):

You can File > Open File... and then File > Create Subcircuit... and then move the outputs around and save under some name.

Notes:

  • Voltages of analog inputs/outputs should be in range between from VEE up to VCC.
  • There is SIMPLE (using analog switch, optimized but less "real") and MOSFET versions (using MOSFETs, maybe bit closer to reality). You might want to add 70 Ohm resistor for on the switching channels for tiny bit more of realism.
  • For MOSFET version there is few more labels: VCC that should be linked to specific voltage (3.3V/5V), you can join it before importing and forget about it. The same goes for GND label, it's there purely to allow it look like DIP16 on the schema. You can even removed them, but it would require to remove GND and mark every VCC label as internal node and join it to specific voltage.
  • You can see history edit of this comment of mine, I made mistakes in the circuit (was working only one polarity, then it wasn't working with negative VEE etc). Current version is hopefully working well.

Screenshot of the example circuit (using simple version):
image

BTW I like CircuitJS so far, there are few annoying things, but it's huge help.

@AgainPsychoX
Copy link

AgainPsychoX commented Mar 26, 2024

Actually there seems to be error in the design, it doesn't work with negative VEE, which is should, and on top of that voltages are weird at best. I will investigate, try to fix it and update the design. I am not really good at electronics :/

It seems the MOSFETs inside are driven not by GND/VCC but VEE/GND logic. And one of MOSFETs seems to be upside down I think.

I will update the comment above (incl. the TXT file links).

Updated the original comment. If anything more is wrong, please let me know.

@conversy
Copy link
Author

conversy commented Apr 26, 2024

(sorry for the delay)

@AgainPsychoX thank you so much!

However, I'm not quite sure I understood how to use a subcircuit in circuitjs, even after searching through "directions" on the falstad.com site... How to add one of your circuit into my own and use it?

@AgainPsychoX
Copy link

AgainPsychoX commented Apr 28, 2024

(Sorry for late response, I missed the e-mail).

Here are instructions:

  1. Open the app in new tab https://www.falstad.com/circuit/circuitjs.html
  2. From the menu in right top corner: File > Open File... (or use Ctrl+O keyboard shortcut).
  3. Select the circuit file you downloaded - there are multiple versions, here I will go with 74HC4052_5V_SIMPLE.txt.
  4. The circuit contents should be loaded and displayed. From the menu: File > Create Subcircuit...:
    image
  5. Now you have to model the reusable element that will be representing the subcircuit.
    • Fill the model name so you can later find it. The name will also be displayed on the element if you select the Show label checkbox. I will go here with 74HC4052_5V_S.
    • You can leave pins as is, or you can move them around by pressing and dragging around. In my case, I rearranged the layout the pins to match DIP16 (flipped X&Y) because it was easiest to drop in to a simulation for a project I was working on.
    • Select the Save Across Sessions checkbox, so the subcircuit is available even in other tabs, after refresh and after browser restarts.
    • After you are finish, press "OK".
      image
  6. You can close the tab and/or open blank circuit, or any other target circuit where you want to place it.
  7. To place the subcircuit, use from the menu: Draw > Subcircuits > Add <name you choosen>:
    image
  8. Click anywhere on your circuit (or if doesn't work: press and drag a bit, it's weird sometimes). After placing the instance, you might want to exit from the drawing mode by pressing Esc or Space or using the menu: Draw > Select/Drag Sel.

That's should be it. Extra notes:

  • You can edit the subcircuit by right click menu > Edit... (or double clicking). Care: Load Model Circuit might replace your current circuit to display the contents; also it might be unavailable if you try edit circuit used inside other circuit.
    image
  • The subcircuits are saved in your browser local storage (if you selected the Save Across Sessions checkbox). You can open the website, and open browser developer console (Chrome/FireFox keyboard shortcut is F12), then navigate to Application (Chrome) or Data tab (Firefox). After selecting the website under Storage > Local Storage you can see all the data the website saves in your browser storage, including subcircuits with keys prefixed with subcircuit:, in my case:
    image
  • You can delete those from there using right click > Delete:
    image
    I might have missed some option to delete saved subcircuits from the app UI itself, but using the browser tools works for me.
  • By the way, the app have many useful keyboard shortcuts, for me it was really really useful to learn them, and they are quite intuitive: Usual copying stuff (Ctrl+C/Ctrl+V; also works between browser tabs), Esc/Space to exit to select mode, w draws wire, r resistors, c/C capacitors, g ground, v/V voltage sources, etc. Make note that the shortcuts are case-sensitive (small/big letter mean different things). / is useful to fast find the components without navigating through menus.
  • In my case, I used the multiplexer in a simulation of analog front-end for DIY oscilloscope, based on FSCOPE-500K Rev 4e. Here is my circuit if you are interested: FSCOPE.txt. Some elements (capacitors) are disconnected to avoid loops in the simulation - the app assumes the elements are perfect and wires have no resistance, etc. The simulation, after all, is inaccurate representation of reality; users need to have some understanding.

Let me know if anything is unclear, I will try to help if I can.

@conversy
Copy link
Author

conversy commented Jun 4, 2024

@AgainPsychoX Sorry I saw your answer the other day but could not find the time to implement it... Thank you so much, these are very clear explanations, that might deserve being put somewhere on the circuitjs website, so that others can find them easily...

Thanks to your explanation, I could create the part in a subcircuit and use it in another circuit.

Your design is not exactly what I expected (it seems there are two input, while I only have one in the part I want to simulate), but I can adapt yours easily I think.

Many thanks again!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants