SPICE

授業で回路シミュレータのSPICE(うちはWindowsを使っているのでWinSPICE)を使って電子回路の解析をしているのでそれに便利な使い方などを紹介していきたいと思います。

電流計

SPICEでは電圧源以外の素子に流れる電流は測定できません。
しかし逆を言えば電圧源が電流計をも兼ねているともいえるのです。
測りたい部分に直列に電圧0の電圧源をつなげば立派に電流計となるわけです。
ただし、問題があって、電圧源としての正極と負極が電流計としての陽極と陰極になっているので、電圧源と電流計を兼ねたとき電流の流れる向きに注意しなければならないのです。

write

うちの実験指導書には「printでデータを表示してテキストエディタにコピーする」なんて書いてあったんですけど、何千ものデータが出てくるのにそんなことやってられません。
SPICEの表示域は元々バグってても字が正しく表示されてないし、キー入力を促すプロンプトも混じっててコピーした後いちいち探して削除しなきゃいけないし、第一SPICEに表示できるのは高々数百行程度なので表示された結果をコピーするなんてことは無茶なのです。
SPICEほどの立派なソフトが解析結果の保存程度のことができないはずがないのです!
それがwriteコマンド。
「write 出力ファイル名」で解析結果を丸ごとテキストファイルに保存してくれます。

.control

先にも書いたようにSPICEは、少なくともWinSPICEとMacSPICEでは表示がおかしくなっているのでできるだけSPICE上での操作は避けたいところです。
SPICE上ですることといえば基本的にコマンド入力とデータの閲覧です。
データをグラフに表示する分には問題ないし、テキストで見る場合もwriteでファイルに書き出せばSPICE上で見る必要はないので、問題はコマンド入力となります。
SPICE上でのコマンド入力は大変不便ですので、使い慣れたテキストエディタで全てのコマンドを打ち込みたいものです。
そこで、回路ファイル中で「.control」と書いた行と「.endc」と書いた行を「.end」の前に追加して、「.control」と「.endc」の間の行に実行したいコマンドを全部並べます。
大方runとplotとwriteあたりのコマンドを使うと思います。

同じ入力で複数の回路の応答を得る

例えば回路の一部の素子の値を変化させて応答の変化を見る場合、回路を作る、SPICE実行、データを記録する、素子の値を変える、またSPICE実行、またデータを記録する、などということを繰り返すのはまどろっこしいわけです。
それにこの場合だとそれぞれの値のデータが個別に出てくるためあとで記録したデータをまとめるまで全体としてどうなっているかわからないのです。
だから、一個の回路ファイルに全部の回路をまとめて入れてしまえば全てのデータが一度に得られるでしょうという話です。
流れる電流によって特性変化のない部分(大抵は入力電圧源)を共通にして他の部分をどんどんコピーしていって増殖させるのです。
ここでコピーした結果をそれぞれ別の名前にしないとエラーが出たり正しい結果が得られなくなったりします。
もちろん共通部分の名前は変えませんよ。

回路の例

せっかくなので回路の例を出してみます。

Circuit 1
*トランジスタに流すベース電流を変化させたときの
*エミッタコレクタ間電圧-コレクタ電流特性の変化を見るのだ!!
*Vcが共通
Vc 2 0 0
*Vcnは電流計
*5uA用回路
Vc5 52 2 0
Ib5 0 51 30u
Q5 52 51 0 QNL
*10uA用回路
Vc10 102 2 0
Ib10 0 101 10u
Q10 102 101 0 QNL
*20uA用回路
Vc20 202 2 0
Ib20 0 201 20u
Q20 202 201 0 QNL
*30uA用回路
Vc30 302 2 0
Ib30 0 301 30u
Q30 302 301 0 QNL
*40uA用回路
Vc40 402 2 0
Ib40 0 401 40u
Q40 402 401 0 QNL
.MODEL QNL NPN()
.dc Vc 0 1 0.01
*実行してグラフ表示して記録する
.control
run
plot ABS(I(Vc5)) ABS(I(Vc10)) ABS(I(Vc20)) ABS(I(Vc40))
write result.txt
.endc
.END

得られた結果をCSVに

writeで得られた結果はなるほど確かにデータの抜け漏れ重複はありませんし明らかに無関係なゴミが混じることもないのですが、それでも所詮解析結果を並べただけ。
このままじゃ値の変化の比較もグラフにすることも面倒で難しく、使い物になりません。
できることなら表計算ソフトで使えるような形式にして保存したいわけです。
出力ファイルを見ているとわかるのですが、全てのデータは規則正しく機械的に並んでいるので、それはそのまま機械的にプログラムで表計算ソフトで読み込める形式に変換できるのです。
そこで私はPerlを使ってとりあえずExcelで読み込めるようにデータをCSV形式に変換するプログラムを作ってみました。
自分のところで動けばいいや程度のプログラムなので使い勝手は悪いのですが…。

# 使用例:perl this.pl <result.txt>result.csv
while (<>) {
	s/\r|\n//g;
	if (/^\s*?(.+?):\s*?(.+)\s*?$/) {
		#通常データ
		print "$1,$2,\n";
	}elsif (/^\s*?(.+):\s*?$/) {
		#連続データ開始
		$datatype="$1";
	}else {
		#連続データ
		if ($datatype eq "Variables") {
			#変数
			if (/^\s*?(\S+)\s+?(\S+)\s+?(\S.+\S)\s*?$/) {
				print "$2,";
			}
		}elsif ($datatype eq "Values") {
			#値
			if (/^\s*?(\S+)\s+?(\S+)\s*?$/) {
				$_ = $2;
				s/,(\S+)/+$1</;s/\+\-/-/;s/</i/;s/0\.0*e\+00\+0\.0*e\+00i/0/;s/\+0\.0*e\+00i//;
				print "\n$_,";
			}elsif (/^\s*?(\S+)\s*?$/) {
				$_ = $1;
				s/,(\S+)/+$1</;s/\+\-/-/;s/</i/;s/0\.0*e\+00\+0\.0*e\+00i/0/;s/\+0\.0*e\+00i//;
				print "$_,";
			}
		}
	}
}

これで一応Excelで読み込めるようにはなったのであとはExcel上で根性で頑張ってください。