AWK(GAWK)

2022年11月 9日 (水)

BSch3V CE3ファイルからコメント文字をピックアップ

常用している回路図CADが、
   水魚堂さんの回路図エディタ BSch3V
仕事、趣味、トランジスタ技術の原稿も、みんなこれ。
  ※指定のある場合を除いて

過日、トラ技編集部から
  「原稿の回路図から文字だけを抜き出したい」
という要望があり、gawkで試してみました。

# BSch3V CE3ファイルからコメント文字をピックアップ
# CE3ファイルはUTF-8N
# gawkとUTF-8Nの相性がもうひとつなので,いったんCE3ファイルをSJISに変換して保存
# +COMMENT,L:0,X:560,Y:100,D:1,DIR:0,W:-1,S:Pch%20MOSFET,FN:Tahoma,TAG:0,FS:12,FF:,-COMMENT
# +COMMENT,L:0,X:780,Y:430,D:1,DIR:0,W:-1,S:マイナス%0D%0A出力,FN:Tahoma,TAG:0,FS:13,FF:,-COMMENT
# 1 2 3 4 5 6 7 |---- 8 ------
# 「Pch MOSFET」「マイナス」「出力」をピックアップ
BEGIN{
FS = "," # 区切りをコンマに
}

#loop
{
if(($0 ~/^+COMMENT/) && ($0 ~/-COMMENT$/)){ # コメント行
if($8 ~/^S:/){ # S:先頭
gsub(/^S:/, "", $8) # S:消す
gsub("%20", " ", $8) # %20はスペース
gsub("%0D", "\r", $8) # 復帰
gsub("%0A", "\n", $8) # 改行
gsub("%2C", ",", $8) # ',' コンマ
print $8 # 出力
}
}
}

CE3ファイルの中から「+COMMENT」~「-COMMENT」の1行を
ピックアップして、コメント文字の本体部を拾い出します。

コメント中の改行はそのまま変換しましたが、編集用には
削除して1行にしてしまうほうが良いかもしれません。

UTF-8N → SJISの変換はテキストエディタの機能を使いました。
  探せばなにか良いツールがあるんでしょうけれど。
GAWKそのものでもなにか対処方法があるのかもしれません。

| | コメント (0)

2022年8月31日 (水)

「トラ技」の記事検索

トランジスタ技術に載っていた記事を探すなら
  ・「トランジスタ技術」目次データベース
解凍して出てくる「TR.txt」(1.7Mバイトほど)がベタの
テキストファイルで、CSV形式になっています。

記事の検索ツールも付いているのですがちょっと不便なことも。
  ・著者名の姓と名がくっついていたり(昔の記事)、
   スペースで分離していたり。
  ・「-」の使い方。
   ADCとかA-Dコンバータとかの言い回しの違い。
  ・「・」で区切った言葉。
  ・英大文字と小文字の区分。
grepで全文検索するとき、小文字大文字の区別は無しでてなことに
しても、ちょっとした違いで見逃しが発生します。

そこで、こんな「gawk」を使ったツールを使っています。

・コマンドプロンプトで。
・バッチファイルから起動。
・gawk.exeをパスが通っているところに置いて。
・tr.txtのあるフォルダで。
・tr 下間憲行
 としたら、私の書いた記事が、がさ~っと出てきます。

◎tr.bat
~~~~~~~~~~~~~~~~~~~
echo off
rem "TR.TXT 文字列検索"
rem "入力文字の確認"
if "%1"=="" GOTO HELP

rem GAWKを起動
gawk -f tr.awk tr.txt %1 %2 %3
goto END

rem ヘルプ表示
:HELP
echo 「TR 検索文字列」と入力してください.
:END
~~~~~~~~~~~~~~~~~~~

◎tr.awk
~~~~~~~~~~~~~~~~~~~
# tr.txt 文字検索
BEGIN{
msg = ARGV[2] # 1つめに"tr.txt"が入って
ARGV[2] = "" # 2つめが検索文字列
msg = tolower(msg) # 小文字で比較
printf("# 検索文字 : %s\n", msg)
print
}
# 検索実行
{
tr = $0 # tr.txtの1行
gsub(/[  ・\-\/]/, "", tr) # 半角全角スペースと・-/を除く
tr = tolower(tr) # 小文字で比較
if(match(tr , msg)) print $0 # 一致で1行出力
}
~~~~~~~~~~~~~~~~~~~

