果報は寝て待て: 2022

2022年7月22日金曜日

中華製の扇風機の修理

 職場の人から、1年前に買った扇風機が動かないから見てほしいとのことで、軽い気持ちで引き受けた。一見、東芝製にみえました。


 

 開けてびっくり、フィルムコンデンサが爆発している。 

ここは軽い気持ちで交換してはいけないところなので、「ホームセンターに持っていってクレーム言った方がいいよ」といったのですが、「新しいの買ったし、レシートが分からないから捨てる」とのこと。

持ち主へ返却の必要がなくなったのでじっくり爆発の原因を調べてみました。

このコンデンサはトランスの代わりにAC100vからACの低圧に下げているものです。その中の金属化樹脂(METARIZED POLIMER) が溶けて噴出して、固まってます。その時オープンになったので何事もなかったのですが、火災につながった可能性もあります。

 
基板全体の写真です。


             マイコンまでの回路図です

VDDはマイコンの1ピンに、VSSは20ピンに入ってます。マイコンはSONIXのSN8F5702という汎用のマイコンで、データシートでは5.5~1.7Vくらいだったと思います。そのためツェナーダイオードは5Vくらいでクランプしてるはずです。試しに単三電池3本をツェナーダイオードの両端につないで動作させたところ数時間何事もなかったように、扇風機は正常に動いてくれました。待機時で8mA,動作時で12mAくらいです。

上の回路図の部品は1.5μ以外すべて異常ありませんでした。基板も熱が加わったようにも見えません。

1か所気になるのが、 破損した1.5μのコンデンサに直列に抵抗が入っていないことです。これならばコンセントを差し込むタイミングが悪ければ、このコンデンサに大電流が流れるので早期に劣化するのかもしれないということです。設計する人はそんなことくらいわかってるはずですし、他のユーザーからもクレームが来ると思います。

  それ以外、私の技量ではどうしても原因がわかりません。どなたか心当たりありませんか?

 




2022年7月3日日曜日

TWELITE DIPで透過モードを使ってみる



 TWELITE DIP REDを透過モードにして使ってみたので、手順を覚書にします。

  パソコンとの通信はいつものやつ、秋月電子の AE-FT231Xを使用します。

 

① TWELITE DIPと秋月電子のAE-FT231Xを接続する。

  透過モードだけどほとんど送るだけの方を送信側とほとんど受けるだけを受信側としてます。 

  送信側

送信時のLEDをつけるのと、ハードウェア制御に似たことをするため、TWELITEのデジタルI/Oの⑤とFT231XのCTSを繋ぎます。

  受信側

LEDは受信側につけるのと、受信のみなのでハードウェア制御はつないでません。


②ファームウェアの書き換え

       1. TWELITE STAGE SDK をダウンロードし、展開する

           https://mono-wireless.com/jp/products/stage/index.html

  2. TWELITEプログラマーをダウンロードし、展開する

       https://mono-wireless.com/jp/products/TWE-APPS/LiteProg/index.html

  3.  TWELITE DIPをプログラムモードで立ち上げる

  

   sw1とsw2を同時にオンにする。次にsw1をオフにし、次にsw2をオフにする

  これでプログラムモードになります。

  4. TWELITEプログラマーを立ち上げる。

     詳しくはTWELITEプログラマーの説明のページで。

  5. 下のbinファイルをドロップします。

    場所は、MWSTAGE\MWSDK\Wks_TweApps\App_Uart\App_Uart\build\App_Uart_RED_L1305_V1-4-6.bin です。

   間違ったファイルをドロップしたら、違いますよと教えてくれました。
 






2022年6月9日木曜日

pythonでラインの稼働状況を棒グラフに表示

 目的は、ちまたでよく見る、工場の自動ラインの稼働状況をモニタで表示することです。当然お金をかければなんぼでもあります。

今のところこんな風に表示されます。

 

 

 

やりたいことです。

① 1時間当たりの出来高を棒グラフで表示します。

② とりあえず48時間前まで表示して1時間ごとに更新します。

③ 棒の下には、月/日/時を表示します。

④真ん中の青い線は、出来高の目標線で、プログラムの立ち上げ時に入力します。

 

次に構成です。

① 自動ラインの最終工程から、完品が1台出るたびに2秒間の信号を出力します。

  三菱シーケンサーから、24vで取り出してます。

