目的は、ちまたでよく見る、工場の自動ラインの稼働状況をモニタで表示することです。当然お金をかければなんぼでもあります。
今のところこんな風に表示されます。
やりたいことです。
① 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桁の文字列を送れるようにしてあります。
でもこれ以上拡張することはなさそうです。
0 件のコメント:
コメントを投稿