private void SimUpdate(object sender, EventArgs e) { if (CurrentSimulator.SimRunning) { CurrentSimulator.Update(); //Graphing may fail with too few points if (CurrentSimulator.GetNumberOfTicks() >= 5) { if (CurrentGraph != null) { CurrentGraph.PlotAll(); } } NumberOfUpdates++; foreach (var component in circuit.Components) { component.UpdateFromSimulation(NumberOfUpdates, CurrentSimulator, SimulationEvent.TICK); } Quantity netVolt = new Quantity("v", "v", "V"); foreach (var wire in circuit.Wires) { int varId = CurrentSimulator.GetNetVoltageVarId(wire.NetName); if (varId != -1) { netVolt.Val = CurrentSimulator.GetValueOfVar(varId, 0); wire.ToolTip = netVolt.ToFixedString(); } else { wire.ToolTip = ""; } } //Run every second if ((NumberOfUpdates % 20) == 0) { Quantity simulationTime = new Quantity("t", "Simulation Time", "s"); simulationTime.Val = CurrentSimulator.GetCurrentTime(); StatusText.Text = "Interactive Simulation Running | t=" + simulationTime.ToFixedString(); } } else { StatusText.Text = "Ready"; NumberOfUpdates = 0; UpdateTimer.Stop(); } Util.DoEvents(); }
//Called so that a component can update its appearance based on the simulation. Used, for example, by LEDs. //Passes what type of event has happened, and the total number of updates that have occurred if it is a tick event public virtual void UpdateFromSimulation(int numberOfUpdates, Simulator sim, SimulationEvent eventType) { if (eventType == SimulationEvent.STARTED) { ConnectedPinVariables.Clear(); //Generate list of pin variables //Using ConnectedNets as a source of pin numbers foreach (int pin in ConnectedNets.Keys) { ConnectedPinVariables.Add(pin, new List <int>()); } Regex regex = new Regex(@"\{([0-9]+)\}"); foreach (string netlistLine in UnmergedNetlist.Split(new char[] { '\n' })) { string[] parts = netlistLine.Trim().Split(new char[] { ' ' }); if (parts.Length >= 3) { //Ignore fixed voltage nets if (parts[0] != "NET") { for (int i = 2; i < parts.Length; i++) { //Look for connections to pin if (regex.IsMatch(parts[i])) { int thisPinNum = int.Parse(regex.Matches(parts[i])[0].Groups[1].Value); //Determine pin number of the subcircuit component based on position int simPinNum = i - 1; string simCompName = parts[1].Replace("{r}", ID); int varId = sim.GetComponentPinCurrentVarId(simCompName, simPinNum); if (varId != -1) { ConnectedPinVariables[thisPinNum].Add(varId); } } } } } } } else if (eventType == SimulationEvent.TICK) { if ((numberOfUpdates % 2) == 0) { Quantity current = new Quantity("I", "Current", "A"); Quantity voltage = new Quantity("V", "Voltage", "V"); foreach (var pin in ConnectedNets.Keys) { string label = ""; if (PinNames.ContainsKey(pin)) { label = PinNames[pin] + "\r\n"; } else { label = "Pin " + pin + "\r\n"; } int netVarId = sim.GetNetVoltageVarId(ConnectedNets[pin]); if (netVarId != -1) { voltage.Val = sim.GetValueOfVar(netVarId, 0); label += voltage.ToFixedString(); } if (ConnectedPinVariables.ContainsKey(pin)) { if (ConnectedPinVariables[pin].Count > 0) { current.Val = 0; foreach (int pinVar in ConnectedPinVariables[pin]) { current.Val += sim.GetValueOfVar(pinVar, 0); } string dir = ""; if (current.Val < 0) { dir = "out"; } if (current.Val > 0) { dir = "in"; } current.Val = Math.Abs(current.Val); label += "\r\n" + current.ToFixedString() + " " + dir; } } foreach (Path p in Children.OfType <Path>()) { if (p.Name == ("pin" + pin)) { p.ToolTip = label; } } } } } else if (eventType == SimulationEvent.STOPPED) { foreach (int pin in ConnectedNets.Keys) { if (PinNames.ContainsKey(pin)) { foreach (Path p in Children.OfType <Path>()) { if (p.Name == ("pin" + pin)) { p.ToolTip = PinNames[pin]; } } } else { foreach (Path p in Children.OfType <Path>()) { if (p.Name == ("pin" + pin)) { p.ToolTip = "Pin " + pin; } } } } } }