② 24vをフォトカプラで受けてaruduino unoで取り込みます。写真ではフォトカプラが6個並んでますが、今回は1個しか使ってません。



aruduino のプログラムです。


// data logger
//degital2~degital7 の6本のi/oを0.5秒毎にpythonへ送信する
//

int signal_1 = 2; // degital入力2 を signal_1に取り込む
int signal_2 = 3; // 
int signal_3 = 4; // 
int signal_4 = 5; // 
int signal_5 = 6; // 
int signal_6 = 7; // 



int led1  = 13;

int keep_sig1_on = 0;  // signal_1がonの状態を読み、ダブルカウント防止
int keep_sig2_on = 0;  //
int keep_sig3_on = 0;  //
int keep_sig4_on = 0;  //
int keep_sig5_on = 0;  //
int keep_sig6_on = 0;  //



void setup(){
    pinMode( signal_1, INPUT_PULLUP );
    pinMode( signal_2, INPUT_PULLUP );
    pinMode( signal_3, INPUT_PULLUP );
    pinMode( signal_4, INPUT_PULLUP );
    pinMode( signal_5, INPUT_PULLUP );
    pinMode( signal_6, INPUT_PULLUP );
    pinMode( 13, OUTPUT );
        
    Serial.begin( 9600 );

}

void loop(){
  //  signal_1がlowになったら keep_sig1_onを 1にする
    if(keep_sig1_on == 0){                    
      if(digitalRead(signal_1) == LOW ){
        keep_sig1_on = 1;
      }
    }
    else{
       if(digitalRead(signal_1) == HIGH ){  
         keep_sig1_on = 0;
        }
    }
  //  signal_2がlowになったら keep_sig2_onを 1にする
    if(keep_sig2_on == 0){                    
      if(digitalRead(signal_2) == LOW ){
        keep_sig2_on = 1;
      }
    }
    else{
       if(digitalRead(signal_2) == HIGH ){  
         keep_sig2_on = 0;
        }
    }
  //  signal_3がlowになったら keep_sig3_onを 1にする
    if(keep_sig3_on == 0){                    
      if(digitalRead(signal_3) == LOW ){
        keep_sig3_on = 1;
      }
    }
    else{
       if(digitalRead(signal_3) == HIGH ){  
         keep_sig3_on = 0;
        }
    }
  //  signal_4がlowになったら keep_sig4_onを 1にする
    if(keep_sig4_on == 0){                    
      if(digitalRead(signal_4) == LOW ){
        keep_sig4_on = 1;
      }
    }
    else{
       if(digitalRead(signal_4) == HIGH ){  
         keep_sig4_on = 0;
        }
    }
  //  signal_5がlowになったら keep_sig5_onを 1にする
    if(keep_sig5_on == 0){                    
      if(digitalRead(signal_5) == LOW ){
        keep_sig5_on = 1;
      }
    }
    else{
       if(digitalRead(signal_5) == HIGH ){  
         keep_sig5_on = 0;
        }
    }
  //  signal_6がlowになったら keep_sig6_onを 1にする
    if(keep_sig6_on == 0){                    
      if(digitalRead(signal_6) == LOW ){
        keep_sig6_on = 1;
      }
    }
    else{
       if(digitalRead(signal_6) == HIGH ){  
         keep_sig6_on = 0;
        }
    }
    

    
//  シリアルポートへ出力 bou_ok_count,ng_count,nc_count
    Serial.flush();
    
    Serial.print( keep_sig1_on );
    Serial.print( keep_sig2_on );
    Serial.print( keep_sig3_on );
    Serial.print( keep_sig4_on );
    Serial.print( keep_sig5_on );
    Serial.println( keep_sig6_on );
    

    

// 各トリガーが掛かれば、LED1を点燈する

    if(digitalRead(signal_1) == LOW){
      digitalWrite(led1,HIGH);
    }
    else if( digitalRead(signal_2) == LOW){
      digitalWrite(led1,HIGH);
    }
    else if( digitalRead(signal_3) == LOW ){
      digitalWrite(led1,HIGH);  
    }  
    else if ( digitalRead(signal_4) == LOW ){
      digitalWrite(led1,HIGH);
    }
    else if ( digitalRead(signal_5) == LOW){
      digitalWrite(led1,HIGH);
    }
    else{
      digitalWrite(led1,LOW);
    }
    
    delay(500 );
}

 

