La simulazione del circuito elettrico contatore l'ho realizzata utilizzando Adobe Flex 2. Questo è un linguaggio basato su xml ed Action Script che, una volta compilato, genera dei filmati flash (swf).

Per prima cosa ho creato i singoli componenti, cioè:
  • interruttore normalmente aperto (library\SwitchNO.mxml)
  • contatto normalmente aperto (library\ContactNO.mxml)
  • contatto in scambio (library\ContactNONC.mxml)
  • relè (library\Rele.mxml)
  • resistenza (library\Resistor.mxml)
e in fine l'applicazione principale (\CircuitoContatore.mxml).

Per generare l'applicativo ho utilizzato Adobe Flex Builder in versione di valutazione per 30 giorni. Con un pò più di fatica si può fare la stessa cosa con notepad ed il Flex SDK 2 scaricabile liberamente.

Ecco i sorgenti per generare la simulazione del circuito elettrico contatore.

File: SwitchNO.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml"
	 width="60" height="50" currentState="0" mouseDown="changeState(event)" 
	 initialize="init()" borderStyle="none">
	<mx:Script>
		<![CDATA[
			public var value:Boolean = false;

			private function init():void
			{
				this.switchLabel.text = this.id;
			}

			private function changeState(e:MouseEvent):void
			{
				value = !value;
				this.currentState = value ? "1" : "0";
			}

		]]>
	</mx:Script>
	<mx:Label x="0" y="32" text="S" id="switchLabel" fontSize="9" fontFamily="Verdana"/>
	<mx:HBox x="2" y="2" width="56" height="46" borderStyle="none" backgroundColor="#ffffa6" backgroundAlpha=".5">
	</mx:HBox>
	<mx:VRule height="10" strokeWidth="1" alpha="1" strokeColor="#000000" y="0" x="29" id="vrule1"/>
	<mx:VRule x="29" y="40" height="10" strokeWidth="1" strokeColor="#000000" alpha="1" id="vrule2"/>
	<mx:VRule x="29" y="40" height="-35" strokeWidth="1" strokeColor="#000000" alpha="1" rotation="-30" id="vrule3"/>
	<mx:VRule height="16" strokeWidth="1" alpha="1" strokeColor="#000000" y="17" x="6" id="vrule4"/>
	<mx:HRule width="6" strokeWidth="1" alpha="1" strokeColor="#000000" y="16" x="6" id="hrule2"/>
	<mx:HRule width="6" strokeWidth="1" alpha="1" strokeColor="#000000" y="32" x="1" id="hrule3"/>
	<mx:HRule width="15" strokeWidth="1" alpha="1" strokeColor="#000000" y="24" x="6" id="hrule1"/>
	<mx:states>
		<mx:State name="1">
			<mx:AddChild position="lastChild">
				<mx:HRule x="20" y="10" width="10" strokeWidth="1" strokeColor="#cc0000" alpha="1"/>
			</mx:AddChild>
			<mx:SetStyle target="{vrule1}" name="strokeColor" value="#cc0000"/>
			<mx:SetStyle target="{vrule2}" name="strokeColor" value="#cc0000"/>
			<mx:SetStyle target="{vrule3}" name="strokeColor" value="#cc0000"/>
			<mx:SetProperty target="{vrule3}" name="rotation" value="-10"/>
			<mx:SetProperty target="{hrule1}" name="x" value="12"/>
			<mx:SetStyle target="{hrule1}" name="strokeColor" value="#cc0000"/>
			<mx:SetProperty target="{vrule4}" name="x" value="12"/>
			<mx:SetProperty target="{hrule2}" name="x" value="12"/>
			<mx:SetProperty target="{hrule3}" name="x" value="7"/>
			<mx:SetStyle target="{vrule4}" name="strokeColor" value="#cc0000"/>
			<mx:SetStyle target="{hrule2}" name="strokeColor" value="#cc0000"/>
			<mx:SetStyle target="{hrule3}" name="strokeColor" value="#cc0000"/>
		</mx:State>
		<mx:State name="0">
		</mx:State>
	</mx:states>
</mx:Canvas>

