2024-03-04 10:23:01 +08:00
|
|
|
|
using Advantech.Motion;
|
|
|
|
|
using AssistClient.Device;
|
|
|
|
|
using AssistClient.Utils;
|
|
|
|
|
using Models;
|
|
|
|
|
using Newtonsoft.Json;
|
|
|
|
|
using Newtonsoft.Json.Linq;
|
|
|
|
|
using OpenCvSharp;
|
|
|
|
|
using SqlSugar;
|
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.ComponentModel;
|
|
|
|
|
using System.Data;
|
|
|
|
|
using System.Drawing;
|
|
|
|
|
using System.Drawing.Imaging;
|
|
|
|
|
using System.Dynamic;
|
|
|
|
|
using System.IO;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Text;
|
|
|
|
|
using System.Threading;
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
using System.Windows.Forms;
|
|
|
|
|
using Yolo5;
|
|
|
|
|
using static AssistClient.Device.SizeLib;
|
|
|
|
|
using Point = System.Drawing.Point;
|
|
|
|
|
using Size = System.Drawing.Size;
|
|
|
|
|
|
|
|
|
|
namespace AssistClient
|
|
|
|
|
{
|
|
|
|
|
public partial class FrmMain : Form
|
|
|
|
|
{
|
|
|
|
|
#region pic缩放变量
|
|
|
|
|
private double ratio = 1; // 图片的起始显示比例
|
|
|
|
|
private double ratioStep = 0.1;
|
|
|
|
|
private Size pic_size;
|
|
|
|
|
private int xPos;
|
|
|
|
|
private int yPos;
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
private bool bExitApp = false;
|
|
|
|
|
private Service.ProductService svcProduct = new Service.ProductService();
|
|
|
|
|
private Service.OrderService svcOrder = new Service.OrderService();
|
|
|
|
|
|
|
|
|
|
private DevContainer devContainer = new DevContainer();
|
|
|
|
|
private Queue<scannerCBmpLoc> scannerCBmpQueue = new Queue<scannerCBmpLoc>();
|
|
|
|
|
private int sizeBmpNum = 0, sizeBmpNumResult = 0;
|
|
|
|
|
private string SN = "";
|
|
|
|
|
private int OrderId = 0;
|
|
|
|
|
private JArray currProductMarkList = null;
|
|
|
|
|
private int currDefectIndex = 0;
|
|
|
|
|
private List<DefectStruct> defectList = new List<DefectStruct>();
|
|
|
|
|
private Dictionary<string, Bitmap> defectBmpsDir = new Dictionary<string, Bitmap>();
|
|
|
|
|
private Dictionary<string, List<List<string>>> defectInfoDir = new Dictionary<string, List<List<string>>>();
|
|
|
|
|
|
|
|
|
|
private object myLock = new object();
|
|
|
|
|
private WarningEnum warningLevel;//警告等级
|
|
|
|
|
private CurrentPTEnum currentPT;//当前点位
|
|
|
|
|
private CurrentStateEnum currentState;//当前状态
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 当前流程ID,暂停/继续时使用
|
|
|
|
|
/// </summary>
|
|
|
|
|
private int currProcessIndex = -1;
|
|
|
|
|
private Models.Product currProductModel = null;//当前产品
|
|
|
|
|
private System.Timers.Timer timer = new System.Timers.Timer();
|
|
|
|
|
Yolo_Class yolo = new Yolo_Class();
|
|
|
|
|
private class scannerCBmpLoc
|
|
|
|
|
{
|
|
|
|
|
public scannerCBmpLoc(string path, double posX, double posY)
|
|
|
|
|
{
|
|
|
|
|
Path = path;
|
|
|
|
|
PosX = posX;
|
|
|
|
|
PosY = posY;
|
|
|
|
|
}
|
|
|
|
|
public scannerCBmpLoc(Bitmap bmp, double posX, double posY)
|
|
|
|
|
{
|
|
|
|
|
BMP = bmp;
|
|
|
|
|
PosX = posX;
|
|
|
|
|
PosY = posY;
|
|
|
|
|
}
|
|
|
|
|
public Bitmap BMP { get; private set; }
|
|
|
|
|
public string Path { get; private set; }
|
|
|
|
|
public double PosX { get; private set; }
|
|
|
|
|
public double PosY { get; private set; }
|
|
|
|
|
}
|
|
|
|
|
public FrmMain()
|
|
|
|
|
{
|
|
|
|
|
InitializeComponent();
|
|
|
|
|
this.tsbtnCloseDev.Visible = false;
|
|
|
|
|
|
|
|
|
|
this.dgvProcess.AutoGenerateColumns = false;
|
|
|
|
|
//显示行号与列宽度自动调整
|
|
|
|
|
dgvProcess.RowHeadersVisible = true;
|
|
|
|
|
dgvProcess.RowHeadersWidth = 30;
|
|
|
|
|
dgvProcess.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.DisableResizing;
|
|
|
|
|
//dgvProcess.RowHeadersWidthSizeMode = DataGridViewRowHeadersWidthSizeMode.AutoSizeToAllHeaders;//数据量过百绑定太变
|
|
|
|
|
dgvProcess.RowPostPaint += (sender, e) =>//序号列头
|
|
|
|
|
{
|
|
|
|
|
Utils.Util.showRowNum_onDataGrid_RowPostPaint(this.dgvProcess, sender, e);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < dgvProcess.Columns.Count; i++)//禁止点击列头排序
|
|
|
|
|
dgvProcess.Columns[i].SortMode = DataGridViewColumnSortMode.NotSortable;
|
|
|
|
|
|
|
|
|
|
//模糊查询,Append自动填充
|
|
|
|
|
this.cbxSN.AutoCompleteMode = AutoCompleteMode.SuggestAppend;
|
|
|
|
|
this.cbxSN.AutoCompleteSource = AutoCompleteSource.ListItems;
|
|
|
|
|
}
|
|
|
|
|
private void FrmMain_Load(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
this.tsbtnPause.Left = this.tsbtnGoDownPT.Left = this.gpbZAxis.Right + 10;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
private void FrmMain_FormClosing(object sender, FormClosingEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
if (devContainer.state)
|
|
|
|
|
{
|
|
|
|
|
MessageBox.Show("请先停止设备后才能关闭程序!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
|
|
|
|
e.Cancel = true;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!bExitApp && MessageBox.Show($"确认退出?", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Question) != DialogResult.Yes)
|
|
|
|
|
{
|
|
|
|
|
e.Cancel = true;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
private void FrmMain_FormClosed(object sender, FormClosedEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
Application.Exit();
|
|
|
|
|
System.GC.Collect();
|
|
|
|
|
System.Environment.Exit(0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#region 菜单
|
|
|
|
|
private void 设备调试ToolStripMenuItem_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
if (devContainer.state)
|
|
|
|
|
{
|
|
|
|
|
MessageBox.Show("请先停止设备,再进行设备调试!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
FrmDebug3 frm = new FrmDebug3();
|
|
|
|
|
frm.ShowDialog();
|
|
|
|
|
}
|
|
|
|
|
private void tsMenuPTSetting_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
if (devContainer.state)
|
|
|
|
|
{
|
|
|
|
|
MessageBox.Show("请先停止设备,再进行设置!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
FrmPTSetting from = new FrmPTSetting();
|
|
|
|
|
from.ShowDialog();
|
|
|
|
|
}
|
|
|
|
|
private void tsMenuCmdSetting_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
if (devContainer.state)
|
|
|
|
|
{
|
|
|
|
|
MessageBox.Show("请先停止设备,再进行设置!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
FrmCMDProcess from = new FrmCMDProcess();
|
|
|
|
|
from.ShowDialog();
|
|
|
|
|
}
|
|
|
|
|
private void tsMenuSysSetting_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
FrmSysSetting frmSetting = new FrmSysSetting();
|
|
|
|
|
frmSetting.ShowDialog();
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
#region 图片缩放控制
|
|
|
|
|
private void reloadPic(Bitmap bmp, List<List<string>> defectInfor2RepairTable, DefectStruct defectInfo)
|
|
|
|
|
{
|
|
|
|
|
//绘框
|
|
|
|
|
if (defectInfor2RepairTable != null && defectInfo != null)
|
|
|
|
|
{
|
|
|
|
|
AddTextEvent("更新图片", $"打标:MainX={defectInfo.MainX},MainY={defectInfo.MainY},CurrIndex={defectInfo.CurrIndex},RepairTable={JsonConvert.SerializeObject(defectInfor2RepairTable)}", warningLevel);
|
|
|
|
|
Mat mat = OpenCvSharp.Extensions.BitmapConverter.ToMat(bmp);
|
|
|
|
|
mat = yolo.RepairTableDrawRec(defectInfor2RepairTable, defectInfo.MainX, defectInfo.MainY, defectInfo.CurrIndex, mat);
|
|
|
|
|
bmp = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(mat);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
AddTextEvent("更新图片", "无需打标!", warningLevel);
|
|
|
|
|
var newSize = Util.getNewSize(splitContainer2.Panel1.ClientSize, new Size(bmp.Size.Width*100, bmp.Size.Height*100));
|
|
|
|
|
this.pnlPic.Size = newSize;
|
|
|
|
|
if (this.pnlPic.Width < splitContainer2.Panel1.ClientSize.Width)
|
|
|
|
|
this.pnlPic.Left = (splitContainer2.Panel1.ClientSize.Width - this.pnlPic.Width) / 2;
|
|
|
|
|
if (this.pnlPic.Height < splitContainer2.Panel1.ClientSize.Height)
|
|
|
|
|
this.pnlPic.Top = (splitContainer2.Panel1.ClientSize.Height - this.pnlPic.Height) / 2;
|
|
|
|
|
|
|
|
|
|
ratio = 1.0;// 图片的起始显示比例
|
|
|
|
|
Size size = bmp.Size;
|
|
|
|
|
|
|
|
|
|
//this.pnlPic.ClientSize = new Size(this.pnlPic.ClientSize.Width,
|
|
|
|
|
// (int)(this.pnlPic.ClientSize.Width * (size.Height * 1.0f / size.Width)));
|
|
|
|
|
this.pictureBox1.Size = this.pnlPic.ClientSize;
|
|
|
|
|
this.pictureBox1.Location = new Point(0, 0);
|
|
|
|
|
this.pictureBox1.Image = bmp;//del
|
|
|
|
|
|
|
|
|
|
pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom;
|
|
|
|
|
//2023-12-22 之前工程师写的,存在bug,屏蔽
|
|
|
|
|
pictureBox1.MouseWheel += new MouseEventHandler(pictureBox1_MouseWheel);
|
|
|
|
|
pictureBox1.MouseMove += pictureBox1_MouseMove;
|
|
|
|
|
pictureBox1.MouseDown += pictureBox1_MouseDown;
|
|
|
|
|
this.ActiveControl = this.pictureBox1; // 设置焦点
|
|
|
|
|
|
|
|
|
|
pic_size = this.pnlPic.ClientSize;
|
|
|
|
|
}
|
|
|
|
|
private void pictureBox1_MouseWheel(object sender, MouseEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
//Point pictureBoxPoint = this.PointToClient(Cursor.Position);
|
|
|
|
|
////this.Text = $"{e.X}:{e.Y}; {pictureBoxPoint.X}:{pictureBoxPoint.Y}; {pictureBox1.Left}:{pictureBox1.Top}; " +
|
|
|
|
|
//// $"{this.pictureBox1.Width}:{this.pictureBox1.Height}; {this.Width}:{this.Height}; " +
|
|
|
|
|
//// $"Cursor:{Cursor.Position.X}:{Cursor.Position.Y}";
|
|
|
|
|
//if (e.Delta > 0)
|
|
|
|
|
//{
|
|
|
|
|
// ratio += ratioStep;
|
|
|
|
|
// if (ratio > 100) // 放大上限
|
|
|
|
|
// ratio = 100;
|
|
|
|
|
// else
|
|
|
|
|
// {
|
|
|
|
|
// int x = (int)(pictureBox1.Left - e.X * (e.X * 1.0d / pictureBox1.Width * ratioStep) + 0.5);
|
|
|
|
|
// int y = (int)(pictureBox1.Top - e.Y * (e.Y * 1.0d / pictureBox1.Height * ratioStep) + 0.5);
|
|
|
|
|
|
|
|
|
|
// //this.Text = $"{pictureBox1.Width}-{pic_size.Width};{ratio},{pictureBox1.Left}-{e.X}* 比例:{e.X*1.0d/pictureBox1.Width}={e.X}/{pictureBox1.Width} * {(ratioStep)}={x} | " +
|
|
|
|
|
// // $"{pictureBox1.Top}-{e.Y}* {e.Y * 1.0f / pictureBox1.Height * (ratio - 1.0d)}={y}";
|
|
|
|
|
// this.changePictureBoxSize(new Point(x, y), ratio);
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
//}
|
|
|
|
|
//else if (ratio - ratioStep >= 1)
|
|
|
|
|
//{
|
|
|
|
|
// ratio -= ratioStep;
|
|
|
|
|
// //if (ratio < 0.1) // 放大下限
|
|
|
|
|
// // ratio = 0.1;
|
|
|
|
|
// //else
|
|
|
|
|
// int x = (int)(pictureBox1.Left + e.X * (e.X * 1.0d / pictureBox1.Width * ratioStep) + 0.5);
|
|
|
|
|
// int y = (int)(pictureBox1.Top + e.Y * (e.Y * 1.0d / pictureBox1.Height * ratioStep) + 0.5);
|
|
|
|
|
// this.changePictureBoxSize(new Point(x, y), ratio);
|
|
|
|
|
//}
|
|
|
|
|
}
|
|
|
|
|
private void changePictureBoxSize(Point location, double ratio)
|
|
|
|
|
{
|
|
|
|
|
//var picSize = pictureBox1.Size;
|
|
|
|
|
//picSize.Width = Convert.ToInt32(picSize.Width * ratio);
|
|
|
|
|
//picSize.Height = Convert.ToInt32(picSize.Height * ratio);
|
|
|
|
|
//pictureBox1.Size = picSize;
|
|
|
|
|
|
|
|
|
|
//if (location.X > 0) location.X = 0;
|
|
|
|
|
//if (location.Y > 0) location.Y = 0;
|
|
|
|
|
//if (picSize.Width + location.X < this.pnlPic.ClientSize.Width) location.X = -(picSize.Width - this.pnlPic.ClientSize.Width);
|
|
|
|
|
//if (picSize.Height + location.Y < this.pnlPic.ClientSize.Height) location.Y = -(picSize.Height - this.pnlPic.ClientSize.Height);
|
|
|
|
|
|
|
|
|
|
////Point location = new Point();
|
|
|
|
|
////location.X = (this.ClientSize.Width - this.pictureBox1.Width) / 2;
|
|
|
|
|
////location.Y = (this.ClientSize.Height - this.pictureBox1.Height) / 2;
|
|
|
|
|
//this.pictureBox1.Location = location;
|
|
|
|
|
}
|
|
|
|
|
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
//try
|
|
|
|
|
//{
|
|
|
|
|
// // 鼠标按下拖拽图片
|
|
|
|
|
// if (e.Button == MouseButtons.Left)
|
|
|
|
|
// {
|
|
|
|
|
// this.Text = $"{e.X}:{e.Y};{xPos}:{yPos}";
|
|
|
|
|
// // 限制拖拽出框
|
|
|
|
|
// if (pictureBox1.Width > this.pnlPic.ClientSize.Width
|
|
|
|
|
// || pictureBox1.Height > this.pnlPic.ClientSize.Height)
|
|
|
|
|
// {
|
|
|
|
|
// int moveX = e.X - xPos;
|
|
|
|
|
// int moveY = e.Y - yPos;
|
|
|
|
|
// if ((pictureBox1.Left + moveX) <= 0
|
|
|
|
|
// && (pictureBox1.Top + moveY) <= 0
|
|
|
|
|
// && (pictureBox1.Right + moveX) >= this.pnlPic.ClientSize.Width
|
|
|
|
|
// && (pictureBox1.Bottom + moveY) >= this.pnlPic.ClientSize.Height)
|
|
|
|
|
// {
|
|
|
|
|
// pictureBox1.Left += moveX;//设置x坐标.
|
|
|
|
|
// pictureBox1.Top += moveY;//设置y坐标.
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
//}
|
|
|
|
|
//catch (Exception dd)
|
|
|
|
|
//{
|
|
|
|
|
// MessageBox.Show(dd.Message);
|
|
|
|
|
//}
|
|
|
|
|
}
|
|
|
|
|
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
//xPos = e.X;//当前x坐标.
|
|
|
|
|
//yPos = e.Y;//当前y坐标.
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region 中断命令Fun
|
|
|
|
|
private Thread threadProcess;
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 启动
|
|
|
|
|
/// </summary>
|
|
|
|
|
private void startCommand()
|
|
|
|
|
{
|
|
|
|
|
if (!devContainer.state || warningLevel != WarningEnum.Normal || currentState != CurrentStateEnum.等待启动)
|
|
|
|
|
return;
|
|
|
|
|
if (currentPT == CurrentPTEnum.MakeTag)
|
|
|
|
|
{
|
|
|
|
|
AddTextEvent("启动", "打标未结束,非可启动状态!", warningLevel);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!devContainer.devAxis.isReady())
|
|
|
|
|
{
|
|
|
|
|
AddTextEvent("启动", "轴状态异常,不可启动!", warningLevel);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (!devContainer.devAxis.IsReset)
|
|
|
|
|
{
|
|
|
|
|
AddTextEvent("启动", "轴需先进行复位操作!", WarningEnum.High);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
devContainer.io_output(CMDName.启动按钮);
|
|
|
|
|
//devContainer.io_output(CMDName.绿灯输出);
|
|
|
|
|
//devContainer.io_output(CMDName.暂停按钮, false, true, 0);
|
|
|
|
|
//devContainer.io_output(CMDName.红灯输出, false, true, 0);
|
|
|
|
|
//devContainer.io_output(CMDName.黄灯输出, false, true, 0);
|
|
|
|
|
|
|
|
|
|
//暂停-》继续
|
|
|
|
|
if (currProcessIndex >= 0 && currentPT == CurrentPTEnum.Moving && currentState == CurrentStateEnum.等待启动)
|
|
|
|
|
{
|
|
|
|
|
AddTextEvent("启动", $"暂停 -> 继续 当前工序索引:{currProcessIndex + 1}");
|
|
|
|
|
threadProcess = new System.Threading.Thread(() =>
|
|
|
|
|
{
|
|
|
|
|
int nextStepId = currProcessIndex;
|
|
|
|
|
do
|
|
|
|
|
{
|
|
|
|
|
currentState = CurrentStateEnum.运行中;
|
|
|
|
|
nextStepId = nextProcess(currProductModel, nextStepId);
|
|
|
|
|
} while (nextStepId >= 0 && !isBreakProcessRun());
|
|
|
|
|
//nextProcess(currProductModel, currProcessIndex);
|
|
|
|
|
});
|
|
|
|
|
threadProcess.IsBackground = true;
|
|
|
|
|
threadProcess.Start();
|
|
|
|
|
this.setButtonEnabled(this.tsbtnPause, true);
|
|
|
|
|
this.setButtonEnabled(this.tsbtnStopNow, true);
|
|
|
|
|
}
|
|
|
|
|
else//开始/重新开始
|
|
|
|
|
{
|
|
|
|
|
//校正从复位-》运行,不会新启动
|
|
|
|
|
resetUIValue();
|
|
|
|
|
AddTextEvent("启动", "移动至上料位...");
|
|
|
|
|
Task.Run(() => { loadOrderSNList(); });//加载SN
|
|
|
|
|
gotoUpPT();
|
|
|
|
|
|
|
|
|
|
this.Invoke(new System.Action(() =>
|
|
|
|
|
{
|
|
|
|
|
//新开始
|
|
|
|
|
runStep();
|
|
|
|
|
}));
|
|
|
|
|
this.setButtonEnabled(this.tsbtnPause, false);
|
|
|
|
|
this.setButtonEnabled(this.tsbtnStopNow, false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.setButtonEnabled(this.tsbtnStart, false);
|
|
|
|
|
this.setButtonEnabled(this.tsbtnReset, false);
|
|
|
|
|
this.setButtonEnabled(this.tsbtnGoDownPT, false);
|
|
|
|
|
}
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 暂停
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="buzzer">是否响蜂鸣</param>
|
|
|
|
|
private void pauseCommand(bool buzzer = false)
|
|
|
|
|
{
|
|
|
|
|
//devContainer.io_output(CMDName.暂停按钮);
|
|
|
|
|
//if (buzzer)
|
|
|
|
|
//{
|
|
|
|
|
// devContainer.io_output(CMDName.红灯输出);
|
|
|
|
|
// devContainer.io_output(CMDName.蜂鸣器输出);
|
|
|
|
|
//}
|
|
|
|
|
//else
|
|
|
|
|
// devContainer.io_output(CMDName.黄灯输出);
|
|
|
|
|
devContainer.io_output(CMDName.启动按钮, false, true, 0);
|
|
|
|
|
//devContainer.io_output(CMDName.绿灯输出, false, true, 0);
|
|
|
|
|
|
|
|
|
|
this.setButtonEnabled(this.tsbtnWarning, true);
|
|
|
|
|
this.setButtonEnabled(this.tsbtnGoDownPT, false);
|
|
|
|
|
this.setButtonEnabled(this.tsbtnStart, false);
|
|
|
|
|
this.setButtonEnabled(this.tsbtnPause, false);
|
|
|
|
|
this.setButtonEnabled(this.tsbtnStopNow, false);
|
|
|
|
|
this.setButtonEnabled(this.tsbtnReset, false);
|
|
|
|
|
AddTextEvent("暂停", $"当前工序索引:{currProcessIndex + 1}", WarningEnum.Low);
|
|
|
|
|
}
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 急停
|
|
|
|
|
/// </summary>
|
|
|
|
|
private void stopNowCommand()
|
|
|
|
|
{
|
|
|
|
|
if (!devContainer.state)
|
|
|
|
|
{
|
|
|
|
|
this.setButtonEnabled(this.tsbtnStopNow, false);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//devContainer.io_output(CMDName.Y轴复位输出, false, true, 0);
|
|
|
|
|
//devContainer.io_output(CMDName.红灯输出);
|
|
|
|
|
//if (!this.disableBuzzer) devContainer.io_output(CMDName.蜂鸣器输出);
|
|
|
|
|
//devContainer.io_output(CMDName.暂停按钮, false, true, 0);
|
|
|
|
|
//devContainer.io_output(CMDName.黄灯输出, false, true, 0);
|
|
|
|
|
devContainer.io_output(CMDName.启动按钮, false, true, 0);
|
|
|
|
|
//devContainer.io_output(CMDName.绿灯输出, false, true, 0);
|
|
|
|
|
|
|
|
|
|
this.setButtonEnabled(this.tsbtnWarning, true);
|
|
|
|
|
this.setButtonEnabled(this.tsbtnGoDownPT, false);
|
|
|
|
|
this.setButtonEnabled(this.tsbtnStart, false);
|
|
|
|
|
this.setButtonEnabled(this.tsbtnPause, false);
|
|
|
|
|
this.setButtonEnabled(this.tsbtnStopNow, false);
|
|
|
|
|
this.setButtonEnabled(this.tsbtnReset, false);
|
|
|
|
|
if(currentState== CurrentStateEnum.运行中)
|
|
|
|
|
AddTextEvent("急停", $"当前工序索引:{currProcessIndex + 1}", WarningEnum.High);
|
|
|
|
|
else
|
|
|
|
|
AddTextEvent("急停", $"已急停,请人工处理。", WarningEnum.High);
|
|
|
|
|
}
|
|
|
|
|
private bool reseting = false;
|
|
|
|
|
private void resetCommand()
|
|
|
|
|
{
|
|
|
|
|
currentState = CurrentStateEnum.等待复位;
|
|
|
|
|
warningLevel = WarningEnum.Normal;
|
|
|
|
|
currentPT = CurrentPTEnum.InitPT;
|
|
|
|
|
this.Invoke(new System.Action(() =>
|
|
|
|
|
{
|
|
|
|
|
this.tsbtnWarning.Enabled = this.tsbtnGoDownPT.Enabled = this.tsbtnStart.Enabled
|
|
|
|
|
= this.tsbtnStopNow.Enabled = this.tsbtnPause.Enabled = this.tsbtnReset.Enabled
|
|
|
|
|
= this.gpbXYAxis.Enabled = gpbZAxis.Enabled = false;
|
|
|
|
|
}));
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
if (devContainer.state && !reseting)
|
|
|
|
|
{
|
|
|
|
|
reseting = true;
|
|
|
|
|
resetUIValue();
|
|
|
|
|
AddTextEvent("复位", $"设备复位中...");
|
|
|
|
|
|
|
|
|
|
this.setButtonEnabled(this.tsbtnReset, false);
|
|
|
|
|
if ((AxisState)devContainer.devAxis.AxState[0] == AxisState.STA_AX_EXT_JOG) devContainer.devAxis.closeJogMode(0);//关闭jog时自动停止
|
|
|
|
|
if ((AxisState)devContainer.devAxis.AxState[1] == AxisState.STA_AX_EXT_JOG) devContainer.devAxis.closeJogMode(1);//关闭jog时自动停止
|
|
|
|
|
// I/O reset后,输出默认状态
|
|
|
|
|
AddTextEvent("复位", $"I/O复位中...");
|
|
|
|
|
if (!devContainer.devIOCard.reset())
|
|
|
|
|
{
|
|
|
|
|
AddTextEvent("复位", "I/O板卡复位失败!", WarningEnum.High);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (!devContainer.io_output(CMDName.IO默认输出))
|
|
|
|
|
{
|
|
|
|
|
//AddTextEvent("复位", "I/O板卡复位默认值失败!", WarningEnum.High);
|
|
|
|
|
//return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//板卡复位输出灯
|
|
|
|
|
//devContainer.io_output(CMDName.复位按钮);
|
|
|
|
|
devContainer.io_output(CMDName.复位按钮, true);//闪
|
|
|
|
|
|
|
|
|
|
//goto ORG
|
|
|
|
|
AddTextEvent("复位", $"轴正在回原点...");
|
|
|
|
|
devContainer.devAxis.closeJogMode();
|
|
|
|
|
devContainer.devAxis.resetAxisState(-1);//reset state
|
|
|
|
|
//AddTextEvent("复位", $"重置轴状态...");
|
|
|
|
|
for (int i = 0; i < Config.Axis_HomeMode.Length; i++)
|
|
|
|
|
{
|
|
|
|
|
//到起始位速度使用回HOME速度
|
|
|
|
|
devContainer.devAxis.setAxisVelParam((double)Config.Axis_HomeVelLow[i], (double)Config.Axis_HomeVelHigh[i],
|
|
|
|
|
(double)Config.Axis_HomeAcc[i], (double)Config.Axis_HomeDec[i], i);
|
|
|
|
|
|
|
|
|
|
//devContainer.devAxis.setAxisVelParam(40000,200000,5000000, 5000000,i,true);
|
|
|
|
|
devContainer.devAxis.home(i, (uint)Config.Axis_HomeMode[i], (uint)Config.Axis_HomeDir[i]);
|
|
|
|
|
}
|
|
|
|
|
AddTextEvent("复位", $"等待轴状态完成...");
|
|
|
|
|
while (!devContainer.devAxis.isReady())
|
|
|
|
|
{
|
|
|
|
|
if (!devContainer.state || currentState != CurrentStateEnum.等待复位)
|
|
|
|
|
{
|
|
|
|
|
AddTextEvent("复位", $"当前状态:" + ((CurrentStateEnum)currentState).ToString());
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
//AddTextEvent("复位", $"轴0状态:"+ ((AxisState)devContainer.devAxis.AxState[0]).ToString());
|
|
|
|
|
//AddTextEvent("复位", $"轴1状态:" + ((AxisState)devContainer.devAxis.AxState[1]).ToString());
|
|
|
|
|
//AddTextEvent("复位", $"轴2状态:" + ((AxisState)devContainer.devAxis.AxState[2]).ToString());
|
|
|
|
|
//AddTextEvent("复位", $"轴3状态:" + ((AxisState)devContainer.devAxis.AxState[3]).ToString());
|
|
|
|
|
|
|
|
|
|
Thread.Sleep(1000);
|
|
|
|
|
//Application.DoEvents();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
if (devContainer.devAxis.isError())
|
|
|
|
|
throw new Exception("轴回原点失败!");
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
//goto InitPT
|
|
|
|
|
AddTextEvent("复位", $"轴回原点完成,回到初始位...");
|
|
|
|
|
JArray arrPT = Config.joPTSetting.Value<JArray>("initPT");
|
|
|
|
|
for (int i = 0; i < arrPT.Count; i++)
|
|
|
|
|
{
|
|
|
|
|
if (!devContainer.state || currentState != CurrentStateEnum.等待复位)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
AddTextEvent($"复位", $"轴{i}准备运动至初始位:{(double)arrPT[i]}(当前轴状态:{((AxisState)devContainer.devAxis.AxState[i]).ToString()})...");
|
|
|
|
|
devContainer.devAxis.move_ptp(i, (double)arrPT[i], AxMoveMode.MODE1_Abs);
|
|
|
|
|
}
|
|
|
|
|
while (!devContainer.devAxis.isReady())
|
|
|
|
|
{
|
|
|
|
|
if (!devContainer.state || warningLevel != WarningEnum.Normal)
|
|
|
|
|
return;
|
|
|
|
|
Thread.Sleep(100);
|
|
|
|
|
//Application.DoEvents();
|
|
|
|
|
}
|
|
|
|
|
if (devContainer.devAxis.isError())
|
|
|
|
|
throw new Exception("轴移动至初始位失败!");
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
this.setButtonEnabled(this.tsbtnReset, true);
|
|
|
|
|
this.setButtonEnabled(this.tsbtnStart, true);
|
|
|
|
|
this.setButtonEnabled(this.tsbtnStopNow, true);
|
|
|
|
|
this.setButtonEnabled(this.tsbtnPause, false);
|
|
|
|
|
this.setButtonEnabled(this.tsbtnGoDownPT, false);
|
|
|
|
|
this.setButtonEnabled(this.tsbtnWarning, false);
|
|
|
|
|
this.setButtonEnabled(this.cbxSN, false);
|
|
|
|
|
|
|
|
|
|
this.Invoke(new System.Action(() =>
|
|
|
|
|
{//根据UI上是否勾选打开激光
|
|
|
|
|
chkLaser_CheckedChanged(null, null);
|
|
|
|
|
}));
|
|
|
|
|
//devContainer.io_output(CMDName.复位按钮, false, true, 0);//熄灭
|
|
|
|
|
devContainer.io_output(CMDName.复位按钮);//长亮
|
|
|
|
|
currentPT = CurrentPTEnum.InitPT;
|
|
|
|
|
currentState = CurrentStateEnum.等待启动;
|
|
|
|
|
AddTextEvent("复位", $"复位完成。");
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
AddTextEvent("复位", "非可复位状态,请先停止后再复位!", WarningEnum.High);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
AddTextEvent("复位", "复位失败 Err:" + ex.Message, WarningEnum.High);
|
|
|
|
|
warning(WarningEnum.High, true);
|
|
|
|
|
}
|
|
|
|
|
finally
|
|
|
|
|
{
|
|
|
|
|
reseting = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 上料
|
|
|
|
|
/// </summary>
|
|
|
|
|
private void gotoUpPT()
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
JArray arrPT = Config.joPTSetting.Value<JArray>("upPT");
|
|
|
|
|
for (int i = 0; i < arrPT.Count; i++)
|
|
|
|
|
{
|
|
|
|
|
if (!devContainer.state || warningLevel != WarningEnum.Normal)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
AddTextEvent($"上料", $"轴{i}准备运动至上料位:{(double)arrPT[i]}(当前轴状态:{((AxisState)devContainer.devAxis.AxState[i]).ToString()})...");
|
|
|
|
|
devContainer.devAxis.move_ptp(i, (double)arrPT[i], AxMoveMode.MODE1_Abs);
|
|
|
|
|
}
|
|
|
|
|
while (!devContainer.devAxis.isReady())
|
|
|
|
|
{
|
|
|
|
|
if (!devContainer.state || warningLevel != WarningEnum.Normal)
|
|
|
|
|
return;
|
|
|
|
|
Thread.Sleep(100);
|
|
|
|
|
}
|
|
|
|
|
if (devContainer.devAxis.isError())
|
|
|
|
|
throw new Exception("轴移动至上料位失败!");
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
currentPT = CurrentPTEnum.UpPT;
|
|
|
|
|
currentState = CurrentStateEnum.等待扫码;
|
|
|
|
|
this.setButtonEnabled(cbxSN, true);
|
|
|
|
|
AddTextEvent($"上料", "到达上料位!");
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
AddTextEvent("上料", "上料初始失败 Err:" + ex.Message, WarningEnum.High);
|
|
|
|
|
warning(WarningEnum.High);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 下料(暂当完成)
|
|
|
|
|
/// </summary>
|
|
|
|
|
private void gotoDownPT()
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
AddTextEvent("下料", "检测状态...");
|
|
|
|
|
if (!devContainer.state || warningLevel != WarningEnum.Normal)
|
|
|
|
|
{
|
|
|
|
|
AddTextEvent("下料失败", "轴状态异常!", WarningEnum.Low);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
AddTextEvent("下料", "开始下料!");
|
|
|
|
|
if (!devContainer.devAxis.isReady())
|
|
|
|
|
{
|
|
|
|
|
AddTextEvent("下料失败", "轴状态异常!", WarningEnum.Low);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (currentState != CurrentStateEnum.打标中 && currentState != CurrentStateEnum.等待启动 && currentState != CurrentStateEnum.自动流程结束)
|
|
|
|
|
{
|
|
|
|
|
AddTextEvent($"下料", $"非可下料状态:{currentState.ToString()}");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
currentState = CurrentStateEnum.下料中;
|
|
|
|
|
|
|
|
|
|
JArray arrPT = Config.joPTSetting.Value<JArray>("downPT");
|
|
|
|
|
for (int i = 0; i < arrPT.Count; i++)
|
|
|
|
|
{
|
|
|
|
|
if (!devContainer.state || warningLevel != WarningEnum.Normal || currentState != CurrentStateEnum.下料中)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
AddTextEvent($"下料", $"轴{i}准备运动至下料位:{(double)arrPT[i]}(当前轴状态:{((AxisState)devContainer.devAxis.AxState[i]).ToString()})...");
|
|
|
|
|
devContainer.devAxis.move_ptp(i, (double)arrPT[i], AxMoveMode.MODE1_Abs);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
while (!devContainer.devAxis.isReady())
|
|
|
|
|
{
|
|
|
|
|
if (!devContainer.state || warningLevel != WarningEnum.Normal || currentState != CurrentStateEnum.下料中)
|
|
|
|
|
return;
|
|
|
|
|
Thread.Sleep(100);
|
|
|
|
|
}
|
|
|
|
|
if (devContainer.devAxis.isError())
|
|
|
|
|
throw new Exception("轴移动至下料位失败!");
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
currentPT = CurrentPTEnum.DownPT;
|
|
|
|
|
currentState = CurrentStateEnum.等待启动;
|
|
|
|
|
devContainer.io_output(CMDName.启动按钮, false, true, 0);
|
|
|
|
|
devContainer.devLight.setDigitalValue(1, 0);//关闭上光源
|
|
|
|
|
devContainer.devLight.setDigitalValue(2, 0);//关闭下光源
|
|
|
|
|
this.Invoke(new System.Action(() =>
|
|
|
|
|
{
|
|
|
|
|
this.chkLaser.Checked = false;
|
|
|
|
|
this.gpbXYAxis.Enabled = gpbZAxis.Enabled = false;
|
|
|
|
|
}));
|
|
|
|
|
setButtonEnabled(tsbtnStart, true);
|
|
|
|
|
setButtonEnabled(tsbtnGoDownPT, false);
|
|
|
|
|
AddTextEvent($"下料", "下料完成!");
|
|
|
|
|
|
|
|
|
|
//更新指定列
|
|
|
|
|
//2023-10-31 加入异常情况
|
|
|
|
|
FrmRepairInfo frmInfo = new FrmRepairInfo();
|
|
|
|
|
DialogResult dr = frmInfo.ShowDialog();
|
|
|
|
|
|
|
|
|
|
if (svcOrder.Update(it => new Order() {
|
|
|
|
|
State = dr == DialogResult.OK? 10 :5 ,
|
2023-11-01 15:13:54 +08:00
|
|
|
|
Abnormalities = frmInfo.RepairInfo,
|
|
|
|
|
RepairCode = Config.loginUser.Code
|
2024-03-04 10:23:01 +08:00
|
|
|
|
}, it => it.Id == OrderId))
|
|
|
|
|
AddTextEvent($"检测结束", $"保存检测结果成功。");
|
|
|
|
|
else
|
|
|
|
|
AddTextEvent($"检测结束", $"保存检测结果失败!",WarningEnum.High);
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
AddTextEvent("下料", "下料失败 Err:" + ex.Message, WarningEnum.High);
|
|
|
|
|
warning(WarningEnum.High);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
private void openLowerLight()//下光源
|
|
|
|
|
{
|
|
|
|
|
var value = devContainer.devLight.getDigitalValue(2);
|
|
|
|
|
devContainer.devLight.setDigitalValue(2, value == 0 ? 255 : 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void setButtonEnabled(ToolStripButton button, bool Enabled)
|
|
|
|
|
{
|
|
|
|
|
this.Invoke(new System.Action(() =>
|
|
|
|
|
{
|
|
|
|
|
button.Enabled = Enabled;
|
|
|
|
|
}));
|
|
|
|
|
}
|
|
|
|
|
private void setButtonEnabled(ToolStripMenuItem button, bool Enabled)
|
|
|
|
|
{
|
|
|
|
|
this.Invoke(new System.Action(() =>
|
|
|
|
|
{
|
|
|
|
|
button.Enabled = Enabled;
|
|
|
|
|
}));
|
|
|
|
|
}
|
|
|
|
|
private void setButtonEnabled(Control button, bool Enabled)
|
|
|
|
|
{
|
|
|
|
|
this.Invoke(new System.Action(() =>
|
|
|
|
|
{
|
|
|
|
|
button.Enabled = Enabled;
|
|
|
|
|
}));
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
#region 自动流程 nextProcess
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 中断工序运行
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
private bool isBreakProcessRun()
|
|
|
|
|
{
|
|
|
|
|
return warningLevel != WarningEnum.Normal || currentState != CurrentStateEnum.运行中;
|
|
|
|
|
}
|
|
|
|
|
private void runStep()
|
|
|
|
|
{
|
|
|
|
|
sizeBmpNum = sizeBmpNumResult = 0;
|
|
|
|
|
AddTextEvent("启动", "等待网版编码扫码...");
|
|
|
|
|
if (devContainer.devCodeScanner != null)
|
|
|
|
|
{
|
|
|
|
|
devContainer.devCodeScanner.stop();
|
|
|
|
|
devContainer.devCodeScanner = null;
|
|
|
|
|
}
|
|
|
|
|
devContainer.devCodeScanner = new CodeScannerDev();
|
|
|
|
|
if (!devContainer.devCodeScanner.start())
|
|
|
|
|
{
|
|
|
|
|
AddTextEvent("扫码枪", "扫码枪初始化失败!");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
devContainer.devCodeScanner.ScanerEvent = (code) =>
|
|
|
|
|
{
|
|
|
|
|
if (devContainer.devCodeScanner.isLock ||!devContainer.state
|
|
|
|
|
|| currentState != CurrentStateEnum.等待扫码 || string.IsNullOrWhiteSpace(code) )
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
devContainer.devCodeScanner.isLock = true;
|
|
|
|
|
Thread threadtest = new System.Threading.Thread(() =>
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
//注:需要重复输入SN时不能在此释放
|
|
|
|
|
//devContainer.devCodeScanner.stop();
|
|
|
|
|
//devContainer.devCodeScanner = null;
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
AddTextEvent("扫码枪", $"开始读取网版编码:{code} 数据...");
|
|
|
|
|
var modOrder = svcOrder.GetModelNav(code);//from sn
|
|
|
|
|
//AddTextEvent("扫码枪", $"读取网版编码:{code}DB数据完成");
|
|
|
|
|
string modeState = "";
|
|
|
|
|
if (modOrder == null)
|
|
|
|
|
AddTextEvent("扫码枪", $"网版编码{code}不存在!");
|
|
|
|
|
if (modOrder.State == 5)
|
|
|
|
|
{
|
|
|
|
|
modeState = $"网版编码{code}已被检测!";
|
|
|
|
|
AddTextEvent("扫码枪", $"网版编码{code}已被检测!");
|
|
|
|
|
loadOrderSNList();
|
|
|
|
|
}
|
|
|
|
|
else if (modOrder.State == 10)
|
|
|
|
|
{
|
|
|
|
|
modeState = $"网版编码{code}已被检测, 并且异常!";
|
2023-11-01 15:13:54 +08:00
|
|
|
|
AddTextEvent("扫码枪", $"网版编码{code}已被检测, 并且异常!");
|
|
|
|
|
loadOrderSNList();
|
2024-03-04 10:23:01 +08:00
|
|
|
|
}
|
2023-11-01 15:13:54 +08:00
|
|
|
|
if(!string.IsNullOrEmpty(modeState))
|
|
|
|
|
{
|
|
|
|
|
if(DialogResult.No == MessageBox.Show(modeState + "是否重新检测!", "网版已被检测", MessageBoxButtons.YesNo, MessageBoxIcon.Information))
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
2024-03-04 10:23:01 +08:00
|
|
|
|
}
|
|
|
|
|
//2023-10-20
|
|
|
|
|
//else if (modOrder.ProductInfo == null)
|
|
|
|
|
if (modOrder.ProductInfo == null)
|
|
|
|
|
AddTextEvent("扫码枪", $"网版编码:{code}对应产品信息已不存在!");
|
|
|
|
|
else if (modOrder.DefectCount < 1)
|
|
|
|
|
AddTextEvent("扫码枪", $"网版编码:{code}没有缺陷!");
|
|
|
|
|
//else if (string.IsNullOrWhiteSpace(modOrder.MarkData))
|
|
|
|
|
// AddTextEvent("扫码枪", $"产品(网版编码:{code})在主机台未保存原始Mark点!");
|
|
|
|
|
else if (modOrder.ProductInfo.AssistStepInfo == null
|
|
|
|
|
|| modOrder.ProductInfo.AssistStepInfo.ProcessList.Count < 1)
|
|
|
|
|
AddTextEvent("扫码枪", $"产品({modOrder.ProductInfo.Name})未配置检测流程!");
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (string.IsNullOrWhiteSpace(modOrder.MarkData))
|
|
|
|
|
{
|
|
|
|
|
AddTextEvent("扫码枪", $"产品(网版编码:{code})在主机台未保存原始Mark点!");
|
|
|
|
|
modOrder.MarkData = "[0,0,0,0,0,0,0,0]";
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
AddTextEvent("主机台", $"主机台Mark数据:{modOrder.MarkData}");
|
|
|
|
|
currProductMarkList = JArray.Parse(modOrder.MarkData);
|
|
|
|
|
if (currProductMarkList.Count < 8)
|
|
|
|
|
{
|
|
|
|
|
AddTextEvent("主机台", $"产品(网版编码:{code})在主机台原始Mark点数量错误!");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
//异步读取
|
|
|
|
|
JObject parm = new JObject()
|
|
|
|
|
{
|
|
|
|
|
{"date",modOrder.CreateTime.ToString("yyyyMMdd") },
|
|
|
|
|
{"sn",code }
|
|
|
|
|
};
|
|
|
|
|
Task.Run(() => loadDefectInfo(parm));
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
devContainer.devCodeScanner.stop();
|
|
|
|
|
devContainer.devCodeScanner = null;
|
|
|
|
|
|
|
|
|
|
currentState = CurrentStateEnum.运行中;
|
|
|
|
|
currentPT = CurrentPTEnum.Moving;
|
|
|
|
|
currProductModel = modOrder.ProductInfo;
|
|
|
|
|
AddTextEvent("扫码枪", $"网版编码:{code}({currProductModel.Name} {currProductModel.Spec} [{currProductModel.Code}])");
|
|
|
|
|
this.Invoke(new System.Action(() =>
|
|
|
|
|
{
|
|
|
|
|
this.cbxSN.Enabled = false;
|
|
|
|
|
this.txtBatchId.Text = modOrder.BatchId.ToString();
|
|
|
|
|
this.txtProductName.Text = currProductModel.Name;
|
|
|
|
|
this.txtProductCode.Text = currProductModel.Code;
|
|
|
|
|
this.txtCreateTime.Text = modOrder.CreateTime.ToString("yyyy-MM-dd HH:mm");
|
|
|
|
|
//this.dgvProcess.DataSource = new BindingSource(currProductModel.StepInfo.ProcessList, null);
|
|
|
|
|
devContainer.libFor.clear();
|
|
|
|
|
devContainer.libIF.clear();
|
|
|
|
|
}));
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
this.SN = code;
|
|
|
|
|
this.OrderId = modOrder.Id;
|
|
|
|
|
this.setButtonEnabled(this.tsbtnPause, true);
|
|
|
|
|
this.setButtonEnabled(this.tsbtnStopNow, true);
|
|
|
|
|
devContainer.devLight.setDigitalValue(2, 255);//下光源
|
|
|
|
|
int nextStepId = 0;
|
|
|
|
|
do
|
|
|
|
|
{
|
|
|
|
|
nextStepId = nextProcess(currProductModel, nextStepId);
|
|
|
|
|
} while (nextStepId >= 0 && !isBreakProcessRun());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
AddTextEvent("扫码枪", $"读取网版编码信息失败:{ex.Message}");
|
|
|
|
|
}
|
|
|
|
|
finally
|
|
|
|
|
{
|
|
|
|
|
if (devContainer.devCodeScanner != null)
|
|
|
|
|
devContainer.devCodeScanner.isLock = false;
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
threadtest.IsBackground = true;
|
|
|
|
|
threadtest.Start();
|
|
|
|
|
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
private void loadDefectInfo(object parm)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
JObject req = (JObject)parm;
|
|
|
|
|
currDefectIndex = 0;
|
|
|
|
|
defectList.Clear();
|
|
|
|
|
defectInfoDir.Clear();
|
|
|
|
|
defectBmpsDir.Clear();
|
|
|
|
|
//从主机台取缺陷文件名列表和JSON数组
|
|
|
|
|
var obj = WebApi.getDefectFromSN(req);
|
|
|
|
|
if (obj.Value<int>("code") != 200)
|
|
|
|
|
throw new Exception(obj.Value<string>("data"));
|
|
|
|
|
//
|
|
|
|
|
var defectInfo = obj.Value<JObject>("data"); //文件名列表(主机台已对文件名排序,这里不需再排序(主机台按各自index进行的排序,比对在缺陷文件名后面)
|
|
|
|
|
if (defectInfo.Count < 1)
|
|
|
|
|
throw new Exception("主机台缺陷文件已不存在!");
|
|
|
|
|
|
|
|
|
|
//string date = req.Value<string>("date");
|
|
|
|
|
//string sn = req.Value<string>("sn");
|
|
|
|
|
getDefectBmpList(req, defectInfo);
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
AddTextEvent("网络访问",$"{ex.Message}",WarningEnum.High);
|
|
|
|
|
warning(WarningEnum.High);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 通过文件名列表取各文件名对应BMP
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="req"></param>
|
|
|
|
|
/// <param name="defectInfo">文件名列表</param>
|
|
|
|
|
private void getDefectBmpList(JObject req, JObject defectInfo)
|
|
|
|
|
{
|
|
|
|
|
int liStep = 0;
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
#region 这里转换绑定没实际用处,只是为了提前显示列表
|
|
|
|
|
foreach (var kv in defectInfo)
|
|
|
|
|
{
|
|
|
|
|
defectInfoDir.Add(kv.Key, JsonConvert.DeserializeObject<List<List<string>>>(kv.Value.ToString()));
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
//["4","3.9","-0.8","dk","0.39"],["index","X","Y","缺陷类型","缺陷的置信度"]
|
|
|
|
|
JArray arr = kv.Value as JArray;//二维数组
|
|
|
|
|
AddTextEvent("主机台", $"缺陷大项:{kv.Key},含小项:{arr.Count}.");
|
|
|
|
|
foreach (JArray arr2 in arr) {
|
|
|
|
|
var obj = new DefectStruct();
|
|
|
|
|
obj.Key = kv.Key;
|
|
|
|
|
obj.Index = Convert.ToInt32(arr2[0].ToString());
|
|
|
|
|
obj.X = Convert.ToDouble(arr2[1].ToString());
|
|
|
|
|
obj.Y = Convert.ToDouble(arr2[2].ToString());
|
|
|
|
|
obj.DefectName = Config.getDefectName(arr2[3].ToString());
|
|
|
|
|
obj.DefectCC = Convert.ToDouble(arr2[4].ToString());
|
|
|
|
|
defectList.Add(obj);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
this.Invoke(new System.Action(() =>
|
|
|
|
|
{
|
|
|
|
|
//注:这样绑定List中的对象必需得用{get;set;}方式定义属性,否则单独格为空内容
|
|
|
|
|
AddTextEvent("主机台", $"准备显示缺陷列表,共{defectList.Count}项.");
|
|
|
|
|
this.dgvProcess.DataSource = new BindingSource(defectList, null);
|
|
|
|
|
AddTextEvent("主机台", $"显示缺陷列表完成.");
|
|
|
|
|
this.gpbDefectList.Text = $"缺陷明细({defectList.Count}条)";
|
|
|
|
|
//2023-11-1 图纸对比缺陷标红
|
2023-11-01 15:13:54 +08:00
|
|
|
|
for (int i = 0; i < defectList.Count; i++)
|
|
|
|
|
{
|
|
|
|
|
string defName = (string)this.dgvProcess.Rows[i].Cells["colDefectName"].Value;
|
|
|
|
|
if ((defName == Config.getDefectName("ds"))||((defName == Config.getDefectName("yx"))))
|
|
|
|
|
this.dgvProcess.Rows[i].DefaultCellStyle.BackColor = Color.Red;
|
2024-03-04 10:23:01 +08:00
|
|
|
|
}
|
|
|
|
|
}));
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
req.Add("file_name", "");
|
|
|
|
|
liStep = 1;
|
|
|
|
|
bool first = true;
|
|
|
|
|
int index = 1;
|
|
|
|
|
foreach (var kv in defectInfo)
|
|
|
|
|
{
|
|
|
|
|
req["file_name"] = kv.Key;
|
|
|
|
|
var obj = WebApi.getDefectBmpBase64(req);
|
|
|
|
|
if (!devContainer.state || warningLevel == WarningEnum.High ||
|
|
|
|
|
(currentState != CurrentStateEnum.运行中 && currentState != CurrentStateEnum.暂停 && currentState != CurrentStateEnum.等待启动 && currentState != CurrentStateEnum.打标中))
|
|
|
|
|
return;
|
|
|
|
|
if (obj.Value<int>("code") != 200)
|
|
|
|
|
throw new Exception(obj.Value<string>("data"));
|
|
|
|
|
Bitmap bmp = new Bitmap(new MemoryStream(Convert.FromBase64String(obj.Value<string>("data"))));
|
|
|
|
|
defectBmpsDir.Add(kv.Key, bmp);
|
|
|
|
|
AddTextEvent("网络访问", $"已读取第{index++}/{defectInfo.Count}张缺陷图片;");
|
|
|
|
|
if (first)
|
|
|
|
|
{
|
|
|
|
|
first = false;
|
|
|
|
|
this.Invoke(new System.Action(() =>
|
|
|
|
|
{
|
|
|
|
|
this.reloadPic(bmp,null,null);
|
|
|
|
|
pictureBox1.Tag = kv.Key;
|
|
|
|
|
}));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
if (liStep == 0)
|
|
|
|
|
{
|
|
|
|
|
AddTextEvent("网络访问", $"解析主机缺陷报文失败:{ex.Message}",WarningEnum.High);
|
|
|
|
|
warning(WarningEnum.High);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
AddTextEvent("网络访问", $"读取主机台缺陷Bmp图片失败:{ex.Message}");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
private void convert2LocXY()
|
|
|
|
|
{
|
|
|
|
|
//AddTextEvent($"缺陷项", $"转换缺陷项坐标值...");
|
|
|
|
|
// public string Key;
|
|
|
|
|
//public string Key0;//index
|
|
|
|
|
//public string Key1;//X
|
|
|
|
|
//public string Key2;//Y
|
|
|
|
|
//public string Key3;//缺陷类型
|
|
|
|
|
//public string Key4;//缺陷的置信度
|
|
|
|
|
currDefectIndex = 0;
|
|
|
|
|
defectList.Clear();
|
|
|
|
|
double X, Y;
|
|
|
|
|
int MainIndex;
|
|
|
|
|
foreach (var item in defectInfoDir)
|
|
|
|
|
{
|
|
|
|
|
//Key : Defect_SN{order.SN}_I{res.index}_X{res.Xmm}_Y{res.Ymm}_C{res.defectCount}
|
|
|
|
|
string[] str = item.Key.Split('_');
|
|
|
|
|
MainIndex = Convert.ToInt32(str[2].Substring(1));
|
|
|
|
|
X = Convert.ToDouble(str[3].Substring(1));
|
|
|
|
|
Y = Convert.ToDouble(str[4].Substring(1));
|
|
|
|
|
|
|
|
|
|
AddTextEvent("主机台", $"转换前,缺陷大项:{item.Key},含小项:{item.Value.Count}.");
|
|
|
|
|
var arr = yolo.ImageXY2RepairTable(item.Value, X, Y, Config.SizeRepairTablePath);
|
|
|
|
|
AddTextEvent("主机台", $"转换后,缺陷大项:{item.Key},含小项:{arr.Count}.");
|
|
|
|
|
int i = 0;
|
|
|
|
|
foreach (var arr2 in arr)
|
|
|
|
|
{
|
|
|
|
|
var obj = new DefectStruct();
|
|
|
|
|
obj.Key = item.Key;
|
|
|
|
|
obj.CurrIndex = i++;
|
|
|
|
|
obj.MainIndex = MainIndex;
|
|
|
|
|
obj.MainX = X;
|
|
|
|
|
obj.MainY = Y;
|
|
|
|
|
obj.Index = Convert.ToInt32(arr2[0].ToString());
|
|
|
|
|
obj.X = Convert.ToDouble(arr2[1].ToString());
|
|
|
|
|
obj.Y = Convert.ToDouble(arr2[2].ToString());
|
|
|
|
|
obj.DefectName = Config.getDefectName(arr2[3].ToString());
|
|
|
|
|
obj.DefectCC = Convert.ToDouble(arr2[4].ToString());
|
|
|
|
|
defectList.Add(obj);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-06 09:51:15 +08:00
|
|
|
|
//2024-03-05 将尺寸未通过排到最前
|
|
|
|
|
for (int i = (defectList.Count - 1); i >=0 ; i--)
|
|
|
|
|
{
|
|
|
|
|
if (defectList[i].DefectName == Config.getDefectName("wtg"))
|
|
|
|
|
{
|
|
|
|
|
defectList.Insert(0, defectList[i]);
|
|
|
|
|
defectList.RemoveAt(i + 1);
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-03-04 10:23:01 +08:00
|
|
|
|
this.Invoke(new System.Action(() =>
|
|
|
|
|
{
|
|
|
|
|
this.dgvProcess.DataSource = null;
|
|
|
|
|
//注:这样绑定List中的对象必需得用{get;set;}方式定义属性,否则单独格为空内容
|
|
|
|
|
this.dgvProcess.DataSource = new BindingSource(defectList, null);
|
|
|
|
|
this.gpbDefectList.Text = $"缺陷明细({defectList.Count}条)";
|
|
|
|
|
}));
|
|
|
|
|
gotoDefctListIndex(currDefectIndex);
|
|
|
|
|
}
|
|
|
|
|
private void gotoDefctListIndex(int index,int preIndex=-1)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
AddTextEvent($"缺陷项", $"移至缺陷项:{index + 1}...");
|
|
|
|
|
this.Invoke(new System.Action(() =>
|
|
|
|
|
{
|
|
|
|
|
string key = defectList[index].Key;
|
|
|
|
|
if (defectBmpsDir.ContainsKey(key))
|
|
|
|
|
{
|
|
|
|
|
if (pictureBox1.Tag == null || pictureBox1.Tag.ToString() != key)
|
|
|
|
|
{
|
|
|
|
|
//reloadPic(defectBmpsDir[key], defectInfoDir[key], defectList[index]);
|
|
|
|
|
pictureBox1.Tag = key;
|
|
|
|
|
}
|
|
|
|
|
reloadPic(defectBmpsDir[key], defectInfoDir[key], defectList[index]);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
AddTextEvent($"缺陷项", $"缺陷图:{defectList[index].Key}还未传输完成!");
|
|
|
|
|
|
|
|
|
|
if (preIndex > -1)
|
|
|
|
|
this.dgvProcess.Rows[preIndex].DefaultCellStyle.BackColor = Color.White;
|
|
|
|
|
|
|
|
|
|
this.dgvProcess.Rows[index].DefaultCellStyle.BackColor = Color.LightGreen;
|
|
|
|
|
this.dgvProcess.Rows[index].Selected = true;
|
|
|
|
|
this.dgvProcess.CurrentCell = this.dgvProcess.Rows[index].Cells["colResult"];
|
|
|
|
|
this.dgvProcess.Rows[index].Cells["colResult"].Value = "已检";
|
|
|
|
|
}));
|
|
|
|
|
if ((defectList[index].X <= 0) || (defectList[index].Y <= 0))
|
|
|
|
|
{
|
|
|
|
|
AddTextEvent($"缺陷项", $"移动报错,当前缺陷项({index + 1})坐标:X{defectList[index].X},Y{defectList[index].Y}", WarningEnum.Low);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
while (!devContainer.devAxis.isReady(0)) Thread.Sleep(100);
|
|
|
|
|
devContainer.devAxis.move_ptp(0, defectList[index].X, AxMoveMode.MODE1_Abs);
|
|
|
|
|
while (!devContainer.devAxis.isReady(1)) Thread.Sleep(100);
|
|
|
|
|
devContainer.devAxis.move_ptp(1, defectList[index].Y, AxMoveMode.MODE1_Abs);
|
|
|
|
|
AddTextEvent($"缺陷项", $"移动完成,当前缺陷项({index + 1})坐标:X{defectList[index].X},Y{defectList[index].Y}");
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
AddTextEvent("缺陷项", "轴移动失败:" + ex.Message, WarningEnum.High);
|
|
|
|
|
warning(WarningEnum.High, true);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
private void gotoNextPic()
|
|
|
|
|
{
|
|
|
|
|
if (currDefectIndex>= defectList.Count-1) return;
|
|
|
|
|
this.Invoke(new System.Action(() =>
|
|
|
|
|
{
|
|
|
|
|
for(int i= currDefectIndex+1;i< defectList.Count; i++)
|
|
|
|
|
{
|
|
|
|
|
if (this.pictureBox1.Tag == null || this.pictureBox1.Tag.ToString() != defectList[i].Key)
|
|
|
|
|
{
|
|
|
|
|
AddTextEvent($"缺陷项", $"移至下张图:{i+1}...");
|
|
|
|
|
int preIndex = currDefectIndex;
|
|
|
|
|
currDefectIndex = i;
|
|
|
|
|
gotoDefctListIndex(currDefectIndex, preIndex);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}));
|
|
|
|
|
}
|
|
|
|
|
private void gotoPrePic()
|
|
|
|
|
{
|
|
|
|
|
if (currDefectIndex < 1) return;
|
|
|
|
|
this.Invoke(new System.Action(() =>
|
|
|
|
|
{
|
|
|
|
|
if (this.pictureBox1.Tag == null) return;
|
|
|
|
|
for (int i = currDefectIndex-1; i >=0; i--)
|
|
|
|
|
{
|
|
|
|
|
if (this.pictureBox1.Tag.ToString() != defectList[i].Key)
|
|
|
|
|
{
|
|
|
|
|
AddTextEvent($"缺陷项", $"移至上张图:{i + 1}...");
|
|
|
|
|
int preIndex = currDefectIndex;
|
|
|
|
|
currDefectIndex = i;
|
|
|
|
|
gotoDefctListIndex(currDefectIndex, preIndex);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}));
|
|
|
|
|
}
|
|
|
|
|
private class DefectStruct
|
|
|
|
|
{
|
|
|
|
|
//Defect_{order.SN}_{res.index}_X{res.Xmm}_Y{res.Ymm}
|
|
|
|
|
public string Key { get; set; }
|
|
|
|
|
public int CurrIndex { get; set; }//当前缺陷在本大图中的索引0-n
|
|
|
|
|
public int MainIndex { get; set; }//大图
|
|
|
|
|
public double MainX { get; set; }//大图X 大相机拍照时原始X,Y轴坐标
|
|
|
|
|
public double MainY { get; set; }//大图X
|
|
|
|
|
|
|
|
|
|
//["4","3.9","-0.8","dk","0.39"],["index","X","Y","缺陷类型","缺陷的置信度"]
|
|
|
|
|
public int Index { get; set; }
|
|
|
|
|
public double X { get; set; }
|
|
|
|
|
public double Y { get; set; }
|
|
|
|
|
public string DefectName { get; set; }//缺陷类型
|
|
|
|
|
public double DefectCC { get; set; }//缺陷的置信度
|
|
|
|
|
|
|
|
|
|
//2023-10-30 修复情况
|
|
|
|
|
public string Restoratory { get; set; }
|
|
|
|
|
}
|
|
|
|
|
private double[] convert(JArray data)
|
|
|
|
|
{
|
|
|
|
|
double[] result = new double[data.Count];
|
|
|
|
|
for (int i = 0; i < data.Count; i++)
|
|
|
|
|
result[i]=Convert.ToDouble(data[i]);
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 工序循环
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="model"></param>
|
|
|
|
|
/// <param name="stepIndex">0-n</param>
|
|
|
|
|
/// <returns>大于等于0正常工序; -1:结束 -2:异常</returns>
|
|
|
|
|
private int nextProcess(Models.Product model, int stepIndex)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
//记录当前index
|
|
|
|
|
this.currProcessIndex = stepIndex;
|
|
|
|
|
//this.Invoke(new System.Action(() =>
|
|
|
|
|
//{
|
|
|
|
|
// try
|
|
|
|
|
// {
|
|
|
|
|
// this.dgvProcess.Rows[stepIndex].Selected = true;
|
|
|
|
|
// dgvProcess.CurrentCell = dgvProcess.Rows[stepIndex].Cells[1];
|
|
|
|
|
// }
|
|
|
|
|
// catch { }
|
|
|
|
|
//}));
|
|
|
|
|
lock (myLock)
|
|
|
|
|
{
|
|
|
|
|
if (isBreakProcessRun())
|
|
|
|
|
return stepIndex;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var processList = model.AssistStepInfo.ProcessList;
|
|
|
|
|
var processInfo = processList[stepIndex];
|
|
|
|
|
string processName = processInfo.ProcessName;
|
|
|
|
|
//AddTextEvent($"{stepIndex + 1}-{processName}", $"工序开始...");
|
|
|
|
|
string jsonParams = null;//配方
|
|
|
|
|
|
|
|
|
|
if (model.ProductProcessList != null && model.ProductProcessList.Count > 0)//使用产品配方
|
|
|
|
|
{
|
|
|
|
|
ProductProcess productProcessParams = model.ProductProcessList.First(m => m.ProcessCode == processInfo.ProcessCode);
|
|
|
|
|
if (productProcessParams != null)
|
|
|
|
|
{
|
|
|
|
|
jsonParams = productProcessParams.ProcessParams;
|
|
|
|
|
AddTextEvent($"{stepIndex + 1}-{processName}", $"使用产品专用配方:{jsonParams}");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (jsonParams == null)//使用流程默认配方
|
|
|
|
|
{
|
|
|
|
|
jsonParams = processInfo.ProcessParams;
|
|
|
|
|
AddTextEvent($"{stepIndex + 1}-{processName}", $"使用流程默认配方:{jsonParams}");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
JObject processParam = JObject.Parse(jsonParams);
|
|
|
|
|
if (!processParam.ContainsKey("Disable") || !processParam.Value<bool>("Disable"))
|
|
|
|
|
{
|
|
|
|
|
AutoResetEvent endEvent;
|
|
|
|
|
uint sleepPre = processParam.Value<uint>("SleepPre");
|
|
|
|
|
uint sleepLater = processParam.Value<uint>("SleepLater");
|
|
|
|
|
if (sleepPre > 0)
|
|
|
|
|
Thread.Sleep((int)sleepPre);
|
|
|
|
|
double limitThresholdVal, lowerThresholdVal;
|
|
|
|
|
|
|
|
|
|
//======Switch 工序类型
|
|
|
|
|
int liStatocStepIndex = stepIndex;
|
|
|
|
|
switch (processInfo.ProcessCode)
|
|
|
|
|
{
|
|
|
|
|
case "IOCard":
|
|
|
|
|
#region
|
|
|
|
|
var direction = (IODirectionEnum)processParam.Value<int>("Direction");
|
|
|
|
|
if (direction == IODirectionEnum.输入 || direction == IODirectionEnum.输入输出)
|
|
|
|
|
{
|
|
|
|
|
uint IN_Waiting_Timeout = processParam.Value<uint>("IN_Waiting_Timeout");
|
|
|
|
|
AddTextEvent($"{stepIndex + 1}-{processName}", $"等待I/O输入信号{(IN_Waiting_Timeout > 0 ? $"(超时时长: {IN_Waiting_Timeout})" : "...")}");
|
|
|
|
|
string[] inValue = processParam.Value<JArray>("IN_OP_SHOW").ToObject<List<string>>().ToArray();
|
|
|
|
|
uint inWaitingTime = 0;
|
|
|
|
|
while (true)
|
|
|
|
|
{
|
|
|
|
|
if (isBreakProcessRun())
|
|
|
|
|
return stepIndex;
|
|
|
|
|
|
|
|
|
|
if (Util.compareIOInput(inValue, devContainer.devIOCard.DIData))
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
Thread.Sleep(10);
|
|
|
|
|
inWaitingTime += 10;
|
|
|
|
|
if (IN_Waiting_Timeout > 0 && inWaitingTime >= IN_Waiting_Timeout)
|
|
|
|
|
{
|
|
|
|
|
AddTextEvent($"{stepIndex + 1}-{processName}", $"输入等待超时告警!", WarningEnum.High);
|
|
|
|
|
warning(WarningEnum.Low);//暂停
|
|
|
|
|
return stepIndex;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
AddTextEvent($"{stepIndex + 1}-{processName}", $"I/O输入信号对比完成!");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (direction == IODirectionEnum.输出 || direction == IODirectionEnum.输入输出)
|
|
|
|
|
devContainer.io_output($"{stepIndex + 1}-{processName}", processParam);
|
|
|
|
|
#endregion
|
|
|
|
|
break;
|
|
|
|
|
case "Axis":
|
|
|
|
|
#region
|
|
|
|
|
bool asynRun = processParam.Value<bool>("AsynRun");//异步
|
|
|
|
|
int AxisIndex = processParam.Value<int>("AxisIndex");
|
|
|
|
|
int DeviceType = processParam.Value<int>("DeviceType");
|
|
|
|
|
|
|
|
|
|
double VelLow = processParam.Value<double>("VelLow");
|
|
|
|
|
double VelHigh = processParam.Value<double>("VelHigh");
|
|
|
|
|
double Acc = processParam.Value<double>("Acc");
|
|
|
|
|
double Dec = processParam.Value<double>("Dec");
|
|
|
|
|
|
|
|
|
|
AxMoveMode MoveMode = (AxMoveMode)processParam.Value<int>("MoveMode");//绝对位置
|
|
|
|
|
double PPUValue = processParam.Value<double>("Value");
|
|
|
|
|
|
|
|
|
|
AddTextEvent($"{stepIndex + 1}-{processName}", $"轴{AxisIndex}准备({(MoveMode == AxMoveMode.MODE1_Abs ? "绝对" : "相对")})运动至{PPUValue}(当前轴状态:{((AxisState)devContainer.devAxis.AxState[AxisIndex]).ToString()})...");
|
|
|
|
|
|
|
|
|
|
////移动Axis前等待厚度传感器收回
|
|
|
|
|
//if (!Config.SkipHeight)
|
|
|
|
|
//{
|
|
|
|
|
// while (devContainer.devHeight.getHeight() < (double)Math.Abs(Config.HeightDev_SafeValue))
|
|
|
|
|
// {
|
|
|
|
|
// if (isBreakProcessRun())
|
|
|
|
|
// return stepIndex;
|
|
|
|
|
// Thread.Sleep(10);
|
|
|
|
|
// }
|
|
|
|
|
//}
|
|
|
|
|
while (!devContainer.devAxis.isReady(AxisIndex))
|
|
|
|
|
{
|
|
|
|
|
Thread.Sleep(100);
|
|
|
|
|
if (isBreakProcessRun())
|
|
|
|
|
return stepIndex;
|
|
|
|
|
}
|
|
|
|
|
devContainer.devAxis.setAxisVelParam(VelLow, VelHigh, Acc, Dec, AxisIndex);
|
|
|
|
|
if (!devContainer.devAxis.move_ptp(AxisIndex, PPUValue, MoveMode))
|
|
|
|
|
{
|
|
|
|
|
AddTextEvent($"{stepIndex + 1}-{processName}", $"轴{AxisIndex}运动失败!", WarningEnum.Low);
|
|
|
|
|
warning(WarningEnum.Low);//终止
|
|
|
|
|
return stepIndex;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
AddTextEvent($"{stepIndex + 1}-{processName}", $"等待轴{AxisIndex}运行完成...");
|
|
|
|
|
while (!asynRun && !devContainer.devAxis.isReady(AxisIndex))
|
|
|
|
|
{
|
|
|
|
|
Thread.Sleep(100);
|
|
|
|
|
if (isBreakProcessRun())
|
|
|
|
|
{
|
|
|
|
|
currProcessIndex = stepIndex + 1;
|
|
|
|
|
return stepIndex;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
AddTextEvent($"{stepIndex + 1}-{processName}", $"轴{AxisIndex}运行完成,当前命令位置:{devContainer.devAxis.getCmdPos_mm(AxisIndex)},反馈位置:{devContainer.devAxis.getActualPos_mm(AxisIndex)}");
|
|
|
|
|
#endregion
|
|
|
|
|
break;
|
|
|
|
|
case "Light":
|
|
|
|
|
#region
|
|
|
|
|
if (Config.SkipLight)
|
|
|
|
|
{
|
|
|
|
|
AddTextEvent($"{stepIndex + 1}-{processName}", $"设备禁用,忽略此步骤!");
|
|
|
|
|
//setDgvContentCol(liStatocStepIndex, $"设备禁用,忽略此步骤!");
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
int ChannelIndex = processParam.Value<int>("ChannelIndex"); //通道
|
|
|
|
|
int DigitalValue = processParam.Value<int>("DigitalValue"); //亮度
|
|
|
|
|
int nowDiaitalValue = devContainer.devLight.getDigitalValue(ChannelIndex);
|
|
|
|
|
AddTextEvent($"{stepIndex + 1}-{processName}", $"通道{ChannelIndex}当前值:{nowDiaitalValue},准备更新值:{DigitalValue}...");
|
|
|
|
|
devContainer.devLight.setDigitalValue(ChannelIndex, DigitalValue);
|
|
|
|
|
nowDiaitalValue = devContainer.devLight.getDigitalValue(ChannelIndex);
|
|
|
|
|
AddTextEvent($"{stepIndex + 1}-{processName}", $"通道{ChannelIndex}更新后当前值:{nowDiaitalValue}。");
|
|
|
|
|
#endregion
|
|
|
|
|
break;
|
|
|
|
|
case "Scanner_CC":
|
|
|
|
|
#region
|
|
|
|
|
if (Config.SkipScannerCC)
|
|
|
|
|
{
|
|
|
|
|
AddTextEvent($"{stepIndex + 1}-{processName}", $"设备禁用,忽略此步骤!");
|
|
|
|
|
//setDgvContentCol(liStatocStepIndex, $"设备禁用,忽略此步骤!");
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
while (!devContainer.devAxis.isReady())//因启用轴异步功能,使用前需等待
|
|
|
|
|
{
|
|
|
|
|
Thread.Sleep(100);
|
|
|
|
|
if (isBreakProcessRun())
|
|
|
|
|
{
|
|
|
|
|
//currProcessIndex = stepIndex;//本工序没执行,step不变
|
|
|
|
|
return stepIndex;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
float ExposureTimeCC = processParam.Value<float>("ExposureTime"); //曝光
|
|
|
|
|
float GainCC = processParam.Value<float>("Gain"); //增益
|
|
|
|
|
float ResultingFrameRateCC = processParam.Value<float>("ResultingFrameRate"); //帧率
|
|
|
|
|
|
|
|
|
|
AddTextEvent($"{stepIndex + 1}-{processName}", $"相机开始采集照片...");
|
|
|
|
|
devContainer.devScannerCC.setParam(ExposureTimeCC, GainCC, ResultingFrameRateCC);
|
|
|
|
|
|
|
|
|
|
AddTextEvent($"{stepIndex + 1}-{processName}", $"相机参数设置完成。");
|
|
|
|
|
AutoResetEvent endEventCC = new AutoResetEvent(false);
|
|
|
|
|
//devContainer.devScannerCC.ScanEvent = (num, bmp2) =>
|
|
|
|
|
//{
|
|
|
|
|
// AddTextEvent($"{stepIndex + 1}-{processName}", $"相机采集照片完成.");
|
|
|
|
|
// scannerCBmpQueue.Enqueue(bmp2,
|
|
|
|
|
// devContainer.devAxis.getActualPos_mm(0),
|
|
|
|
|
// devContainer.devAxis.getActualPos_mm(1))
|
|
|
|
|
// endEventCC.Set();//线程返回
|
|
|
|
|
//};
|
|
|
|
|
devContainer.devScannerCC.ScanEventPath += new System.Action<int, string>((num, path2) =>
|
|
|
|
|
{
|
|
|
|
|
AddTextEvent($"{stepIndex + 1}-{processName}", $"相机采集照片完成.");
|
|
|
|
|
scannerCBmpQueue.Enqueue(new scannerCBmpLoc(path2,
|
|
|
|
|
devContainer.devAxis.getActualPos_mm(0),
|
|
|
|
|
devContainer.devAxis.getActualPos_mm(1)));//Dequeue
|
|
|
|
|
AddTextEvent($"{stepIndex + 1}-{processName}", $"图像队列数量: {scannerCBmpQueue.Count}");
|
|
|
|
|
endEventCC.Set();//线程返回
|
|
|
|
|
});
|
|
|
|
|
if (!devContainer.devScannerCC.scan(1))//软触发拍照
|
|
|
|
|
{
|
|
|
|
|
devContainer.devScannerCC.ScanEventPath = null;
|
|
|
|
|
AddTextEvent($"{stepIndex + 1}-{processName}", $"相机采集照片失败!", WarningEnum.Low);
|
|
|
|
|
warning(WarningEnum.Low);//终止
|
|
|
|
|
return stepIndex;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!endEventCC.WaitOne(5000))
|
|
|
|
|
{
|
|
|
|
|
devContainer.devScannerCC.ScanEventPath = null;
|
|
|
|
|
AddTextEvent($"{stepIndex + 1}-{processName}", $"相机采集照片超时!", WarningEnum.Low);
|
|
|
|
|
warning(WarningEnum.Low);//终止
|
|
|
|
|
return stepIndex;
|
|
|
|
|
}
|
|
|
|
|
devContainer.devScannerCC.ScanEventPath = null;
|
|
|
|
|
#endregion
|
|
|
|
|
break;
|
|
|
|
|
case "Size":
|
|
|
|
|
#region
|
|
|
|
|
limitThresholdVal = processParam.Value<double>("LimitThresholdVal");
|
|
|
|
|
lowerThresholdVal = processParam.Value<double>("LowerThresholdVal");
|
|
|
|
|
int sizeIndex = processParam.Value<int>("Index");
|
|
|
|
|
double xPos = 0;
|
|
|
|
|
double yPos = 0;
|
|
|
|
|
if (scannerCBmpQueue.Count < 1)
|
|
|
|
|
{
|
|
|
|
|
AddTextEvent($"{stepIndex + 1}-{processName}", $"尺寸检测异常,无源图像!!", WarningEnum.Low);
|
|
|
|
|
warning(WarningEnum.Low);//暂停
|
|
|
|
|
return stepIndex;
|
|
|
|
|
}
|
|
|
|
|
var bmpCBmpQueue = scannerCBmpQueue.Dequeue();
|
|
|
|
|
AddTextEvent($"{stepIndex + 1}-{processName}", $"开始尺寸检测,index:{sizeIndex},图像队列数量: {scannerCBmpQueue.Count}...");
|
|
|
|
|
//需要偏移校正,index=0时不能异步
|
|
|
|
|
endEvent = new AutoResetEvent(false);
|
|
|
|
|
sizeBmpNum++;
|
|
|
|
|
devContainer.libSize.add(new SizeTask()
|
|
|
|
|
{
|
|
|
|
|
index = sizeIndex,
|
|
|
|
|
stepIndex = stepIndex,//仅供回调时用
|
|
|
|
|
engineName = processParam.Value<string>("EngineName"),
|
|
|
|
|
bmp = bmpCBmpQueue.BMP,//bmp/file_path二选一,优先bmp
|
|
|
|
|
file_path = bmpCBmpQueue.Path,
|
|
|
|
|
posX = bmpCBmpQueue.PosX,
|
|
|
|
|
posY = bmpCBmpQueue.PosY,
|
|
|
|
|
MarkPointList= convert(currProductMarkList),
|
|
|
|
|
finishEvent = (res) =>
|
|
|
|
|
{
|
|
|
|
|
if(res.isSucceed)
|
|
|
|
|
{
|
|
|
|
|
AddTextEvent($"{stepIndex + 1}-{processName}", $"尺寸检测完成,index:{res.index}。");
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
//setDgvContentCol(liStatocStepIndex, $"失败:{res.resultInfo}");
|
|
|
|
|
AddTextEvent($"{res.stepIndex + 1}-{processName}", $"尺寸检测失败index:{res.index}:{res.resultInfo}");
|
|
|
|
|
//warning(WarningEnum.Low);//暂停 这里不能暂停,stepIndex和scannerBmpQueue队列也不对了
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sizeBmpNumResult++;
|
|
|
|
|
string sizeSavePath = Config.SizeBmp_Path + "\\" + DateTime.Now.ToString("yyyyMMdd") + "\\";
|
|
|
|
|
if (!Directory.Exists(sizeSavePath))
|
|
|
|
|
Directory.CreateDirectory(sizeSavePath);
|
|
|
|
|
sizeSavePath += $"SN{this.SN}_I{res.index}_X{res.posX}_Y{res.posY}.bmp";
|
|
|
|
|
if (res.bmp != null)
|
|
|
|
|
{
|
|
|
|
|
res.bmp.Save(sizeSavePath,ImageFormat.Bmp);
|
|
|
|
|
res.bmp.Dispose();
|
|
|
|
|
res.bmp = null;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
//File.Copy(res.file_path, defectFileName + ".bmp", true);
|
|
|
|
|
API.CopyFile(res.file_path, sizeSavePath, false);//更快
|
|
|
|
|
File.Delete(res.file_path);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
#endregion
|
|
|
|
|
break;
|
|
|
|
|
case "For":
|
|
|
|
|
#region
|
|
|
|
|
long UniqueId = processParam.Value<long>("UniqueId");
|
|
|
|
|
int GotoStepIndex = processParam.Value<int>("GotoStepIndex");//1-n
|
|
|
|
|
int LimitNum = processParam.Value<int>("LimitNum");//1-n
|
|
|
|
|
bool Reset = processParam.Value<bool>("Reset");
|
|
|
|
|
if (GotoStepIndex - 1 == stepIndex)
|
|
|
|
|
{
|
|
|
|
|
AddTextEvent($"{stepIndex + 1}-{processName}", $"For死循环!!!");
|
|
|
|
|
warning(WarningEnum.High);
|
|
|
|
|
return stepIndex;
|
|
|
|
|
}
|
|
|
|
|
if (!devContainer.libFor.dicData.ContainsKey(UniqueId))
|
|
|
|
|
devContainer.libFor.dicData.Add(UniqueId, 0);
|
|
|
|
|
//
|
|
|
|
|
int Num = devContainer.libFor.dicData[UniqueId];
|
|
|
|
|
Num++;
|
|
|
|
|
if (Num <= LimitNum)
|
|
|
|
|
{
|
|
|
|
|
if (Num == LimitNum)
|
|
|
|
|
{
|
|
|
|
|
//setDgvContentCol(liStatocStepIndex, $"第[{Num}/{LimitNum}]次,循环完成");
|
|
|
|
|
AddTextEvent($"{stepIndex + 1}-{processName}", $"第[{Num}/{LimitNum}]次,循环完成。");
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
//setDgvContentCol(liStatocStepIndex, $"第[{Num}/{LimitNum}]次");
|
|
|
|
|
AddTextEvent($"{stepIndex + 1}-{processName}", $"第[{Num}/{LimitNum}]次跳转到步骤[{GotoStepIndex}]...");
|
|
|
|
|
stepIndex = GotoStepIndex - 2;
|
|
|
|
|
}
|
|
|
|
|
devContainer.libFor.dicData[UniqueId] = Num;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
//setDgvContentCol(liStatocStepIndex, $"已失效不执行");
|
|
|
|
|
AddTextEvent($"{stepIndex + 1}-{processName}", $"本循环已失效不执行!");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//达到limit重置0
|
|
|
|
|
if (devContainer.libFor.dicData[UniqueId] >= LimitNum && Reset)
|
|
|
|
|
{
|
|
|
|
|
devContainer.libFor.dicData[UniqueId] = 0;
|
|
|
|
|
//setDgvContentCol(liStatocStepIndex, $"第[0/{LimitNum}]次");
|
|
|
|
|
AddTextEvent($"{stepIndex + 1}-{processName}", $"计数器已重置。");
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
break;
|
|
|
|
|
case "If":
|
|
|
|
|
#region
|
|
|
|
|
long UniqueId_if = processParam.Value<long>("UniqueId");
|
|
|
|
|
int GotoStepIndex_if = processParam.Value<int>("GotoStepIndex");//1-n
|
|
|
|
|
int LimitNum_if = processParam.Value<int>("LimitNum");//1-n
|
|
|
|
|
bool Reset_if = processParam.Value<bool>("Reset");
|
|
|
|
|
if (GotoStepIndex_if - 1 == stepIndex)
|
|
|
|
|
{
|
|
|
|
|
AddTextEvent($"{stepIndex + 1}-{processName}", $"If死循环,不可自我跳转!!!");
|
|
|
|
|
warning(WarningEnum.High);
|
|
|
|
|
return stepIndex;
|
|
|
|
|
}
|
|
|
|
|
//
|
|
|
|
|
if (!devContainer.libIF.dicData.ContainsKey(UniqueId_if))
|
|
|
|
|
devContainer.libIF.dicData.Add(UniqueId_if, 0);
|
|
|
|
|
//
|
|
|
|
|
int Num_if = devContainer.libIF.dicData[UniqueId_if];
|
|
|
|
|
Num_if++;
|
|
|
|
|
if (Num_if <= LimitNum_if)
|
|
|
|
|
{
|
|
|
|
|
if (Num_if == LimitNum_if)
|
|
|
|
|
{
|
|
|
|
|
//setDgvContentCol(liStatocStepIndex, $"第[{Num_if}/{LimitNum_if}]次,跳转至[{GotoStepIndex_if}]");
|
|
|
|
|
AddTextEvent($"{stepIndex + 1}-{processName}", $"计数器[{Num_if}/{LimitNum_if}],跳转至步骤[{GotoStepIndex_if}]...");
|
|
|
|
|
stepIndex = GotoStepIndex_if - 2;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
//setDgvContentCol(liStatocStepIndex, $"第[{Num_if}/{LimitNum_if}]次,不跳转");
|
|
|
|
|
AddTextEvent($"{stepIndex + 1}-{processName}", $"计数器[{Num_if}/{LimitNum_if}],不跳转。");
|
|
|
|
|
}
|
|
|
|
|
//
|
|
|
|
|
devContainer.libIF.dicData[UniqueId_if] = Num_if;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
//setDgvContentCol(liStatocStepIndex, $"已失效不执行");
|
|
|
|
|
AddTextEvent($"{stepIndex + 1}-{processName}", $"本IF已失效不执行。");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//达到limit重置0
|
|
|
|
|
if (devContainer.libIF.dicData[UniqueId_if] >= LimitNum_if && Reset_if)
|
|
|
|
|
{
|
|
|
|
|
devContainer.libIF.dicData[UniqueId_if] = 0;
|
|
|
|
|
//setDgvContentCol(liStatocStepIndex, $"第[0/{LimitNum_if}]次");
|
|
|
|
|
AddTextEvent($"{stepIndex + 1}-{processName}", $"计数器已重置。");
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
AddTextEvent($"{stepIndex + 1}-{processName}", $"未知工序:{processInfo.ProcessCode}");
|
|
|
|
|
warning(WarningEnum.High);
|
|
|
|
|
return stepIndex;
|
|
|
|
|
}
|
|
|
|
|
if (sleepLater > 0) Thread.Sleep((int)sleepLater);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//============结束,判断是否自动下料
|
|
|
|
|
if (stepIndex == processList.Count - 1)
|
|
|
|
|
{
|
|
|
|
|
setButtonEnabled(tsbtnPause, false);//后面手动模式暂停无意义
|
|
|
|
|
//等待Mark图处理完成
|
|
|
|
|
while (sizeBmpNum != sizeBmpNumResult)
|
|
|
|
|
Thread.Sleep(100);
|
|
|
|
|
//
|
|
|
|
|
this.Invoke(new System.Action(() =>
|
|
|
|
|
{
|
|
|
|
|
this.chkLaser.Checked = true;
|
|
|
|
|
this.gpbXYAxis.Enabled = gpbZAxis.Enabled = true;
|
|
|
|
|
}));
|
|
|
|
|
AddTextEvent("完成", $"Mark点计算工序结束,开始转换主机台缺陷坐标...");
|
|
|
|
|
convert2LocXY();
|
|
|
|
|
AddTextEvent("完成", $"开始进行人工修复...");
|
|
|
|
|
currentPT = CurrentPTEnum.MakeTag;
|
|
|
|
|
currentState = CurrentStateEnum.打标中;
|
|
|
|
|
setButtonEnabled(tsbtnGoDownPT, true);
|
|
|
|
|
setButtonEnabled(tsbtnReset, true);
|
|
|
|
|
|
|
|
|
|
//==
|
|
|
|
|
currProcessIndex = -1;
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
else //继续
|
|
|
|
|
{
|
|
|
|
|
return ++stepIndex;
|
|
|
|
|
//return nextProcess(model, ++stepIndex);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
if (devContainer.devAxis.isError())
|
|
|
|
|
{
|
|
|
|
|
AddTextEvent("工序", $"[{stepIndex}] Err:" + ex.Message);
|
|
|
|
|
warning(WarningEnum.High);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
AddTextEvent("工序", $"[{stepIndex}] Err:" + ex.Message);
|
|
|
|
|
warning(WarningEnum.Low);
|
|
|
|
|
}
|
|
|
|
|
return -2;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
#region Fun
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 全局中断
|
|
|
|
|
/// </summary>
|
|
|
|
|
private void globalBreakEvent(int portIndex, byte data)
|
|
|
|
|
{
|
|
|
|
|
AddTextEvent("中断命令", $"{portIndex}-HEX:{Convert.ToString(data, 16)}");
|
|
|
|
|
if (compareIOInput(CMDName.启动按钮) && this.tsbtnStart.Enabled)
|
2024-03-13 11:12:05 +08:00
|
|
|
|
{
|
|
|
|
|
AddTextEvent("中断命令", $"启动-按钮");
|
2024-03-04 10:23:01 +08:00
|
|
|
|
startCommand();
|
2024-03-13 11:12:05 +08:00
|
|
|
|
AddTextEvent("中断命令", $"启动-完成");
|
|
|
|
|
}
|
2024-03-04 10:23:01 +08:00
|
|
|
|
else if (compareIOInput(CMDName.暂停按钮) && this.tsbtnPause.Enabled)
|
2024-03-13 11:12:05 +08:00
|
|
|
|
{
|
|
|
|
|
AddTextEvent("中断命令", $"暂停-按钮");
|
2024-03-04 10:23:01 +08:00
|
|
|
|
warning(WarningEnum.Low, false);
|
2024-03-13 11:12:05 +08:00
|
|
|
|
AddTextEvent("中断命令", $"暂停-完成");
|
|
|
|
|
}
|
2024-03-04 10:23:01 +08:00
|
|
|
|
else if (compareIOInput(CMDName.完成下料) && this.tsbtnGoDownPT.Enabled)
|
2024-03-13 11:12:05 +08:00
|
|
|
|
{
|
|
|
|
|
AddTextEvent("中断命令", $"完成-按钮");
|
2024-03-04 10:23:01 +08:00
|
|
|
|
gotoDownPT();
|
2024-03-13 11:12:05 +08:00
|
|
|
|
AddTextEvent("中断命令", $"完成-完成");
|
|
|
|
|
}
|
2024-03-04 10:23:01 +08:00
|
|
|
|
else if (compareIOInput(CMDName.下光源按钮))
|
2024-03-13 11:12:05 +08:00
|
|
|
|
{
|
|
|
|
|
AddTextEvent("中断命令", $"下光源-按钮");
|
2024-03-04 10:23:01 +08:00
|
|
|
|
openLowerLight();
|
2024-03-13 11:12:05 +08:00
|
|
|
|
AddTextEvent("中断命令", $"下光源-完成");
|
|
|
|
|
}
|
2024-03-04 10:23:01 +08:00
|
|
|
|
else if (compareIOInput(CMDName.上一张图) && currentState == CurrentStateEnum.打标中 && currDefectIndex > 0)
|
2024-03-13 11:12:05 +08:00
|
|
|
|
{
|
|
|
|
|
AddTextEvent("中断命令", $"上一张图-按钮");
|
2024-03-04 10:23:01 +08:00
|
|
|
|
gotoPrePic();
|
2024-03-13 11:12:05 +08:00
|
|
|
|
AddTextEvent("中断命令", $"上一张图-完成");
|
|
|
|
|
}
|
2024-03-04 10:23:01 +08:00
|
|
|
|
else if (compareIOInput(CMDName.下一张图) && currentState == CurrentStateEnum.打标中 && currDefectIndex < defectList.Count - 1)
|
2024-03-13 11:12:05 +08:00
|
|
|
|
{
|
|
|
|
|
AddTextEvent("中断命令", $"下一张图-按钮");
|
2024-03-04 10:23:01 +08:00
|
|
|
|
gotoNextPic();
|
2024-03-13 11:12:05 +08:00
|
|
|
|
AddTextEvent("中断命令", $"下一张图-完成");
|
|
|
|
|
}
|
2024-03-04 10:23:01 +08:00
|
|
|
|
else if (compareIOInput(CMDName.上一缺陷) && currentState == CurrentStateEnum.打标中 && currDefectIndex > 0)
|
2024-03-13 11:12:05 +08:00
|
|
|
|
{
|
|
|
|
|
AddTextEvent("中断命令", $"上一缺陷-按钮");
|
2024-03-04 10:23:01 +08:00
|
|
|
|
gotoDefctListIndex(--currDefectIndex, currDefectIndex + 1);
|
2024-03-13 11:12:05 +08:00
|
|
|
|
AddTextEvent("中断命令", $"上一缺陷-完成");
|
|
|
|
|
}
|
2024-03-04 10:23:01 +08:00
|
|
|
|
else if (compareIOInput(CMDName.下一缺陷) && currentState == CurrentStateEnum.打标中 && currDefectIndex < defectList.Count - 1)
|
2024-03-13 11:12:05 +08:00
|
|
|
|
{
|
|
|
|
|
AddTextEvent("中断命令", $"下一缺陷-按钮");
|
2024-03-04 10:23:01 +08:00
|
|
|
|
gotoDefctListIndex(++currDefectIndex, currDefectIndex - 1);
|
2024-03-13 11:12:05 +08:00
|
|
|
|
AddTextEvent("中断命令", $"下一缺陷-完成");
|
|
|
|
|
}
|
2024-03-04 10:23:01 +08:00
|
|
|
|
else if (compareIOInput(CMDName.复位按钮) && this.tsbtnReset.Enabled)
|
2024-03-13 11:12:05 +08:00
|
|
|
|
{
|
|
|
|
|
AddTextEvent("中断命令", $"复位-按钮");
|
2024-03-04 10:23:01 +08:00
|
|
|
|
resetCommand();
|
2024-03-13 11:12:05 +08:00
|
|
|
|
AddTextEvent("中断命令", $"复位-完成");
|
|
|
|
|
}
|
2024-03-04 10:23:01 +08:00
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
if (devContainer.state && warningLevel == WarningEnum.Normal
|
|
|
|
|
&& currentState == CurrentStateEnum.打标中 && currentPT == CurrentPTEnum.MakeTag)
|
|
|
|
|
{
|
|
|
|
|
int axisIndex = 0;
|
|
|
|
|
bool isJog_axis = (AxisState)devContainer.devAxis.AxState[axisIndex] == AxisState.STA_AX_EXT_JOG;
|
|
|
|
|
if(!handleJog(axisIndex, CMDName.手柄左移,1) && !handleJog(axisIndex, CMDName.手柄右移,0))
|
|
|
|
|
{
|
|
|
|
|
if (isJog_axis)
|
|
|
|
|
{
|
|
|
|
|
AddTextEvent("中断命令", $"轴{axisIndex}关闭JOG模式!");
|
|
|
|
|
devContainer.devAxis.closeJogMode(axisIndex);//关闭jog时自动停止
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
axisIndex = 1;
|
|
|
|
|
isJog_axis = (AxisState)devContainer.devAxis.AxState[axisIndex] == AxisState.STA_AX_EXT_JOG;
|
|
|
|
|
if (!handleJog(axisIndex, CMDName.手柄前移,0) && !handleJog(axisIndex, CMDName.手柄后移,1))
|
|
|
|
|
{
|
|
|
|
|
if (isJog_axis)
|
|
|
|
|
{
|
|
|
|
|
AddTextEvent("中断命令", $"轴{axisIndex}关闭JOG模式!");
|
|
|
|
|
devContainer.devAxis.closeJogMode(axisIndex);//关闭jog时自动停止
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
private bool compareIOInput(CMDName key)
|
|
|
|
|
{
|
|
|
|
|
JObject joJson = Config.CMDProcess[key];
|
|
|
|
|
IODirectionEnum direction = (IODirectionEnum)joJson.Value<int>("Direction");
|
|
|
|
|
if (direction == IODirectionEnum.输入 || direction == IODirectionEnum.输入输出)
|
|
|
|
|
{
|
|
|
|
|
return Util.compareIOInput(
|
|
|
|
|
joJson.Value<JArray>("IN_OP_SHOW").ToObject<List<string>>().ToArray(),
|
|
|
|
|
devContainer.devIOCard.DIData);
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
private bool handleJog(int axisIndex,CMDName cmd,ushort dir)
|
|
|
|
|
{
|
|
|
|
|
if (compareIOInput(cmd) && currentState == CurrentStateEnum.打标中)
|
|
|
|
|
{
|
|
|
|
|
AddTextEvent("中断命令", $"{cmd.ToString()}:开");
|
|
|
|
|
devContainer.devAxis.openJogMode(axisIndex);
|
|
|
|
|
devContainer.devAxis.setAxisVelParam((double)Config.Axis_JogVelLow[axisIndex], (double)Config.Axis_JogVelLow[axisIndex],
|
|
|
|
|
(double)Config.Axis_JogVelLow[axisIndex], (double)Config.Axis_JogVelLow[axisIndex], axisIndex, true);
|
|
|
|
|
devContainer.devAxis.jog(axisIndex, dir);//jog move
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 报警,只响应low,high
|
|
|
|
|
/// </summary>
|
|
|
|
|
private void warning(WarningEnum level, bool buzzer = true)
|
|
|
|
|
{
|
|
|
|
|
if (level == WarningEnum.Normal)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
lock (myLock)
|
|
|
|
|
warningLevel = level;
|
|
|
|
|
if (level == WarningEnum.Low)//暂停
|
|
|
|
|
{
|
|
|
|
|
currentState = CurrentStateEnum.暂停;
|
|
|
|
|
pauseCommand(buzzer);
|
|
|
|
|
}
|
|
|
|
|
else if (level == WarningEnum.High)//急停
|
|
|
|
|
{
|
|
|
|
|
currentState = CurrentStateEnum.急停;
|
|
|
|
|
devContainer.devAxis.stopNow();
|
|
|
|
|
|
|
|
|
|
stopNowCommand();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//启用报警消除按钮
|
|
|
|
|
setButtonEnabled(tsbtnWarning, true);
|
|
|
|
|
}
|
|
|
|
|
private void resetUIValue()
|
|
|
|
|
{
|
|
|
|
|
currProcessIndex = -1;
|
|
|
|
|
currProductModel = null;
|
|
|
|
|
currProductMarkList = null;
|
|
|
|
|
scannerCBmpQueue.Clear();
|
|
|
|
|
defectBmpsDir.Clear();
|
|
|
|
|
this.Invoke(new System.Action(() =>
|
|
|
|
|
{
|
|
|
|
|
cbxSN.Enabled = false;
|
|
|
|
|
cbxSN.Text = txtProductCode.Text = txtProductName.Text = txtBatchId.Text =
|
|
|
|
|
txtBatchId.Text = txtCreateTime.Text = "";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
this.gpbDefectList.Text = $"缺陷明细";
|
|
|
|
|
this.dgvProcess.DataSource = null;
|
|
|
|
|
this.lstLog.Items.Clear();
|
|
|
|
|
|
|
|
|
|
this.pictureBox1.Image = null;
|
|
|
|
|
pictureBox1.Refresh();
|
|
|
|
|
}));
|
|
|
|
|
}
|
|
|
|
|
private void delDirFiles(string dirPath)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
var files = Directory.EnumerateFiles(dirPath, "*.bmp", SearchOption.TopDirectoryOnly);
|
|
|
|
|
foreach (string file in files)
|
|
|
|
|
API.DeleteFile(file);
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public delegate void AddTextDelegate(string tag, string msg, WarningEnum level);
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 异步输出日志
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="tag">模板标识</param>
|
|
|
|
|
/// <param name="msg">内容</param>
|
|
|
|
|
/// <param name="type"></param>
|
|
|
|
|
private void AddTextEvent(string tag, string msg, WarningEnum level = WarningEnum.Normal)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
if (InvokeRequired)
|
|
|
|
|
{
|
|
|
|
|
Invoke(new AddTextDelegate(AddTextEvent), new object[]
|
|
|
|
|
{
|
|
|
|
|
tag,
|
|
|
|
|
msg,
|
|
|
|
|
level
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (tag != null && tag != "")
|
|
|
|
|
tag = $" - [{tag}]";
|
|
|
|
|
|
|
|
|
|
var now = DateTime.Now;
|
|
|
|
|
msg = now.ToString("HH:mm:ss fff") + tag + " - " + msg;
|
|
|
|
|
//cont = MyHelper.subString(cont, 300);
|
|
|
|
|
|
|
|
|
|
//写日志,warn和error日志直接写
|
|
|
|
|
writeLog(now, level, msg);
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
//if (type > 0)
|
|
|
|
|
// cont = $"<color=\"{(type == 1 ? "Yellow" : "Red")}\">{cont}</color>";
|
|
|
|
|
|
|
|
|
|
msg = (level == WarningEnum.Normal ? "B" : level == WarningEnum.Low ? "Y" : "R") + msg;
|
|
|
|
|
this.Invoke(new System.Action(() =>
|
|
|
|
|
{
|
|
|
|
|
if (this.lstLog.Items.Count > 1000)
|
|
|
|
|
this.lstLog.Items.Clear();
|
|
|
|
|
lstLog.Items.Insert(0, msg);
|
|
|
|
|
}));
|
|
|
|
|
//日志滚动
|
|
|
|
|
//lstLog.SelectedIndex = lstLog.Items.Count - 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
//MessageBox.Show("AddTextEvent ex=(" + ex.Message + ")", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, 0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
private void lstLog_DrawItem(object sender, DrawItemEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
e.DrawBackground();
|
|
|
|
|
if (e.Index < 0) return;
|
|
|
|
|
|
|
|
|
|
string str = lstLog.Items[e.Index].ToString();
|
|
|
|
|
e.Graphics.DrawString(str.Substring(1), e.Font,
|
|
|
|
|
new SolidBrush(str[0] == 'R' ? Color.Red : (str[0] == 'Y' ? Color.Orange : Color.Black)),
|
|
|
|
|
e.Bounds);
|
|
|
|
|
}
|
|
|
|
|
private void writeLog(DateTime now, WarningEnum level, string text)
|
|
|
|
|
{
|
|
|
|
|
string directory = Config.LogPath + "\\" + DateTime.Now.ToString("yyyyMM") + "\\";
|
|
|
|
|
//if (type == 0) directory = Application.StartupPath + "\\Log\\Info\\";
|
|
|
|
|
//else if (type == 1) directory = Application.StartupPath + "\\Log\\Warn\\";
|
|
|
|
|
//else directory = Application.StartupPath + "\\Log\\Error\\";
|
|
|
|
|
|
|
|
|
|
if (!System.IO.Directory.Exists(directory))
|
|
|
|
|
System.IO.Directory.CreateDirectory(directory);
|
|
|
|
|
|
|
|
|
|
File.AppendAllText(directory + now.ToString("yyyyMMdd") + ".log", text + "\r\n");
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
private void tsbtnOpenDev_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
Config.LoadAllConfig();
|
|
|
|
|
if(string.IsNullOrWhiteSpace(Config.DBConStr)|| string.IsNullOrWhiteSpace(Config.ServerIP))
|
|
|
|
|
{
|
|
|
|
|
AddTextEvent("设备启动", "启动失败,请先设置数据库和主机台通讯地址!",WarningEnum.High);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
//设置程序最小/大线程池
|
|
|
|
|
// Get the current settings.
|
|
|
|
|
int minWorker, minIOC;
|
|
|
|
|
ThreadPool.GetMinThreads(out minWorker, out minIOC);
|
|
|
|
|
ThreadPool.SetMinThreads(25, minIOC);
|
|
|
|
|
//ThreadPool.SetMaxThreads(256, 256);
|
|
|
|
|
|
|
|
|
|
this.tsbtnOpenDev.Enabled = false;
|
|
|
|
|
scannerCBmpQueue.Clear();
|
|
|
|
|
//scannerCBmpIndex = 0;
|
|
|
|
|
|
|
|
|
|
this.resetUIValue();
|
|
|
|
|
currentState = CurrentStateEnum.等待复位;
|
|
|
|
|
warningLevel = WarningEnum.Normal;
|
|
|
|
|
currentPT = CurrentPTEnum.InitPT;
|
|
|
|
|
this.tsbtnWarning.Enabled = this.tsbtnGoDownPT.Enabled = this.tsbtnStart.Enabled
|
|
|
|
|
= this.tsbtnStopNow.Enabled = this.tsbtnPause.Enabled = this.tsbtnReset.Enabled
|
|
|
|
|
= this.gpbXYAxis.Enabled = gpbZAxis.Enabled = false;
|
|
|
|
|
//后台线程回调事件
|
|
|
|
|
devContainer.StateChange = (state, msg) =>
|
|
|
|
|
{
|
|
|
|
|
if (state)
|
|
|
|
|
{
|
|
|
|
|
//全局中断
|
|
|
|
|
devContainer.devIOCard.INEvent = globalBreakEvent;
|
|
|
|
|
devContainer.OutDebugEvent = (tag, debugInfo) =>
|
|
|
|
|
{
|
|
|
|
|
AddTextEvent(tag, debugInfo);
|
|
|
|
|
};
|
|
|
|
|
//
|
|
|
|
|
AddTextEvent("设备启动", "请先进行复位操作!");
|
|
|
|
|
this.Invoke(new System.Action(() =>
|
|
|
|
|
{
|
|
|
|
|
this.tsbtnReset.Enabled = true;
|
|
|
|
|
tsbtnWarning.Enabled = this.tsbtnStart.Enabled = this.tsbtnGoDownPT.Enabled
|
|
|
|
|
= this.tsbtnPause.Enabled = this.tsbtnStopNow.Enabled = false;
|
|
|
|
|
|
|
|
|
|
this.chkLaser.Enabled = true;
|
|
|
|
|
this.tsbtnOpenDev.Enabled = true;
|
|
|
|
|
this.tsbtnOpenDev.Visible = false;
|
|
|
|
|
this.tsbtnCloseDev.Visible = true;
|
|
|
|
|
}));
|
|
|
|
|
|
|
|
|
|
timer.Elapsed += Timer_Elapsed;
|
|
|
|
|
timer.Interval = 500;
|
|
|
|
|
timer.Start();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
AddTextEvent("设备启动", $"启动失败,{msg}", WarningEnum.High);
|
|
|
|
|
this.Invoke(new System.Action(() =>
|
|
|
|
|
{
|
|
|
|
|
this.chkLaser.Enabled = false;
|
|
|
|
|
this.tsbtnOpenDev.Enabled = true;
|
|
|
|
|
this.tsbtnOpenDev.Visible = true;
|
|
|
|
|
this.tsbtnCloseDev.Visible = false;
|
|
|
|
|
}));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
};
|
|
|
|
|
devContainer.WarningEvent = (level, msg) =>
|
|
|
|
|
{
|
|
|
|
|
AddTextEvent("设备事件", msg, level);
|
|
|
|
|
if (level == WarningEnum.High)
|
|
|
|
|
warning(level, true);
|
|
|
|
|
};
|
|
|
|
|
AddTextEvent("设备启动", "启动");
|
|
|
|
|
devContainer.start(IntPtr.Zero, IntPtr.Zero);
|
|
|
|
|
}
|
|
|
|
|
private void Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
this.Invoke(new System.Action(() =>
|
|
|
|
|
{
|
|
|
|
|
this.tsAxisState.Text = $"[命令位:{devContainer.devAxis.CmdPos[0]} 反馈位:{devContainer.devAxis.ActualPos[0]} ({((AxisState)devContainer.devAxis.AxState[0]).ToString()})] | " +
|
|
|
|
|
$"[命令位:{devContainer.devAxis.CmdPos[1]} 反馈位:{devContainer.devAxis.ActualPos[1]} ({((AxisState)devContainer.devAxis.AxState[1]).ToString()})] | " +
|
|
|
|
|
$"[命令位:{devContainer.devAxis.CmdPos[2]} 反馈位:{devContainer.devAxis.ActualPos[2]} ({((AxisState)devContainer.devAxis.AxState[2]).ToString()})] | " +
|
|
|
|
|
$"[命令位:{devContainer.devAxis.CmdPos[3]} 反馈位:{devContainer.devAxis.ActualPos[3]} ({((AxisState)devContainer.devAxis.AxState[3]).ToString()})] | ";
|
|
|
|
|
}));
|
|
|
|
|
}
|
|
|
|
|
private void tsbtnCloseDev_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
AddTextEvent("设备停止", $"设备停止...");
|
|
|
|
|
this.tsbtnOpenDev.Visible = true;
|
|
|
|
|
this.tsbtnCloseDev.Visible = false;
|
|
|
|
|
|
|
|
|
|
this.chkLaser.Enabled = false;
|
|
|
|
|
this.tsbtnReset.Enabled = tsbtnWarning.Enabled = this.tsbtnStart.Enabled = this.tsbtnGoDownPT.Enabled
|
|
|
|
|
= this.tsbtnPause.Enabled = this.tsbtnStopNow.Enabled
|
|
|
|
|
= this.gpbXYAxis.Enabled = this.gpbZAxis.Enabled = false;
|
|
|
|
|
|
|
|
|
|
if (devContainer.state)
|
|
|
|
|
{
|
|
|
|
|
devContainer.devIOCard.reset();
|
|
|
|
|
devContainer.io_output(CMDName.IO默认输出);
|
|
|
|
|
}
|
|
|
|
|
timer.Stop();
|
|
|
|
|
devContainer.stop();
|
|
|
|
|
}
|
|
|
|
|
private void dgvProcess_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
if (e.RowIndex < 0 || !devContainer.state || currentState != CurrentStateEnum.打标中)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
int preIndex = currDefectIndex;
|
|
|
|
|
currDefectIndex = e.RowIndex;
|
|
|
|
|
gotoDefctListIndex(currDefectIndex, preIndex);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void 流程管理ToolStripMenuItem_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
if (devContainer.state)
|
|
|
|
|
{
|
|
|
|
|
MessageBox.Show("请先停止设备,再进行流程修改!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
FrmStepList frm = new FrmStepList();
|
|
|
|
|
frm.ShowDialog();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void 产品管理ToolStripMenuItem_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
//if (devContainer.state)
|
|
|
|
|
//{
|
|
|
|
|
// MessageBox.Show("请先停止设备,再进行产品修改!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
|
|
|
|
// return;
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
FrmProductList frm = new FrmProductList();
|
|
|
|
|
frm.ShowDialog();
|
|
|
|
|
}
|
|
|
|
|
private void loadOrderSNList()
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
//ConditionalType: 0-等于 3-大于等于 5-小于等于 6-IN "CSharpTypeName":"int"
|
|
|
|
|
JArray domainList =new JArray();
|
|
|
|
|
domainList.Add(new JObject()
|
|
|
|
|
{
|
|
|
|
|
{"FieldName","State" },
|
|
|
|
|
{"FieldValue",0 },//0-初始; 5-已检测
|
|
|
|
|
{"ConditionalType",0 },
|
|
|
|
|
});
|
|
|
|
|
domainList.Add(new JObject()
|
|
|
|
|
{
|
|
|
|
|
{"FieldName","DefectCount" },
|
|
|
|
|
{"FieldValue",1 },
|
|
|
|
|
{"ConditionalType",3 },
|
|
|
|
|
});
|
|
|
|
|
domainList.Add(new JObject()
|
|
|
|
|
{
|
|
|
|
|
{"FieldName","CreateTime" },
|
|
|
|
|
{"FieldValue",DateTime.Now.AddDays(-1) },
|
|
|
|
|
{"ConditionalType",3 },
|
|
|
|
|
});
|
|
|
|
|
var list = svcOrder.GetList("Order", "SN", domainList.ToString(), "SN DESC");
|
|
|
|
|
List<string> snList = new List<string>();
|
|
|
|
|
foreach(var item in list)
|
|
|
|
|
snList.Add(item.ToList().Select(m => m.Value.ToString()).ToArray()[0]);
|
|
|
|
|
|
|
|
|
|
this.Invoke(new System.Action(() =>
|
|
|
|
|
{
|
|
|
|
|
this.cbxSN.Text = "";
|
|
|
|
|
this.cbxSN.Items.Clear();
|
|
|
|
|
this.cbxSN.Items.AddRange(snList.ToArray());
|
|
|
|
|
}));
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
AddTextEvent("启动", "加载已检测网版编码失败:" + ex.Message, WarningEnum.Low);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void splitContainer1_SizeChanged(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
this.gpbProductInfo.Width = this.gpbDefectList.Width = splitContainer1.Panel2.Width-10;
|
|
|
|
|
this.gpbProductInfo.Top = this.splitContainer1.ClientSize.Height- this.gpbProductInfo.Height;
|
|
|
|
|
this.gpbDefectList.Height = this.gpbProductInfo.Top-10;
|
|
|
|
|
|
|
|
|
|
this.cbxSN.Width= this.txtProductCode.Width = this.txtProductName.Width
|
|
|
|
|
= this.txtBatchId.Width = this.txtCreateTime.Width = this.gpbProductInfo.Width- this.cbxSN.Left-5;
|
|
|
|
|
//this.dgvProcess.Width = gpbDefectList.Width - 10;
|
|
|
|
|
//this.dgvProcess.Height = this.splitContainer1.ClientSize.Height - this.gpbProductInfo.Height;
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
private void splitContainer2_SizeChanged(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
this.tsbtnPause.Left = this.tsbtnGoDownPT.Left = this.splitContainer1.SplitterDistance- this.tsbtnPause.Width - 10;
|
|
|
|
|
this.gpbZAxis.Left = this.tsbtnPause.Left - this.gpbZAxis.Width-10;
|
|
|
|
|
this.gpbXYAxis.Left = this.gpbZAxis.Left - this.gpbXYAxis.Width - 10;
|
|
|
|
|
this.gpbLog.Width = this.gpbXYAxis.Left - 10;
|
|
|
|
|
this.splitContainer2.SplitterDistance = this.ClientRectangle.Height - gpbLog.Height - 10;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void tsbtnReset_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
Task.Run(() => this.resetCommand());
|
|
|
|
|
}
|
|
|
|
|
private void tsbtnStart_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
Task.Run(() => this.startCommand());
|
|
|
|
|
}
|
|
|
|
|
private void tsbtnPause_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
warning(WarningEnum.Low, false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void tsbtnGoDownPT_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
AddTextEvent("下料", "准备下料。。。");
|
|
|
|
|
// Task.Run(() => this.gotoDownPT());
|
|
|
|
|
gotoDownPT();
|
|
|
|
|
}
|
|
|
|
|
private void tsbtnWarning_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
//if (warningLevel == WarningEnum.Normal)
|
|
|
|
|
//{
|
|
|
|
|
// tsbtnWarning.Enabled = false;
|
|
|
|
|
// return;
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
//重置AXIS状态
|
|
|
|
|
devContainer.devAxis.resetAxisState();
|
|
|
|
|
if (!devContainer.devAxis.isReady())
|
|
|
|
|
{
|
|
|
|
|
AddTextEvent("解除报警", "轴状态未恢复,解除报警失败!", warningLevel);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (devContainer.devAxis.isError())
|
|
|
|
|
{
|
|
|
|
|
AddTextEvent("解除报警", "轴IO状态异常,解除报警失败!", warningLevel);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
//if (!this.disableDoorSensor && compareIOInput(CMDName.门磁告警输入))
|
|
|
|
|
//{
|
|
|
|
|
// AddTextEvent("解除报警", "门磁告警未清除 ,解除报警失败!", warningLevel);
|
|
|
|
|
// return;
|
|
|
|
|
//}
|
|
|
|
|
//if (!this.disableDoorSensor && compareIOInput(CMDName.喷墨告警输入))
|
|
|
|
|
//{
|
|
|
|
|
// AddTextEvent("解除报警", "喷墨告警输入未清除 ,解除报警失败!", warningLevel);
|
|
|
|
|
// return;
|
|
|
|
|
//}
|
|
|
|
|
////关闭蜂鸣器
|
|
|
|
|
//devContainer.io_output(CMDName.蜂鸣器输出, false, true, 0);
|
|
|
|
|
//devContainer.io_output(CMDName.红灯输出, false, true, 0);
|
|
|
|
|
//devContainer.io_output(CMDName.复位按钮, false, true, 0);
|
|
|
|
|
if (warningLevel == WarningEnum.High)
|
|
|
|
|
{
|
|
|
|
|
AddTextEvent("解除报警", "急停告警已解除,但必需进行复位操作!", warningLevel);
|
|
|
|
|
currentState = CurrentStateEnum.等待复位;
|
|
|
|
|
this.tsbtnReset.Enabled = true;
|
|
|
|
|
tsbtnWarning.Enabled = this.tsbtnStart.Enabled = this.tsbtnGoDownPT.Enabled
|
|
|
|
|
= this.tsbtnPause.Enabled = this.tsbtnStopNow.Enabled = false;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
//devContainer.io_output(CMDName.黄灯输出);
|
|
|
|
|
AddTextEvent("解除报警", "告警已解除,请继续选择下一步操作!", warningLevel);
|
|
|
|
|
if (currentPT == CurrentPTEnum.MakeTag)
|
|
|
|
|
currentState = CurrentStateEnum.打标中;
|
|
|
|
|
else
|
|
|
|
|
currentState = CurrentStateEnum.等待启动;
|
|
|
|
|
|
|
|
|
|
tsbtnWarning.Enabled = false;
|
|
|
|
|
this.tsbtnStart.Enabled = this.tsbtnGoDownPT.Enabled = true;
|
|
|
|
|
this.tsbtnReset.Enabled = this.tsbtnPause.Enabled = this.tsbtnStopNow.Enabled = true;
|
|
|
|
|
}
|
|
|
|
|
warningLevel = WarningEnum.Normal;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void 测试ToolStripMenuItem_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
//devContainer.start(IntPtr.Zero, IntPtr.Zero);
|
|
|
|
|
//devContainer.state = true;
|
|
|
|
|
//currentState = CurrentStateEnum.等待扫码;
|
|
|
|
|
//cbxSN.Enabled = true;
|
|
|
|
|
//runStep();
|
|
|
|
|
|
|
|
|
|
//Bitmap bmp = (Bitmap)Bitmap.FromFile(Application.StartupPath + "\\test.bmp");
|
|
|
|
|
//AddTextEvent("", $"{this.splitContainer1.Width},{this.pnlPic.Width},bmp:{bmp.Width}");
|
|
|
|
|
//pnlPic.BackColor = Color.Red;
|
|
|
|
|
//reloadPic(bmp);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//for (int i = 0; i < 100; i++)
|
|
|
|
|
// this.dgvProcess.Rows.Add(i, i, i, i, i, i, i, i, i, i, i);
|
|
|
|
|
//this.dgvProcess.Rows[1].DefaultCellStyle.BackColor = Color.LightGreen;
|
|
|
|
|
|
|
|
|
|
//loadOrderSNList();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void btnFront_MouseDown(object sender, MouseEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
if (devContainer.state && currentState == CurrentStateEnum.打标中)
|
|
|
|
|
{
|
|
|
|
|
ushort dir;
|
|
|
|
|
int axisIndex;
|
|
|
|
|
PictureBox btn = sender as PictureBox;
|
|
|
|
|
switch (btn.Name)
|
|
|
|
|
{
|
|
|
|
|
case "btnFront":
|
|
|
|
|
dir = 1;
|
|
|
|
|
axisIndex = 1;
|
|
|
|
|
break;
|
|
|
|
|
case "btnBack":
|
|
|
|
|
dir = 0;
|
|
|
|
|
axisIndex = 1;
|
|
|
|
|
break;
|
|
|
|
|
case "btnLeft":
|
|
|
|
|
dir = 1;
|
|
|
|
|
axisIndex = 0;
|
|
|
|
|
break;
|
|
|
|
|
case "btnRight":
|
|
|
|
|
dir = 0;
|
|
|
|
|
axisIndex = 0;
|
|
|
|
|
break;
|
|
|
|
|
case "btnZUp":
|
|
|
|
|
dir = 0;
|
|
|
|
|
axisIndex = 2;
|
|
|
|
|
break;
|
|
|
|
|
case "btnZDown":
|
|
|
|
|
dir = 1;
|
|
|
|
|
axisIndex = 2;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
devContainer.devAxis.openJogMode(axisIndex);
|
|
|
|
|
devContainer.devAxis.setAxisVelParam((double)Config.Axis_JogVelLow[axisIndex], (double)Config.Axis_JogVelLow[axisIndex],
|
|
|
|
|
(double)Config.Axis_JogVelLow[axisIndex], (double)Config.Axis_JogVelLow[axisIndex], axisIndex, true);
|
|
|
|
|
devContainer.devAxis.jog(axisIndex, dir);//jog move
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
private void btnFront_MouseUp(object sender, MouseEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
devContainer.devAxis.closeJogMode();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void chkLaser_CheckedChanged(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
if (!devContainer.state) return;
|
|
|
|
|
|
|
|
|
|
if(chkLaser.Checked)
|
|
|
|
|
devContainer.io_output(CMDName.激光灯输出);
|
|
|
|
|
else
|
|
|
|
|
devContainer.io_output(CMDName.激光灯输出, false, true, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void tsbtnLog_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
if (string.IsNullOrWhiteSpace(Config.LogPath)) return;
|
|
|
|
|
string lsPath = (Config.LogPath + "\\" + DateTime.Now.ToString("yyyyMM") + "\\").Replace("\\\\", "\\");
|
|
|
|
|
if (!Directory.Exists(lsPath))
|
|
|
|
|
Directory.CreateDirectory(lsPath);
|
|
|
|
|
System.Diagnostics.Process.Start("explorer.exe", lsPath);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void FrmMain_KeyUp(object sender, KeyEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
//AddTextEvent("KEY",e.KeyCode.ToString());
|
|
|
|
|
switch (e.KeyCode)
|
|
|
|
|
{
|
|
|
|
|
//case Keys.Left://上一张图
|
|
|
|
|
// if (devContainer.state && currentState == CurrentStateEnum.打标中 && currDefectIndex > 0)
|
|
|
|
|
// gotoPrePic();
|
|
|
|
|
// break;
|
|
|
|
|
case Keys.F:// Keys.Right://下一张图
|
|
|
|
|
if (devContainer.state && currentState == CurrentStateEnum.打标中 && currDefectIndex < defectList.Count - 1)
|
|
|
|
|
gotoNextPic();
|
|
|
|
|
break;
|
|
|
|
|
case Keys.K://Keys.Up://上一缺陷
|
|
|
|
|
if (devContainer.state && currentState == CurrentStateEnum.打标中 && currDefectIndex > 0)
|
|
|
|
|
gotoDefctListIndex(--currDefectIndex, currDefectIndex+1);
|
|
|
|
|
break;
|
|
|
|
|
case Keys.P://Keys.Down://下一缺陷
|
|
|
|
|
if (devContainer.state && currentState == CurrentStateEnum.打标中 && currDefectIndex < defectList.Count - 1)
|
|
|
|
|
gotoDefctListIndex(++currDefectIndex, currDefectIndex-1);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void 关于ToolStripMenuItem_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void cbxSN_KeyUp(object sender, KeyEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
if (e.KeyCode == Keys.Enter)
|
|
|
|
|
{
|
|
|
|
|
if (currentState != CurrentStateEnum.等待扫码) return;
|
|
|
|
|
string sn = this.cbxSN.Text.Trim();
|
|
|
|
|
if (string.IsNullOrWhiteSpace(sn))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
//FrmInput frm = new FrmInput(productCodeList, "请选择产品编码:");
|
|
|
|
|
//if (frm.ShowDialog() != DialogResult.OK && string.IsNullOrWhiteSpace(frm.inputData))
|
|
|
|
|
// return;
|
|
|
|
|
Task.Factory.StartNew(() =>
|
|
|
|
|
{
|
|
|
|
|
devContainer.devCodeScanner.ScanerEvent?.Invoke(sn);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void tsbtnGoDownPT_Click_1(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
AddTextEvent("下料", "准备下料。。。");
|
|
|
|
|
// Task.Run(() => this.gotoDownPT());
|
|
|
|
|
gotoDownPT();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void cbxSN_KeyPress(object sender, KeyPressEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
//if (e.KeyChar == (char)Keys.Enter)
|
|
|
|
|
//{
|
|
|
|
|
// if (currentState != CurrentStateEnum.等待扫码) return;
|
|
|
|
|
// string sn = this.cbxSN.Text.Trim();
|
|
|
|
|
// if (string.IsNullOrWhiteSpace(sn))
|
|
|
|
|
// return;
|
|
|
|
|
|
|
|
|
|
// //FrmInput frm = new FrmInput(productCodeList, "请选择产品编码:");
|
|
|
|
|
// //if (frm.ShowDialog() != DialogResult.OK && string.IsNullOrWhiteSpace(frm.inputData))
|
|
|
|
|
// // return;
|
|
|
|
|
// Task.Factory.StartNew(() =>
|
|
|
|
|
// {
|
|
|
|
|
// devContainer.devCodeScanner.ScanerEvent?.Invoke(sn);
|
|
|
|
|
// });
|
|
|
|
|
//}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|