aruduinoは、ただ0.5秒ごとに 000000 をusbでpythonに送ってて、完品の信号が入力されたら 000001 を送信して、2秒たったらまた 000000 に戻すだけの仕事です。

③ LINUXMINT32BIT版に入ってるpython3 で、aruduinoからの信号を受け取り、1時間ごとに集計してリストに加え、tkinterで棒グラフ表示します。

 

# -*- coding: utf-8 -*-
"""
Created on Fri Apr 22 21:52:16 2022
7.1 for windows
@author: osada
"""

import tkinter as tk
import serial as sl
import time
import re
import datetime as dt

signal_1 = 0
signal_2 = 0
signal_3 = 0
signal_4 = 0
signal_5 = 0
signal_6 = 0

old_signal_1 = 1
old_signal_2 = 1
old_signal_3 = 1
old_signal_4 = 1
old_signal_5 = 1
old_signal_6 = 1

deki__count1 = 0
deki__count2 = 0
deki__count3 = 0
deki__count4 = 0
deki__count5 = 0
deki__count6 = 0
ave_774 = int(input("774Lの時間当たりの平均数を入力してください"))
data = []
#data= [10,15,20,15,10,14,12,10,5,7,15,16,9,14,12,11]
data_hour = []
#data_hour = ["04/27 21","04/27 20","04/27 19","04/27 18","04/27 17","04/27 16","04/27 15","04/27 14","04/27 13","04/27 12","04/27 11","04/27 10","04/27 09","04/27 08","04/27 07","04/27 06"]
now_time_hour = dt . datetime . now ( ).strftime("%m/%d %H")
data_hour.insert(0,now_time_hour) # data_hourリストの末尾に now_time_hour を追加する
triger_flug = 0
old_line = None
clear_count_triger = None
#ウインドを作成
root=tk.Tk()
root.geometry('1000x700')
root.title('canvasの使い方')

finFlag = True
serial = None

serial = sl.Serial('/dev/ttyACM0', 9600, timeout=0)
#serial = sl.Serial('COM5', 9600, timeout=0)  #

while( serial.is_open is False):
    time.sleep(100)

#図形を壁画するキャンバスをウインド上に作成
canvas = tk.Canvas(root, width = 1000, height = 650)
canvas.grid(column=1, row=3, columnspan=1,rowspan=8)
now_time_hour = dt . datetime . now ( ).strftime("%m/%d %H")
#stop_time=3600 #目標終了時間

#無限ループ
while True:
    #  シリアルポートの操作
    line = None
    if ( serial.is_open):
        line = serial.readline()
        new_line = line.strip().decode('utf-8')
        #print(new_line)
        
    if len(new_line) == 13 and old_line != new_line :
        
        now_time = dt . datetime . now ( ).strftime("%Y/%m/%d %H:%M:%S")
        #print(now_time)

        print("new_line ",new_line)
        #print("old_line ",old_line)
        signal_1 = re.search(r'A(.+)B',new_line).group(1)
        #print("signal_1 ",signal_1)
        signal_2 = re.search(r'B(.+)C',new_line).group(1)
        #print("signal_2 ",signal_2)
        signal_3 = re.search(r'C(.+)D',new_line).group(1)
        #print("signal_3 ",signal_3)
        signal_4 = re.search(r'D(.+)E',new_line).group(1)
        #print("signal_4 ",signal_4)
        signal_5 = re.search(r'E(.+)F',new_line).group(1)
        #print("signal_5 ",signal_5)
        signal_6 = re.search(r'F(.+)G',new_line).group(1)
        #print("signal_6 ",signal_6)
        print(now_time,"      ",signal_1,signal_2,signal_3,signal_4,signal_5,signal_6)
        old_line = new_line
        
    if signal_1 != old_signal_1 : # シグナル1に変化があった
        if signal_1 == "1" :
            deki__count1 = deki__count1 + 1 # 出来高カウントに1をプラス
            print("deki__count1  ",deki__count1)
        old_signal_1 = signal_1
        print(clear_count_triger,data)
    
    clear_count_triger = dt . datetime . now ( ).strftime("%M%S") #"%M%S" 毎時0分0秒がトリガー
    #print(clear_count_triger,data) # 0000
        
    if clear_count_triger == "0000" and triger_flug == 0 :
        now_time_hour = dt . datetime . now ( ).strftime("%m/%d %H")
        data.insert(0,deki__count1) # dataリストの末尾に deki__count1 を追加する
        data_hour.insert(0,now_time_hour) # data_hourリストの末尾に now_time_hour を追加する
        
        if len(data) > 48 : # dataリストが48要素を超えたら先頭を削除する
            data.pop()
        if len(data_hour) > 49 : # dataリストが48要素を超えたら先頭を削除する
            data_hour.pop()
        deki__count1 = 0 # deki__count1をクリアー
        triger_flug = 1
        now_time = dt . datetime . now ( ).strftime("%Y/%m/%d %H:%M:%S")
        print(now_time,data)        
        print(now_time,data_hour)
    if clear_count_triger != "0000" and triger_flug == 1:
        triger_flug = 0    
   
    canvas.delete("rect") # タグ"rect"を消去する
    canvas.create_text(500, 40, text= "774Lの過去48hの時間当たり生産数  " ,tag="rect",fill="black",font=('Helvetica 40 bold'))
    canvas.create_line(960-20*len(data), 600-(ave_774)*20, 1000 ,600-(ave_774)*20,tag="rect",fill="Blue",width = 2)
    for i in range(len(data)):
        canvas.create_rectangle(980-20*i,600-20*data[i],995-20*i,600,tag="rect",fill = 'green')
        canvas.create_text(988-20*i, 590-20*data[i], text= str(data[i]),tag="rect",fill="black",font=('Helvetica 8 bold'))
        canvas.create_text(988-20*i, 630, text= str(data_hour[i+1]),tag="rect",fill="black",font=('Helvetica 8 bold'), angle=90)
    root.update()
    