File: ContactNO.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" 
	 width="60" height="50" currentState="0" initialize="init()">
	<mx:Script>
		<![CDATA[
			//current ststus of contact
			public var value:Boolean = false;
			//set component id to label
			private function init():void
			{
				this.contactLabel.text = this.id;
			}
			//change state of contact
			public function setState(state:Boolean):void
			{
				value = state;
				this.currentState = value ? "1" : "0";
			}

		]]>
	</mx:Script>
	<mx:Label x="0" y="32" text="R" id="contactLabel" fontSize="9" fontFamily="Verdana"/>
	<mx:VRule height="10" strokeWidth="1" alpha="1" strokeColor="#000000" y="0" x="29" id="S1"/>
	<mx:VRule x="29" y="40" height="10" strokeWidth="1" strokeColor="#000000" alpha="1" id="S2"/>
	<mx:VRule x="29" y="40" height="-35" strokeWidth="1" strokeColor="#000000" alpha="1" rotation="-30" id="vrule1"/>
	<mx:states>
		<mx:State name="1">
			<mx:AddChild position="lastChild">
				<mx:HRule x="20" y="10" width="10" strokeWidth="1" strokeColor="#cc0000" alpha="1"/>
			</mx:AddChild>
			<mx:SetProperty target="{vrule1}" name="rotation" value="-10"/>
			<mx:SetStyle target="{vrule1}" name="strokeColor" value="#cc0000"/>
			<mx:SetStyle target="{S1}" name="strokeColor" value="#cc0000"/>
			<mx:SetStyle target="{S2}" name="strokeColor" value="#cc0000"/>
		</mx:State>
		<mx:State name="0">
		</mx:State>
	</mx:states>
</mx:Canvas>

File: ContactNONC.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml"
	 width="60" height="50" currentState="0" initialize="init()">
	<mx:Script>
		<![CDATA[
			public var value:Boolean = false;

			private function init():void
			{
				this.contactLabel.text = this.id;
			}

			public function setState(state:Boolean):void
			{
				value = state;
				this.currentState = value ? "1" : "0";
			}
		]]>
	</mx:Script>
	<mx:Label x="0" y="32" text="R" id="contactLabel" fontSize="9" fontFamily="Verdana"/>
	<mx:VRule height="10" strokeWidth="1" alpha="1" strokeColor="#000000" y="0" x="7" id="S1"/>
	<mx:VRule height="10" strokeWidth="1" alpha="1" strokeColor="#000000" y="0" x="52" id="S0"/>
	<mx:VRule x="29" y="40" height="10" strokeWidth="1" strokeColor="#000000" alpha="1" id="S2"/>
	<mx:HRule x="38" y="10" width="15" strokeWidth="1" strokeColor="#000000" alpha="1"/>
	<mx:HRule x="7" y="10" width="15" strokeWidth="1" strokeColor="#000000" alpha="1"/>
	<mx:VRule x="29" y="40" height="-35" strokeWidth="1" strokeColor="#000000" alpha="1" rotation="20" id="vrule1"/>
	<mx:states>
		<mx:State name="1">
			<mx:SetProperty target="{vrule1}" name="rotation" value="-20"/>
			<mx:SetStyle target="{vrule1}" name="strokeColor" value="#cc0000"/>
		</mx:State>
		<mx:State name="0">
		</mx:State>
	</mx:states>
</mx:Canvas>

File: Rele.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml"
	 width="60" height="50" currentState="0" initialize="init()">
	<mx:Script>
		<![CDATA[
			public var value:Boolean = false;
			
			private function init():void
			{
				this.releLabel.text = this.id;
			}
			public function setState(state:Boolean):void
			{
				this.value = state;
				this.currentState = (this.value == true) ? "1" : "0";
			}
		]]>
	</mx:Script>
	<mx:VRule height="17" strokeWidth="1" alpha="1" strokeColor="#000000" y="0" x="29" id="vrule1"/>
	<mx:VRule x="29" y="32" height="18" strokeWidth="1" strokeColor="#000000" alpha="1" id="vrule2"/>
	<mx:HBox x="15" y="17" width="30" height="15" borderColor="#000000" alpha="1"
		 borderStyle="solid" id="hbox1" backgroundColor="#c0c0c0" backgroundAlpha="1">
	</mx:HBox>
	<mx:Label text="R" textAlign="left" width="40" height="18" id="releLabel" fontFamily="Verdana" x="0" y="32" fontSize="9"/>
	
	<mx:states>
		<mx:State name="1">
			<mx:SetStyle target="{vrule1}" name="strokeColor" value="#cc0000"/>
			<mx:SetStyle target="{vrule2}" name="strokeColor" value="#cc0000"/>
			<mx:SetStyle target="{hbox1}" name="backgroundColor" value="#cc0000"/>
			<mx:SetStyle target="{hbox1}" name="backgroundAlpha" value="1"/>
		</mx:State>
		<mx:State name="0">
		</mx:State>
	</mx:states>
