Re: Simulating simple electric circuits
Bjoern Schliessmann wrote: class Source(object): Little bug: The __init__ method of class Source should look like this. def __init__(self, ID, neighbour = None): self.connections = [] self.ID = ID if neighbour: self.connections.append(neighbour) Regards, Björn -- BOFH excuse #102: Power company testing new voltage spike (creation) equipment -- http://mail.python.org/mailman/listinfo/python-list
Re: Simulating simple electric circuits
Bjoern Schliessmann wrote: I suspect that this is a dead end though, because in more complex designs the creation of circuits becomes cumbersome. Also, for the system I want to model, the circuits are OOH very complex and OTOH I don't have access to all circuit diagrams. :( So I think I'll try next to transfer my problem to digital two-level logic. Erm, no. Doesn't work. I'll still stick with the circuit approach ... Regards, Björn -- BOFH excuse #367: Webmasters kidnapped by evil cult. -- http://mail.python.org/mailman/listinfo/python-list
Re: Simulating simple electric circuits
Arnaud Delobelle wrote: I'm interested! I was tempted to have a go at it after your initial post, it sounded like a nice little project :) Here you go, see below (quite long). It works from Python 2.5 and above and should be straightly executable from command line. (It'll work with lower Python versions if you backtranslate the few A if (condition) else B parts.) We have: - class CurrentController which does the main work - classes Source and Ground for convenience when creating circuits - class Relay for the realisation of logic Please have a look at the example at the end. It's taken from my actual project. A relay ZT is brought up if an outside key is pressed. This forces the normally-up latching relay ZTS down. This in turn causes relay FTS to go up (which causes many other complicated stuff). I'm open for questions and/or suggestions. :) The names used and docstrings may sound a bit strange since I hastily translated the source from german (we have some very special terms regarding relay technology). I suspect that this is a dead end though, because in more complex designs the creation of circuits becomes cumbersome. Also, for the system I want to model, the circuits are OOH very complex and OTOH I don't have access to all circuit diagrams. :( So I think I'll try next to transfer my problem to digital two-level logic. I'll go with Dave Baum's suggestion with the event queue and post again here soon with report of my achievements ... Regards, Björn ---snip--- #!/usr/bin/env python class CurrentController(object): def __init__(self): self.currentSources = {} # Contents: {ID1: source1, ID2: source2, ...} self.circuits = {} # Contents: {ID1: [all circuits starting at source 1], ID2: [...], ...} def newID(self): ID = 0 while ID in self.currentSources: ID += 1 return ID def newSource(self, func = None): id = self.newID() s = Source(id, func) self.currentSources[id] = s return s def newGround(self): e = Ground() return e def newRelay(self, name, **argv): r = Relay(name, **argv) return r def changed(self, relay): Relay relay changed. Re-try all circuits containing it. print CurrentController: changed:, relay.name, up if relay.up else down for ID, circuits in self.circuits.items(): for circuit in circuits: if circuit.contains(relay): circuit.test() def showCircuits(self, activeOnly = False): Show all circuits. If activeOnly is True, show only active ones. print | Circuits: for ID, circuits in self.circuits.items(): print | ID: %i % ID for circuit in circuits: if (not activeOnly) or circuit.active: print circuit def start(self): All circuits are defined -- try them out and start monitoring changes. for ID, source in self.currentSources.items(): source.start() for ID, circuits in self.circuits.items(): for circuit in circuits: circuit.test() def toGround(self, telegram): Save telegram as valid circuit and monitor it. Called from the outside if a telegram reaches ground (i. e., circuit closed). try: self.circuits[telegram.ID].append(telegram) except KeyError: self.circuits[telegram.ID] = [telegram] class CurrentTelegram(object): Class for recording and managing a circuit. usedIDs = [] def __init__(self, id): self.relays = [] # Contents: [(group name, relay object, coil function), ...] self.switches = [] # Format: [(group name, relay object, switch function), ...] self.ID = id # ID of the source of this telegram self.circuitID = self.newID() # unique telegram ID # default priority is 1. Should always be 0. # It's used for weighing of multiple currents, see Relay class. self.prio = 1 self.active = False def newID(self): ID = 0 while ID in self.usedIDs: ID += 1 self.usedIDs.append(ID) return ID def __str__(self): relays = [] # for an extra newline at the beginning of the string to return for group, r, f in self.relays: type = repr(f) temp = ||| Group %s, Relay %s %s % (group, r.name, type) relays.append(temp) relays = \n.join(relays) switches = [] for group, r, f in self.switches: type = repr(f) temp = ||| Group %s, Relay %s %s % (group, r.name, type)
Re: Simulating simple electric circuits
Arnaud Delobelle wrote: I'm interested! I was tempted to have a go at it after your initial post, it sounded like a nice little project :) Please stand by a day. I'm momentarily facing problems with currents that never end (going in a circle). And my code doesn't look that beatiful and/or clean to me, as is using this framework. But judge yourself (soonest tomorrow). I'm already looking forward to comments and suggestions. :) Regards, Björn -- BOFH excuse #198: Post-it Note Sludge leaked into the monitor. -- http://mail.python.org/mailman/listinfo/python-list
Re: Simulating simple electric circuits
On May 11, 10:02 pm, Bjoern Schliessmann usenet- [EMAIL PROTECTED] wrote: [...] P.S.: If anyone happens to be interested in details, just ask, I'll post some code. I'm interested! I was tempted to have a go at it after your initial post, it sounded like a nice little project :) -- Arnaud -- http://mail.python.org/mailman/listinfo/python-list
Re: Simulating simple electric circuits
Dave Baum wrote: Sounds reasonable. Depending on the size of your network, I might not worry too much about precomputing and saving information. Thanks. Yes, I'm actually testing it presently without any optimizations and it runs very well. If your circuit has loops in it (where the output of a later relay circles back to an earlier relay's coil), then it is possible for the circuit to oscillate, so you might have to be careful about this. That's no substancial problem, with real relay circuits this happens sometimes too :) (even in the systems I'm modelling) After all, I'm quite pleased now with how well the last approach I mentioned works. I've been able to model a medium complex switching sequence today, and it worked flawlessly. (The only problem I have now arises when I make relays react delayed, using Twisted's reactor.callLater. Sometimes, a relay gets current and loses it shortly after, but the event loop in rare cases executes the status change functions the other way round (no current, then current). I've been trying to fix that by detection if a timer already runs. Anyhow, the inconsistencies only vanish if I let the relays react delayless again. I'm going to have to look into this further ...) Regards, Björn P.S.: If anyone happens to be interested in details, just ask, I'll post some code. -- BOFH excuse #319: Your computer hasn't been returning all the bits it gets from the Internet. -- http://mail.python.org/mailman/listinfo/python-list
Re: Simulating simple electric circuits
In article [EMAIL PROTECTED], Bjoern Schliessmann [EMAIL PROTECTED] wrote: Sounds more familiar than the analog approach. Maybe I misunderstood something ... but I can't transfer my problem to this way of thinking yet. My biggest problem is the fact that relays aren't really interested in voltage, but current. Also, I find it difficult to transfer this circuit logic to boolean logic I can contruct logic gates from. Sometimes, electric circuits are used in different directions. Yep, the traditional digital simulation techniques don't apply very well to things like switches and relays. Going with a different approach is probably cleaner. I set up the mentioned controller which, at the beginning, tries out all possible ways through the network and saves them. So, for every possible circuit it knows which switches must be closed and which relays will work if it's on. In theory, it should now be possible to try out every path, tell the relays if they have voltage/current, and let the relays report back in to the controller if their status changes so it can again test the circuits that may have changed. I haven't tried out the last step, but I will in the next days. Is there any logic error in my strategy? Sounds reasonable. Depending on the size of your network, I might not worry too much about precomputing and saving information. If your circuit has loops in it (where the output of a later relay circles back to an earlier relay's coil), then it is possible for the circuit to oscillate, so you might have to be careful about this. For example, if your basic simulation flow was: 1) set initial conditions (switches, etc) 2) let power flow through the system 3) determine which relays will be thrown 4) if any relays have changed state, go to 2 Then an oscillating circuit would never quit. You might want to put a limit on the number of iterations through the loop, or logic that explicitly checks for oscillation. Or you could analyze the circuit ahead of time to see whether it has oscillation or not. Dave -- http://mail.python.org/mailman/listinfo/python-list
Re: Simulating simple electric circuits
Stef Mientki wrote: Bjoern Schliessmann wrote: - sources (here begin currents) - ground (here end currents) that doesn't bring you anywhere ;-) It does :) Current doesn't start or end at some location, current flows through a closed circuit. The part I omit is the voltage source. All currents I need in my system flow from plus to ground. And let's forget about capacitors, inductors and semi-conductors for this moment ! Yep, because I largely don't have any here, only in few special cases (where I also can use some kind of current priority). Here is a simulation package, although designed for MatLab, it might give you a good idea of what your need. http://www.swarthmore.edu/NatSci/echeeve1/Ref/mna/MNA6.html Wow ... Overkill :) There are few simulation related packages, but not directly suited for electronics http://www.mcs.vuw.ac.nz/cgi-bin/wiki/SimPy I once looked at this, but couldn't find out how to use it with my problem. :\ http://www.linuxjournal.com/article/7542 http://pyastra.sourceforge.net/ http://www.nelsim.com/scriptsim/python_man.html Those are all a bit daunting ... As an little test I wrote a PIC simulator (only core) in Python, it's very rough code (generated in a few evenings), if you're interested I could look it up. Thank you for the offer. I'm presently having problems understanding even the examples, so I'll call in if I get so far. Regards, Björn -- BOFH excuse #380: Operators killed when huge stack of backup tapes fell over. -- http://mail.python.org/mailman/listinfo/python-list
Re: Simulating simple electric circuits
Dave Baum wrote: Are you trying to do logic simulation (digital) or analog circuit simulation? Mh, a mix of both :) I want to simulate (in principle simple) magnetic relay circuits. The only evil tricks that are used are - shortcuts (e. g. a relay coil is bypassed and thus the relay gets no voltage and it relaxes) - low currents (so a relay has current but doesn't switch) I don't want to go into too much more detail about this one because I have a hunch you are really looking at digital, but if you're interested in the analog approach let me know and I'll fill in more of the details. Good hunch :) But thanks for the explanations. The fully analog network approach is definitely overkill here. For digital: Event based simulation is typical here. These simulations generally are concerned with voltage, not current. A circuit consists of signals and devices. At any given time, each signal has a certain state (high/low, on/off, 9 level logic, whatever). Devices are connected to one another by signals. You'll also need events (a signal, a time, and a new state), and an event queue (events sorted by time). This is easier if each signal is driven by at most one device: 1) pop the next event off the queue 2) if the event's signal's state is the same as the new state, go to 1 3) set the event's signal's state to the new state 4) for each device that is attached to the signal, run the device's code, which should look at all of its inputs, and post new events to the queue for any outputs (do this even if the computed output is the same as the current output). These events are usually posted for some time in the future (1 simulation 'tick' is fine). 5) go to 1 This approach is pretty simple to do in Python. I wrote a sample digital simulator a while back and the core of the simulator was around 50 lines of code. Rounded out with some basic logic gates and helper functions to probe the simulation, it was around 150 lines. It was only 2 level logic and signals could only be driven by a single device. The devices that you want to model (switches, loads, etc) don't have explicit inputs and outputs, and you'll need to deal with a signal being driven from multiple sources, so it will get a bit more complicated. You will probably also need 9 level logic (or something equivalent) to deal with the fact that ground beats a source through a load when determining a node's state. The basic idea is that each signal has multiple drivers, each of which has an internal state. When a device wants to set an output, it only changes its driver's state. The signal then has code that looks at the state of all drivers and combines them in some way (this is called a resolution function). That combined state is what devices see when they read the signal. It isn't *that* complicated to implement, but if you can turn your problem into one with 2 level logic and no multiple drivers, then it will be easier to write and debug. Sounds more familiar than the analog approach. Maybe I misunderstood something ... but I can't transfer my problem to this way of thinking yet. My biggest problem is the fact that relays aren't really interested in voltage, but current. Also, I find it difficult to transfer this circuit logic to boolean logic I can contruct logic gates from. Sometimes, electric circuits are used in different directions. This is how far I've come with my first approach yet: I set up the mentioned controller which, at the beginning, tries out all possible ways through the network and saves them. So, for every possible circuit it knows which switches must be closed and which relays will work if it's on. In theory, it should now be possible to try out every path, tell the relays if they have voltage/current, and let the relays report back in to the controller if their status changes so it can again test the circuits that may have changed. I haven't tried out the last step, but I will in the next days. Is there any logic error in my strategy? Regards, Björn -- BOFH excuse #122: because Bill Gates is a Jehovah's witness and so nothing can work on St. Swithin's day. -- http://mail.python.org/mailman/listinfo/python-list
Re: Simulating simple electric circuits
Arnaud Delobelle wrote: When you turn a switch off, it would send a message to the paths that depend on it (maybe via the controller?) so that they would be deactivated. In turn the lightbulbs on these paths would be informed that they are no longer active. When you turn a switch on, it would send a message to the paths that depend on it so that those who do not have another off switch would be activated. In turn the lightbulbs on these paths would be informed that they have a new power source. Wow, as I read your reply again, this is exactly the approach I thought of yesterday. :) As mentioned in an adjacent posting, I'll try it out. Thanks to all for comments. This list is great. :) Regards, Björn -- BOFH excuse #133: It's not plugged in. -- http://mail.python.org/mailman/listinfo/python-list
RE: Simulating simple electric circuits
From: Bjoern Schliessmann Sounds more familiar than the analog approach. Maybe I misunderstood something ... but I can't transfer my problem to this way of thinking yet. My biggest problem is the fact that relays aren't really interested in voltage, but current. Also, I find it difficult to transfer this circuit logic to boolean logic I can contruct logic gates from. Sometimes, electric circuits are used in different directions. You shouldn't have to worry about current degrading. You apply a current to the relay's coil, and it passes through the coil to ground and triggers the relay. The relay's outputs open or close connections from the current source to the connected devices' inputs. The only time you'd have to worry about low currents is if a single relay is connected to a lot of device inputs, because the current is split across the inputs. From a logic standpoint, all you care about is whether each input and output is on or off. --- -Bill Hamilton -- http://mail.python.org/mailman/listinfo/python-list
Re: Simulating simple electric circuits
In article [EMAIL PROTECTED], Bjoern Schliessmann [EMAIL PROTECTED] wrote: Hello all, I'm trying to simulate simple electric logic (asynchronous) circuits. By simple I mean that I only want to know if I have current or no current (it's quite digital) and the only elements need to be (with some level of abstraction to my specific problem) - sources (here begin currents) - ground (here end currents) - joints - switches (which are able to let current pass or not, depending on outside influence) - loads (which can signal change in current flow to the outside -- just like a light bulb) Are you trying to do logic simulation (digital) or analog circuit simulation? The only reason I ask is that the simulation techniques are very different, and you used both logic and current in your description, so I'm not quite sure which direction you are heading. For analog: If you are ignoring time related effects (no inductance or capacitance), then the system is solvable as a set of linear equations. Basically your circuit consists of a set of nodes and edges. Wires are edges, joints are nodes. An open switch is nothing, a closed switch is an edge. A load is an edge. You'll have to assign resistances to the edges (anything non-zero will do) in order for the equations to make sense. Then you can use Kirchoff's laws to analyze the circuit and construct the equations to solve. A good linear algebra library (numpy) will help in solving the equations. Opening or closing a switch would result in a new set of equations, and thus a new solution. You might be able to get clever and model open switches as edges with infinite resistance, which would allow you to skip the Kirchoff stuff each time a switch is flipped. You'd only have to change coefficients and solve the system of equations. However, the system of equations would be singular, so you'd have to do something like an SVD rather than an inverse. I don't want to go into too much more detail about this one because I have a hunch you are really looking at digital, but if you're interested in the analog approach let me know and I'll fill in more of the details. For digital: Event based simulation is typical here. These simulations generally are concerned with voltage, not current. A circuit consists of signals and devices. At any given time, each signal has a certain state (high/low, on/off, 9 level logic, whatever). Devices are connected to one another by signals. You'll also need events (a signal, a time, and a new state), and an event queue (events sorted by time). This is easier if each signal is driven by at most one device: 1) pop the next event off the queue 2) if the event's signal's state is the same as the new state, go to 1 3) set the event's signal's state to the new state 4) for each device that is attached to the signal, run the device's code, which should look at all of its inputs, and post new events to the queue for any outputs (do this even if the computed output is the same as the current output). These events are usually posted for some time in the future (1 simulation 'tick' is fine). 5) go to 1 This approach is pretty simple to do in Python. I wrote a sample digital simulator a while back and the core of the simulator was around 50 lines of code. Rounded out with some basic logic gates and helper functions to probe the simulation, it was around 150 lines. It was only 2 level logic and signals could only be driven by a single device. The devices that you want to model (switches, loads, etc) don't have explicit inputs and outputs, and you'll need to deal with a signal being driven from multiple sources, so it will get a bit more complicated. You will probably also need 9 level logic (or something equivalent) to deal with the fact that ground beats a source through a load when determining a node's state. The basic idea is that each signal has multiple drivers, each of which has an internal state. When a device wants to set an output, it only changes its driver's state. The signal then has code that looks at the state of all drivers and combines them in some way (this is called a resolution function). That combined state is what devices see when they read the signal. It isn't *that* complicated to implement, but if you can turn your problem into one with 2 level logic and no multiple drivers, then it will be easier to write and debug. Dave -- http://mail.python.org/mailman/listinfo/python-list
Re: Simulating simple electric circuits
On May 7, 7:05 pm, Bjoern Schliessmann usenet- [EMAIL PROTECTED] wrote: Hello all, I'm trying to simulate simple electric logic (asynchronous) circuits. By simple I mean that I only want to know if I have current or no current (it's quite digital) and the only elements need to be (with some level of abstraction to my specific problem) - sources (here begin currents) - ground (here end currents) - joints - switches (which are able to let current pass or not, depending on outside influence) - loads (which can signal change in current flow to the outside -- just like a light bulb) Is there any library for this? I couldn't find one. I tried to implement this using objects that are two-way linked; every object has ports. For every port, there is - an input function (that is called by the neighbour if current comes in) - a reference to the neighbour's input function, to be able to let current flow the other way There is a master current controller object which tells the source object to start a current by calling its neighbour. The calls traverse the network until they reach a ground object. Specifically, the source passes a telegram instance with these calls, and everyone it passes through registers himself with it (telegrams are duplicated at joints). Then, the ground object calls back to the controller with all received telegrams. Like this I'm already able to get all possible ways through the network. Then you can get all 'potential' paths that depend on one or more switches being on. Each path could know what switches it depends on and be 'active' if and only if all those switches are on. And each switch would know what paths depend on it. Similarly each lightbulb would know what paths it depends on and be 'on' if at least one path is active; and each path would know which lightbulbs it powers But that's where my ideas go out. Let's assume there is a load in the middle of such a current, e. g. a light bulb. So if the current flows through it it gets notice of this because there is a telegram passing through it. But what if a contact before it now cuts the current, how could I notify all objects behind the cut? I tried several ways the past few days, but all lead to confusing (and non-working) code. (I'm sorry I can't provide any working code yet) Often it boils down to the need to check all possible ways in the entire network with every change. This shouldn't, in perfomance terms, be a big problem for me here, but it feels very dirty, and I smell inconsistencies. When you turn a switch off, it would send a message to the paths that depend on it (maybe via the controller?) so that they would be deactivated. In turn the lightbulbs on these paths would be informed that they are no longer active. When you turn a switch on, it would send a message to the paths that depend on it so that those who do not have another off switch would be activated. In turn the lightbulbs on these paths would be informed that they have a new power source. It seems to me that it would work well with the way you started it out, but I may have misunderstood some aspects or overlooked some problems ;) -- Arnaud -- http://mail.python.org/mailman/listinfo/python-list
Re: Simulating simple electric circuits
Arnaud Delobelle wrote: On May 7, 7:05 pm, Bjoern Schliessmann usenet- There is a master current controller object which tells the source object to start a current by calling its neighbour. The calls traverse the network until they reach a ground object. Specifically, the source passes a telegram instance with these calls, and everyone it passes through registers himself with it (telegrams are duplicated at joints). Then, the ground object calls back to the controller with all received telegrams. Like this I'm already able to get all possible ways through the network. Then you can get all 'potential' paths that depend on one or more switches being on. Each path could know what switches it depends on and be 'active' if and only if all those switches are on. And each switch would know what paths depend on it. Similarly each lightbulb would know what paths it depends on and be 'on' if at least one path is active; and each path would know which lightbulbs it powers In principle, I thought so too, but I didn't like the fact that this involves all possible circuits be determined only once. But it seems like there is no reasonable, different way. When you turn a switch off, it would send a message to the paths that depend on it (maybe via the controller?) so that they would be deactivated. In turn the lightbulbs on these paths would be informed that they are no longer active. When you turn a switch on, it would send a message to the paths that depend on it so that those who do not have another off switch would be activated. In turn the lightbulbs on these paths would be informed that they have a new power source. Yep. Looks like I have to do extended bookkeeping for this. I was looking for a more dynamic, general way. It seems to me that it would work well with the way you started it out, but I may have misunderstood some aspects or overlooked some problems ;) Thanks for your input. The biggest problem I got until now are the crummy interfaces for interconnection which quickly get inconcise. I've had a look at the NetworkX tutorial and it seems like this could simplify the code a bit. Regards, Björn -- BOFH excuse #173: Recursive traversal of loopback mount points -- http://mail.python.org/mailman/listinfo/python-list
Re: Simulating simple electric circuits
Bjoern Schliessmann [EMAIL PROTECTED] wrote in message news:[EMAIL PROTECTED] Hello all, | I'm trying to simulate simple electric logic (asynchronous)circuits. [snip] Some network simulators use connection objects in addition to node objects, with connections joined to nodes but not the same type to each other. But I do not see this as applying here. Another 'trick' is to make all connections one-way, so a two-way connection is a pair of opposite one-way connections. This might make it easier to keep track of what is turning on (or off) what. tjr -- http://mail.python.org/mailman/listinfo/python-list
Re: Simulating simple electric circuits
hi Bjoern, Bjoern Schliessmann wrote: Hello all, I'm trying to simulate simple electric logic (asynchronous) circuits. By simple I mean that I only want to know if I have current or no current (it's quite digital) and the only elements need to be (with some level of abstraction to my specific problem) - sources (here begin currents) - ground (here end currents) that doesn't bring you anywhere ;-) Current doesn't start or end at some location, current flows through a closed circuit. And that's the first law you need: Kirchoff's current law: the total current in every node is ZERO !! The second formula you need: Kirchoff's voltage law, the sum of all voltages following any closed loop is ZERO. That's all you need, it gives you a set of linear equations, enough to let them solve by SciPy / NumPy. And let's forget about capacitors, inductors and semi-conductors for this moment ! Here is a simulation package, although designed for MatLab, it might give you a good idea of what your need. http://www.swarthmore.edu/NatSci/echeeve1/Ref/mna/MNA6.html There are few simulation related packages, but not directly suited for electronics http://www.mcs.vuw.ac.nz/cgi-bin/wiki/SimPy http://www.linuxjournal.com/article/7542 http://pyastra.sourceforge.net/ http://www.nelsim.com/scriptsim/python_man.html As an little test I wrote a PIC simulator (only core) in Python, it's very rough code (generated in a few evenings), if you're interested I could look it up. cheers, Stef Mientki -- http://mail.python.org/mailman/listinfo/python-list