root.mainloop()

6ライン分の稼働状況を1台で管理できるよう6桁の文字列を送れるようにしてあります。

でもこれ以上拡張することはなさそうです。



2022年2月19日土曜日

winCAD3のデータをQCADで読み取る

数年前に退社された方のパソコンがなぜか私の手元に来ました。

 中をのぞくと、社内で10年以上にわたり作成、改造した冶具のcad図面のデータが入ってます。これは会社の貴重な財産です。パソコンごと捨てられる前にバックアップしました。 

 さて、それを利用したいのですが、win3.1の時代のWINCAD3という CADソフトのDXFデータです。迎え撃つのは、フリーのQCADです。

 結論として、今のところ、線の太さの情報がデータに入ってないようで、すべて同じ太さの線になりますが、破線や一点鎖線は元通りに取り込めます。コメント表示の文字化けもなくなりました。十分実用になります。

 

  やり方です。

 ① WINCAD3のデータをDXFの拡張子でPYTHONの実行ファイルと同じフォルダに保存する。

 DXFファイルの グループコードの値は次の事がわかってます。  

  0 種類(ARC,CIRCLE,TEXT,LINE等) 

  6 ラインタイプ(CONTINUOUS:連続線,HIDDEN:破線    1,DASHDOT:一点鎖線,)

  8 画層:レイヤー

  10 開始点のx座標

  20 開始点のy座標

  11  終了点のx座標

  21 終了点のy座標

  40 半径

  50 開始角度

  51 終了角度

  370 線の太さ ー1;画層による。-2;ブロックによる。 30:0.3㎜

 

②  テキスト部分をUNICODEに書き換える(PYTHONにやってもらいます)

    pythonと同じフォルダに置いてある"ABCD-00.DXF"を”ABCD-00X.DXF”に変換します。 

 'KANJI'と書いてある行を探し、その2行上の行のコードを変換します

  WINCAD3コードそのままで変換しないのは

             0x0000 ~ 0x0390  

             0x0450 ~ 0x2fff

             0x3001 ~ 0x3030

  それ以外は UTF-16に変換します。

また、'ff9f' は  '00b0'に変換します。

いまのところこれで文字化けには遭遇してません。

以下実行コードです

 

 

import glob
files = glob.glob("*.DXF")
for file in files:
print(file)

before2_line = ''
before1_line = ''
KANJI_flag = 0

with open(file) as f , open((str(file)[:-4])+"X.DXF",'w') as new_f :
l = f.readlines()
print(type(l))
print(l)
for line in l:
#print(line)
new_line = ''