</mx:Canvas>

File: Resistor.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" width="35" height="35">
	<mx:HRule width="5" strokeWidth="1" alpha="1" strokeColor="#000000" y="20" x="0"/>
	<mx:HRule x="30" y="20" width="5" strokeWidth="1" strokeColor="#000000" alpha="1"/>
	<mx:HBox x="5" y="16" width="25" height="10" borderStyle="solid" alpha="1" borderColor="#00000"/>
	<mx:Label text="1k" textAlign="center" width="35" height="15" id="resistorLabel" fontFamily="Verdana" x="0" y="0" fontSize="9"/>
</mx:Canvas>

File: CircuitoContatore.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
	xmlns:ns1="library.*" mouseDown="schemaRefresh(event);"
	width="550" height="480" backgroundGradientColors="[#ffffff, #e8e8e8]">
	<mx:Script>
		<![CDATA[
			private function schemaRefresh(e:MouseEvent):void
			{
				//elabora i pulsanti
				this.R1.setState(S1.value);
				this.R2.setState(S2.value);
				this.R3.setState(S3.value);
				this.R4.setState(S4.value);
				
				//comando RC1
				R1a.setState(R1.value);
				R2a.setState(R2.value);
				R3a.setState(R3.value);
				R4a.setState(R4.value);
				var outRC1:Boolean = R1a.value || R2a.value || R3a.value || R4a.value;
				this.RC1.setState(outRC1);

				//comando RC2
				R1b.setState(R1.value);
				R2b.setState(R2.value);
				R2c.setState(R2.value);
				R3b.setState(R3.value);
				R3c.setState(R3.value);
				R3d.setState(R3.value);
				R4b.setState(R4.value);
				R4c.setState(R4.value);
				R4d.setState(R4.value);
				var outRC2b:Boolean = R1b.value && (R2b.value || R3b.value || R4b.value);
				var outRC2c:Boolean = R2c.value && (R3c.value || R4c.value);
				var outRC2d:Boolean = R3d.value && R4d.value;
				RC2.setState(outRC2b || outRC2c || outRC2d);
				
				//comando RC3
				R1e.setState(R1.value);
				R1f.setState(R1.value);
				R2e.setState(R2.value);
				R2f.setState(R2.value);
				R3e.setState(R3.value);
				R3f.setState(R3.value);
				R4e.setState(R4.value);
				R4f.setState(R4.value);
				var outRC3e:Boolean = R1e.value && R2e.value && (R3e.value || R4e.value);
				var outRC3f:Boolean = (R1f.value || R2f.value) && R3f.value && R4f.value;
				RC3.setState(outRC3e || outRC3f);
				
				//comando RC4
				R1g.setState(R1.value);
				R2g.setState(R2.value);
				R3g.setState(R3.value);
				R4g.setState(R4.value);
				//posso usare direttamente i rele
				//anzichè  i contatt R1g, R2g...
				var outRC4g:Boolean = R1.value && R2.value && R3.value && R4.value;
				RC4.setState(outRC4g);
				
				//partitore resistivo
				R1h.setState(RC1.value);
				R2h.setState(RC2.value);
				R3h.setState(RC3.value);
				R4h.setState(RC4.value);
				
				//visualizza volt in uscita
				var out:Number = 0;
				if(RC4.value == true){
					out = 10;
				}
				else if(RC3.value == true){
					out = 7.5;
				}
				else if(RC2.value == true){
					out = 5;
				}
				else if(RC1.value == true){
					out = 2.5;
				}
				this.voltOut.text = out.toString() + "V";
				this.voltBar.setProgress(out, 10);
			}
			
			private function openSgart(event:MouseEvent):void
            {
                var urlRequest:URLRequest = new URLRequest("http://www.sgart.it")
                navigateToURL(urlRequest, "_blank");    
            }
		]]>
	</mx:Script>
	<mx:HRule x="10" y="10" width="530" strokeWidth="1" strokeColor="#000000" alpha="1"/>
	<mx:HRule x="10" y="108" width="530" strokeWidth="1" strokeColor="#000000" alpha="1"/>
	<mx:HRule x="10" y="117" width="350" strokeWidth="1" strokeColor="#000000" alpha="1"/>
	<mx:HRule x="10" y="264" width="350" strokeWidth="1" strokeColor="#000000" alpha="1"/>
	<mx:HRule x="334" y="59" width="177" strokeWidth="1" strokeColor="#000000" alpha="1"/>
	<mx:HRule x="453" y="221" width="12" strokeWidth="1" strokeColor="#000000" alpha="1"/>
	<mx:HRule x="521" y="152" width="12" strokeWidth="1" strokeColor="#000000" alpha="1"/>
	<mx:HRule x="420" y="270" width="22" strokeWidth="1" strokeColor="#000000" alpha="1"/>
	<mx:HRule x="385" y="319" width="34" strokeWidth="1" strokeColor="#000000" alpha="1"/>
	<mx:HRule x="440" y="405" width="54" strokeWidth="1" strokeColor="#000000" alpha="1"/>
	<mx:VRule height="38" strokeWidth="1" alpha="1" strokeColor="#000000" y="368" x="440"/>
	<mx:VRule height="28" strokeWidth="1" alpha="1" strokeColor="#000000" y="405" x="493"/>
	<mx:VRule height="300" strokeWidth="1" alpha="1" strokeColor="#000000" y="133" x="532"/>
	<mx:VRule height="21" strokeWidth="1" alpha="1" strokeColor="#000000" y="152" x="487"/>
	<mx:VRule height="70" strokeWidth="1" alpha="1" strokeColor="#000000" y="152" x="453"/>
	<mx:VRule height="20" strokeWidth="1" alpha="1" strokeColor="#000000" y="153" x="487"/>
	<mx:VRule height="119" strokeWidth="1" alpha="1" strokeColor="#000000" y="152" x="419"/>
	<mx:VRule height="187" strokeWidth="1" alpha="1" strokeColor="#000000" y="133" x="385"/>
	<mx:VRule height="50" strokeWidth="1" alpha="1" strokeColor="#000000" y="370" x="297"/>

	<ns1:SwitchNO x="10" y="10" id="S1"></ns1:SwitchNO>
	<ns1:Rele x="10" y="59" id="R1"></ns1:Rele>
	<ns1:SwitchNO x="78" y="10" id="S2"></ns1:SwitchNO>
	<ns1:Rele x="78" y="59" id="R2"></ns1:Rele>
	<ns1:SwitchNO x="146" y="10" id="S3"></ns1:SwitchNO>
	<ns1:Rele x="146" y="59" id="R3"></ns1:Rele>
	<ns1:SwitchNO x="214" y="10" id="S4"></ns1:SwitchNO>
	<ns1:Rele x="214" y="59" id="R4"></ns1:Rele>
	<ns1:Rele x="305" y="59" id="RC1"></ns1:Rele>
	<ns1:ContactNO x="305" y="10" id="R1a"></ns1:ContactNO>
	<ns1:ContactNO x="364" y="10" id="R2a"></ns1:ContactNO>
	<ns1:ContactNO x="423" y="10" id="R3a"></ns1:ContactNO>
	<ns1:ContactNO x="481" y="10" id="R4a"></ns1:ContactNO>
	<ns1:ContactNO x="9" y="117" id="R1b"></ns1:ContactNO>
	<ns1:ContactNO x="9" y="166" id="R2b"></ns1:ContactNO>
	<ns1:ContactNO x="69" y="166" id="R3b"></ns1:ContactNO>
	<ns1:ContactNO x="128" y="166" id="R4b"></ns1:ContactNO>
	<ns1:ContactNO x="187" y="117" id="R2c"></ns1:ContactNO>
	<ns1:ContactNO x="187" y="166" id="R3c"></ns1:ContactNO>
	<ns1:Rele x="9" y="215" id="RC2"></ns1:Rele>
	<ns1:ContactNO x="245" y="166" id="R4c"></ns1:ContactNO>
	<ns1:ContactNO x="305" y="117" id="R3d"></ns1:ContactNO>
	<ns1:ContactNO x="305" y="166" id="R4d"></ns1:ContactNO>
	<mx:HRule x="38" y="166" width="120" strokeWidth="1" strokeColor="#000000" alpha="1" />
	<mx:HRule x="38" y="215" width="297" strokeWidth="1" strokeColor="#000000" alpha="1" />
	<mx:HRule x="216" y="166" width="59" strokeWidth="1" strokeColor="#000000" alpha="1" />
	<mx:HRule x="10" y="273" width="350" strokeWidth="1" strokeColor="#000000" alpha="1"/>
	<mx:HRule x="10" y="468" width="350" strokeWidth="1" strokeColor="#000000" alpha="1"/>
	<mx:HRule x="274" y="419" width="24" strokeWidth="1" strokeColor="#000000" alpha="1"/>
	<mx:HRule x="296.5" y="370" width="39" strokeWidth="1" strokeColor="#000000" alpha="1"/>
	<mx:HRule x="39" y="419" width="119" strokeWidth="1" strokeColor="#000000" alpha="1"/>
	<mx:HRule x="157" y="322" width="59" strokeWidth="1" strokeColor="#000000" alpha="1"/>
	<mx:HRule x="39" y="370" width="60" strokeWidth="1" strokeColor="#000000" alpha="1"/>
	<ns1:ContactNO x="10" y="273" id="R1e"></ns1:ContactNO>
	<ns1:ContactNO x="10" y="321" id="R2e"></ns1:ContactNO>
	<ns1:ContactNO x="10" y="370" id="R3e"></ns1:ContactNO>
	<ns1:Rele x="10" y="419" id="RC3"></ns1:Rele>
	<ns1:ContactNO x="69" y="370" id="R4e"></ns1:ContactNO>
	<ns1:ContactNO x="128" y="370" id="R4f"></ns1:ContactNO>
	<ns1:ContactNO x="128" y="321" id="R3f"></ns1:ContactNO>
	<ns1:ContactNO x="128" y="273" id="R1f"></ns1:ContactNO>
	<ns1:ContactNO x="186" y="273" id="R2f"></ns1:ContactNO>
	<ns1:ContactNO x="245" y="273" id="R1g"></ns1:ContactNO>
	<ns1:ContactNO x="245" y="321" id="R2g"></ns1:ContactNO>
	<ns1:Rele x="305" y="419" id="RC4"></ns1:Rele>
	<ns1:ContactNO x="245" y="370" id="R3g"></ns1:ContactNO>
	<ns1:ContactNO x="305" y="370" id="R4g"></ns1:ContactNO>
	<ns1:ContactNONC x="457" y="221" id="R2h"></ns1:ContactNONC>
	<ns1:ContactNONC x="434" y="270" id="R3h"></ns1:ContactNONC>
	<ns1:ContactNONC x="411" y="319" id="R4h"></ns1:ContactNONC>
	<ns1:ContactNONC x="480" y="172" id="R1h"></ns1:ContactNONC>
	<ns1:Resistor x="487" y="132"></ns1:Resistor>
	<ns1:Resistor x="453" y="132"></ns1:Resistor>
	<ns1:Resistor x="419" y="132"></ns1:Resistor>
	<ns1:Resistor x="385" y="132"></ns1:Resistor>
	<mx:Label x="525" y="119" text="0V" fontSize="8" fontFamily="Verdana" color="#000000" alpha="1"/>
	<mx:Label x="480" y="119" text="2.5V" fontSize="8" fontFamily="Verdana" color="#808080" alpha="1"/>
	<mx:Label x="442" y="119" text="5V" fontSize="8" fontFamily="Verdana" color="#808080" alpha="1"/>
	<mx:Label x="412" y="119" text="7.5V" fontSize="8" fontFamily="Verdana" color="#808080" alpha="1"/>
	<mx:Label x="378" y="119" text="10V" fontSize="8" fontFamily="Verdana" alpha="1" color="#000000"/>
	<mx:Label y="441" text="ingresso" fontFamily="Verdana" fontSize="10" textAlign="center" horizontalCenter="239" width="60"/>
	<mx:Label y="452" text="inverter" fontFamily="Verdana" fontSize="10" textAlign="center" horizontalCenter="239" width="60"/>
	<mx:Label x="493" y="419" text="0V" width="40" textAlign="center" fontFamily="Verdana" fontSize="10" id="voltOut"/>
	<mx:ProgressBar y="381" labelPlacement="center" minimum="0" maximum="100" id="voltBar" 
		width="85" label="uscita: %3 %%" alpha="1" height="15" indeterminate="false" enabled="true"
		borderColor="#800000" themeColor="#ff8000" mode="manual" textAlign="center" horizontalCenter="211"/>
	<mx:LinkButton x="385" y="448" label="Sgart.it" fontFamily="Verdana" fontSize="10"
		color="#808080" click="openSgart(event)" textAlign="center"/>
</mx:Application>

Il tutto può essere compilato con il solo Flex SDK tramite il comando:
mxmlc.exe CircuitoContatore.mxml