※追記

長音記号「ー」も無視できるようにするほうが良いかと。

(1) バッチファイル起動で入力する文字の
  「・ーー-/」を消してしまう。

BEGIN{ のところ
ARGV[2] = "" # 2つめが検索文字列
gsub(/[・ー\-\-\/]/, "", msg) # 記号を除く
msg = tolower(msg) # 小文字で比較


(2) 読み出し処理での無視文字に「ーー」を追加

tr = $0 # tr.txtの1行
gsub(/[  ・ー\-\-\/]/, "", tr) # スペースと記号を除く
tr = tolower(tr) # 小文字で比較

~~~~~~~~~~~~~~~~~~~~~~~~~~~

著者名「氏名の分離」を無くすのと「・/-」の無視だけで、
だいぶと使いやすくなります。

  ※tr.txtに「全角英数」文字は出てこないみたいです。


| | コメント (0)

2021年8月11日 (水)

サーミスタ温度計、何ビットのA/Dコンバータがいるか?

サーミスタで温度測定するとき、
 ・A/Dコンバータの分解能の違いで、何度の桁まで測れるか?
あるいは、
 ・何度の桁まで計りたい時は何ビットのA/Dが必要か?

この答えのグラフがトランジスタ技術2012年1月号p89
図3に出ていました。
 ●特集:エレクトロニクス格言集
  3-6 抵抗分圧比をA-D変換する時の
  基準電源ICは無駄遣い  著者:星聡

Ad01
8ビット分解能でも1℃ステップで測れないことはない
というキャプション。

先日作った温度計で使った「103JT」サーミスタの
温度特性から、これと同じような表を作ってみました。

セミテック103JTの温度:抵抗値表

#SEMITEC 103JT 温度・抵抗特性
#温度 抵抗値
#℃ Ω
-20 71020.0
-10 43670.0
0 27700.0
10 18070.0
20 12110.0
25 10000.0
30 8301.0
40 5811.0
50 4147.0
60 3011.0
70 2224.0
80 1668.0
85 1451.0
90 1267.0
100 975.3
110 759.7
120 598.1


それを「gawk」に食わせて1℃ごとのテーブルを作成

#####   サーミスタ抵抗値計算プログラム    #####
# 下間憲行  jh3dbo@jarl.com
# 10℃ごとの温度,抵抗値テーブルから
# 1℃ごとの抵抗値データを作成
# メモ awkのlogは自然対数

BEGIN{
# 定数指定
K_273 = 273.15 # ケルビン温度
Rref = 10.0e3 # 直列抵抗 10kΩ
Aref = 65536 # 16bit A/D max
# タイトル表示
print("* サーミスタ抵抗値計算 (2015-06-10)\n") > "/dev/stderr"
nbr = 1 # 読み込みデータ数
}
# 「BEGIN」おわり (以下、ファイル読み出し処理)

##### 温度,抵抗値テーブルを読み出す #####
# 10℃ごとの温度と抵抗値を順に読む
{
if( $0 ~/^#/ ) next # 先頭文字が「#」ならコメント
# 数値入力
temp[nbr] = $1 # 温度
ohm[nbr] = $2 # 抵抗値
# printf("%d %s %s\n", nbr , temp[nbr], ohm[nbr])
nbr++ # 配列 +1
}
# ファイル処理おわり (以下、END処理)

##### 10℃ごとのB定数計算して1℃ごとの処理 #####
# ※基準は25℃なので、20~25~30℃となっているので注意
END{
# B定数計算 10℃ごと
print("# B定数")
for(i = 1; i < (nbr - 1); i++){
t1 = temp[i]
t2 = temp[i+1]
r1 = ohm[i]
r2 = ohm[i+1]
B[i] = (log(r1 / r2)) / ((1 / (t1+K_273)) - (1 / (t2+K_273)))
printf("# %d℃~%d℃ %3.1fΩ~%3.1fΩ B=%3.1f\n",
t1, t2, r1, r2, B[i])
}
# 1℃ごとの抵抗値を計算
print("# ℃ Ω")
m = 1 # 1℃ごと (0.1℃ステップなら10に)
for(i = 1; i < (nbr - 1); i++){ # 10℃のテーブル
n = (temp[i+1] - temp[i]) * m # 表の温度差
for(j = 0; j < n; j++){ # 1℃ピッチで
R = tohm(temp[i] + (j / m), temp[i], ohm[i], B[i])
ad = Aref * (R / (Rref + R)) # A/D値
printf("%6.1f %12.2f %6d", # 温度と抵抗値
temp[i] + (j / m), R, ad)
if(f){
printf(" %8.2f %8.2f", # 抵抗値とA/D値の差分
r0 - R, ad0 - ad)
}
printf("\n")
r0 = R;
ad0 = ad;
f = 1;
}
}
}

##### 温度による抵抗値計算 #####
# T1 = 計算する温度
# Tm = 基準温度
# Rm = 基準温度での抵抗値,
# Bconst:B定数, 273:ケルビン温度
# 1 1
# R = Rm * exp( Bconst * (--------- - -----------) )
# t1 + 273 Tm + 273
function tohm(T1, Tm, Rm, Bconst){
return(Rm * exp(Bconst*((1.0 / (T1 + K_273)) - (1.0 / (Tm + K_273)))))
}


その結果を「gnuplot」で処理

set term wxt 0
set ytics nomirror
set y2tics
set xrange [-20:110]
set yrange [0.001:10]
set y2range [0:800]
set title "A/D値が1LSB変化したときの温度変化 【サーミスタ103JT Rs=10kΩ】"
set xlabel "温度 (℃)"
set ylabel "1LSB変化したときの温度変化(℃)"
set y2label "16 bit A/Dでの1℃あたりの変換値変化"
set grid
set xtics 10
#set ytics 500
set key right top
set pointsize 0.5
set logscale y
set label "" at second -8, 770
set label "16bit A/D値変化(右目盛)" at second 2, 660
set label "8bit A/D" at second 11, 560
set label "10bit A/D" at second 12, 440
set label "12bit A/D" at second 13, 320
set label "14bit A/D" at second 14, 200
set label "16bit A/D" at second 15, 80
plot "ohm3.txt" using 1:5 with line lw 2 ti "" axes x1y2,\
"ohm3.txt" using 1:(1 / ($5/256)) with line lw 2 ti "",\
"ohm3.txt" using 1:(1 / ($5/64)) with line lw 2 ti "",\
"ohm3.txt" using 1:(1 / ($5/16)) with line lw 2 ti "",\
"ohm3.txt" using 1:(1 / ($5/4)) with line lw 2 ti "",\
"ohm3.txt" using 1:(1 / $5) with line lw 2 ti ""


こんなグラフが得られます。
Cap005_20210811095101
8,10,12,14,16ビットのA/Dコンバータを使った
時の分解能の変化を示しています。
   ※A/D変換器や周辺回路の精度が加味されますんで、
    1bitの変動でもきびしい状態が浮かんでくるかと。

10℃~25℃あたりが良くて、1℃あたりのA/D変換値変化量
が減る高温域(70℃を越える)になると分解能が悪化するのが
見えます。
  ※8bitA/Dで「水温・湯温」を計ろうとしたとき、
   0℃~40℃くらいまでは0.5℃ピッチで読めます。
   しかし、80℃を越えると1℃ピッチでの読みが
   しんどくなります。
   昔々・・・4bitマイコンで電気温水器の仕事をした
   ときは(東芝の8bit A/D内蔵品)、出てきた
   8bit値(256バイト)をそのまま1℃単位の温度に変換する
   テーブルを作って処理しました。
     水温が正しくない上下の値はエラー処理
     (氷温以下と沸騰温度以上)

分解能16bitのA/Dを使っても、A/Dの誤差を考えると「0.01℃」の
測定はなかなかむつかしいということで。


| | コメント (0)

2020年10月21日 (水)

gawk 文字列から1文字を取り出して8bit数値として扱いたい

「XOR」によるサムチェック・コードの生成、この処理
の確認用テストプログラムの作成に手こずりました。

通信電文の処理ですんで、CR、LFで区切られたテキスト。
GAWKを使ってチェックしたろっと、
  ちょちょいと・・・のはずが・・・

手順としてはこんなの
  (実際はもうチョイ別の処理も
   入りますが、核の部分だけ)

・入力した1行文字列の文字数を数える。
・先頭から1文字取り出す。
・順にXORしてサムチェックコードを作る。
・全文字完了で2桁の16進値で出力。

試したのはこんなGAWKのコード。

# 文字コードをXORしたい
BEGIN{
a = "ABCDEF"; # チェック文字
n = length(a); # 文字数
sum = 0; # XOR結果
for(i = 1; i <= n; i++){ # 先頭=1から最後まで
c = substr(a, i , 1); # 1文字取り出し
printf("%c", c); # ★1 確認で出力
printf("(%02X)", c); # ★2 HEXで出力
sum = xor(sum, c); # ★3 XOR演算
sum = and(sum, 255); # 00~FFでマスク
}
printf(" : %02X\n", sum); # 結果出力 sum
}

しかし結果はこんなのに。

  A(00)B(00)C(00)D(00)E(00)F(00) : 00

取り出した1文字を、printf("%c",c)で文字として出力
できていますが、8bit数値としての処理ができてません。
ゼロのまま。
  ★1は動作。
  ★2、★3がゼロのまま。

  「c + 0」とか・・・(awkでは+0で変数が数値になる)
  「int(c)」とかを試しましたがダメ。

たしか「昔に同じことをしたよな~」っと思い出して
古いプログラムを探しますと、この解決方法が出てきました。

ちょっと面倒ですが、まず0~255の値に対する配列を作ります。
その配列番号として使うのはsprintf("%c",i)で作った8bit文字
その中に0~255の数値を入れます。

以後、このテーブルを使って8bit文字の数値を得ます。
すると、XOR演算や16進での出力ができるという仕掛け。

こんなテストプログラム。

# 文字コードをXORしたい
BEGIN{
a = "ABCDEF"; # チェック文字
# 0~255の数字テーブルを作成
for(i = 0; i < 256; i++){ # 0~255
t = sprintf("%c", i); # 配列番号を文字で
tbl[t] = i; # 値をテーブルに入れる
}
# 実行
n = length(a); # 文字数
sum = 0; # XOR結果
for(i = 1; i <= n; i++){ # 先頭=1から最後まで
c = substr(a, i , 1); # 1文字取り出し
printf("%c", c); # ★1 確認で出力
printf("(%02X)", tbl[c]); # ★2 HEXで出力
sum = xor(sum, tbl[c]); # ★3 XOR演算
sum = and(sum, 255); # 00~FFでマスク
}
printf(" : %02X\n", sum); # 結果出力 sum
}

結果、ちゃんと16進値が出るようになりました。

  A(41)B(42)C(43)D(44)E(45)F(46) : 07

めでたし、めでたし。


| | コメント (0)

2020年3月 5日 (木)

ダイソーReVOLTES単3 JIS C8708:2019充放電試験途中経過

ダイソーReVOLTES単3によるJIS C8708:2019充放電試験
やっと45サイクルを終えました。
50サイクルごとの0.2C放電による放電カーブ 、最初のまで
あともう一息。

Aa1

このグラフは1cyc~49cycで行う、0.5C充放電での
充放電時間の変化です。
右目盛の青線は充放電比になります。

ところどころ凸状になって効率が上がっているところが
見えます。
これ、どうやら仕事をしている時の室温の影響のようで、
30サイクルのところから月曜が始まり、月・火・水・木と
4日分が見えています。
暖房を入れてるものだから室温が上昇して「電池が元気に」
というところでしょう。

充電はまだ「132分充電(1割増し充電)」を維持。
「-ΔV」検出には至っていません。

放電は「2時間:120分」を越えています。

ReVOLTES、充電放電とも「絶好調」というところでしょうか。

 

充放電実行中、実験回路からこんなデータが出力
されます。

#Start
#D 0.2C 0cyc 0/8 0h00m 1.294V
#Break
#Start
#D 0.2C 0cyc 0/8 0h00m 1.293V
#D 0.2C 0cyc 0/8 4h03m 1.000V
#D-Wait 0cyc 0/8 1h00m 1.167V
#Next
#C 0.5C 1cyc 1/8 2h12m 1.549V
#C-Wait 1cyc 1/8 0h20m 1.440V
#D 0.5C 1cyc 1/8 1h59m 1.000V
#D-Wait 1cyc 1/8 0h10m 1.177V
#C 0.5C 2cyc 1/8 2h12m 1.557V
#C-Wait 2cyc 1/8 0h20m 1.449V
#D 0.5C 2cyc 1/8 2h01m 1.000V
#D-Wait 2cyc 1/8 0h10m 1.176V
#C 0.5C 3cyc 1/8 2h12m 1.562V
#C-Wait 3cyc 1/8 0h20m 1.454V
#D 0.5C 3cyc 1/8 2h01m 1.000V
#D-Wait 3cyc 1/8 0h10m 1.173V
#C 0.5C 4cyc 1/8 2h00m 1.535V
#C 0.5C 4cyc 1/8 2h01m 1.539V
#C 0.5C 4cyc 1/8 2h02m 1.543V
#C 0.5C 4cyc 1/8 2h03m 1.546V
#C 0.5C 4cyc 1/8 2h04m 1.549V

これを「GAWK」で処理して0.5C充放電の部分
(#C #Dの行)をピックアップして放電時間(分)
と充電時間を得ます。
d/cは充放電比率です。

#cyc d-cg chg  d/c
  1 119 132 90.2%
  2 121 132 91.7%
  3 121 132 91.7%
  4 123 132 93.2%
  5 123 132 93.2%
  6 122 132 92.4%
  7 122 132 92.4%
  8 122 132 92.4%
  9 123 132 93.2%
 10 124 132 93.9%

これをGNU-PLOTでグラフ化。

awkはこんなスクリプト。 (表示の関係で全角スペースにしてます)

BEGIN{
  print "#cyc d-cg chg  d/c";
}
#loop
{
  if(($1 == "#Start")   ||   # 無視する文字
    ($1 == "#Break")   ||
    ($1 == "#Next")   ||
    ($1 == "#D-Wait")  ||
    ($1 == "#C-Wait")  ||
    ($1 == "#Batt")   ||
    ($1 == "#cyc")    ||
    ($1 == "#")     ||   # #だけ
    ($1 ~ /^#[0-9]+$/)  ||   # #10,#11,#12...
    ($1 ~ /^[0-9.V]+$/) ||   # 1.23Vを除去
    ($1 ~ /^[0-9/]+$/)  ||   # 2020/01/02を除去
    ($3 == "50cyc")   ||   # 50cyc除去
    ($3 == "0cyc")){       # 0cyc除去
      next;          # 次レコードへ
  }
  cy1 = $3 + 0;         # 新サイクル
  split($4, cn8, "/");      # 1/8,2/8...→50,100...
  cn50 = cn8[1];         # 1,2,3...
  split($5, hm, /[hm]/);     # 時分
  tm = 60 * hm[1] + hm[2];    # 分値に
  if(cyc1 != cy1){        # cyc変化で出力
    dataprint();        # 前に取得したデータで結果出力
  }
  cyc1 = cy1;          # 次回出力チェックのサイクル
  cyn50 = cn50;
  if($1 == "#C")   tmc = tm;  # 充電時間
  if($1 == "#D")   tmd = tm;  # 放電時間
}
#おわり
END{
  dataprint();        # 最終サイクルの結果出力
}

#データ出力
function dataprint(){
  if((cyc1 != 0) &&     # 0cycは出力しない
    (cyn50 != 0) &&     # 1/8検出前は出力しない
    (tmc  != 0)){      # 充電時間=0なら出力しない
    printf("%4d %4d %4d %5.1f%\r\n",
      50*(cyn50-1)+cyc1,   # サイクル
      tmd, tmc,        # 放電,充電時間(分)
      (tmd / tmc) * 100);   # 充放電率 (100%)
  }
}

サイクル値が変わった(1cyc→2cycになった時)に
直前の充放電データを出力しています。
  実験装置は、1分ごとに出力するような
  モードがあるので、次のサイクルで前の
  結果を出力するという処理にしてます。


GNU-PLOTのはこんなの。

set title "ダイソー ReVOLTES(1300mAh) JIS C8708:2019 充放電実験"
set y2tics
set xrange [0:60]
set yrange [60:160]
set y2range [50:100]
set xlabel "充放電サイクル"
set ylabel "充放電時間(分)"
set y2label "放電度(%)"
set grid
set xtics 10
set ytics 10
set y2tics 10
set key left bottom
plot "t1.txt" index 0 using 1:2 with lines lw 2 ti "0.5C放電時間(分)" ,\
   "t1.txt" index 0 using 1:3 with lines lw 2 ti "0.5C充電時間(分)" ,\
   "t1.txt" index 0 using 1:4 with lines lw 2 ti "充放電比 D/C(%)" axes x1y2


2020年3月30日:ダイソーReVOLTE単3 JIS C8708:2019充放電試験途中経過 -ΔV検出開始
電池あれこれ まとめ

| | コメント (2)

2020年1月14日 (火)

メモ:awk(gawk)で「arcsin」

※エクセルでの文章はキライ!
エクセルで図と文を混ぜて書いて「ハイ、これが仕様書」っと渡させるとちょいとイライラします。
そんなときは「こちらの環境が悪いのか見にくいのでpdfにして送り直してちょ」と返答するようにしています。
まぁ↑は置いておいて・・・

数式処理の確認も、エクセルを使うと簡単にグラフ化できたりと便利なのは間違いないんですが、私の場合、「あまりしたくない感」が勝ってしまいます。
そんな場合、何を使うかというと「awk(gawk)」。

テキストエディターでスクリプトを書いて、コマンドプロンプトで実行。
リダイレクトで結果をテキストファイルに。
グラフ化したいなら、その結果をエクセルに食わせるという具合。

先日のこと、逆三角関数arcsin、arccosを使った処理の検証をしようとしたところ、・・・awk(gawk)には「asin()、acos()」関数は実装されていなかった。・・・あれま。

三角関数sin、cos、atan2、それにsqrtは実装されてますんで、これらを使ってどうにかしなくちゃなりません。
三角関数の変換式を検索しながら、awk(gawk)に関連付けて探すと、発見!
これ↓。
function asin(x) { return atan2(x, sqrt(1-x*x)) }
function acos(x) { return atan2(sqrt(1-x*x), x) }

asin()とacos()が得られました。
簡単にテスト。

BEGIN{
 PAI = atan2(0, -1)  # パイは数字指定じゃなくatan2で
 for(i=-1;i<+1;i+=0.1){ #-1~+1を0.1ピッチで
  printf("%+4.1f %+7.2f %+7.2f\n",
    i, asin(i)*180/PAI, acos(i)*180/PAI);
 }
}
function asin(x) { return atan2(x, sqrt(1-x*x)) }
function acos(x) { return atan2(sqrt(1-x*x), x) }

で、その結果
-1.0 -90.00 +180.00
-0.9 -64.16 +154.16
-0.8 -53.13 +143.13
-0.7 -44.43 +134.43
-0.6 -36.87 +126.87
-0.5 -30.00 +120.00
-0.4 -23.58 +113.58
-0.3 -17.46 +107.46
-0.2 -11.54 +101.54
-0.1 -5.74 +95.74
-0.0 -0.00 +90.00
+0.1 +5.74 +84.26
+0.2 +11.54 +78.46
+0.3 +17.46 +72.54
+0.4 +23.58 +66.42
+0.5 +30.00 +60.00
+0.6 +36.87 +53.13
+0.7 +44.43 +45.57
+0.8 +53.13 +36.87
+0.9 +64.16 +25.84
+1.0 +90.00 +0.00

 

| | コメント (2)

2019年3月 1日 (金)

DOS版OrCADの部品ライブラリをBSch3VのLB3ファイルに

先日来、GAWKの「正規表現」でお騒がせしていますが、
部品ライブラリの変換ツールが動き始めています。
   ※まだまだ手直しするところは残ってますが・・・
で、作業を進めていて、出来ないことや苦手なところが
判明。

・グラフィックパーツのFILL:黒塗りが未対応。
   *OrCADはfillポイントを座標で指定。
   LB3は円や四角のパラメータで指定。

・ヒステリシス記号のベクトルデータが出ない。
     * OrCADではシンボル定義文字HYSTERESISで
   描いている。

・ベクトルでの文字入れが不安定。

・ARC(円弧)の処理が不安定。
       * OrCADはXY座標,LB3は角度で処理。

・ピン指定の細かいところがちょいと。

ざっと、こんなところ。

LB3にしたときの変換がうまくいかない例
  ※LCoVで編集中の画面をコピー

・シュミット記号のベクトルデータが出ない。
 ビットマップでの形は出ている。
10

・文字位置が微妙
13

・FILL:黒塗りつぶしができない
12

・円弧のベクトルデータ、始点終点が部品枠外になった
 場合でも、出てしまう。
    OrCADでの元データ作成時の手抜きが原因
11

「ちゃんといったなぁ」というのがトランス類。
円弧の処理が気になっていたのです。
OrCADでの円弧は、中心座標、半径、始点座標、終点座標
で指定します。
LB3は、中心座標、半径、始点の角度、終点の角度で指定
と、元データの座標を角度に直さなくてはならないのです。
その時、角度の基準が「3時の位置が0度」で、0度→360度の
増加方向が反時計回り。
この時、始点と終点を逆にしちゃうと、60度の円弧が300度に
なってしまったりと、びっくりな絵が出てきます。

トランスの変換例。
21
もうひとつ。
22

ただ、古いOrCADの部品だと、ベクトルデータを入れてなくって
ビットマップだけのがあります。
元データがビットマップだけですと、こんな具合になっちゃいます。
23

ベクトルデータが無いとちょいとさみしい・・・・

「GAWK」のスクリプトですんで、あれこれ手を入れてもらうことは
可能かと。
650行ほどのファイルです。
     アップロード、ちょいと待ってくださいな。
Vectorの 「gawk 3.1.5 for Windows」 で実行確認してます。

GAWKをダウンロードしてもらって、コマンドプロンプトで
実行する環境を整えておいてください。
説明書なしで「libsv3.awk」だけアップロードしておきました。
・場所:http://act-ele.c.ooco.jp/jisaku/libsv3/libsv3.htm   ←説明入り
・ファイル:http://act-ele.c.ooco.jp/jisaku/libsv3/libsv3.zip

DOS版OrCADの部品ライブラリー(.LIBファイル)を「DECOMP.EXE」で
部品ソースファイル(テキスト)に変換してから、今回のツールに
食わせます。

| | コメント (5) | トラックバック (0)

2019年2月20日 (水)

「gawk」の正規表現・・・続き:文字の順番を入れ替える

もう一つ、gawkの処理で「簡単に!」を実現したののが
「負論理記号」。

例えば「74138」。

X1
部品ライブラリの「ピン名称」、Bsch3Vだと「¥G¥2」のよう
¥が先に来て負論理のupper barが次文字の上に出ます。

+PIN,N:A,DF:FFFFFFFF,L:L1,T:,M:1,-PIN
+PIN,N:B,DF:FFFFFFFF,L:L2,T:,M:2,-PIN
+PIN,N:C,DF:FFFFFFFF,L:L3,T:,M:3,-PIN
+PIN,N:\G\2\A,DF:FFFFFFFF,L:L5,T:N,M:4,-PIN
+PIN,N:\G\2\B,DF:FFFFFFFF,L:L6,T:N,M:5,-PIN
+PIN,N:G1,DF:FFFFFFFF,L:L7,T:,M:6,-PIN
+PIN,N:\Y\0,DF:FFFFFFFF,L:R1,T:N,M:15,-PIN
+PIN,N:\Y\1,DF:FFFFFFFF,L:R2,T:N,M:14,-PIN
+PIN,N:\Y\2,DF:FFFFFFFF,L:R3,T:N,M:13,-PIN
+PIN,N:\Y\3,DF:FFFFFFFF,L:R4,T:N,M:12,-PIN
+PIN,N:\Y\4,DF:FFFFFFFF,L:R5,T:N,M:11,-PIN
+PIN,N:\Y\5,DF:FFFFFFFF,L:R6,T:N,M:10,-PIN
+PIN,N:\Y\6,DF:FFFFFFFF,L:R7,T:N,M:9,-PIN
+PIN,N:\Y\7,DF:FFFFFFFF,L:R8,T:N,M:7,-PIN

ところが、OrCADだと「G¥2¥」となって、
文字の後ろに¥があると、その文字の上にバーが付くのです。

'74LS138'
{X Size =}   7      {Y Size =}   9      {Parts per Package =}   1
L1      1         IN  'A'
L2      2         IN  'B'
L3      3         IN  'C'
L6      6         IN  'G1'
L7      4 DOT     IN  'G\2\A\'
L8      5 DOT     IN  'G\2\B\'
R1     15 DOT     OUT 'Y\0\'
R2     14 DOT     OUT 'Y\1\'
R3     13 DOT     OUT 'Y\2\'
R4     12 DOT     OUT 'Y\3\'
R5     11 DOT     OUT 'Y\4\'
R6     10 DOT     OUT 'Y\5\'
R7      9 DOT     OUT 'Y\6\'
R8      7 DOT     OUT 'Y\7\'
T0     16         PWR 'VCC'
B0      8         PWR 'GND'

単純な文字の入れ替えなんですが、うまい表現が思いつきません。
と同じように、¥の検出で、その直前の文字列の最後尾を1文字
抜き出し、¥を挿入後に抜いた文字を加えるという処理をして
います。
これ、どうにかスマートにする手法って無いでしょかね。

| | コメント (1) | トラックバック (0)

2019年2月11日 (月)

gawkの関数:「length」でつまづく!

MS-DOS時代の「jgawk」なら大丈夫なのに、Vectorでダウンロードした
gawk(3.1.5)」でアウト。
「正規表現」 は関係ありません。
おかしな挙動をしたのが「length」。
文字のバイト数を返す関数。
gawkで使うと、おかしなことが起こったんです。
検証のため、こんなテストプログラムを実行。

{
    n = length($0);           # 入力文字列のバイト数
    printf("n:%d\n", n)     # いったん確認
    r1 = "";                    # バッファをクリア
    for(i = 1; i <= n; i++){    # 入力文字数でloop
        c1 = substr($0, i, 1);     # 1文字取り出し
        r1 = r1 c1;                 # バッファに文字として結合
        printf("%s:%d\n",r1,length(r1));   # バッファの文字列とバイト数を表示
    }
}

これがgawkだと、
12345  ←入力文字
n:5    合ってる
1:1    ところが、増えていくはずが・・・
12:1
123:1
1234:1
12345:1   5文字ループしたのに「1」

abcdefg
   7文字入力
n:7    合ってる
a:1    ところが・・・
ab:1
abc:1
abcd:1
abcde:1
abcdef:1
abcdefg:1  やはり1のままで違ってる

正しい値は・・・
行末の数字が1234・・・と+1ずつ増加しなくちゃなりません。
で、正しい答えを出す方法。

gawkのままで
 1:     r1 = r1 c1 "";           # 空文字を結合
 2:     printf("%s:%d\n",r1,length(r1 ""));   同じく
 3:     起動オプションに -W ctype=ASCIIを加える

   ctype=SJISだとダメ。

jgawkだとそのままでok

むちゃ悩んだぞ~~~っと。
どうしたものか。

※結果・・・
gawkのバージョンを上げるということで対応。(4.1.4に)
ここからダウンロード。
Free download of the version 4.1.4 (Aug 2016)
(Version 4.1.4)

Win32 executable

Version in English Version in English


※ところが・・・
4.1.4では日本語がアウト。
起動オプションも見当たらず。

 

| | コメント (4) | トラックバック (0)

2019年2月10日 (日)

「gawk」の正規表現・・・続き

の続きで、gawkの正規表現で悩んでいます。

・やりたいこと
OrCADの部品ライブライーソースファイルの中に出てくる
こんな文字列(「'xxxx'」というふうに「'」で区切られている)内の
「スペース」を「_」(下線記号)に変えたい。

・例 文字列
  'VOLTAGE REGULATOR'
  L1  3  SHORT   IN  'PLUS INPUT'
    R1  'C2' CLK  OUT 'CLK OUT'

・なぜか
gawkの「スペースで文字列を文字単位に」分割するという
機能、「'」で区切られた文字列内にスペースがあると、
そこで切られてしまいす。
「'  '」内のスペース、これを「_」(下線記号)に変えて、
分割されないようにしたいわけで。

・条件
1行に複数個の「'  '」が出現することもある。

・試したのはこんな処理
    while(1){                                 # 「'  '」がいくつもあるかもしれないので
        match($0, /'[^']*'/);
        if(RSTART == 0)     break;     # 「'  '」がなければおわり
        s1 = substr($0, 1, RSTART-1);             # 「'  '」の左側
        s2 = substr($0, RSTART, RLENGTH);   # 「'  '」の部分
        s3 = substr($0, RSTART+RLENGTH);   # 「'  '」の右側
        gsub("'", "@", s2)      # 「'  '」部分の「']をいったん@に
        gsub(" ", "_", s2)       # 「'  '」部分スペースを「_」に
        $0 = s1 s2 s3            # あらたな$0
    }   
    gsub("@", "'", $0)         # @を「'」に変えて元に戻す

「'  '」が複数個出るかもということで、「']をいったん@に変えて、
1行の先頭から処理するようにしました。
gawkらしく、もっとスマートな方法は?
   ※Cだとチカラ技で処理を進めるですが、gawkの書式はパズルです。
     1文字ずつ読み出して「'」が来たらスペースを「_」にというほうが
     良いかな。

そういや、こういった記述にも対応しないと。
R1    24   OUT 'QA''' ← QA'が信号名で 二つの「''」で
文字としての「'」を示すわけでして・・・。

 

| | コメント (3) | トラックバック (0)

より以前の記事一覧