if 'KANJI' in line :
#print(before2_line)
#print(before1_line)
for car in before2_line:
#print(car)
utf_car =hex(ord(car))
#print(utf_car)
utf_car2 = utf_car[2:]
#print(utf_car2)
"""
encode: ~ 0x3031
0x3000
0x044f ~ 0x0391
no_encode: 0x3030 ~ 0x3001
0x2fff ~ 0x0450
0x0390 ~ 0x0000
"""
if ((int(utf_car2,16) <= 0X3030 and int(utf_car2,16) > 0X3000)
or (int(utf_car2,16) <= 0X2fff and int(utf_car2,16) > 0X044f)
or int(utf_car2,16) < 0X0391 ) :
new_line = new_line +(car)
else :
if utf_car2 == 'ff9f' :
new_line = new_line +(r'\U+' + '00b0')
elif len(utf_car2) == 1 :
new_line = new_line +(r'\U+' + '000' + utf_car2)
elif len(utf_car2) == 2 :
new_line = new_line +(r'\U+' + '00' + utf_car2)
elif len(utf_car2) == 3 :
new_line = new_line +(r'\U+' + '0' + utf_car2)
else :
new_line = new_line +(r'\U+' + utf_car2)
#new_line = new_line[:-4]
print(new_line)
new_f.write(new_line )
KANJI_flag = 2
else :
if KANJI_flag == 0 :
print(before2_line)
new_f.write(before2_line )
#new_f.write(before2_line + '\n')

elif KANJI_flag == 2 :
KANJI_flag = 1
else :
KANJI_flag = 0

before2_line = before1_line
before1_line = line
print(before2_line)
new_f.write(before2_line )
print(before1_line)
new_f.write(before1_line )
print('EOF')
new_f.write('EOF' )
f.close()
new_f.close() 

>

 

 

③ QCADでファイルを開いて何もせずに上書き保存する。

    QCADで ○○X.DXFというファイルを一括で開いて、上書き保存→閉じる、上書き保存→閉じる、を全数繰り返します。これが一番面倒です。

  

④ テキストのSTANDARD 表示をUNICODEに変更する(PYTHONにやってもらいます)

      pythonと同じフォルダに置いてある"ABCD-00X.DXF"を”ABCD-00Y.DXF”に変換

 テキストごとに STANDARDというフォントを全ファイル一括でUNICODEに書き換えます。これでテキストの文字は日本語で表示されます。

 

import glob

files = glob.glob("*X.DXF")
for file in files:
print(file)

before2_line = ''
before1_line = ''
KANJI_flag = 0
with open(file) as f, open((str(file)[:-5])+"Y.DXF",'w')as new_f:
l = f.readlines()
print(type(l))
#print(l)
for line in l:
#print(line)
new_line = ''
if 'Standard' in line :
line = 'Unicode ' + '\n'
print(line)
new_f.write(line )
f.close()
new_f.close()      


⑤ 文字の大きさを変更する 

     pythonと同じフォルダに置いてある"ABCD-00Y.DXF"を”ABCD-00Z.DXF”に変換

   ”ABCD-00Y.DXF” で読めますが、文字サイズが大きく見ずらいので変更します。

文字の倍率は mag_textで指定します。0.7倍で見やすくなりました。


import glob
mag_text = 0.7
def is_num(x):
try:
float(x)
except ValueError:
return False
else:
return True


files = glob.glob("*Y.DXF")
for file in files:
print(file)
base_line = 0
before2_line = ''
before1_line = ''
line_count = 0
KANJI_flag = 0
line_list = []
with open(file) as f, open((str(file)[:-5])+"Z.DXF",'w')as new_f:
l = f.readlines()
print(type(l))
#print(l)
for line in l:
line_count = line_count + 1
line_list.append(line)
print (line_count)
#print(line)
#new_line = ''
for line_number in range (line_count):
if line_list[line_number] == 'AcDbText\n':
print (line_list[line_number + 8])
if is_num(line_list[line_number + 8]) :
line_list[line_number + 8] = str(float(line_list[line_number + 8]) * mag_text)+"\n"

for line in line_list :
new_f.write(line )
f.close()
new_f.close()      

実際の図面の絵のビフォーアフターを乗せれないのが残念です。

WINCAD3はネットでさがしてもほとんど情報が得られないので、古いデータの活用をあきらめてる方がおられるやも知れません。こんな再利用方法もありますよ。