initial commit

This commit is contained in:
2025-11-25 20:14:41 +09:00
commit 5cb1ff372c
559 changed files with 149800 additions and 0 deletions

View File

@@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using AR;
using arDev;
namespace Project
{
public partial class FMain
{
}
}

View File

@@ -0,0 +1,475 @@
using AR;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Project
{
public partial class FMain
{
private void Keyence_BarcodeRecv(object sender, Device.KeyenceBarcode.RecvDataEvent e)
{
var dev = sender as Device.KeyenceBarcode;
if (e.RawData.StartsWith("ERROR"))
{
//로그가 너무 많이 쌓이니 해제한다
//Pub.log.AddE("Reader RES : " + resp);
}
else if (e.RawData.StartsWith("OK,BLOAD"))
{
var str = e.RawData.Replace("\r", "").Replace("\n", "");
PUB.log.AddI($"[{dev.Tag}] {str}");
}
else if (e.RawData.StartsWith("OK,BSAVE"))
{
var str = e.RawData.Replace("\r", "").Replace("\n", "");
PUB.log.AddI($"[{dev.Tag}] {str}");
}
else if (e.RawData.StartsWith("OK"))
{
//OK회신
}
else
{
//값은 받았다
if (PUB.sm.Step != eSMStep.HOME_FULL && PUB.sm.Step != eSMStep.HOME_QUICK)
{
// PUB.logKeyence.Add($"{resp.Replace("\n", "").Replace("\r", "")}");
var rawdata = e.RawData; //↔▲▼
rawdata = rawdata.Replace('\x1D', '↔').Replace('\x1E', '▲').Replace('\x04', '▼');
var lines = rawdata.Split(new char[] { '\r' },StringSplitOptions.RemoveEmptyEntries);
foreach(var line in lines)
ParseBarcode(line, dev.Tag.ToString());
}
else
{
//PUB.logKeyence.Add($"Code Ignore by Home Process({resp.Replace("\n", "").Replace("\r", "")})");
}
}
}
bool imageprocess = false;
private void Keyence_ImageRecv(object sender, Device.KeyenceBarcode.RecvImageEvent e)
{
var dev = sender as Device.KeyenceBarcode;
System.Windows.Forms.PictureBox keyenceview;
if (dev.Tag == "R") keyenceview = keyenceviewR;
else keyenceview = keyenceviewF;
if (imageprocess == false)
{
imageprocess = true;
if (PUB.sm.Step >= eSMStep.IDLE && this.IsDisposed == false && this.Disposing == false)
{
//var oimage = this.pictureBox1.Image;
//this.pictureBox1.Image = e.Image;
//if (oimage != null) oimage.Dispose();
if (keyenceview.Image == null)
{
//var newbitmap = new Bitmap(e.Image.Width,e.Image.Height, e.Image.PixelFormat);
var old = keyenceview.Image;
//var newbitmap = PUB.keyence.CreateBitmap(e.Image.Width, e.Image.Height);
//PUB.keyence.UpdateBitmap((Bitmap)e.Image, newbitmap);
keyenceview.Image = e.Image;
if (old != null) old.Dispose();
PUB.log.AddAT("First image received");
}
else
{
//내용ㅁㄴ업데이트하자
var preimage = keyenceview.Image as Bitmap;
keyenceview.Image = e.Image;
if (preimage != null) preimage.Dispose();
//PUB.keyence.UpdateBitmap((Bitmap)e.Image, preimage);
//this.pictureBox2.Invalidate();
}
}
if (this.IsDisposed)
{
dev.Dispose();
}
imageprocess = false;
}
}
double GetAngle(Point pt1, Point pt2)
{
var val = Math.Asin((pt2.Y - pt1.Y) / Math.Sqrt(Math.Pow(pt2.X - pt1.X, 2.0) + Math.Pow(pt2.Y - pt1.Y, 2.0)));
double retval = 0.0;
if ((pt2.X - pt1.X) >= 0 && (pt2.Y - pt1.Y) >= 0)
retval = val;
else if ((pt2.X - pt1.X) < 0 && (pt2.Y - pt1.Y) >= 0)
retval = Math.PI - val;
else if ((pt2.X - pt1.X) < 0 && (pt2.Y - pt1.Y) < 0)
retval = Math.PI - val;
else if ((pt2.X - pt1.X) >= 0 && (pt2.Y - pt1.Y) < 0)
retval = Math.PI * 2 + val;
return retval;
}
private string KeyenceBarcodeDataF = string.Empty;
private string KeyenceBarcodeDataR = string.Empty;
/// <summary>
/// 키엔스로부터 받은 데이터를 분석한다.
/// </summary>
/// <param name="response"></param>
/// <param name="Source"></param>
void ParseBarcode(string response, string Source)
{
//220901 - 특문있었ㅇ츰
var r1 = (char)0x1D;
var r2 = (char)0x1E;
var r3 = (char)0x04;
var r4 = (char)0x00;
response = response.Replace(r1.ToString(), "");
response = response.Replace(r2.ToString(), "");
response = response.Replace(r3.ToString(), "");
response = response.Replace(r4.ToString(), "");
response = response.Replace("\r", "");
response = response.Replace("\n", "");
response = response.Replace("\0", "");
response = response.RemoveNoneASCII().Trim();
///101409576:522/1171:427/1143:429/1134:524/1155:475/1151\r
var frames = response.Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
var itemC = PUB.Result.ItemDataC;
//키엔스바코드패턴검사
var Pattern = @"^(\d+):(\w+.*):(\d+/\d+):(\d+/\d+):(\d+/\d+):(\d+/\d+):(\d+/\d+)";
Pattern = @"^(\d+):(.*):(\d+/\d+):(\d+/\d+):(\d+/\d+):(\d+/\d+):(\d+/\d+)";
var RegX = new System.Text.RegularExpressions.Regex(Pattern);
foreach (var resp in frames)
{
var bcddata = resp.Trim().Split(',');
if (resp.Equals("0:ERROR"))
{
PUB.log.AddE($"[{Source}] {resp}");
continue;
}
else if (bcddata.Length > 2 && bcddata[1] == "BLOAD")
{
if (bcddata[0] == "ER")
{
PUB.log.AddE($"[{Source}]Bacode Memory Read Error({resp})");
}
else
{
PUB.log.AddI($"[{Source}]Bacode Memory Read Complete({resp})");
}
continue;
}
else if (bcddata.Length > 2 && bcddata[1] == "BSAVE")
{
if (bcddata[0] == "ER")
{
PUB.log.AddE($"[{Source}]Bacode Memory Read Error({resp})");
}
else
{
PUB.log.AddI($"[{Source}]Bacode Memory Read Complete({resp})");
}
continue;
}
else if (RegX.IsMatch(resp.Trim()) == false)
{
//에러처리 221018
if (resp.StartsWith("0:ERROR")) continue;
PUB.log.AddE($"***Barcode({Source}) response data error value (please check Keyence transmission format) " + resp);
listView21.SetText(9, 3, "ERR");//.setTitle(8, 1, "ERR");
continue;
}
if (AR.VAR.BOOL[eVarBool.JOB_PickON_Retry]) //221110
{
if (PUB.sm.Step == eSMStep.RUN)
PUB.log.AddAT($"Picker({Source}) is retrying, ignoring barcode:{resp}");
continue;
}
var MatchList = RegX.Matches(resp.Trim());
var buf = MatchList[0].Groups;
var angle = 0;
var sym = buf[1].Value; //symbol
var vData = buf[2].Value.Trim(); //data
if (Source == "R") KeyenceBarcodeDataR = vData; //rear
else KeyenceBarcodeDataF = vData; //front
//바코드 무시조건 확인
//if (PUB.Result.BCDIgnorePattern != null)
//{
// Boolean ignore = false;
// foreach (var ignoreitem in PUB.Result.BCDIgnorePattern)
// {
// if (ignoreitem.Pattern.isEmpty()) continue;
// RegX = new System.Text.RegularExpressions.Regex(ignoreitem.Pattern);
// if (RegX.IsMatch(vData))
// {
// var igmsg = "무시바코드 Patter: " + ignoreitem.Pattern + ",값=" + vData;
// ignore = true;
// break;
// }
// }
// if (ignore) continue;
//}
var vV1 = buf[3].Value.Split('/');
var vV2 = buf[4].Value.Split('/');
var vV3 = buf[5].Value.Split('/');
var vV4 = buf[6].Value.Split('/');
var vCP = buf[7].Value.Split('/');
var vertex = new Point[4];
vertex[0] = new Point(int.Parse(vV1[0]), int.Parse(vV1[1]));
vertex[1] = new Point(int.Parse(vV2[0]), int.Parse(vV2[1]));
vertex[2] = new Point(int.Parse(vV3[0]), int.Parse(vV3[1]));
vertex[3] = new Point(int.Parse(vV4[0]), int.Parse(vV4[1]));
var vertextCP = new Point(int.Parse(vCP[0]), int.Parse(vCP[1]));
var ReelCP = Point.Empty;
if (itemC.VisionData.ReelSize == eCartSize.Inch13)
ReelCP = AR.SETTING.Data.CenterPosition13;
else
ReelCP = AR.SETTING.Data.CenterPosition7;
//각도를 이곳에서 처리함
angle = (int)(GetAngle(vertex[0], vertex[1]) * 180.0 / Math.PI);
//var atkstdbcd = new StdLabelPrint.CAmkorSTDBarcode(vData);
//if (atkstdbcd.DisposalCode) //사용하지않는 103코드라면 아에 처리안함
//{
// PUB.log.AddE("***폐기된 103 코드형태라 처리하지 않음" + vData);
// continue;
//}
//특정좌표가 기준점으로부터 몇도 틀어져 있는가?
//math.atan2(PY - CY, PX - CX)
//회전후좌표계산
//x = root((px - cx) ^ 2 + (py - cy) ^ 2) * cos@ +cx
//y = root(px ^ 2 + py ^ 2) * sin@ +cy
double theta = 0.0;// Pub.Result.ItemData[1].VisionData.BaseAngle;
if (itemC.VisionData.BaseAngle(out string msg, out Class.KeyenceBarcodeData angbcd))
{
theta = angbcd.Angle;
}
var theta_rad = -theta * Math.PI / 180.0;
var PX = (int)(Math.Cos(theta_rad) * (vertextCP.X - ReelCP.X) - Math.Sin(theta_rad) * (vertextCP.Y - ReelCP.Y)) + ReelCP.X;
var PY = (int)(Math.Sin(theta_rad) * (vertextCP.X - ReelCP.X) + Math.Cos(theta_rad) * (vertextCP.Y - ReelCP.Y)) + ReelCP.Y;
float LabelAngRad = (float)(Math.Atan2(PY - ReelCP.Y, PX - ReelCP.X));// 2; //라벨의 위치값을 찾아서 입력해야한다.
var labelpos = (float)(LabelAngRad * 180.0 / Math.PI);
if (labelpos < 0) labelpos = 360 + labelpos;
byte lp = 0;
if (labelpos >= 15 * 22.5 && labelpos <= 360) lp = 6;
else if (labelpos >= 0 && labelpos <= 22.5) lp = 6;
else if (labelpos >= 1 * 22.5 && labelpos <= 3 * 22.5) lp = 3;
else if (labelpos >= 3 * 22.5 && labelpos <= 5 * 22.5) lp = 2;
else if (labelpos >= 5 * 22.5 && labelpos <= 7 * 22.5) lp = 1;
else if (labelpos >= 7 * 22.5 && labelpos <= 9 * 22.5) lp = 4;
else if (labelpos >= 9 * 22.5 && labelpos <= 11 * 22.5) lp = 7;
else if (labelpos >= 11 * 22.5 && labelpos <= 13 * 22.5) lp = 8;
else if (labelpos >= 13 * 22.5 && labelpos <= 15 * 22.5) lp = 9;
else
{
}
//중첩된 데이터가 있는가?
lock (itemC.VisionData.barcodelist)
{
//키값에 소스위치도 같이 포함한다
var valuekey = Source + vData;
var bcdin = itemC.VisionData.barcodelist.ContainsKey(valuekey);//.Where(t => t.Value.CheckIntersect(vertextCP, vData) == true).FirstOrDefault();
if (bcdin == false)
{
//신규바코드데이터이므로 추가한다.
PUB.logKeyence.Add($"{resp.Replace("\n", "").Replace("\r", "")}");
var newitem = new Class.KeyenceBarcodeData()
{
AmkorData = new StdLabelPrint.CAmkorSTDBarcode(vData),
CenterPX = vertextCP,
Data = vData,
vertex = vertex,
Angle = angle,
LabelPosition = lp,
barcodeSymbol = sym,
barcodeSource = Source,
};
var addok = itemC.VisionData.barcodelist.TryAdd(valuekey, newitem);
if (addok) PUB.log.Add($"[O]BCD RESERV[NEW:{sym}] " + Source + " " + vData);
else PUB.log.AddE($"[X]BCD RESERV[NEW:{sym}] " + Source + " " + vData);
itemC.VisionData.UpdateBarcodePositionData();
itemC.VisionData.BarcodeTouched = true;
}
else
{
//기존데이터와 좌표가 겹치면 두고 다르면 업데이트한다
var predata = itemC.VisionData.barcodelist[valuekey];
if (predata.CheckIntersect(vertextCP, vData) == false)
{
var newitem = new Class.KeyenceBarcodeData()
{
AmkorData = new StdLabelPrint.CAmkorSTDBarcode(vData),
CenterPX = vertextCP,
Data = vData,
vertex = vertex,
Angle = angle,
LabelPosition = lp,
barcodeSymbol = sym,
barcodeSource = Source,
};
//기존정보를 지우고
PUB.log.Add($"[UPD]BCD RESERV:{sym}] " + Source + " " + vData);
itemC.VisionData.barcodelist[valuekey] = newitem;
itemC.VisionData.UpdateBarcodePositionData();
itemC.VisionData.BarcodeTouched = true;
}
}
}
listView21.SetText(9, 3, $"{angle} > {theta}");
listView21.SetText(10, 3, itemC.VisionData.QRInputRaw.isEmpty() ? $"DETECT" : $"NONE");
listView21.SetText(13, 2, $"LABEL");
listView21.SetText(13, 3, $"{labelpos:N1}");
}
}
Boolean IsSIDValue(string data)
{
if (data.Length != 9) return false;
decimal a = 0;
if (decimal.TryParse(data, out a) == false) return false;
if (data.StartsWith("10") == false) return false;
return true;
}
Boolean IsDateValue(string date, out string datestr)
{
//821123 과 19821123 의 데이터를 판별한다
datestr = string.Empty;
date = date.Replace("-", "").Replace("/", "");
if (date.Length == 6)
{
var vy = date.Substring(0, 2);
var vm = date.Substring(2, 2);
var vd = date.Substring(4, 2);
if (isDigit(vy) == false || isDigit(vm) == false || isDigit(vd) == false)
return false;
if (vy.toInt() < 0 || vy.toInt() > 29) return false;
if (vm.toInt() < 1 || vm.toInt() > 12) return false;
if (vd.toInt() < 1 || vd.toInt() > 21) return false;
datestr = "20" + vy + vm + vd;
return true;
}
else if (date.Length == 8)
{
var vy = date.Substring(0, 4);
var vm = date.Substring(4, 2);
var vd = date.Substring(6, 2);
if (isDigit(vy) == false || isDigit(vm) == false || isDigit(vd) == false)
return false;
if (vy.toInt() < 2000 || vy.toInt() > 2900) return false;
if (vm.toInt() < 1 || vm.toInt() > 12) return false;
if (vd.toInt() < 1 || vd.toInt() > 31) return false;
datestr = vy + vm + vd;
return true;
}
else return false;
}
Boolean isDigit(string v)
{
int a;
return int.TryParse(v, out a);
}
string cmd = string.Empty;
DateTime LastTrigOnTime = DateTime.Now;
Boolean bTrgOn = false;
//private void Keyence_Trigger(bool bOn)
//{
// if (PUB.flag.get(eVarBool.KEYENCE_TRIGGER) == bOn) return;
// if (bOn)
// cmd = "LON";
// else
// cmd = "LOFF";
// if (bOn) LastTrigOnTime = DateTime.Now;
// string resp = reader.ExecCommand(cmd);
// bTrgOn = bOn;
// PUB.logKeyence.Add("BARCODE", $"트리거 전송({cmd})");
// _isCrevisACQ[1] = bOn;
// //트리거
// PUB.flag.set(eVarBool.KEYENCE_TRIGGER, bOn, "JOB");
//}
private void SaveImage(string filename)
{
var fi = new System.IO.FileInfo(filename);
var ext = fi.Extension;
var nameonly = fi.FullName.Replace(fi.Extension, "");
var fiF = new System.IO.FileInfo(nameonly + "F" + ext);
var fiR = new System.IO.FileInfo(nameonly + "F" + ext);
if (PUB.keyenceF != null)
{
var img = this.keyenceviewF.Image;
if (img == null) return;
using (var newimg = new Bitmap(img.Width, img.Height, img.PixelFormat))
{
PUB.keyenceR.UpdateBitmap((Bitmap)img, newimg);
if (fiF.Directory.Exists == false) fiF.Directory.Create();
if (fiF.Exists) fiF.Delete();
newimg.Save(fiF.FullName);
}
}
if (PUB.keyenceR != null)
{
var img = this.keyenceviewR.Image;
if (img == null) return;
using (var newimg = new Bitmap(img.Width, img.Height, img.PixelFormat))
{
PUB.keyenceR.UpdateBitmap((Bitmap)img, newimg);
if (fiR.Directory.Exists == false) fiR.Directory.Create();
if (fiR.Exists) fiR.Delete();
newimg.Save(fiR.FullName);
}
}
}
}
}

View File

@@ -0,0 +1,71 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using AR;
namespace Project
{
public partial class FMain
{
///// <summary>
///// RQ바코드값 사용 여부
///// </summary>
///// <param name="vData"></param>
//Boolean Process_ReturnReel(string vData)
//{
// //120326 - return 수량 관련 (오토에서만 사용한다)
// var qrbuf = vData.Split(';');
// if (vData.EndsWith(";;;") && qrbuf.Length > 4 && VAR.BOOL[eVarBool.Opt_UserQtyRQ]== false)
// {
// var qrsid = qrbuf[0].Trim();
// var qrlot = qrbuf[1].Trim();
// var qrqty = qrbuf[2].Trim();
// if (double.TryParse(qrqty, out double qtynum) && qrsid.Length == 9 && qrsid.StartsWith("10"))
// {
// //수량이 맞고 sid 가 101로 들어있는 경우에만 처리한다
// PUB.log.Add("리턴릴 임시 바코드로 확인되어 데이터를 사용합니다 값:" + vData);
// PUB.log.Add("SID값 변경함 #2 " + PUB.Result.ItemDataC.VisionData.SID + "=>" + qrsid);
// if (PUB.Result.ItemDataC.VisionData.QTY != qrqty)
// {
// PUB.AddSystemLog(AppContext.BaseDirectory, "_KEYENCE", $"리턴릴세미형태에서 QTY값을 적용 함({qrqty})");
// }
// PUB.Result.ItemDataC.VisionData.QTY = qrqty;
// PUB.Result.ItemDataC.VisionData.SID = qrsid;
// PUB.Result.ItemDataC.VisionData.VLOT = qrlot;
// }
// }
// //리턴릴수량추가확인(수동일때에만 사용)
// if (vData.StartsWith("RQ"))
// {
// //리턴릴 바코드는 무조건 적용한다
// var rqqtystr = vData.Substring(2);
// if (int.TryParse(rqqtystr, out int rqqty))
// {
// //시스템로기
// if (PUB.Result.ItemDataC.VisionData.QTY != rqqtystr || PUB.Result.ItemDataC.VisionData.QTYRQ == false)
// {
// PUB.AddSystemLog(AppContext.BaseDirectory, "_KEYENCE", $"리턴릴 QTY값 적용({rqqtystr})");
// //수량
// PUB.Result.ItemDataC.VisionData.QTYRQ = true;
// PUB.Result.ItemDataC.VisionData.QTY = rqqtystr;
// PUB.log.Add("리턴릴 바코드값=" + vData + "을 적용합니다");
// }
// }
// else
// {
// PUB.log.AddE("리턴릴 바코드값=" + vData + "을 적용 실패");
// }
// return true;
// }
// return false;
//}
}
}

View File

@@ -0,0 +1,44 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Windows.Forms;
namespace Project
{
public partial class FMain
{
delegate void ShowLotTextHandler(string value);
delegate void UpdateDMTextHandler(string value1);
//void UpdateResultText(string value1)
//{
// if (this.lbResult.InvokeRequired)
// {
// lbResult.BeginInvoke(new UpdateDMTextHandler(UpdateResultText), new object[] { value1 });
// }
// else
// {
// lbResult.Text = value1;
// }
//}
delegate void UpdateLabelTextHandler(Control ctl, string value);
void UpdateLabelText(Control ctl, string value)
{
if (ctl.InvokeRequired)
{
ctl.BeginInvoke(new UpdateLabelTextHandler(UpdateLabelText), new object[] { ctl, value });
}
else
{
ctl.Text = value;
}
}
}
}

View File

@@ -0,0 +1,63 @@
using AR;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace Project
{
public partial class FMain
{
void _Display_Interval_1min()
{
//리셋카운트
AutoResetCount();
PUB.CheckFreeSpace();
}
/// <summary>
/// 환경설정에따른 카운트를 리셋처리한다. 171128
/// </summary>
void AutoResetCount()
{
//수량누적시 자동으로 소거하게 되었다
//if (COMM.SETTING.Data.datetime_Check_1 && COMM.SETTING.Data.datetime_Reset_1 != "") //오전
//{
// try
// {
// DateTime SetTime = DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd") + " " + COMM.SETTING.Data.datetime_Reset_1 + ":00");
// DateTime LastClearTime = SETTING.Counter.;
// //현재 시간이 클리어대상 시간보다 크고, 마지막으로 클리어한 시간이 지정시간보다 작아야함
// if (DateTime.Now > SetTime && LastClearTime < SetTime)
// {
// Pub.log.AddI("Count Reset #1");
// SETTING.Counter.ClearDay();
// }
// }
// catch { }
//}
//if (COMM.SETTING.Data.datetime_Check_2 && COMM.SETTING.Data.datetime_Reset_2 != "") //오후
//{
// try
// {
// DateTime SetTime = DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd") + " " + COMM.SETTING.Data.datetime_Reset_2 + ":00");
// DateTime LastClearTime = SETTING.Counter.CountReset;
// //현재 시간이 클리어대상 시간보다 크고, 마지막으로 클리어한 시간이 지정시간보다 작아야함
// if (DateTime.Now > SetTime && LastClearTime < SetTime)
// {
// Pub.log.AddI("Count Reset #2");
// SETTING.Counter.ClearDay();
// }
// }
// catch { }
//}
}
}
}

View File

@@ -0,0 +1,629 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using AR;
namespace Project
{
public partial class FMain
{
void _Display_Interval_250ms()
{
//타워램프조정
//if (COMM.SETTING.Data.Disable_TowerLamp == false) Update_TowerLamp();
TowerLamp.Update(PUB.sm.Step);
//컨베이어가동시간을 추적한다 230926
if (VAR.BOOL[eVarBool.Use_Conveyor])
{
////왼쪽컨베이어에 아이템이 존재하는 경우에만 누적
//if (DIO.GetIOOutput(eDOName.LEFT_CONV) && VAR.BOOL[eVarBool.LEFT_ITEM_PICKOFF])
//{
// if (VAR.TIME[eVarBool.LEFT_ITEM_PICKOFF].Year == 1982)
// VAR.TIME[eVarBool.LEFT_ITEM_PICKOFF] = DateTime.Now; //시간초기화
// else
// {
// var ts = DateTime.Now - VAR.TIME[eVarBool.LEFT_ITEM_PICKOFF];
// VAR.DBL[eVarDBL.LEFT_ITEM_PICKOFF] += ts.TotalSeconds; //경과시간누적
// VAR.TIME[eVarBool.LEFT_ITEM_PICKOFF] = DateTime.Now; //시간초기화
// }
//}
////오른쪽컨베이어에 아이템이 존재하는 경우에만 누적
//if (DIO.GetIOOutput(eDOName.RIGHT_CONV) && VAR.BOOL[eVarBool.RIGT_ITEM_PICKOFF] )
//{
// if(VAR.TIME[eVarBool.RIGT_ITEM_PICKOFF].Year == 1982)
// {
// VAR.TIME[eVarBool.RIGT_ITEM_PICKOFF] = DateTime.Now; //시간초기화
// }
// else
// {
// var ts = DateTime.Now - VAR.TIME[eVarBool.RIGT_ITEM_PICKOFF];
// VAR.DBL[eVarDBL.RIGT_ITEM_PICKOFF] += ts.TotalSeconds; //경과시간누적
// VAR.TIME[eVarBool.RIGT_ITEM_PICKOFF] = DateTime.Now; //시간초기화
// }
//}
var t1 = VAR.I32[eVarInt32.LEFT_ITEM_COUNT];
var t2 = VAR.I32[eVarInt32.RIGT_ITEM_COUNT];
groupBox2.Text = $"Barcode({t1:N1}/{t2:N1})";
}
else
{
groupBox2.Text = "Barcode";
}
if((VAR.BOOL?.Get(eVarBool.Use_Conveyor) ?? false) == true)
{
btAutoReelOut.BackColor = PUB.Result.AutoReelOut ? Color.Lime : SystemColors.Control;
btAutoReelOut.Visible = true;
}
else
{
btAutoReelOut.Visible = false;
}
groupBox1.Text = $"Equipment Operation({PUB.sm.Loop_ms:N0}ms)";
//릴사이즈가 맞지 않으면 깜박인다.
if (DIO.getCartSize(1) != eCartSize.None)
{
if (VAR.BOOL[eVarBool.Use_Conveyor] == false && DIO.getCartSize(1) != DIO.getCartSize(0))
{
if (listView21.GetStyle(0, 1).BackColor != Color.Red)
{
listView21.GetStyle(0, 1).BackColor = Color.Red;
}
else
{
listView21.GetStyle(0, 1).BackColor = Color.FromArgb(32, 32, 32);
}
}
else
{
listView21.GetStyle(0, 1).BackColor = Color.FromArgb(32, 32, 32);
}
if (VAR.BOOL[eVarBool.Use_Conveyor] == false && DIO.getCartSize(1) != DIO.getCartSize(2))
{
if (listView21.GetStyle(0, 5).BackColor != Color.Red)
{
listView21.GetStyle(0, 5).BackColor = Color.Red;
}
else
{
listView21.GetStyle(0, 5).BackColor = Color.FromArgb(32, 32, 32);
}
}
else
{
listView21.GetStyle(0, 5).BackColor = Color.FromArgb(32, 32, 32);
}
}
else
{
//모두 동일하게 흑색한다
//lbSize0.BackColor = Color.FromArgb(32, 32, 32);
//lbSize1.BackColor = Color.FromArgb(32, 32, 32);
//lbSize2.BackColor = Color.FromArgb(32, 32, 32);
listView21.GetStyle(0, 1).BackColor = Color.FromArgb(32, 32, 32);
listView21.GetStyle(0, 3).BackColor = Color.FromArgb(32, 32, 32);
listView21.GetStyle(0, 5).BackColor = Color.FromArgb(32, 32, 32);
listView21.GetStyle(0, 1).ForeColor = Color.White;
listView21.GetStyle(0, 3).ForeColor = Color.White;
listView21.GetStyle(0, 5).ForeColor = Color.White;
}
//락정보
var l0 = DIO.GetIOOutput(eDOName.PORTL_MAGNET);
var l1 = DIO.GetIOOutput(eDOName.PORTC_MAGNET);
var l2 = DIO.GetIOOutput(eDOName.PORTR_MAGNET);
lbLock0.Text = l0 ? "Cart Exchange" : "No Cart";
lbLock1.Text = l1 ? "Cart Exchange" : "No Cart";
lbLock2.Text = l2 ? "Cart Exchange" : "No Cart";
var sbVisTitle0 = listView21.GetCell(0, 1);
var sbVisTitle2 = listView21.GetCell(0, 5);
if (PUB.wsL == null || PUB.wsL.Connected == false)
{
sbVisTitle0.ForeColor = Color.Red;
}
else
{
//데이터수신시간에 따른 색상
var tswecv = DateTime.Now - VAR.TIME[eVarTime.lastRecvWSL];
if (tswecv.TotalSeconds > 5)
{
sbVisTitle0.ForeColor = Color.HotPink;
}
else
{
if (PUB.flag.get(eVarBool.FG_RDY_CAMERA_L))
sbVisTitle0.ForeColor = Color.Lime;
else
sbVisTitle0.ForeColor = Color.Magenta;
}
}
//
if (PUB.wsR == null || PUB.wsR.Connected == false)
{
sbVisTitle2.ForeColor = Color.Red;
}
else
{
var tswecv = DateTime.Now - VAR.TIME[eVarTime.lastRecvWSR];
if (tswecv.TotalSeconds > 5)
{
sbVisTitle2.ForeColor = Color.HotPink;
}
else
{
if (PUB.flag.get(eVarBool.FG_RDY_CAMERA_R))
sbVisTitle2.ForeColor = Color.Lime;
else
sbVisTitle2.ForeColor = Color.Magenta;
}
}
//arLabel18.Text = camliveBusy ? "카메라 (라이브뷰)" : "카메라";
btStart.Enabled = PUB.flag.get(eVarBool.FG_MOVE_PICKER) == false;
btStop.Enabled = PUB.flag.get(eVarBool.FG_MOVE_PICKER) == false;
btSetting.Enabled = PUB.flag.get(eVarBool.FG_MOVE_PICKER) == false;
//btPickerMove.Visible = (Pub.mot.IsInit && PUB.mot.HasHomeSetOff == true); //피커의 수동 이동 버튼표시여부
var hwcol = 0;
if (PUB.keyenceF != null)
{
HWState.setTitle(1, hwcol, (PUB.keyenceF.IsConnect ? (PUB.keyenceF.IsTriggerOn ? "TRIG" : "ON") : "OFF"));
if (PUB.keyenceF.IsConnect)
{
if (PUB.keyenceF.IsTriggerOn)
{
HWState.setValue(1, hwcol, 2);
}
else
{
HWState.setValue(1, hwcol, 1);
}
}
else
{
HWState.setValue(1, hwcol, 3);
}
}
else
{
HWState.setTitle(1, hwcol, "SET");
HWState.setValue(1, hwcol, 0);
}
hwcol++;
if (PUB.keyenceR != null)
{
HWState.setTitle(1, hwcol, (PUB.keyenceR.IsConnect ? (PUB.keyenceR.IsTriggerOn ? "TRIG" : "ON") : "OFF"));
if (PUB.keyenceR.IsConnect)
{
if (PUB.keyenceR.IsTriggerOn)
{
HWState.setValue(1, hwcol, 2);
}
else
{
HWState.setValue(1, hwcol, 1);
}
}
else
{
HWState.setValue(1, hwcol, 3);
}
}
else
{
HWState.setTitle(1, hwcol, "SET");
HWState.setValue(1, hwcol, 0);
}
hwcol++;
if (PUB.wsL != null)
{
HWState.setTitle(1, hwcol, (PUB.wsL.Connected ? "ON" : "OFF"));
HWState.setValue(1, hwcol++, (ushort)(PUB.wsL.Connected ? 1 : 3));
}
if (PUB.wsR != null)
{
HWState.setTitle(1, hwcol, (PUB.wsR.Connected ? "ON" : "OFF"));
HWState.setValue(1, hwcol++, (ushort)(PUB.wsR.Connected ? 1 : 3));
}
HWState.setTitle(1, hwcol, (PUB.BarcodeFix.IsOpen() ? AR.SETTING.Data.Barcode_Port : "OFF"));
HWState.setValue(1, hwcol++, (ushort)(PUB.BarcodeFix.IsOpen() ? 1 : 3));
if (PUB.PrinterL != null)
{
HWState.setTitle(1, hwcol, (PUB.PrinterL.IsOpen ? AR.SETTING.Data.PrintL_Port : "OFF"));
HWState.setValue(1, hwcol++, (ushort)(PUB.PrinterL.IsOpen ? 1 : 3));
}
else HWState.setTitle(1, hwcol++, "SET");
if (PUB.PrinterR != null)
{
HWState.setTitle(1, hwcol, (PUB.PrinterR.IsOpen ? AR.SETTING.Data.PrintR_Port : "OFF"));
HWState.setValue(1, hwcol++, (ushort)(PUB.PrinterR.IsOpen ? 1 : 3));
}
else HWState.setTitle(1, hwcol++, "SET");
if (PUB.plc != null)
{
HWState.setTitle(1, hwcol, (PUB.plc.Init ? AR.SETTING.Data.swplc_name : "OFF"));
HWState.setValue(1, hwcol++, (ushort)(PUB.plc.Init ? 2 : 1));
}
else HWState.setTitle(1, hwcol++, "SET");
HWState.Invalidate();
IOState.setTitle(0, 0, $"{PUB.sm.Step}"); //this.sbStep.Text = Pub.sm.Step.ToString();
IOState.setTitle(0, 9, $"MC({PUB.MCCode}/{AR.SETTING.Data.McName})");
IOState.setTitle(1, 0, $"{PUB.sm.Loop_ms.ToString("N1")}ms");// / " + intlockcnt.ToString();io
IOState.setValue(0, 1, (ushort)(DIO.isSaftyDoorF(2, false) ? 0 : 2));
IOState.setValue(0, 2, (ushort)(DIO.isSaftyDoorF(1, false) ? 0 : 2));
IOState.setValue(0, 3, (ushort)(DIO.isSaftyDoorF(0, false) ? 0 : 2));
IOState.setValue(1, 1, (ushort)(DIO.GetIOOutput(eDOName.BUZZER) ? 2 : 0));
IOState.setValue(1, 2, (ushort)(DIO.GetIOOutput(eDOName.ROOMLIGHT) ? 1 : 0));
IOState.setValue(1, 3, (ushort)(DIO.GetIOInput(eDIName.AIR_DETECT) ? 1 : 0));
IOState.setValue(0, 4, (ushort)(DIO.GetIOInput(eDIName.PORTL_DET_UP) ? 1 : 0));
IOState.setValue(0, 5, (ushort)(DIO.GetIOInput(eDIName.PORTC_DET_UP) ? 1 : 0));
IOState.setValue(0, 6, (ushort)(DIO.GetIOInput(eDIName.PORTR_DET_UP) ? 1 : 0));
IOState.setValue(1, 4, (ushort)(DIO.GetIOInput(eDIName.PORTL_LIM_UP) ? 2 : 0));
IOState.setValue(1, 5, (ushort)(DIO.GetIOInput(eDIName.PORTC_LIM_UP) ? 2 : 0));
IOState.setValue(1, 6, (ushort)(DIO.GetIOInput(eDIName.PORTR_LIM_UP) ? 2 : 0));
IOState.setValue(1, 9, (ushort)(PUB.flag.get(eVarBool.FG_KEYENCE_TRIGGER) ? 2 : 0));
IOState.setValue(0, 10, (ushort)(PUB.flag.get(eVarBool.VS_DETECT_REEL_L) ? 2 : 0)); //reel-left detect
IOState.setValue(0, 11, (ushort)(PUB.flag.get(eVarBool.VS_DETECT_REEL_R) ? 2 : 0)); //reel-right detect
IOState.setValue(1, 10, (ushort)(PUB.flag.get(eVarBool.VS_DETECT_CONV_L) ? 2 : 0)); //conv-left detect
IOState.setValue(1, 11, (ushort)(PUB.flag.get(eVarBool.VS_DETECT_CONV_R) ? 2 : 0)); //conv-right detect
IOState.Invalidate();
if (PUB.Result.isSetvModel)
{
var modelVision = PUB.Result.vModel;
var modelName = modelVision.Title;
var modelNameM = string.Empty;
if (PUB.Result.isSetmModel) modelNameM = PUB.Result.mModel.Title;
if (modelNameM.ToUpper().StartsWith("CONV"))
{
arLabel1.Text = "CONVEYOR ON";
arLabel1.ForeColor = Color.Blue;
}
else
{
arLabel1.Text = "CONVEYOR OFF";
arLabel1.ForeColor = Color.Red;
}
//시스템바이패스
if (SETTING.Data.SystemBypass)
{
lbModelName.Text = $"SYSTEM BYPASS";
lbModelName.ForeColor = Color.White;
lbModelName.BackColor = Color.Blue;
lbModelName.BackColor2 = Color.DeepSkyBlue;
lbModelName.ShadowColor = Color.DimGray;
}
else
{
//바이패스는 색깔을 달리한다.
if (modelName.ToUpper().Contains("BYPASS"))
{
lbModelName.Text = $"{modelName}";
lbModelName.ForeColor = Color.DarkGreen;
lbModelName.BackColor = Color.Gold;
lbModelName.BackColor2 = Color.Yellow;
lbModelName.ShadowColor = Color.WhiteSmoke;
}
else if (modelName.ToUpper().Contains("CONVERT"))
{
lbModelName.Text = $"{modelName}";
lbModelName.ForeColor = Color.DarkBlue;
lbModelName.BackColor = Color.Gold;
lbModelName.BackColor2 = Color.Yellow;
lbModelName.ShadowColor = Color.WhiteSmoke;
}
else
{
var custname = VAR.STR[eVarString.JOB_CUSTOMER_CODE];
if (custname.isEmpty() == false)
lbModelName.Text = $"[{custname}] {modelName}";
else
lbModelName.Text = $"{modelName}";
lbModelName.ForeColor = Color.Black;
lbModelName.BackColor = Color.White;
lbModelName.BackColor2 = Color.WhiteSmoke;
lbModelName.ShadowColor = Color.DimGray;
}
}
}
else
{
lbModelName.Text = "Please select a model";
lbModelName.ForeColor = Color.Blue;
lbModelName.BackColor = Color.Tomato;
lbModelName.BackColor2 = Color.Red;
lbModelName.ShadowColor = Color.DimGray;
}
arLabel1.BackColor = lbModelName.BackColor;
arLabel1.BackColor2 = lbModelName.BackColor2;
try
{
//바코드정보표시
var row = 1;
var col = 1;
Class.VisionData visdata = PUB.Result.ItemDataL.VisionData;
listView21.SetText(row++, col, visdata.RID);
listView21.SetText(row++, col, visdata.SID);
listView21.SetText(row++, col, visdata.QTY);
listView21.SetText(row++, col, visdata.VNAME);
listView21.SetText(row++, col, visdata.VLOT);
listView21.SetText(row++, col, visdata.MFGDATE);
listView21.SetText(row++, col, visdata.PARTNO);
listView21.SetText(row++, col, visdata.ReelSize == eCartSize.None ? "--" : visdata.ReelSize.ToString());
if (PUB.flag.get(eVarBool.FG_ENABLE_LEFT) == false)
{
sbVisTitle0.Text = "DISABLE";
sbVisTitle0.BackColor = Color.Orange;
sbVisTitle0.BackColor2 = Color.Tomato;
}
else
{
listView21.SetText(0, col, DIO.getCartSize(0) == eCartSize.None ? "?" : DIO.getCartSize(0).ToString());
}
if (VAR.BOOL[eVarBool.Use_Conveyor]) listView21.GetStyle(0, 1).ForeColor = Color.White;
else
listView21.GetStyle(0, 1).ForeColor = AR.SETTING.Data.Detect_CartL ? Color.White : Color.Red;
if (VAR.BOOL[eVarBool.Use_Conveyor]) listView21.GetStyle(0, 5).ForeColor = Color.White;
else
listView21.GetStyle(0, 5).ForeColor = AR.SETTING.Data.Detect_CartR ? Color.White : Color.Red;
//lbSize0.ForeColor = COMM.SETTING.Data.Detect_CartL ? Color.White : Color.Red;
listView21.SetText(row, col, visdata.RID2);
if (visdata.RID2.isEmpty() == false && visdata.RID.Equals(visdata.RID2) == false) listView21.SetColor(row++, col - 1, 2);
else listView21.SetColor(row++, col, 1);
listView21.SetText(row, col, visdata.SID2);
if (visdata.SID2.isEmpty() == false && visdata.SID.Equals(visdata.SID2) == false) listView21.SetColor(row++, col - 1, 2);
else listView21.SetColor(row++, col - 1, 1);
if (visdata.QTY2.Equals("0")) listView21.SetText(row, 1, string.Empty);
else listView21.SetText(row, col, visdata.QTY2);
if (visdata.QTY2.isEmpty() == false && visdata.QTY2.Equals("0") == false && visdata.QTY.Equals(visdata.QTY2) == false) listView21.SetColor(row++, col - 1, 2);
else listView21.SetColor(row++, col - 1, 1);
listView21.SetText(row, col, visdata.VNAME2);
if (visdata.VNAME2.isEmpty() == false && visdata.VNAME.Equals(visdata.VNAME2) == false) listView21.SetColor(row++, col - 1, 2);
else listView21.SetColor(row++, col - 1, 1);
listView21.SetText(row, col, visdata.VLOT2);
if (visdata.VLOT2.isEmpty() == false && visdata.VLOT.Equals(visdata.VLOT2) == false) listView21.SetColor(row++, col - 1, 2);
else listView21.SetColor(row++, col - 1, 1);
listView21.SetText(row, col, visdata.MFGDATE2);
if (visdata.MFGDATE2.isEmpty() == false && visdata.MFGDATE.Equals(visdata.MFGDATE2) == false) listView21.SetColor(row++, col - 1, 2);
else listView21.SetColor(row++, col - 1, 1);
listView21.SetText(row, col, visdata.PARTNO2);
if (visdata.PARTNO2.isEmpty() == false && visdata.PARTNO.Equals(visdata.PARTNO2) == false) listView21.SetColor(row++, col - 1, 2);
else listView21.SetColor(row++, col - 1, 1);
}
catch { }
try
{
var visdata = PUB.Result.ItemDataC.VisionData;
Color textColor = visdata.Confirm ? Color.Lime : Color.WhiteSmoke;
var row = 1;
var col = 3;
this.listView21.SetText(row, col, visdata.RID);
if (visdata.RID_Trust)
{
if (visdata.RIDNew) //new reelid mode
{
listView21.SetColor(row++, col - 1, 3);
}
else
{
listView21.SetColor(row++, col - 1, 6);
}
}
else
{
listView21.SetColor(row++, col - 1, 0);
}
if (visdata.SID0.isEmpty())
listView21.SetText(row, col, visdata.SID);
else
listView21.SetText(row, col, visdata.SID + "\n<< " + visdata.SID0);
listView21.SetColor(row++, col - 1, (ushort)(visdata.SID_Trust ? 6 : 0));
if (PUB.Result.ItemDataC.VisionData.QTYRQ)
{
listView21.SetText(row, col, "RQ:" + visdata.QTY);
listView21.SetColor(row++, col - 1, 6);
}
else
{
if (visdata.QTY.Equals("0")) listView21.SetText(row, col, string.Empty);
else listView21.SetText(row, col, visdata.QTY);
listView21.SetColor(row++, col - 1, (ushort)(visdata.QTY_Trust ? 6 : 0));
}
listView21.SetText(row, col, visdata.VNAME); listView21.SetColor(row++, col - 1, (ushort)(visdata.VNAME_Trust ? 6 : 0));
listView21.SetText(row, col, visdata.VLOT); listView21.SetColor(row++, col - 1, (ushort)(visdata.VLOT_Trust ? 6 : 0));
listView21.SetText(row, col, visdata.MFGDATE); listView21.SetColor(row++, col - 1, (ushort)(visdata.MFGDATE_Trust ? 6 : 0));
listView21.SetText(row, col, visdata.PARTNO); listView21.SetColor(row++, col - 1, (ushort)(visdata.PARTNO_Trust ? 6 : 0));
//lbSize1.Text = DIO.getCartSize(1) == eCartSize.None ? "?" : DIO.getCartSize(1).ToString();
listView21.SetText(0, col, DIO.getCartSize(1) == eCartSize.None ? "?" : DIO.getCartSize(1).ToString());
listView21.GetStyle(0, col - 1).ForeColor = AR.SETTING.Data.Detect_CartC ? Color.White : Color.Red;
listView21.SetText(row++, col, visdata.ReelSize == eCartSize.None ? "--" : visdata.ReelSize.ToString());
//Degree
row++; //gridView2.setTitle(row++, 1, visdata.PARTNO);
//QR
row++; //gridView2.setTitle(row++, 1, visdata.PARTNO);
//바코드수량
//listView21.SetText(row, col-1, "BACD");
listView21.SetText(row++, col, $"{visdata.barcodelist.Count}");
listView21.SetText(row, col - 1, "REGEX");
listView21.SetText(row++, col, $"{PUB.Result.BCDPattern.Count}");
row++;//
listView21.SetText(row, col - 1, "BATCH");
listView21.SetText(row++, col, $"{visdata.BATCH}");
listView21.SetText(row, col - 1, "MAX");
listView21.SetText(row++, col, $"{visdata.QTYMAX}");
var textcolor = visdata.Confirm ? 7 : 0;
var crow = 1;
listView21.SetColor(crow++, 3, textcolor);
listView21.SetColor(crow++, 3, textcolor);
listView21.SetColor(crow++, 3, textcolor);
listView21.SetColor(crow++, 3, textcolor);
listView21.SetColor(crow++, 3, textcolor);
listView21.SetColor(crow++, 3, textcolor);
listView21.SetColor(crow++, 3, textcolor);
//arLabel25.ForeColor = textColor;
//listView21.SetColor(2, 1, (visdata.QTYRQ ? 3 : 1));
}
catch { }
try
{
var row = 1;
var col = 5;
Class.VisionData visdata = PUB.Result.ItemDataR.VisionData;
listView21.SetText(row++, col, visdata.RID);
listView21.SetText(row++, col, visdata.SID);
listView21.SetText(row++, col, visdata.QTY);
listView21.SetText(row++, col, visdata.VNAME);
listView21.SetText(row++, col, visdata.VLOT);
listView21.SetText(row++, col, visdata.MFGDATE);
listView21.SetText(row++, col, visdata.PARTNO);
listView21.SetText(row++, col, visdata.ReelSize == eCartSize.None ? "--" : visdata.ReelSize.ToString());
if (PUB.flag.get(eVarBool.FG_ENABLE_RIGHT) == false)
{
sbVisTitle2.Text = "DISABLE";
sbVisTitle2.BackColor = Color.Orange;
sbVisTitle2.BackColor2 = Color.Tomato;
}
else
{
listView21.SetText(0, col, DIO.getCartSize(2) == eCartSize.None ? "?" : DIO.getCartSize(2).ToString());
}
listView21.GetStyle(0, col).ForeColor = AR.SETTING.Data.Detect_CartR ? Color.White : Color.Red;
//lbSize2.Text = DIO.getCartSize(2) == eCartSize.None ? "?" : DIO.getCartSize(2).ToString();
//lbSize2.ForeColor = COMM.SETTING.Data.Detect_CartR ? Color.White : Color.Red;
listView21.SetText(row, col, visdata.RID2);
if (visdata.RID2.isEmpty() == false && visdata.RID.Equals(visdata.RID2) == false) listView21.SetColor(row++, col - 1, 2);
else listView21.SetColor(row++, col - 1, 1);
listView21.SetText(row, col, visdata.SID2);
if (visdata.SID2.isEmpty() == false && visdata.SID.Equals(visdata.SID2) == false) listView21.SetColor(row++, col - 1, 2);
else listView21.SetColor(row++, col - 1, 1);
if (visdata.QTY2.Equals("0")) listView21.SetColor(row, col, 0);
else listView21.SetText(row, col, visdata.QTY2);
if (visdata.QTY2.isEmpty() == false && visdata.QTY2.Equals("0") == false && visdata.QTY.Equals(visdata.QTY2) == false) listView21.SetColor(row++, col - 1, 2);
else listView21.SetColor(row++, col - 1, 1);
listView21.SetText(row, col, visdata.VNAME2);
if (visdata.VNAME2.isEmpty() == false && visdata.VNAME.Equals(visdata.VNAME2) == false) listView21.SetColor(row++, col - 1, 2);
else listView21.SetColor(row++, col - 1, 1);
listView21.SetText(row, col, visdata.VLOT2);
if (visdata.VLOT2.isEmpty() == false && visdata.VLOT.Equals(visdata.VLOT2) == false) listView21.SetColor(row++, col - 1, 2);
else listView21.SetColor(row++, col - 1, 1);
listView21.SetText(row, col, visdata.MFGDATE2);
if (visdata.MFGDATE2.isEmpty() == false && visdata.MFGDATE.Equals(visdata.MFGDATE2) == false) listView21.SetColor(row++, col - 1, 2);
else listView21.SetColor(row++, col - 1, 1);
listView21.SetText(row, col, visdata.PARTNO2);
if (visdata.PARTNO2.isEmpty() == false && visdata.PARTNO.Equals(visdata.PARTNO2) == false) listView21.SetColor(row++, col - 1, 2);
else listView21.SetColor(row++, col - 1, 1);
}
catch { }
listView21.Invalidate();
listView21.Refresh();
lbLock0.BackColor = l0 ? Color.FromArgb(0xff, 0x4c, 0x0e) : Color.FromArgb(32, 32, 32);
lbLock0.BackColor2 = l0 ? Color.FromArgb(0xff, 0x4c, 0x0e) : Color.FromArgb(80, 80, 80);
lbLock1.BackColor = l1 ? Color.FromArgb(0xff, 0x4c, 0x0e) : Color.FromArgb(32, 32, 32);
lbLock1.BackColor2 = l1 ? Color.FromArgb(0xff, 0x4c, 0x0e) : Color.FromArgb(80, 80, 80);
lbLock2.BackColor = l2 ? Color.FromArgb(0xff, 0x4c, 0x0e) : Color.FromArgb(32, 32, 32);
lbLock2.BackColor2 = l2 ? Color.FromArgb(0xff, 0x4c, 0x0e) : Color.FromArgb(80, 80, 80);
//display mesasge
UpdateStatusMessage(); //left
}
}
}

View File

@@ -0,0 +1,63 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using AR;
namespace Project
{
public partial class FMain
{
void _Display_Interval_500ms()
{
//홈진행중에는 모델쪽을 건드릴수 없게 한다
toolStripButton7.Enabled = !PUB.sm.Step.ToString().StartsWith("HOME");
//현재시간표시
if (PUB.sm.Step == eSMStep.INIT)
lbTime.Text = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
else
lbTime.Text = PUB.sm.UpdateTime.ToString("yyyy-MM-dd HH:mm:ss");
//키엔스 데이터를 바로 표시한다.
tbBarcodeF.Text = KeyenceBarcodeDataF;
tbBarcodeR.Text = KeyenceBarcodeDataR;
lbCntLeft.Text = $"{VAR.I32[eVarInt32.LPickOfCount]}";
lbCntRight.Text = $"{VAR.I32[eVarInt32.RPickOfCount]}";
lbCntPicker.Text = $"{VAR.I32[eVarInt32.PickOfCount]}";
//lbCntPrnL.Text = $"{SETTING.Counter.CountPrintL}";
//lbCnrPrnR.Text = $"{SETTING.Counter.CountPrintR}";
if (AR.SETTING.Data.Enable_SpeedLimit)
grpProgress.Text = $"작업 수량(속도제한:{AR.SETTING.Data.LimitSpeed})";
else
grpProgress.Text = $"작업 수량";
//display Room Light
btLightRoom.BackColor = DIO.GetIOOutput(eDOName.ROOMLIGHT) ? Color.Gold : SystemColors.Control;
//상태를 DB에 저장한다.
//EEMStatus.UpdateStatusSQL(PUB.sm.Step);
//컨베이어 가동시간계싼
if(DIO.GetIOOutput(eDOName.LEFT_CONV) && VAR.TIME[eVarTime.CONVL_START].Year != 1982)
{
var t = (DateTime.Now - VAR.TIME[eVarTime.CONVL_START]).TotalSeconds;
if (t > 999) t = 999;
VAR.DBL[eVarDBL.CONVL_RUNTIME] = t;
}
if (DIO.GetIOOutput(eDOName.RIGHT_CONV) && VAR.TIME[eVarTime.CONVR_START].Year != 1982)
{
var t = (DateTime.Now - VAR.TIME[eVarTime.CONVR_START]).TotalSeconds;
if (t > 999) t = 999;
VAR.DBL[eVarDBL.CONVR_RUNTIME] = t;
}
}
}
}

View File

@@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace Project
{
public partial class FMain
{
void _Display_Interval_5min()
{
//남은디스크확인
PUB.CheckFreeSpace();
}
}
}

View File

@@ -0,0 +1,367 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using AR;
namespace Project
{
public partial class FMain
{
DateTime tm500minute = DateTime.Now.AddDays(-1);
DateTime tm250minute = DateTime.Now.AddDays(-1);
DateTime tm1minute = DateTime.Now.AddDays(-1);
DateTime tm5minute = DateTime.Now;
Boolean displayOn = false;
Boolean needShowSummary = false;
private void _DisplayTimer(object sender, EventArgs e)
{
if (displayOn == false) displayOn = true;
else
{
PUB.log.AddAT("Display Timer Overlab");// Console.WriteLine("display overlab");
return;
}
//lbOnline.Text = COMM.SETTING.Data.OnlineMode ? "ON-LINE" : "OFF-LINE";
//lbOnline.ForeColor = COMM.SETTING.Data.OnlineMode ? Color.Black : Color.Red;
//toolStripLabel1.Visible = Pub.Result.DryRun;
//if(Pub.Result.DryRun)
//{
// if (toolStripLabel1.ForeColor == Color.Red) toolStripLabel1.ForeColor = Color.Black;
// else toolStripLabel1.ForeColor = Color.Red;
//}
try
{
UpdateDisplayTimerData();
}
catch
{
}
//작업수량 업데이트
UpdateJobCount();
#region "250ms time 루틴"
var ts250 = DateTime.Now - tm250minute;
if (ts250.TotalMilliseconds >= 250)
{
_Display_Interval_250ms();
tm250minute = DateTime.Now;
}
#endregion
#region "500ms time 루틴"
var ts500 = DateTime.Now - tm500minute;
if (ts500.TotalMilliseconds >= 500)
{
_Display_Interval_500ms();
tm500minute = DateTime.Now;
}
#endregion
#region retgion"1분 time 루틴"
var ts = DateTime.Now - tm1minute;
if (ts.TotalMinutes >= 1)
{
//리셋카운트
_Display_Interval_1min();
tm1minute = DateTime.Now;
}
#endregion
#region retgion"5분 time 루틴"
ts = DateTime.Now - tm5minute;
if (ts.TotalMinutes >= 5)
{
//남은디스크확인
_Display_Interval_5min();
tm5minute = DateTime.Now;
}
#endregion
displayOn = false;
}
void UpdateDisplayTimerData()
{
if (PUB.sm.Step > eSMStep.INIT &&
panTopMenu.Enabled == false) panTopMenu.Enabled = true;
//쓰레드로인해서 메인에서 진행하게한다. SPS는 메인쓰레드에서 진행 됨
//팝을 제거 혹은 표시하는 기능
if (PUB.popup.needShow) PUB.popup.showMessage();
else if (PUB.popup.needClose) PUB.popup.Visible = false; // .setVision(false)();
////업로드화면을 표시해야하느 ㄴ경우
if (needShowSummary)
{
ShowSummary();
needShowSummary = false;
}
//시스템 정보를 메인 UI에 표시한다
UpdateLoaderDisplay();
}
void UpdateJobCount()
{
}
void UpdateLoaderDisplay()
{
hmi1.L_PICK_FW = DIO.GetIOInput(eDIName.L_PICK_FW); //피커의 실린더 전후진 상태
hmi1.L_PICK_BW = DIO.GetIOInput(eDIName.L_PICK_BW); //피커의 실린더 전후진 상태
hmi1.R_PICK_FW = DIO.GetIOInput(eDIName.R_PICK_FW); //피커의 실린더 전후진 상태
hmi1.R_PICK_BW = DIO.GetIOInput(eDIName.R_PICK_BW); //피커의 실린더 전후진 상태
hmi1.PrintLPICK = DIO.GetIOInput(eDIName.L_PICK_VAC);
hmi1.PrintRPICK = DIO.GetIOInput(eDIName.R_PICK_VAC);
hmi1.arPortLItemOn = PUB.flag.get(eVarBool.FG_PORTL_ITEMON);
hmi1.arPortRItemOn = PUB.flag.get(eVarBool.FG_PORTR_ITEMON);
hmi1.arPLItemON = PUB.flag.get(eVarBool.FG_PL_ITEMON);
hmi1.arPRItemON = PUB.flag.get(eVarBool.FG_PR_ITEMON);
hmi1.arFGVision0RDY = PUB.flag.get(eVarBool.FG_PRC_VISIONL);
hmi1.arFGVision1RDY = false;// PUB.flag.get(eVarBool.RDY_VISION1);
hmi1.arFGVision2RDY = PUB.flag.get(eVarBool.FG_PRC_VISIONR);
hmi1.arFGVision0END = PUB.flag.get(eVarBool.FG_END_VISIONL);
hmi1.arFGVision1END = false;// PUB.flag.get(eVarBool.END_VISION1);
hmi1.arFGVision2END = PUB.flag.get(eVarBool.FG_END_VISIONR);
hmi1.arFGPrinter0RDY = PUB.flag.get(eVarBool.FG_RUN_PRINTL);
hmi1.arFGPrinter1RDY = PUB.flag.get(eVarBool.FG_RUN_PRINTR);
hmi1.arFGPrinter0END = PUB.flag.get(eVarBool.FG_OK_PRINTL);
hmi1.arFGPrinter1END = PUB.flag.get(eVarBool.FG_OK_PRINTR);
hmi1.arMagnet0 = DIO.GetIOOutput(eDOName.PORTL_MAGNET);
hmi1.arMagnet1 = DIO.GetIOOutput(eDOName.PORTC_MAGNET);
hmi1.arMagnet2 = DIO.GetIOOutput(eDOName.PORTR_MAGNET);
hmi1.arPickerSafeZone = DIO.GetIOInput(eDIName.PICKER_SAFE);
hmi1.arMotPosNamePX = MOT.GetPosName(eAxis.PX_PICK);
hmi1.arMotPosNamePZ = MOT.GetPosName(eAxis.PZ_PICK);
hmi1.arMotPosNameLM = MOT.GetPosName(eAxis.PL_MOVE);
hmi1.arMotPosNameLZ = MOT.GetPosName(eAxis.PL_UPDN);
hmi1.arMotPosNameRM = MOT.GetPosName(eAxis.PR_MOVE);
hmi1.arMotPosNameRZ = MOT.GetPosName(eAxis.PR_UPDN);
hmi1.arMotILockPKX = PUB.iLock[(int)eAxis.PX_PICK].IsEmpty() == false;
hmi1.arMotILockPKZ = PUB.iLock[(int)eAxis.PZ_PICK].IsEmpty() == false;
hmi1.arMotILockPLM = PUB.iLock[(int)eAxis.PL_MOVE].IsEmpty() == false;
hmi1.arMotILockPLZ = PUB.iLock[(int)eAxis.PL_UPDN].IsEmpty() == false;
hmi1.arMotILockPRM = PUB.iLock[(int)eAxis.PR_MOVE].IsEmpty() == false;
hmi1.arMotILockPRZ = PUB.iLock[(int)eAxis.PR_UPDN].IsEmpty() == false;
hmi1.arMotILockPRL = PUB.iLockPRL.IsEmpty() == false;
hmi1.arMotILockPRR = PUB.iLockPRR.IsEmpty() == false;
hmi1.arMotILockVS0 = PUB.iLockVS0.IsEmpty() == false;
hmi1.arMotILockVS1 = PUB.iLockVS1.IsEmpty() == false;
hmi1.arMotILockVS2 = PUB.iLockVS2.IsEmpty() == false;
hmi1.arMotILockCVL = PUB.iLockCVL.IsEmpty() == false;
hmi1.arMotILockCVR = PUB.iLockCVR.IsEmpty() == false;
hmi1.arIsRunning = PUB.sm.isRunning;
hmi1.arUnloaderSeq = PUB.Result.UnloaderSeq;
//연결상태
hmi1.arConn_MOT = PUB.mot.IsInit;
hmi1.arConn_DIO = PUB.dio.IsInit;
hmi1.arAIRDetect = DIO.GetIOInput(eDIName.AIR_DETECT);
hmi1.arJobEND = PUB.flag.get(eVarBool.FG_JOB_END);
hmi1.arConn_REM = PUB.remocon.IsOpen();
hmi1.arDI_Emergency = DIO.GetIOInput(eDIName.BUT_EMGF) == true;
hmi1.arDI_SaftyOk = DIO.isSaftyDoorF();
hmi1.arVisionProcessL = PUB.flag.get(eVarBool.FG_PRC_VISIONL);
hmi1.arVisionProcessC = false;// PUB.flag.get(eVarBool.RDY_VISION1);
hmi1.arVisionProcessR = PUB.flag.get(eVarBool.FG_PRC_VISIONR);
try
{
hmi1.arVision_RID = PUB.Result.ItemDataC.VisionData.RID; //200925
hmi1.arVision_SID = PUB.Result.ItemDataC.VisionData.SID; //200925
hmi1.arVar_Picker[0].PortPos = PUB.Result.ItemDataL.PortPos; //200925
}
catch { }
for (short i = 0; i < 3; i++)
{
if (PUB.mot != null && PUB.mot.IsInit)
{
hmi1.arMOT_HSet[i] = PUB.mot.IsHomeSet(i);
hmi1.arMOT_Alm[i] = PUB.mot.IsServAlarm(i);
hmi1.arMOT_LimUp[i] = PUB.mot.IsLimitP(i);
hmi1.arMOT_LimDn[i] = PUB.mot.IsLimitN(i);
hmi1.arMOT_Origin[i] = PUB.mot.IsOrg(i);
hmi1.arMOT_SVOn[i] = PUB.mot.IsServOn(i);
}
else
{
hmi1.arMOT_HSet[i] = false;
hmi1.arMOT_Alm[i] = false;
hmi1.arMOT_LimUp[i] = false;
hmi1.arMOT_LimDn[i] = false;
hmi1.arMOT_Origin[i] = false;
hmi1.arMOT_SVOn[i] = false;
}
}
//포트 리밋센서
hmi1.arVar_Port[0].LimitLower = DIO.GetIOInput(eDIName.PORTL_LIM_DN); //front-left
hmi1.arVar_Port[0].LimitUpper = DIO.GetIOInput(eDIName.PORTL_LIM_UP);
hmi1.arVar_Port[0].DetectUp = DIO.GetIOInput(eDIName.PORTL_DET_UP);
hmi1.arVar_Port[0].SaftyErr = !DIO.isSaftyDoorF(0, false);
hmi1.arVar_Port[0].reelCount = SETTING.Counter.CountP0;
hmi1.arVar_Port[0].CartSize = (int)DIO.getCartSize(0);
hmi1.arVar_Port[1].LimitLower = DIO.GetIOInput(eDIName.PORTC_LIM_DN); //front-right
hmi1.arVar_Port[1].LimitUpper = DIO.GetIOInput(eDIName.PORTC_LIM_UP);
hmi1.arVar_Port[1].DetectUp = DIO.GetIOInput(eDIName.PORTC_DET_UP);
hmi1.arVar_Port[1].SaftyErr = !DIO.isSaftyDoorF(1, false);
hmi1.arVar_Port[1].reelCount = SETTING.Counter.CountP1;
hmi1.arVar_Port[1].CartSize = (int)DIO.getCartSize(1);
hmi1.arVar_Port[2].LimitLower = DIO.GetIOInput(eDIName.PORTR_LIM_DN); //front-left
hmi1.arVar_Port[2].LimitUpper = DIO.GetIOInput(eDIName.PORTR_LIM_UP);
hmi1.arVar_Port[2].DetectUp = DIO.GetIOInput(eDIName.PORTR_DET_UP);
hmi1.arVar_Port[2].SaftyErr = !DIO.isSaftyDoorF(2, false);
hmi1.arVar_Port[2].reelCount = SETTING.Counter.CountP2;
hmi1.arVar_Port[2].CartSize = (int)DIO.getCartSize(2);
hmi1.arCountPrint0 = SETTING.Counter.CountPrintL;
hmi1.arCountPrint1 = SETTING.Counter.CountPrintR;
if (VAR.BOOL[eVarBool.Use_Conveyor])
{
hmi1.arVar_Port[0].reelCount = VAR.I32[eVarInt32.LEFT_ITEM_COUNT];
hmi1.arVar_Port[2].reelCount = VAR.I32[eVarInt32.RIGT_ITEM_COUNT];
}
hmi1.arCountV1 = SETTING.Counter.CountV1;
hmi1.arCountV0 = SETTING.Counter.CountV0;
hmi1.arCountV2 = SETTING.Counter.CountV2;
//피커 백큠감지 상태(Front)
hmi1.arVar_Picker[0].VacOutput[0] = DIO.GetIOOutput(eDOName.PICK_VAC1);
hmi1.arVar_Picker[0].VacOutput[1] = DIO.GetIOOutput(eDOName.PICK_VAC2);
hmi1.arVar_Picker[0].VacOutput[2] = DIO.GetIOOutput(eDOName.PICK_VAC3);
hmi1.arVar_Picker[0].VacOutput[3] = DIO.GetIOOutput(eDOName.PICK_VAC4);
hmi1.arVar_Picker[0].ItemOn = PUB.flag.get(eVarBool.FG_PK_ITEMON);
}
Color StatusBackColor = Color.FromArgb(150, 150, 150);
/// <summary>
/// 상태표시라벨의 진행값을 변경 합니다
/// </summary>
/// <param name="idx"></param>
/// <param name="value"></param>
/// <param name="max"></param>
/// <param name="title"></param>
void SetStatusProgress(double value, string title, double max = 0, Color? textColor = null, Color? shadowColor = null)
{
arCtl.arLabel lbl = lbMsg;//idx == 0 ? lbMsgL : (idx == 1 ? lbMsgC : (idx == 2 ? lbMsgR : lbMsg));
if (lbl.ProgressEnable == false) lbl.ProgressEnable = true;
if (lbl.ProgressValue != value) lbl.ProgressValue = (float)value;
if (lbl.Text != title) lbl.Text = title;
if (max != 0)
{
if (lbl.ProgressMax != max) lbl.ProgressMax = (float)max;
}
if (textColor != null)
{
if (lbl.ProgressForeColor != textColor) lbl.ProgressForeColor = (Color)textColor;
}
if (shadowColor != null)
{
if (lbl.ShadowColor != shadowColor) lbl.ShadowColor = (Color)shadowColor;
}
}
///// <summary>
///// 상태표시라벨의 메세지를 변경 합니다
///// </summary>
///// <param name="idx"></param>
///// <param name="dispmsg"></param>
///// <param name="bColor"></param>
///// <param name="bColor2"></param>
///// <param name="fcolor"></param>
///// <param name="shadow"></param>
///// <param name="blank"></param>
//void SetStatusMessage(string dispmsg, Color bColor, Color bColor2, Color fcolor, Color? shadow = null, Boolean blank = false)
//{
// arCtl.arLabel lbl = lbMsg;//idx == 0 ? lbMsgL : (idx == 1 ? lbMsgC : (idx == 2 ? lbMsgR : lbMsg));
// if (shadow == null) shadow = Color.Transparent;
// if (lbl.ProgressValue != 0 || dispmsg != lbl.Text || lbl.ForeColor != fcolor || lbl.ShadowColor != (Color)shadow || (lbl.BackColor != bColor && lbl.BackColor2 != bColor))
// {
// lbl.ProgressValue = 0;
// lbl.BackColor = bColor;
// lbl.BackColor2 = bColor2;
// lbl.ForeColor = fcolor;
// lbl.ShadowColor = (Color)shadow;
// lbl.Text = dispmsg;
// if (blank) lbl.Tag = "BLINK";
// else lbl.Tag = null;
// }
//}
void SetStatusMessage(string dispmsg, Color fcolor, Color backcolor, Color? backColor2 = null, Color? shadow = null, Boolean blank = false)
{
arCtl.arLabel lbl = lbMsg;//idx == 0 ? lbMsgL : (idx == 1 ? lbMsgC : (idx == 2 ? lbMsgR : lbMsg));
if (shadow == null) shadow = Color.Transparent;
if (backColor2 == null) backColor2 = backcolor;
var bg1ok = lbl.BackColor == backcolor && lbl.BackColor2 == backColor2;
var bg2ok = lbl.BackColor2 == backcolor && lbl.BackColor == backColor2;
if (lbl.ProgressValue != 0 || dispmsg != lbl.Text ||
lbl.ForeColor != fcolor || lbl.ShadowColor != (Color)shadow || (bg1ok == false && bg2ok == false))
{
lbl.ProgressValue = 0;
lbl.BackColor = backcolor;
lbl.BackColor2 = (Color)backColor2;
lbl.ForeColor = fcolor;
lbl.ShadowColor = (Color)shadow;
lbl.Text = dispmsg;
if (blank) lbl.Tag = "BLINK";
else lbl.Tag = null;
}
else if (lbl.ProgressEnable)
{
lbl.ProgressEnable = false;
}
}
}
}

View File

@@ -0,0 +1,210 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using AR;
namespace Project
{
public partial class FMain
{
/// <summary>
/// Automatic message change for status display labels
/// </summary>
/// <param name="idx"></param>
void UpdateStatusMessage()
{
arCtl.arLabel lbl = lbMsg;
//Check if message window should blink
if (lbl.Tag != null && lbl.Tag.ToString() == "BLINK")
{
var bg1 = lbl.BackColor;
var bg2 = lbl.BackColor2;
if(bg2 != null) lbl.BackColor = (Color)bg2;
lbl.BackColor2 = bg1;
lbl.Invalidate();
}
if (PUB.sm.Step == eSMStep.INIT)
{
SetStatusMessage("Initialization in progress", Color.White, Color.FromArgb(0x38, 0x4d, 0x9d));
}
else if (PUB.sm.Step == eSMStep.IDLE)
{
//Check various I/O and display error messages
var msg = string.Empty;
bool errst = true;
if (PUB.mot.IsInit == false) msg = "Motion card not ready";
else if (PUB.dio.IsInit == false) msg = "I/O card not ready";
else if (PUB.dio.HasDIOn == false) msg = "Power check required (input port not detected)";
else if (PUB.mot.HasServoAlarm == true) msg = "Servo alarm occurred";
else if (PUB.mot.HasHoming == true) msg = "Home search in progress";
else if (PUB.mot.HasServoOff == true) msg = "Servo OFF occurred";
else if (DIO.GetIOOutput(eDOName.SOL_AIR) == false) msg = "AIR output failed (Press the front blue AIR button)";
else if (DIO.GetIOInput(eDIName.AIR_DETECT) == false) msg = "AIR not detected";
else if (DIO.isSaftyDoorF() == false) msg = "Front Door Safty Error";
else if (DIO.isSaftyDoorR() == false) msg = "Rear Door Safty Error";
else if (PUB.mot.HasHomeSetOff == true)
{
if (DIO.GetIOInput(eDIName.PICKER_SAFE) == false)
{
msg = "Please move the picker (X) axis to center (Function-Management screen)";
}
else
{
msg = "Home search is required";
}
}
else
{
var limport = new List<string>();
if (PUB.mot.HasLimitError == true)
{
for (short i = 0; i < SETTING.System.MotaxisCount; i++)
{
if (PUB.mot.IsUse(i) == false) continue;
if (PUB.mot.IsLimitN(i))
{
var useOrgSensor = PUB.system_mot.GetUseOrigin;
if (useOrgSensor[i] == true) limport.Add(i.ToString());
}
else if (PUB.mot.IsLimitP(i))
limport.Add(i.ToString());
else if (PUB.mot.IsLimitSWN(i))
limport.Add(i.ToString());
else if (PUB.mot.IsLimitSWP(i))
limport.Add(i.ToString());
}
}
if (limport.Any())
{
msg = "Servo LIMIT alarm occurred (Ax:" + string.Join(",", limport) + ")";
}
else
{
msg = "Press START to begin operation";
errst = false;
}
}
if (errst)
{
SetStatusMessage(msg, Color.White, Color.Red, Color.IndianRed, Color.DimGray, blank: true);
}
else
{
Color fColor = Color.FromArgb(200, 200, 200);
Color bColor1 = Color.DimGray;
Color bColor2 = Color.DarkGray;
SetStatusMessage(msg, Color.Lime, bColor1, bColor2, Color.Black, true);
}
}
else if (PUB.sm.Step == eSMStep.WAITSTART)
{
SetStatusMessage("[Waiting to Start] ", Color.Gold, Color.FromArgb(50, 50, 50));
}
else if (PUB.sm.Step == eSMStep.ERROR)
{
var msglis = PUB.Result.ResultMessage.Split(new char[] { '\n' }, StringSplitOptions.RemoveEmptyEntries);
SetStatusMessage($"{msglis[0]}", Color.White, Color.Red);
}
else if (PUB.sm.Step == eSMStep.PAUSE)
{
SetStatusMessage("[Paused] ", Color.Gold, Color.FromArgb(50, 50, 50));
}
else if (PUB.sm.Step == eSMStep.HOME_FULL)// || Pub.sm.Step == eSMStep.QHOME)
{
SetStatusMessage($"Checking home position of all motion axes", Color.White, Color.FromArgb(0x98, 0x79, 0xd0), shadow: Color.DimGray);
}
else if (PUB.sm.Step == eSMStep.HOME_DELAY)// || Pub.sm.Step == eSMStep.QHOME)
{
SetStatusMessage($"Please wait a moment (homing in progress)", Color.White, Color.FromArgb(0x98, 0x79, 0xd0), shadow: Color.DimGray);
}
else if (PUB.sm.Step == eSMStep.HOME_CONFIRM)// || Pub.sm.Step == eSMStep.QHOME)
{
SetStatusMessage($"Completing home operation", Color.White, Color.FromArgb(0x98, 0x79, 0xd0), shadow: Color.DimGray);
}
else if (PUB.sm.Step == eSMStep.RUN)
{
double cur = PUB.sm.seq.GetTime(PUB.sm.Step).TotalSeconds;
double max = AR.SETTING.Data.Timeout_StepMaxTime;
string msg = $"In Progress";
Color fColor = Color.Gold;
if (PUB.flag.get(eVarBool.FG_JOB_END))
{
msg = "Loader is empty. Operation will be completed shortly";
cur = max = 0;
fColor = Color.Lime;
}
else if (PUB.flag.get(eVarBool.FG_WAIT_LOADERINFO))
{
msg = "Waiting for user information input";
cur = 100;
max = 100;
}
else //if (PUB.flag.get(eVarBool.RDY_VISION1) == true && PUB.flag.get(eVarBool.RDY_PORT_PC) == true && idx == 9)
{
msg = "Working";
if (PUB.flag.get(eVarBool.FG_PRC_VISIONL) && PUB.flag.get(eVarBool.FG_END_VISIONL) == false)
msg += "(LEFT-QR validation)";
if (PUB.flag.get(eVarBool.FG_PRC_VISIONR) && PUB.flag.get(eVarBool.FG_END_VISIONR) == false)
msg += "(RIGHT-QR validation)";
//Conveyor interlock check in conveyor usage mode
if (VAR.BOOL[eVarBool.Use_Conveyor])
{
if (DIO.GetIOInput(eDIName.R_CONV1) || DIO.GetIOInput(eDIName.R_CONV4))
{
if (PUB.iLockCVR.IsEmpty() == false)
msg += "(Waiting for right conveyor interlock release)";
}
if (DIO.GetIOInput(eDIName.L_CONV1) || DIO.GetIOInput(eDIName.L_CONV4))
{
if (PUB.iLockCVL.IsEmpty() == false)
msg += "(Waiting for left conveyor interlock release)";
}
}
cur = VAR.TIME.RUN((int)eVarTime.LIVEVIEW1).TotalSeconds;
max = AR.SETTING.Data.Timeout_VisionProcessL / 1000.0;
}
//else if (PUB.flag.get(eVarBool.RDY_ZL_PICKON))
//{
// var ts = DateTime.Now - Pub.GetVarTime(eVarTime.JOB_END);
// msg = string.Format("UNLOADER PICK ON #{0}", PUB.sm.seq.Get(step));
// cur = Pub.getRunSteptime(0).TotalSeconds;//ts.TotalSeconds;
// max = 10;//COMM.SETTING.Data.Timeout_JOBEnd;
//}
//else if (PUB.mot.IsMotion((int)eAxis.Y_PICKER])
//{
// msg = string.Format("Moving");
// cur = 0;// Pub.getRunSteptime(0).TotalSeconds;// ts.TotalSeconds;
// max = 10;//COMM.SETTING.Data.Timeout_JOBEnd;
//}
SetStatusProgress(cur, msg, max, fColor, Color.FromArgb(50, 50, 50));
}
else if (PUB.flag.get(eVarBool.FG_MOVE_PICKER))
{
SetStatusMessage("X-axis can be moved with buttons", Color.Black, Color.White);
}
else
{
SetStatusMessage("[" + PUB.sm.Step.ToString() + "]", Color.Red, Color.White);
}
}
}
}

View File

@@ -0,0 +1,64 @@
using AR;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
namespace Project
{
public partial class FMain
{
private void _SM_MAIN_ERROR(Boolean isFirst, eSMStep Step, TimeSpan StepTime)
{
//모션의 위치를 저장해준다. - 재시작시 변경이 잇다면 오류로 처리한다
for (short i = 0; i < PUB.mot.DeviceCount; i++)
PUB.Result.PreventMotionPosition[i] = PUB.mot.GetLastCmdPos(i);
var errorMessage = string.Empty;
//에러메세지가 있는 경우에만 표시함
if (PUB.Result.ResultCode != eResult.NOERROR && PUB.Result.ResultMessage != "")
errorMessage += PUB.Result.ResultMessage;
//에러메세지가 있는 경우에만 표시함
if (errorMessage != "")
{
//사용자 값 입력창에서는 오류를 표시하지않는다
if (Step == eSMStep.PAUSE && PUB.flag.get(eVarBool.FG_WAIT_LOADERINFO))
PUB.log.Add("Pause message not displayed because barcode information input window is open");
else
PUB.popup.setMessage(errorMessage);
}
if (Step == eSMStep.EMERGENCY)
{
PUB.log.AddE("Enter Emergency Step");
}
else if (Step == eSMStep.PAUSE)
{
PUB.log.AddE("Enter Pause Step 1 : " + PUB.Result.ResultMessage);
}
else
{
//홈 검색실패로 인해 멈췄다면 모든 축을 멈춘다
if (Step == eSMStep.ERROR && PUB.Result.ResultCode == eResult.SAFTY)
PUB.mot.MoveStop("홈검색 실패");
PUB.log.AddE(string.Format("Enter Error Step 1 : {0}", PUB.Result.ResultMessage));
}
//lbMsgR.ProgressEnable = false;
DIO.SetBuzzer(true);
DIO.SetPortMotor(0, eMotDir.CW, false, "ERROR");
DIO.SetPortMotor(1, eMotDir.CW, false, "ERROR");
DIO.SetPortMotor(2, eMotDir.CW, false, "ERROR");
//컨베어멈춤
DIO.SetOutput(AR.eDOName.LEFT_CONV, false);
DIO.SetOutput(AR.eDOName.RIGHT_CONV, false);
}
}
}

View File

@@ -0,0 +1,167 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using AR;
namespace Project
{
public partial class FMain
{
async public Task<bool> _SM_RUN_STARTCHKSW(bool isFirst, TimeSpan stepTime)
{
var mc = PUB.Result.mModel;
var mv = PUB.Result.vModel;
double free = 0;
var savepath = PUB.getSavePath(out free);
if (free < 3.0)
{
string msg = "FREE SPACE ERROR\n" +
"Insufficient disk space (3%) to proceed with the work\n" +
"Storage path: {0}\n" +
"Please delete data or check the deletion cycle in settings";
msg = string.Format(msg, AR.SETTING.Data.GetDataPath());
PUB.popup.setMessage(msg);
DIO.SetBuzzer(true);
PUB.sm.SetNewStep(eSMStep.IDLE);
return false;
}
if (PUB.Result.isSetmModel == false)
{
string msg = "Motion model not selected\nPlease check the 'MOTION' item in the work model";
PUB.popup.setMessage(msg);
DIO.SetBuzzer(true);
PUB.sm.SetNewStep(eSMStep.IDLE);
return false;
}
//모션의 모든 위치가 원점이 아니라면 홈 초기화를 요청한다.
var initMsg = "";
if (initMsg != "")
{
PUB.popup.setMessage(initMsg);
DIO.SetBuzzer(true);
PUB.sm.SetNewStep(eSMStep.IDLE);
return false;
}
//모델정보가 설정되어있는지 확인
if (PUB.Result == null ||
PUB.Result.vModel == null ||
PUB.Result.vModel.Title.isEmpty())
{
PUB.Result.SetResultMessage(eResult.SETUP, eECode.NOMODELV, eNextStep.ERROR);
return false;
}
//모션모델자동선택 230823
var motionmode = VAR.BOOL[eVarBool.Use_Conveyor] ? "Conveyor" : "Default";
if (PUB.SelectModelM(motionmode) == false)
{
PUB.Result.SetResultMessage(eResult.SETUP, eECode.NOMODELM, eNextStep.ERROR);
return false;
}
//모델정보가 설정되어있는지 확인
if (PUB.Result == null ||
PUB.Result.mModel == null ||
PUB.Result.mModel.Title.isEmpty())
{
PUB.Result.SetResultMessage(eResult.SETUP, eECode.NOMODELM, eNextStep.ERROR);
return false;
}
//ECS데이터확인 230823
var conv = VAR.BOOL[eVarBool.Use_Conveyor];
if (conv)
{
var sidinfo = await PUB.UpdateSIDInfo();
var systembypass = SETTING.Data.SystemBypass;
if (systembypass == false && sidinfo.Item1 == false)
{
PUB.Result.SetResultMessage(eResult.SETUP, eECode.NOECSDATA, eNextStep.ERROR, sidinfo.Item2);
return false;
}
//else if (systembypass == false && sidinfo.Item3 < 1)
//{
// PUB.Result.SetResultMessage(eResult.SETUP, eECode.NOECSDATAACTIVE, eNextStep.ERROR, sidinfo.Item2);
// return false;
//}
}
//SID변환정보 필요 230823
//이값도 테이블에서 실시간으로 조회되므로 미리 불러올 필요 없다
//사용자추가정보 필요 230823
//기존에 사용하던 사용자 추가 정보
//ECS정보가 수신되면 기존 TABLE 을 삭제하는 구조이므로 병행할수 없음
//데이터는 테이블에서 실시간으로 조 회됨
//사용자스텝실행
if (PUB.flag.get(eVarBool.FG_USERSTEP))
{
PUB.flag.set(eVarBool.FG_USERSTEP, false, "STACHKSW");
PUB.log.AddI("H/W inspection ignore function disabled due to work start");
}
//Auto Reel Out 250926
PUB.Result.AutoReelOut = PUB.Result.vModel.AutoOutConveyor > 0;
//공용변수초기화
PUB.log.Add("Common variable (count) values initialized");
VAR.I32.Clear((int)eVarInt32.LPickOfCount);
VAR.I32.Clear((int)eVarInt32.LPickOnCount);
VAR.I32.Clear((int)eVarInt32.RPickOfCount);
VAR.I32.Clear((int)eVarInt32.RPickOnCount);
VAR.I32.Clear((int)eVarInt32.PickOfCount);
VAR.I32.Clear((int)eVarInt32.PickOnCount);
VAR.I32.Clear((int)eVarInt32.PickOnRetry); //221102
PUB.flag.set(eVarBool.FG_RUN_LEFT, false, "POSREST");
PUB.flag.set(eVarBool.FG_RUN_RIGHT, false, "POSREST");
VAR.BOOL[eVarBool.JOB_Empty_SIDConvertInfo] = false;
VAR.BOOL[eVarBool.FG_AUTOOUTCONVL] = false;
VAR.BOOL[eVarBool.FG_AUTOOUTCONVR] = false;
AutoConvOutTimeL = new DateTime(1982, 11, 23);
AutoConvOutTimeR = new DateTime(1982, 11, 23);
PUB.Result.ItemDataL.Clear("START_CHKSW");
PUB.Result.ItemDataC.Clear("START_CHKSW");
PUB.Result.ItemDataR.Clear("START_CHKSW");
var modelName = PUB.Result.vModel.Title;
lock (PUB.Result.BCDPatternLock)
{
PUB.Result.BCDPattern = PUB.GetPatterns(modelName, false);
PUB.Result.BCDIgnorePattern = PUB.GetPatterns(modelName, true);
PUB.log.Add($"Model pattern loading: {PUB.Result.BCDPattern.Count}/{PUB.Result.BCDIgnorePattern.Count}");
}
//변환SID SID확인여부데이터 삭제
PUB.Result.DTSidConvertEmptyList.Clear();
PUB.Result.DTSidConvertMultiList.Clear();
PUB.Result.JobStartTime = DateTime.Now;
warninactivelist.Clear();
//작업락기능해제
LockPK.Set();
LockUserL.Set();
LockUserR.Set();
return true;
}
}
}

View File

@@ -0,0 +1,179 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using AR;
namespace Project
{
public partial class FMain
{
/// <summary>
/// 장치의 초기화 여부를 우선 체크 한다.
/// 장치에 문제가 있는 경우에는 ERROR상황으로 뺀다
/// ERROR 상황은 RESET 시 IDLE로 전환된다.
/// 복구불가능한 오류 상황이다.
///
/// </summary>
/// <param name="isFirst"></param>
/// <param name="stepTime"></param>
/// <returns></returns>
public Boolean _SM_RUN_STARTCHKHW(bool isFirst, TimeSpan stepTime)
{
var mc = PUB.Result.mModel;
var mv = PUB.Result.vModel;
//최초시작이므로 - 셔틀2의 안전위치 이동 플래그를 OFF해준다.
//장치초기화 확인
if (PUB.mot.IsInit == false || PUB.dio.IsInit == false)
{
PUB.Result.SetResultMessage(eResult.HARDWARE, eECode.AZJINIT, eNextStep.ERROR);
return false;
}
//서보 off 상태 확인
if (PUB.mot.HasServoOff)
{
PUB.Result.SetResultMessage(eResult.MOTION, eECode.MOT_SVOFF, eNextStep.ERROR);//, msg);
return false;
}
//홈 검색완료 체크1
if (PUB.mot.HasHomeSetOff)
{
PUB.Result.SetResultMessage(eResult.MOTION, eECode.MOT_HSET, eNextStep.ERROR);
return false;
}
//air확인
if (DIO.GetIOOutput(eDOName.SOL_AIR) == false)
{
PUB.Result.SetResultMessage(eResult.SENSOR, eECode.AIRNOOUT, eNextStep.ERROR);
return false;
}
//카메라초기화체크(초기화가 오래걸려서 쓰레드분리함) - 201229
if (VAR.BOOL[eVarBool.Opt_DisableCamera] == false && AR.SETTING.Data.Enable_Unloader_QRValidation && PUB.flag.get(eVarBool.FG_RDY_CAMERA_L) == false && AR.SETTING.Data.Disable_Left == false)
{
PUB.Result.SetResultMessage(eResult.HARDWARE, eECode.CAM_LEFT, eNextStep.ERROR);
return false;
}
if (VAR.BOOL[eVarBool.Opt_DisableCamera] == false && AR.SETTING.Data.Enable_Unloader_QRValidation && PUB.flag.get(eVarBool.FG_RDY_CAMERA_R) == false && AR.SETTING.Data.Disable_Right == false)
{
PUB.Result.SetResultMessage(eResult.HARDWARE, eECode.CAM_RIGHT, eNextStep.ERROR);
return false;
}
//안전위치 센서가 안들어와잇으면 오류 처리한다
if (DIO.GetIOInput(eDIName.PICKER_SAFE) == false)
{
PUB.Result.SetResultMessage(eResult.MOTION, eECode.NEED_JOBCANCEL, eNextStep.ERROR, eAxis.PL_MOVE, PUB.mot.ErrorMessage);
return false;
}
//프린터확인
if (PUB.flag.get(eVarBool.FG_INIT_PRINTER) == false)
{
PUB.Result.SetResultMessage(eResult.HARDWARE, eECode.PRINTER, eNextStep.ERROR);
return false;
}
//부착 실린더 위치 확인
if (AR.SETTING.Data.Enable_PickerCylinder)
{
if (DIO.GetIOInput(eDIName.L_CYLUP) == false)
{
PUB.Result.SetResultMessage(eResult.HARDWARE, eECode.PRINTER_LPRINTER_NOUP, eNextStep.ERROR);
return false;
}
if (DIO.GetIOInput(eDIName.R_CYLUP) == false)
{
PUB.Result.SetResultMessage(eResult.HARDWARE, eECode.PRINTER_RPRINTER_NOUP, eNextStep.ERROR);
return false;
}
}
//부착 실린더 위치 확인
if (DIO.GetIOInput(eDIName.L_PICK_BW) == false)
{
PUB.Result.SetResultMessage(eResult.HARDWARE, eECode.PRINTER_LPICKER_NOBW, eNextStep.ERROR);
return false;
}
if (DIO.GetIOInput(eDIName.R_PICK_BW) == false)
{
PUB.Result.SetResultMessage(eResult.HARDWARE, eECode.PRINTER_RPICKER_NOBW, eNextStep.ERROR);
return false;
}
//컨베이어 모드에서 컨베이어에 릴이 감지되면 시작하지 못한다
if (VAR.BOOL[eVarBool.Use_Conveyor])
{
if (DIO.GetIOInput(eDIName.L_CONV1))
{
//감지되면 안된다
var ssname = $"X{eDIName.L_CONV1}";
PUB.Result.SetResultMessage(eResult.OPERATION, eECode.LCONVER_REEL_DECTECT_ALL, eNextStep.ERROR, ssname);
return false;
}
if (DIO.GetIOInput(eDIName.R_CONV1) ||
DIO.GetIOInput(eDIName.R_CONV4))
{
//감지되면 안된다
var ssname = $"X{eDIName.R_CONV1}";
PUB.Result.SetResultMessage(eResult.OPERATION, eECode.RCONVER_REEL_DECTECT_ALL, eNextStep.ERROR, ssname);
return false;
}
}
////카메라체크
//for (int i = 0; i < _isCrevisOpen.Length; i++)
//{
// if (COMM.SETTING.Data.DisableCamera(i) == true)
// {
// PUB.log.AddAT($"카메라({i})번 비활성 됨(환경설정)");
// }
// else if (_isCrevisOpen[i] == false)
// {
// if (i == 0 && COMM.SETTING.Data.DisableCamera0 == false && COMM.SETTING.Data.Disable_Left == false)
// {
// PUB.Result.SetResultMessage(eResult.HARDWARE, eECode.VISION_NOCONN, eNextStep.ERROR, i);
// return false;
// }
// if (i == 2 && COMM.SETTING.Data.DisableCamera2 == false && COMM.SETTING.Data.Disable_Right == false)
// {
// PUB.Result.SetResultMessage(eResult.HARDWARE, eECode.VISION_NOCONN, eNextStep.ERROR, i);
// return false;
// }
// }
//}
//트리거 OFF작업
WS_Send(eWorkPort.Left, PUB.wsL, "", "OFF", "");
WS_Send(eWorkPort.Right, PUB.wsR, "", "OFF", "");
var systembypassmode = SETTING.Data.SystemBypass;
//바코드설정업데이트
if (systembypassmode == false)
{
bool k1, k2;
k1 = PUB.MemLoadBarcodeConfig(PUB.keyenceF);
k2 = PUB.MemLoadBarcodeConfig(PUB.keyenceR);
if (k1 == false && k2 == false) //결과확인하도록함 230511
{
PUB.Result.SetResultMessage(eResult.HARDWARE, eECode.CONFIG_KEYENCE, eNextStep.ERROR);
return false;
}
}
return true;
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,405 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using AR;
using Project.Class;
namespace Project
{
public partial class FMain
{
public enum EResultKeyence
{
Wait = 0,
Complete,
TimeOut,
MultiSID,
Nothing,
}
public EResultKeyence KEYENCE_READ(eWorkPort target, eSMStep cmdIndex)
{
UInt16 idx = 1;
var mv = PUB.Result.vModel;
var mc = PUB.Result.mModel;
var funcName = System.Reflection.MethodBase.GetCurrentMethod().Name;
var seqTime = PUB.sm.seq.GetTime(cmdIndex);
var msgType = (Class.eStatusMesage)target;
var itemC = PUB.Result.ItemDataC;
if (PUB.sm.getNewStep != eSMStep.RUN) return EResultKeyence.Wait;
//var Jobtype = VAR.STR[eVarString.JOB_TYPE];
var CVMode = VAR.BOOL[eVarBool.Use_Conveyor];
var OPT_PrinterOff = PUB.OPT_PRINTEROFF(target);
var OPT_CameraOff = PUB.OPT_CAMERA();
var OPT_BYPASS = PUB.OPT_BYPASS();
//데이터가 완료되었는지 확인
if (itemC.VisionData.Confirm)
{
PUB.log.AddAT("Removing barcode messages due to vision data completion");
itemC.VisionData.bcdMessage.Clear();
return EResultKeyence.Complete;
}
//사용자 입력 대기중이면 아에 처리하지 않는다 210203
if (PUB.flag.get(eVarBool.FG_WAIT_LOADERINFO) == true)
{
PUB.WaitMessage[1] = "Wait for User Confirm Interface";
return EResultKeyence.Wait;
}
//####################################################
//### 작업시작
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
if (PUB.Result.DryRun)
{
PUB.log.Add($"[{target}] Completed due to DRY-RUN");
SetDryrunData();
}
else
{
PUB.logDbg.Add($"[{target}] Keyence reading started");
if (PUB.keyenceF != null) PUB.keyenceF.Trigger(true);
if (PUB.keyenceR != null) PUB.keyenceR.Trigger(true);
}
VAR.BOOL[eVarBool.Need_UserConfirm_Data] = false;
VAR.STR[eVarString.MULTISID_FIELDS] = string.Empty;
VAR.STR[eVarString.MULTISID_QUERY] = string.Empty;
VAR.TIME.Update(eVarTime.KEYENCEWAIT);
PUB.sm.seq.Update(cmdIndex);
return EResultKeyence.Wait;
}
//####################################################
//###
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
//아무것도안함
PUB.sm.seq.Update(cmdIndex);
return EResultKeyence.Wait;
}
//####################################################
//### 키엔스데이터를 처리해준다.
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
bool vQtyOK = false;
var vdata = itemC.VisionData;
//동작중이아니라면 처리하지 않음
if (PUB.sm.getNewStep != eSMStep.RUN) return EResultKeyence.Wait;
//바이패스라면 무조건ok한다.
var systembypassmode = SETTING.Data.SystemBypass;
if (systembypassmode && PUB.flag.get(eVarBool.FG_RDY_PORT_PC))
{
vdata.SetRID("BP" + DateTime.Now.ToString("yyyyMMddHHmmss"), "bp");
vdata.SID = ("100000000");
vdata.VNAME = "BYPASS";
vdata.MFGDATE = DateTime.Now.ToString("yyyy-MM-dd");
vdata.VLOT = "BYPASS";
vdata.CUSTCODE = "0000";
vdata.CUSTNAME = "BYPASS";
vdata.QTY = "10000";
vdata.ConfirmUser = true;
vdata.PrintPositionData = "1";
vdata.PrintPositionCheck = true;
vdata.MFGDATE_Trust = true;
vdata.PARTNO_Trust = true;
vdata.QTY_Trust = true;
vdata.RID_Trust = true;
vdata.SID_Trust = true;
vdata.VLOT_Trust = true;
vdata.VNAME_Trust = true;
return EResultKeyence.Complete;
}
//로더정보를 사용자가 처리중이면 동작 안함
if (VAR.BOOL[eVarBool.FG_WAIT_LOADERINFO]) return EResultKeyence.TimeOut;
//다중SID환경에서 데이터를 선택하고 있다.
if (VAR.BOOL[eVarBool.FG_WAIT_INFOSELECT]) return EResultKeyence.Wait;
//데이터 처리 시간을 넘어서면 사용자 확인 창을 띄운다 220621
var ts = VAR.TIME.RUN((int)eVarTime.KEYENCEWAIT);
if (VAR.BOOL[eVarBool.FG_RDY_PORT_PC] && ts.TotalMilliseconds > AR.SETTING.Data.Timeout_VisionProcessL)
{
//화면업데이트를 종료한다
if (PUB.keyenceF != null) PUB.keyenceF.Trigger(false);
if (PUB.keyenceR != null) PUB.keyenceR.Trigger(false);
//이미지저장용 작업시작
var tempfileF = System.IO.Path.Combine(UTIL.CurrentPath, "Temp", "Image", DateTime.Now.ToString("yyyMMddHhmmss_fff" + "F.bmp"));
var tempfileR = System.IO.Path.Combine(UTIL.CurrentPath, "Temp", "Image", DateTime.Now.ToString("yyyMMddHhmmss_fff" + "R.bmp"));
var tempfiF = new System.IO.FileInfo(tempfileF);
var tempfiR = new System.IO.FileInfo(tempfileR);
if (tempfiF.Directory.Exists == false) tempfiF.Directory.Create();
if (tempfiR.Directory.Exists == false) tempfiR.Directory.Create();
//마지막 사진을 추출한다
var CurImageF = PUB.keyenceF.SaveImage(tempfiF.FullName);
var CurImageR = false;
if (PUB.keyenceR != null) CurImageR = PUB.keyenceR.SaveImage(tempfiR.FullName);
PUB.keyenceF.Trigger(true);
PUB.keyenceR.Trigger(true);
return EResultKeyence.TimeOut;
}
var prcResult = BCDProcess_ALL(itemC, "SEQ", true);
if (prcResult != EResultKeyence.Nothing)
return prcResult;
PUB.sm.seq.Update(cmdIndex);
return EResultKeyence.Wait;
}
//####################################################
//###
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
PUB.sm.seq.Update(cmdIndex);
return EResultKeyence.Wait;
}
PUB.sm.seq.Clear(cmdIndex);
return EResultKeyence.Complete;
}
/// <summary>
/// 데이터입력이 완료되었는지 확인 합니다
/// </summary>
/// <param name="item"></param>
/// <param name="Source"></param>
/// <param name="mainjob"></param>
void CheckDataComplte(Class.JobData item, string Source, bool mainjob)
{
Boolean NeedConfirm = false;
//var Jobtype = VAR.STR[eVarString.JOB_TYPE];
var OPT_BYPASS = SETTING.Data.SystemBypass;// Jobtype == "BP";
var CVMode = VAR.BOOL[eVarBool.Use_Conveyor];
var CustomerCode = VAR.STR[eVarString.JOB_CUSTOMER_CODE];
if (item.VisionData.Confirm)
{
//사용자에의해 완성된 자료는 완료된 자료이다
if (item.VisionData.bcdMessage.Count > 0) item.VisionData.bcdMessage.Clear();
return;
}
//처음작업이면 반드시 확인을 한다
if (OPT_BYPASS == false && PUB.Result.JobFirst)
{
//사용자확인이 필요없는 상태라면 활성화해준다
//프린트를 하지 않는다면 처리하지 않는다.
if (VAR.BOOL[eVarBool.Opt_DisablePrinter] == false)
{
if (mainjob && item.VisionData.bcdMessage.ContainsKey(6) == false) item.VisionData.bcdMessage.Add(6, "First reel confirmation required");
NeedConfirm = true;
}
}
//서버의수량업데이트기능
if (OPT_BYPASS == false && VAR.BOOL[eVarBool.Opt_ServerQty])
{
//수량원본이 없는 경우
if (item.VisionData.QTY0.isEmpty())
{
string msg = "Server quantity update feature is not applicable to WMS, contact developer if needed";
var cnt = 0;// (int)(Amkor.RestfulService.get_stock_count(item.VisionData.RID, out msg));
if (mainjob)
{
PUB.log.AddE("Server quantity update feature is not applicable to WMS, contact developer if needed");
}
if (cnt > 0)
{
//새로받은 데이터를 실제 수량에 추가한다
item.VisionData.QTY0 = item.VisionData.QTY;
item.VisionData.QTY = cnt.ToString();
if (mainjob) PUB.log.Add($"Server quantity update RID:{item.VisionData.RID} Old:{item.VisionData.QTY}, New:{cnt}");
}
else
{
if (mainjob) PUB.log.AddE($"Quantity update failed rID:{item.VisionData.RID}, Message={msg}");
NeedConfirm = true;
if (mainjob && item.VisionData.bcdMessage.ContainsKey(1) == false)
item.VisionData.bcdMessage.Add(1, "Quantity update failed");
}
}
}
//수량입력 210708
if (OPT_BYPASS == false && VAR.BOOL[eVarBool.Opt_UserQtyRQ])
{
if (item.VisionData.QTYRQ && item.VisionData.QTY.isEmpty() == false)
{
//RQ값이 이전 값이 오기도 하니 바코드 목록에서 값을 다시 써준다. 210825
var rqBcd = PUB.Result.ItemDataC.VisionData.barcodelist.Where(t => t.Value.Data.StartsWith("RQ")).FirstOrDefault();
if (rqBcd.Value != null)
{
var newqty = rqBcd.Value.Data.Substring(2).Trim();
if (mainjob) PUB.log.Add($"Quantity update (01) {item.VisionData.QTY}->{newqty}");
item.VisionData.QTY = newqty;
if (mainjob) PUB.log.AddI("Manual quantity input mode but RQ value confirmed, no user confirmation required");
}
else
{
if (mainjob && item.VisionData.bcdMessage.ContainsKey(2) == false) item.VisionData.bcdMessage.Add(2, "RQ value error (auto mode not possible)");
NeedConfirm = true;
}
}
else
{
if (mainjob && item.VisionData.bcdMessage.ContainsKey(3) == false) item.VisionData.bcdMessage.Add(3, "Manual quantity input required");
NeedConfirm = true;
}
}
//프린트위치확인
BCDProcess_BCDPrint(item);
if (item.VisionData.PrintPositionData.isEmpty() == true || item.VisionData.PrintPositionCheck == false)
{
if (mainjob && item.VisionData.bcdMessage.ContainsKey(4) == false) item.VisionData.bcdMessage.Add(4, "Attachment position not found");
NeedConfirm = true;
}
//SID 존재여부 확인
if (OPT_BYPASS == false && item.VisionData.SID_Trust && VAR.BOOL[eVarBool.Opt_CheckSIDExist])
{
//ECS목록에 데이터가 업다면 오류로 처리한다
var SID = item.VisionData.SID;
var ta = new DataSet1TableAdapters.QueriesTableAdapter();
var exist = ta.CheckSIDExist(SID) > 0;
PUB.log.Add($"SID Exist Check SID:{item.VisionData.SID},Result={exist}");
if (exist == false)
{
PUB.Result.SetResultMessage(eResult.OPERATION, eECode.NOSIDINFOFROMDB, eNextStep.PAUSE, SID);
return;
}
}
//sid변환기능확인
var SIDOK = false;
if (OPT_BYPASS == false &&
VAR.BOOL[eVarBool.Opt_SIDConvert] &&
PUB.flag.get(eVarBool.FG_WAIT_LOADERINFO) == false &&
VAR.BOOL[eVarBool.JOB_Empty_SIDConvertInfo] == false)
{
//시드값이 유효한지 확인한다.
SIDOK = item.VisionData.SID_Trust && item.VisionData.SID0.isEmpty() == false && item.VisionData.SID.isEmpty() == false;
}
else SIDOK = (item.VisionData.SID_Trust && item.VisionData.SID.isEmpty() == false); //시드변환을 사용하지 않으므로 시드값여부에따라 다르다
//수량확인
if (OPT_BYPASS == false)
{
if(double.TryParse(item.VisionData.QTY,out double qtyvalue)==false)
{
if (mainjob && item.VisionData.bcdMessage.ContainsKey(8) == false) item.VisionData.bcdMessage.Add(8, "Qty invalid");
NeedConfirm = true;
}
}
//사용자확인이 필요한 옵션이라면 사용한다
if (OPT_BYPASS == false && VAR.BOOL[eVarBool.Opt_UserConfim])
{
if (mainjob && item.VisionData.bcdMessage.ContainsKey(5) == false) item.VisionData.bcdMessage.Add(5, "User confirmation required");
NeedConfirm = true;
}
//변환작업인데 원본 값이 없다.
//혹은 변환값과 원본이 같다
if (OPT_BYPASS == false && VAR.BOOL[eVarBool.Opt_SIDConvert] && (item.VisionData.SID0.isEmpty() == true || item.VisionData.SID0 == item.VisionData.SID))
{
if (mainjob && item.VisionData.bcdMessage.ContainsKey(7) == false) item.VisionData.bcdMessage.Add(7, "SID conversion value confirmation required");
NeedConfirm = true;
}
//데이터의 신뢰성을 확인하고 모두 입력되었다면 자동 확정을 진행한다
if (item.VisionData.MFGDATE_Trust &&
item.VisionData.PARTNO_Trust &&
item.VisionData.QTY_Trust &&
item.VisionData.RID_Trust &&
item.VisionData.SID_Trust &&
SIDOK && item.VisionData.VLOT_Trust &&
item.VisionData.VNAME_Trust)
{
//데이터를 확정짓는다 다만 화면을 표시하지 않아야하는 경우에만 처리해준다
if (NeedConfirm == false)
{
if (OPT_BYPASS)
{
PUB.log.Add("All data confirmed, proceeding with automatic confirmation (bypass mode)");
if (item.VisionData.bcdMessage.Count > 0) item.VisionData.bcdMessage.Clear();
item.VisionData.ConfirmBypass = true;
}
else if (item.VisionData.ConfirmAuto == false)
{
PUB.log.Add("All data confirmed, proceeding with automatic confirmation");
if (item.VisionData.bcdMessage.Count > 0) item.VisionData.bcdMessage.Clear();
item.VisionData.ConfirmAuto = true;
}
}
}
else if (item.VisionData.QRInputRaw.isEmpty() == false)
{
if (mainjob)
{
NeedConfirm = true;
PUB.log.AddAT($"Data incomplete but QR has been read, showing confirmation window immediately");
}
}
//확인창을 띄우기 위해 Timeout 오류를 발생시킨다.
VAR.BOOL[eVarBool.Need_UserConfirm_Data] = NeedConfirm;
if (NeedConfirm)
{
if (mainjob)
{
var newtime = DateTime.Now.AddMilliseconds(-AR.SETTING.Data.Timeout_VisionProcessL);
VAR.TIME.Set(eVarTime.KEYENCEWAIT, newtime);
}
}
else if (PUB.Result.ItemDataC.VisionData.ConfirmAuto == false)
{
PUB.logDbg.Add($"Vision automatic confirmation processing {Source}");
PUB.Result.ItemDataC.VisionData.ConfirmAuto = true;
}
}
List<string> warninactivelist = new List<string>();
private void SetDryrunData()
{
var item = PUB.Result.ItemDataC;
PUB.log.AddAT("Dry run basic data input");
if (item.VisionData.QTY.isEmpty()) item.VisionData.QTY = DateTime.Now.ToString("HHmm");
if (item.VisionData.MFGDATE.isEmpty()) item.VisionData.MFGDATE = DateTime.Now.ToString("yy-MM-dd");
if (item.VisionData.SID.isEmpty()) item.VisionData.SID = "108" + "0" + DateTime.Now.ToString("HH").PadLeft(2, '0') + DateTime.Now.ToString("fff").PadLeft(3, '0');
if (item.VisionData.VLOT.isEmpty()) item.VisionData.VLOT = "SUPNAME" + DateTime.Now.ToString("fff");
if (item.VisionData.PARTNO.isEmpty()) item.VisionData.PARTNO = "PARTNO" + DateTime.Now.ToString("yyyyMMddHHmmss.fff");
if (item.VisionData.RID.isEmpty())
{
var newid = PUB.MakeNewREELID(item.VisionData.SID);// Amkor.RestfulService.Allocation_Unique_ReelID_AmkorSTD("1234", "4", "A", out string err);
if (newid.success == false) item.VisionData.SetRID("RID" + DateTime.Now.ToString("yyyyMMddHHmmss.fff"), "DRY");
else item.VisionData.SetRID(newid.newid, "DRY");
}
if (item.VisionData.PrintPositionData.isEmpty()) item.VisionData.PrintPositionData = "2";
item.VisionData.PrintPositionCheck = true;
item.VisionData.ConfirmAuto = true;
}
}
}

View File

@@ -0,0 +1,278 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using AR;
namespace Project
{
public partial class FMain
{
public Boolean PICKER_ON(eWorkPort target, eSMStep cmdIndex)
{
UInt16 idx = 1;
var mv = PUB.Result.vModel;
var mc = PUB.Result.mModel;
var funcName = System.Reflection.MethodBase.GetCurrentMethod().Name;
var seqTime = PUB.sm.seq.GetTime(cmdIndex);
var msgType = (Class.eStatusMesage)target;
var iLockX = PUB.iLock[(int)eAxis.PX_PICK];
var iLockZ = PUB.iLock[(int)eAxis.PZ_PICK];
var CVMode = VAR.BOOL[eVarBool.Use_Conveyor];
//option check
var OPT_PrinterOff = PUB.OPT_PRINTEROFF(target);
var OPT_CameraOff = PUB.OPT_CAMERA();
var OPT_BYPASS = PUB.OPT_BYPASS();
//####################################################
//### 인터락 확인
//####################################################
Boolean MotMoveX = PUB.mot.IsMotion((int)eAxis.PX_PICK);
Boolean MotMoveZ = PUB.mot.IsMotion((int)eAxis.PZ_PICK);
if (iLockX.IsEmpty() == false && MotMoveX)
{
var locklistX = MOT.GetActiveLockList(eAxis.PX_PICK, iLockX);
PUB.mot.MoveStop("ILock(" + string.Join(",", locklistX) + ")", (int)eAxis.PX_PICK);
}
if (iLockZ.IsEmpty() == false && MotMoveZ)
{
var locklistZ = MOT.GetActiveLockList(eAxis.PZ_PICK, iLockZ);
PUB.mot.MoveStop("ILock(" + string.Join(",", locklistZ) + ")", (int)eAxis.PZ_PICK);
}
//####################################################
//### 작업시작
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
PUB.log.Add($"[{target}] Picker ON work started");
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### ON 위치로 이동
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
if (iLockX.IsEmpty() == false) return false;
if (iLockZ.IsEmpty() == false) return false;
var Pos = MOT.GetPXPos(ePXLoc.PICKON);
var PosZ = MOT.GetPZPos(ePZLoc.READY);
if (MOT.CheckMotionPos(seqTime, PosZ, funcName) == false) return false;
if (MOT.CheckMotionPos(seqTime, Pos, funcName) == false) return false;
PUB.log.Add($"[{target}] Picker ON X,Y ready position confirmed");
DIO.SetPickerVac(true);
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### Z축을 내린다.
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
var PortRDY = PUB.flag.get(eVarBool.FG_RDY_PORT_PC);
if (PortRDY == false) return false;
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### Z축을 내린다.
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
// if (iLockX.IsEmpty() == false) return false;
if (iLockZ.IsEmpty() == false) return false;
var Pos = MOT.GetPZPos(ePZLoc.PICKON);
var PosMatch = MOT.getPositionMatch(Pos);
//var PortRDY = PUB.flag.get(eVarBool.RDY_PORT_PC);
//if (PosMatch==false ) return false;
if (MOT.CheckMotionPos(seqTime, Pos, funcName) == false) return false;
VAR.I32[eVarInt32.PickOnCount] += 1;
PUB.flag.set(eVarBool.FG_PK_ITEMON, true, funcName);
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### Z축을 올린다.
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
//if (iLockX.IsEmpty() == false) return false;
if (iLockZ.IsEmpty() == false) return false;
var Pos = MOT.GetPZPos(ePZLoc.READY);
if (MOT.CheckMotionPos(seqTime, Pos, funcName) == false) return false;
PUB.flag.set(eVarBool.FG_PK_ITEMON, true, funcName);
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### 프린트부착위치가 상/하가 아니라면 추가적인 회전이 필요하다 - 210207
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
var vData = target == eWorkPort.Left ? PUB.Result.ItemDataL.VisionData : PUB.Result.ItemDataR.VisionData;
if (vData.PrintPositionData == "4") // 왼쪽찍기
{
if (vData.ReelSize == eCartSize.Inch7)
{
vData.NeedCylinderForward = false;
double targerPos = 0.0;
if (target == eWorkPort.Left) //left printer
{
vData.PositionAngle = -90; //90도 회전한다
}
else
{
vData.PositionAngle = -90;
}
}
else
{
//13inch
vData.NeedCylinderForward = true;
if (target == eWorkPort.Left) //left printer
{
vData.PositionAngle = -180;
}
else
{
vData.PositionAngle = 0;
}
}
}
else if (vData.PrintPositionData == "6") //오른쪽찍기
{
if (vData.ReelSize == eCartSize.Inch7)
{
vData.NeedCylinderForward = false;
if (target == eWorkPort.Left) //left printer
{
vData.PositionAngle = 90; //90도 회전한다
}
else
{
vData.PositionAngle = 90; //90도 회전한다
}
}
else
{
//13inch
vData.NeedCylinderForward = true;
double targerPos = 0.0;
if (target == eWorkPort.Left) //left printer
{
vData.PositionAngle = 0;
}
else
{
vData.PositionAngle = 180;
}
}
}
else
{
vData.NeedCylinderForward = false; //상하에 붙이는건 실린더를 원위치해야함
vData.PositionAngle = 0;
}
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### 바코드에의한 자동 회전
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
//속도값만 취한다
var thpos = MOT.GetPTPos(ePTLoc.READY);
// Baseangle 값으로 변경 210126 - qr의 각도가잇다면 그것이 기준이됨
double baseAngle = 0;
string baseSource = "F";
var vdata = target == eWorkPort.Left ? PUB.Result.ItemDataL.VisionData : PUB.Result.ItemDataR.VisionData;
if (vdata.BaseAngle(out string msg, out Class.KeyenceBarcodeData bcd))
{
baseAngle = bcd.Angle;
baseSource = bcd.barcodeSource; //230504 각도
PUB.log.AddI($"[{target}] Angle calculation: {msg}, Barcode: {bcd.Data}, ID: {vdata.RID}"); //210602
}
else if (PUB.Result.DryRun)
{
PUB.log.AddAT($"[{target}] Angle not applied due to dry run");
}
else
{
PUB.log.AddE($"[{target}] base ange error : {msg},ID:{vdata.RID}");
}
var addangle = baseSource == "R" ? SETTING.Data.RearBarcodeRotate : SETTING.Data.FrontBarcodeRotate;
var rotAngle = baseAngle + addangle + vdata.PositionAngle;
PUB.log.AddI($"[{target}] Source: {baseSource} Rotation value (Base: {baseAngle} + Additional: {addangle} + Vision: {vdata.PositionAngle} = {rotAngle})");
int dir = -1;
while (true)
{
if (rotAngle > 360.0)
rotAngle = rotAngle - 360.0; //한반퀴 더 도는것은 역 처리한다
else break;
}
//rotAngle += 90; //비젼이 90도 돌아가잇으니 다시 적용필요함 //상단이위로가도록 함
if (rotAngle > 180)
{
rotAngle = 360 - rotAngle;
dir = 1;
}
PUB.log.AddI($"[{target}] Rotation (Final) [{rotAngle} degrees, Direction: {dir}], RID: {vdata.RID}");
if (target == eWorkPort.Left)
PUB.Result.ItemDataL.VisionData.ApplyAngle = rotAngle; //회전각도를 넣는다
else
PUB.Result.ItemDataR.VisionData.ApplyAngle = rotAngle; //회전각도를 넣는다
var curtheta = PUB.mot.GetActPos((int)eAxis.Z_THETA);
var newPos = curtheta + (dir * rotAngle);
PUB.log.Add($"Motor position before rotation: {curtheta}, Target position: {newPos}, Speed: {thpos.Speed}, Acceleration: {thpos.Acc}");
if (target == eWorkPort.Left)
VAR.DBL[(int)eVarDBL.ThetaPositionL] = newPos;
else
VAR.DBL[(int)eVarDBL.ThetaPositionR] = newPos;
//if (ByPassMode == false)
//{
//바이패스에서도 추가 회전을 한다
MOT.Move(eAxis.Z_THETA, newPos, thpos.Speed, thpos.Acc, false);
//}
//else PUB.log.AddAT($"bypass 로 인해 회전을 하지 않습니다");
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//###
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
PUB.sm.seq.Update(cmdIndex);
return false;
}
return true;
}
}
}

View File

@@ -0,0 +1,244 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using AR;
namespace Project
{
public partial class FMain
{
/// <summary>
/// 키엔스가 실패했을때 재시도 하는 작업이다
/// 중앙에서 잡고 79도 틀고, 내려 놓고 피한다
/// </summary>
/// <param name="target"></param>
/// <param name="cmdIndex"></param>
/// <returns></returns>
public Boolean PICKER_RETRY(eWorkPort target, eSMStep cmdIndex)
{
UInt16 idx = 1;
var mv = PUB.Result.vModel;
var mc = PUB.Result.mModel;
var funcName = System.Reflection.MethodBase.GetCurrentMethod().Name;
var seqTime = PUB.sm.seq.GetTime(cmdIndex);
var msgType = (Class.eStatusMesage)target;
var iLockX = PUB.iLock[(int)eAxis.PX_PICK];
var iLockZ = PUB.iLock[(int)eAxis.PZ_PICK];
var PickerRetryCount = AR.VAR.I32[(int)eVarInt32.PickOnRetry];
//####################################################
//### 인터락 확인
//####################################################
Boolean MotMoveX = PUB.mot.IsMotion((int)eAxis.PX_PICK);
Boolean MotMoveZ = PUB.mot.IsMotion((int)eAxis.PZ_PICK);
if (iLockX.IsEmpty() == false && MotMoveX)
{
var locklistX = MOT.GetActiveLockList(eAxis.PX_PICK, iLockX);
PUB.mot.MoveStop("ILock(" + string.Join(",", locklistX) + ")", (int)eAxis.PX_PICK);
}
if (iLockZ.IsEmpty() == false && MotMoveZ)
{
var locklistZ = MOT.GetActiveLockList(eAxis.PZ_PICK, iLockZ);
PUB.mot.MoveStop("ILock(" + string.Join(",", locklistZ) + ")", (int)eAxis.PZ_PICK);
}
//####################################################
//### 작업시작
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
PUB.log.Add($"[{target}] Picker RETRY work started ({PickerRetryCount}/{AR.SETTING.Data.RetryPickOnMaxCount})");
//기존자료를 모두 삭제 한다 221102
if (PUB.Result.ItemDataC != null && PUB.Result.ItemDataC.VisionData != null && PUB.Result.ItemDataC.VisionData.barcodelist != null)
{
lock (PUB.Result.ItemDataC.VisionData.barcodelist)
{
PUB.Result.ItemDataC.VisionData.Clear(funcName, true);
}
}
AR.VAR.BOOL[eVarBool.JOB_PickON_Retry] = true;
PUB.mot.ClearPosition((int)eAxis.Z_THETA);
PUB.sm.seq.Update(cmdIndex);
DIO.SetPickerVac(false);
return false;
}
//####################################################
//### Z를 먼저 Ready 로 이동
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
if (iLockZ.IsEmpty() == false) return false;
var Pos = MOT.GetPZPos(ePZLoc.READY);
if (MOT.CheckMotionPos(seqTime, Pos, funcName) == false) return false;
DIO.SetPickerVac(true);
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### X를 픽온위치로 이동
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
if (iLockX.IsEmpty() == false) return false;
var Pos = MOT.GetPXPos(ePXLoc.PICKON);
if (MOT.CheckMotionPos(seqTime, Pos, funcName) == false) return false;
DIO.SetPickerVac(true);
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### Z축 내리기 조건확인
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
var PortRDY = PUB.flag.get(eVarBool.FG_RDY_PORT_PC);
if (PortRDY == false) return false;
DIO.SetPickerVac(true);
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### Z축을 내린다.
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
if (iLockZ.IsEmpty() == false) return false;
var Pos = MOT.GetPZPos(ePZLoc.PICKON);
if (MOT.CheckMotionPos(seqTime, Pos, funcName) == false) return false;
VAR.I32[eVarInt32.PickOnCount] += 1;
//PUB.flag.set(eVarBool.PK_ITEMON, true, funcName);
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### 100ms 대기
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
if (seqTime.TotalMilliseconds < 100) return false;
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### Z축을 올린다.
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
if (iLockZ.IsEmpty() == false) return false;
var Pos = MOT.GetPZPos(ePZLoc.READY);
if (MOT.CheckMotionPos(seqTime, Pos, funcName) == false) return false;
//PUB.flag.set(eVarBool.PK_ITEMON, true, funcName);
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### 현재위치에서 79도 회전
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
//속도값만 취한다
var Pos = MOT.GetPTPos(ePTLoc.READY);
Pos.Position = PUB.mot.GetActPos((int)eAxis.Z_THETA) + AR.SETTING.Data.RetryPickOnAngle;
VAR.DBL[(int)eVarDBL.ThetaPosition] = Pos.Position;
MOT.Move(Pos);
//if (MOT.CheckMotionPos(seqTime, Pos, funcName) == false) return false;
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### 현재위치에서 79도 회전
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
//속도값만 취한다
var Pos = MOT.GetPTPos(ePTLoc.READY);
Pos.Position = VAR.DBL[(int)eVarDBL.ThetaPosition];
if (MOT.CheckMotionPos(seqTime, Pos, funcName) == false) return false;
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### Z를 pick on 위치로 1/3 지점으로 이동한다
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
if (iLockZ.IsEmpty() == false) return false;
var PosS = MOT.GetPZPos(ePZLoc.READY);
var PosT = MOT.GetPZPos(ePZLoc.PICKON);
var offset = (int)(Math.Abs(PosT.Position - PosS.Position) * 0.7f);
PosS.Position += offset; //시작위치에서 절반만 이동한다
if (MOT.CheckMotionPos(seqTime, PosS, funcName) == false) return false;
DIO.SetPickerVac(false); //릴을 내려 놓는다
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### Z축을 올린다.
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
if (iLockZ.IsEmpty() == false) return false;
var Pos = MOT.GetPZPos(ePZLoc.READY);
if (MOT.CheckMotionPos(seqTime, Pos, funcName) == false) return false;
DIO.SetPickerVac(false); //백큠을 꺼서 원복한다
hmi1.arVar_Port[1].AlignReset(); //231013
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### 키엔스를 읽어야 하므로 피해준다
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
if (iLockX.IsEmpty() == false) return false;
sPositionData Pos;
if (target == eWorkPort.Left) Pos = MOT.GetPXPos(ePXLoc.READYL);
else Pos = MOT.GetPXPos(ePXLoc.READYR);
//theta모터 위치 초기화
PUB.mot.ClearPosition((int)eAxis.Z_THETA);
if (MOT.CheckMotionPos(seqTime, Pos, funcName) == false) return false;
PUB.log.AddAT($"###### Retry work avoidance movement completed ({target})");
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### 비젼데이터를 초기화 해준다.
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
PUB.log.Add($"Deleting vision data due to retry completion");
PUB.Result.ItemDataC.VisionData.Clear(funcName, true);
AR.VAR.BOOL[eVarBool.JOB_PickON_Retry] = false;
PUB.sm.seq.Update(cmdIndex);
return false;
}
//일련번호 초기화 해준다
PUB.sm.seq.Clear(cmdIndex);
return true;
}
}
}

View File

@@ -0,0 +1,458 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using AR;
namespace Project
{
public partial class FMain
{
public Boolean PICKER_OFF(eWorkPort target, eSMStep cmdIndex)
{
UInt16 idx = 1;
var mv = PUB.Result.vModel;
var mc = PUB.Result.mModel;
var funcName = System.Reflection.MethodBase.GetCurrentMethod().Name;
var seqTime = PUB.sm.seq.GetTime(cmdIndex);
var msgType = (Class.eStatusMesage)target;
var item = target == eWorkPort.Left ? PUB.Result.ItemDataL : PUB.Result.ItemDataR;
// var Jobtype = VAR.STR[eVarString.JOB_TYPE];
//var ByPassMode = Jobtype == "BP";
var CVMode = VAR.BOOL[eVarBool.Use_Conveyor];
//option check
var OPT_PrinterOff = PUB.OPT_PRINTEROFF(target);
var OPT_CameraOff = PUB.OPT_CAMERA();
var OPT_BYPASS = PUB.OPT_BYPASS();
var iLockX = PUB.iLock[(int)eAxis.PX_PICK];
var iLockZ = PUB.iLock[(int)eAxis.PZ_PICK];
//####################################################
//### 인터락 확인
//####################################################
Boolean MotMoveX = PUB.mot.IsMotion((int)eAxis.PX_PICK);
Boolean MotMoveZ = PUB.mot.IsMotion((int)eAxis.PZ_PICK);
if (iLockX.IsEmpty() == false && MotMoveX)
{
var locklistX = MOT.GetActiveLockList(eAxis.PX_PICK, iLockX);
PUB.mot.MoveStop("ILock(" + string.Join(",", locklistX) + ")", (int)eAxis.PX_PICK);
}
if (iLockZ.IsEmpty() == false && MotMoveZ)
{
var locklistZ = MOT.GetActiveLockList(eAxis.PZ_PICK, iLockZ);
PUB.mot.MoveStop("ILock(" + string.Join(",", locklistZ) + ")", (int)eAxis.PZ_PICK);
}
//####################################################
//### 작업시작
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
//컨베이어모드에서는 센서가 감지되면 내려놓지 않게 한다
if (CVMode)
{
if (target == eWorkPort.Left)
{
if (DIO.GetIOInput(eDIName.L_CONV1)) return false;
if (VAR.I32[eVarInt32.LEFT_ITEM_COUNT] > 0) return false;
}
else if (target == eWorkPort.Right)
{
if (DIO.GetIOInput(eDIName.R_CONV1)) return false;
if (VAR.I32[eVarInt32.RIGT_ITEM_COUNT] > 0) return false;
}
PUB.log.Add($"Conveyor is empty in CV MODE");
}
PUB.log.Add($"[{target}] Picker OFF work started");
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### Y축안전확인
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
//PUB.log.Add($"[{target}] 프린터 Y축 위치 확인");
var Pos = target == eWorkPort.Left ? MOT.GetLMPos(eLMLoc.READY) : MOT.GetRMPos(eRMLoc.READY);
if (MOT.getPositionMatch(Pos) == false)
{
PUB.Result.SetResultMessage(eResult.OPERATION, eECode.POSITION_ERROR, eNextStep.PAUSE, "Printer Y-axis is not at ready position");
return false;
}
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### OFF 위치로 이동
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
if (iLockX.IsEmpty() == false) return false;
sPositionData PosX;
if (PUB.flag.get(eVarBool.FG_RUN_LEFT))
{
PosX = MOT.GetPXPos(ePXLoc.PICKOFFL);
}
else
{
PosX = MOT.GetPXPos(ePXLoc.PICKOFFR);
}
if (MOT.CheckMotionPos(seqTime, PosX, funcName) == false) return false;
//컨베이어모드라면 컨베이어를 멈추게한다
if (CVMode)
{
if (target == eWorkPort.Left)
PUB.iLockCVL.set((int)eILockCV.BUSY, true, funcName);
else
PUB.iLockCVR.set((int)eILockCV.BUSY, true, funcName);
}
else
{
if (target == eWorkPort.Left)
PUB.iLockCVL.set((int)eILockCV.BUSY, false, funcName);
else
PUB.iLockCVR.set((int)eILockCV.BUSY, false, funcName);
}
PUB.sm.seq.Update(cmdIndex);
return false;
}
////####################################################
////### 프린트부착위치가 상/하가 아니라면 추가적인 회전이 필요하다 - 210207
////####################################################
//if (PUB.sm.seq.Get(cmdIndex) == idx++)
//{
// var vData = item.VisionData;
// if (vData.PrintPositionData == "4") // 왼쪽찍기
// {
// if (vData.ReelSize == eCartSize.Inch7)
// {
// vData.NeedCylinderForward = false;
// double targerPos = 0.0;
// if (target == eWorkShuttle.Left) //left printer
// {
// targerPos = vData.ApplyAngle + 90; //90도 회전한다
// }
// else
// {
// targerPos = vData.ApplyAngle + 90;
// }
// //if (vData.ApplyAngle > 180.0) targerPos = vData.ApplyAngle - 180.0;
// //else targerPos = vData.ApplyAngle + 180.0;
// //추가보정
// if (targerPos > 360.0) targerPos = targerPos - 360.0;
// if (targerPos < -360.0) targerPos = targerPos + 360.0;
// //지정값대로 추가 회전을 한다
// var basePosInfo = MOT.GetPTPos(ePTLoc.READY);
// basePosInfo.Position = targerPos;
// if (MOT.CheckMotionPos(seqTime, basePosInfo, funcName) == false) return false;
// }
// else
// {
// //13inch
// vData.NeedCylinderForward = true;
// double targerPos = 0.0;
// if (target == eWorkShuttle.Left) //left printer
// {
// targerPos = vData.ApplyAngle + 180; //90도 회전한다
// }
// else
// {
// targerPos = vData.ApplyAngle + 0;
// }
// //if (vData.ApplyAngle > 180.0) targerPos = vData.ApplyAngle - 180.0;
// //else targerPos = vData.ApplyAngle + 180.0;
// //추가보정
// if (targerPos > 360.0) targerPos = targerPos - 360.0;
// if (targerPos < -360.0) targerPos = targerPos + 360.0;
// //지정값대로 추가 회전을 한다
// var basePosInfo = MOT.GetPTPos(ePTLoc.READY);
// basePosInfo.Position = targerPos;
// if (MOT.CheckMotionPos(seqTime, basePosInfo, funcName) == false) return false;
// }
// }
// else if (vData.PrintPositionData == "6") //오른쪽찍기
// {
// if (vData.ReelSize == eCartSize.Inch7)
// {
// vData.NeedCylinderForward = false;
// double targerPos = 0.0;
// if (target == eWorkShuttle.Left) //left printer
// {
// targerPos = vData.ApplyAngle - 90; //90도 회전한다
// }
// else
// {
// targerPos = vData.ApplyAngle - 90;
// }
// //if (vData.ApplyAngle > 180.0) targerPos = vData.ApplyAngle - 180.0;
// //else targerPos = vData.ApplyAngle + 180.0;
// //추가보정
// if (targerPos > 360.0) targerPos = targerPos - 360.0;
// if (targerPos < -360.0) targerPos = targerPos + 360.0;
// //지정값대로 추가 회전을 한다
// var basePosInfo = MOT.GetPTPos(ePTLoc.READY);
// basePosInfo.Position = targerPos;
// if (MOT.CheckMotionPos(seqTime, basePosInfo, funcName) == false) return false;
// }
// else
// {
// //13inch
// vData.NeedCylinderForward = true;
// double targerPos = 0.0;
// if (target == eWorkShuttle.Left) //left printer
// {
// targerPos = vData.ApplyAngle + 0; //90도 회전한다
// }
// else
// {
// targerPos = vData.ApplyAngle + 180;
// }
// //if (vData.ApplyAngle > 180.0) targerPos = vData.ApplyAngle - 180.0;
// //else targerPos = vData.ApplyAngle + 180.0;
// //추가보정
// if (targerPos > 360.0) targerPos = targerPos - 360.0;
// if (targerPos < -360.0) targerPos = targerPos + 360.0;
// //지정값대로 추가 회전을 한다
// var basePosInfo = MOT.GetPTPos(ePTLoc.READY);
// basePosInfo.Position = targerPos;
// if (MOT.CheckMotionPos(seqTime, basePosInfo, funcName) == false) return false;
// }
// }
// else vData.NeedCylinderForward = false; //상하에 붙이는건 실린더를 원위치해야함
// PUB.sm.seq.Update(cmdIndex);
// return false;
//}
//####################################################
//### 사용자회전적용
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
if (item.VisionData.ApplyOffset == false)
{
//적용옵셋
var OffsetAngle = target == eWorkPort.Left ? AR.SETTING.Data.AngleOffsetL : AR.SETTING.Data.AngleOffsetR;
if (OffsetAngle != 0f)
{
if (OPT_BYPASS == true || OPT_PrinterOff)
{
PUB.log.AddAT($"Additional rotation not performed due to bypass");
}
else
{
//모터회전
//var thpos = MOT.GetPTPos(ePTLoc.READY); //적용할 속도값용
//MOT.Move(eAxis.Z_THETA, OffsetAngle, thpos.Speed, thpos.Acc, true);
MOT.Rotation(OffsetAngle, funcName);
double theta = 0;
if (target == eWorkPort.Left) theta = VAR.DBL[(int)eVarDBL.ThetaPositionL];
else theta = VAR.DBL[(int)eVarDBL.ThetaPositionR];
//값을 누적시켜준다
item.VisionData.ApplyAngle += OffsetAngle;
if (target == eWorkPort.Left) VAR.DBL[(int)eVarDBL.ThetaPositionL] = theta + OffsetAngle;
else VAR.DBL[(int)eVarDBL.ThetaPositionR] = theta + OffsetAngle;
if (AR.SETTING.Data.Log_Debug)
PUB.logDbg.Add($"[{target}] Motor additional rotation: {OffsetAngle}");
}
}
item.VisionData.ApplyOffset = true;
}
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### 회전축 완료 확인
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
if (OPT_BYPASS == false && OPT_PrinterOff == false)
{
var Theta = target == eWorkPort.Left ? VAR.DBL[(int)eVarDBL.ThetaPositionL] : VAR.DBL[(int)eVarDBL.ThetaPositionR];
var Pos = MOT.GetPTPos(ePTLoc.READY);
Pos.Position = Theta;
if (MOT.CheckMotionPos(seqTime, Pos, funcName, false) == false) return false;
PUB.log.Add($"[{target}] Rotation axis verification complete Position: {Theta}, Motor value: {PUB.mot.GetActPos((int)eAxis.Z_THETA)} => Position initialized");
PUB.mot.ClearPosition((int)eAxis.Z_THETA);
}
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### 포트상태확인
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
// if (iLockX.IsEmpty() == false) return false;
if (iLockZ.IsEmpty() == false) return false;
var PortRDY = target == eWorkPort.Left ? PUB.flag.get(eVarBool.FG_RDY_PORT_PL) : PUB.flag.get(eVarBool.FG_RDY_PORT_PR);
if (PortRDY == false) return false;
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### Z축을 내린다.
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
// if (iLockX.IsEmpty() == false) return false;
if (iLockZ.IsEmpty() == false) return false;
//컨베어모드라면 센서에 감지되는 것이 없어야 한다
if (OPT_BYPASS == false && VAR.BOOL[eVarBool.Use_Conveyor])
{
if (target == eWorkPort.Left)
{
//컨베이어가 움직이고 있다면 단순 대기한다
if (DIO.GetIOOutput(eDOName.LEFT_CONV) == false)
{
//놓일위치에서 센서가 감지되었다
if (DIO.GetIOInput(eDIName.L_CONV1))
{
var ssname = $"X{eDIName.L_CONV1}";
PUB.Result.SetResultMessage(eResult.OPERATION, eECode.LCONVER_REEL_DECTECT_IN, eNextStep.PAUSE, ssname);
return false;
}
}
else
{
if (seqTime.TotalSeconds > 10)
{
var ssname = $"Y{eDOName.LEFT_CONV}";
PUB.Result.SetResultMessage(eResult.OPERATION, eECode.LCONVER_MOVING, eNextStep.PAUSE, ssname);
}
return false;
}
}
else
{
//컨베이어가 움직이고 있다면 단순 대기한다
if (DIO.GetIOOutput(eDOName.RIGHT_CONV) == false)
{
//놓일위치에서 센서가 감지되었다
if (DIO.GetIOInput(eDIName.R_CONV1))
{
var ssname = $"X{eDIName.R_CONV1}";
PUB.Result.SetResultMessage(eResult.OPERATION, eECode.RCONVER_REEL_DECTECT_IN, eNextStep.PAUSE, ssname);
return false;
}
}
else
{
if (seqTime.TotalSeconds > 10)
{
var ssname = $"Y{eDOName.RIGHT_CONV}";
PUB.Result.SetResultMessage(eResult.OPERATION, eECode.RCONVER_MOVING, eNextStep.PAUSE, ssname);
}
return false;
}
}
}
var fg = target == eWorkPort.Left ? eVarBool.FG_RUN_LEFT : eVarBool.FG_RUN_RIGHT;
var Loc = target == eWorkPort.Left ? ePZLoc.PICKOFFL : ePZLoc.PICKOFFR;
var Pos = MOT.GetPZPos(Loc);
if (MOT.CheckMotionPos(seqTime, Pos, funcName) == false) return false;
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### 진공파기
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
DIO.SetPickerVac(false);
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### Z축을 올린다.
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
// if (iLockX.IsEmpty() == false) return false;
if (iLockZ.IsEmpty() == false) return false;
var Pos = MOT.GetPZPos(ePZLoc.READY);
if (MOT.CheckMotionPos(seqTime, Pos, funcName) == false) return false;
PUB.flag.set(eVarBool.FG_PK_ITEMON, false, funcName);
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//###
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
IncCount(1, 1);
if (target == eWorkPort.Left)
{
if (AR.SETTING.Data.Disable_PortL == false && AR.SETTING.Data.Disable_Left == false)
{
hmi1.arVar_Port[0].AlignReset();
}
}
else
{
if (AR.SETTING.Data.Disable_PortR == false && AR.SETTING.Data.Disable_Right == false)
{
hmi1.arVar_Port[2].AlignReset();
}
}
VAR.I32[eVarInt32.PickOfCount] += 1;
PUB.sm.seq.Update(cmdIndex);
return false;
}
return true;
}
}
}

View File

@@ -0,0 +1,246 @@
using AR;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
namespace Project
{
public partial class FMain
{
public Boolean PRINTER(eWorkPort target, eSMStep cmdIndex)
{
UInt16 idx = 1;
var mv = PUB.Result.vModel;
var mc = PUB.Result.mModel;
var funcName = System.Reflection.MethodBase.GetCurrentMethod().Name;
var seqTime = PUB.sm.seq.GetTime(cmdIndex);
var msgType = (Class.eStatusMesage)target;
var item = target == eWorkPort.Left ? PUB.Result.ItemDataL : PUB.Result.ItemDataR;
var Printer = target == eWorkPort.Left ? PUB.PrinterL : PUB.PrinterR;
//var Jobtype = VAR.STR[eVarString.JOB_TYPE];
var CVMode = VAR.BOOL[eVarBool.Use_Conveyor];
//option check
var OPT_PrinterOff = PUB.OPT_PRINTEROFF(target);
var OPT_CameraOff = PUB.OPT_CAMERA();
var OPT_BYPASS = PUB.OPT_BYPASS();
//####################################################
//### 작업시작
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
PUB.log.Add($"[{target}] Print operation started");
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### 프린트 모션 위치 확인
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
sPositionData PosY, PosZ;
if (target == eWorkPort.Left)
{
PosY = MOT.GetLMPos(eLMLoc.READY);
PosZ = MOT.GetLZPos(eLZLoc.PICKON);
}
else
{
PosY = MOT.GetRMPos(eRMLoc.READY);
PosZ = MOT.GetRZPos(eRZLoc.PICKON);
}
if (MOT.CheckMotionPos(seqTime, PosY, funcName) == false) return false;
if (MOT.CheckMotionPos(seqTime, PosZ, funcName) == false) return false;
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### 인쇄데이터 확인
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
if (item.VisionData.RID.isEmpty())
{
if (target == eWorkPort.Left)
{
PUB.Result.SetResultMessage(eResult.OPERATION, eECode.NOPRINTLDATA, eNextStep.PAUSE);
}
else
{
PUB.Result.SetResultMessage(eResult.OPERATION, eECode.NOPRINTRDATA, eNextStep.PAUSE);
}
return false;
}
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### 인쇄데이터전송
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
if (OPT_PrinterOff == false)
{
string zpl, qrdata;
zpl = Printer.makeZPL_210908(new Class.Reel
{
SID = item.VisionData.SID,
venderLot = item.VisionData.VLOT,
venderName = item.VisionData.VNAME,
qty = item.VisionData.QTY.isEmpty() ? -1 : int.Parse(item.VisionData.QTY),
id = item.VisionData.RID,
mfg = item.VisionData.MFGDATE,
PartNo = item.VisionData.PARTNO,
}, AR.SETTING.Data.DrawOutbox, out qrdata);
item.VisionData.ZPL = zpl;
item.VisionData.PrintQRData = qrdata;
PUB.log.Add("PRINT", $"[{target}] Printing");//QR=" + item.VisionData.QRData);
if (target == eWorkPort.Left)
{
var prn = Printer.Print(zpl);
//PUB.PrintSend(true, zpl); //PUB.PrintL.Write(zpl);
if (prn.result == false)
{
PUB.Result.SetResultMessage(eResult.HARDWARE, eECode.PRINTL, eNextStep.ERROR);
return false;
}
else
{
SETTING.Counter.CountPrintL += 1;
item.PrintTime = DateTime.Now;
}
}
else
{
var prn = Printer.Print(zpl);
//PUB.PrintSend(false, zpl); //PUB.PrintR.Write(zpl);
if (prn.result == false)
{
PUB.log.AddE(prn.errmessage);
PUB.Result.SetResultMessage(eResult.HARDWARE, eECode.PRINTR, eNextStep.ERROR);
return false;
}
else
{
SETTING.Counter.CountPrintR += 1;
item.PrintTime = DateTime.Now;
}
}
}
else PUB.log.AddAT($"[{target}] Printer function OFF (bypass or model or setting)");
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### 잠시대기
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
var WaitMS = target == eWorkPort.Left ? AR.SETTING.Data.PrintLWaitMS : AR.SETTING.Data.PrintRWaitMS;
if (OPT_PrinterOff == false && seqTime.TotalMilliseconds < WaitMS) return false;
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### 위쪽흡기 ON
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
if (OPT_PrinterOff == false)
{
if (target == eWorkPort.Left)
{
DIO.SetPrintLVac(ePrintVac.inhalation);
}
else
{
DIO.SetPrintRVac(ePrintVac.inhalation);
}
}
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### 잠시대기
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
if (OPT_PrinterOff == false && seqTime.TotalMilliseconds < 100) return false;
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### 아래쪽 블로우
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
if (OPT_PrinterOff == false && SETTING.Data.Disable_BottomAirBlow == false)
{
if (target == eWorkPort.Left)
{
DIO.SetPrintLAir(true);
}
else
{
DIO.SetPrintRAir(true);
}
}
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### 잠시대기
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
if (OPT_PrinterOff == false && seqTime.TotalMilliseconds < 100) return false;
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### 장비기술데이터저장
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
PUB.log.Add($"6.PRINT : EE-SAVE");
SaveData_EE(item, (target == eWorkPort.Left ? "L" : "R"), "","printer");
//RefreshList(); //목록업데이트
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### spare
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
PUB.sm.seq.Update(cmdIndex);
return false;
}
return true;
}
}
}

View File

@@ -0,0 +1,224 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using AR;
namespace Project
{
public partial class FMain
{
public Boolean PRINTER_ON(eWorkPort target, eSMStep cmdIndex)
{
UInt16 idx = 1;
var mv = PUB.Result.vModel;
var mc = PUB.Result.mModel;
var funcName = System.Reflection.MethodBase.GetCurrentMethod().Name;
var seqTime = PUB.sm.seq.GetTime(cmdIndex);
var msgType = (Class.eStatusMesage)target;
var item = target == eWorkPort.Left ? PUB.Result.ItemDataL : PUB.Result.ItemDataR;
var Printer = target == eWorkPort.Left ? PUB.PrinterL : PUB.PrinterR;
//var Jobtype = VAR.STR[eVarString.JOB_TYPE];
//var ByPassMode = Jobtype == "BP";
var CVMode = VAR.BOOL[eVarBool.Use_Conveyor];
//option check
var OPT_PrinterOff = PUB.OPT_PRINTEROFF(target);
var OPT_CameraOff = PUB.OPT_CAMERA();
var OPT_BYPASS = PUB.OPT_BYPASS();
//####################################################
//### 인터락 확인
//####################################################
Boolean MotMoveM, MotMoveZ;
AR.CInterLock iLockM, iLockZ;
eAxis axisM = target == eWorkPort.Left ? eAxis.PL_MOVE : eAxis.PR_MOVE;
eAxis axisZ = target == eWorkPort.Left ? eAxis.PL_UPDN : eAxis.PR_UPDN;
if (target == eWorkPort.Left)
{
MotMoveM = PUB.mot.IsMotion((int)eAxis.PL_MOVE);
MotMoveZ = PUB.mot.IsMotion((int)eAxis.PL_UPDN);
iLockM = PUB.iLock[(int)eAxis.PL_MOVE];
iLockZ = PUB.iLock[(int)eAxis.PL_UPDN];
}
else
{
MotMoveM = PUB.mot.IsMotion((int)eAxis.PR_MOVE);
MotMoveZ = PUB.mot.IsMotion((int)eAxis.PR_UPDN);
iLockM = PUB.iLock[(int)eAxis.PR_MOVE];
iLockZ = PUB.iLock[(int)eAxis.PR_UPDN];
}
if (iLockM.IsEmpty() == false && MotMoveM)
{
var locklistX = MOT.GetActiveLockList(axisM, iLockM);
PUB.mot.MoveStop("ILock(" + string.Join(",", locklistX) + ")", (short)axisM);
}
if (iLockZ.IsEmpty() == false && MotMoveZ)
{
var locklistZ = MOT.GetActiveLockList(axisZ, iLockZ);
PUB.mot.MoveStop("ILock(" + string.Join(",", locklistZ) + ")", (short)axisZ);
}
//####################################################
//### 작업시작
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
PUB.log.Add($"[{target}] Print ON operation started");
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### 종이감지확인
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
var = target == eWorkPort.Left ? eDIName.L_PICK_VAC : eDIName.R_PICK_VAC;
var = target == eWorkPort.Left ? AR.SETTING.Data.Detect_PrintL : AR.SETTING.Data.Detect_PrintR;
if (OPT_PrinterOff == false)
{
if ( == false)
{
if (seqTime.TotalMilliseconds < 100) return false;
PUB.log.AddAT($"[{target}] Paper detection function OFF(proceed after 3 seconds)");
}
else
{
var ioresult = DIO.checkDigitalO(, seqTime, true, 0, false);
if (ioresult == eNormalResult.Error)
{
var errCode = target == eWorkPort.Left ? eECode.NO_PAPER_DETECT_L : eECode.NO_PAPER_DETECT_R;
PUB.Result.SetResultMessage(eResult.HARDWARE, errCode, eNextStep.PAUSE, );
return false;
}
else if (ioresult == eNormalResult.False) return false;
}
}
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### Z올리기(slow)
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
if (iLockZ.IsEmpty() == false) return false;
if (OPT_BYPASS == false)
{
if (seqTime.TotalMilliseconds < 3000) return false;
sPositionData PosZ;
if (target == eWorkPort.Left)
{
PosZ = MOT.GetLZPos(eLZLoc.PICKON);
}
else
{
PosZ = MOT.GetRZPos(eRZLoc.PICKON);
}
PosZ.Position -= 10;
if (PosZ.Position < 1) PosZ.Position = 1;
PosZ.Speed = 5;
if (MOT.CheckMotionPos(seqTime, PosZ, funcName) == false) return false;
}
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### 종이감지확인
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
if (OPT_PrinterOff == false)
{
var = target == eWorkPort.Left ? eDIName.L_PICK_VAC : eDIName.R_PICK_VAC;
var = target == eWorkPort.Left ? AR.SETTING.Data.Detect_PrintL : AR.SETTING.Data.Detect_PrintR;
if ( == false)
{
if (seqTime.TotalMilliseconds < 100) return false;
PUB.log.AddAT($"[{target}] Paper detection function OFF(proceed after 3 seconds)");
}
else
{
var ioresult = DIO.checkDigitalO(, seqTime, true, 0, false);
if (ioresult == eNormalResult.Error)
{
var errCode = target == eWorkPort.Left ? eECode.NO_PAPER_DETECT_L : eECode.NO_PAPER_DETECT_R;
PUB.Result.SetResultMessage(eResult.HARDWARE, errCode, eNextStep.PAUSE, );
return false;
}
else if (ioresult == eNormalResult.False) return false;
}
}
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### Z올리기
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
if (iLockZ.IsEmpty() == false) return false;
if (OPT_BYPASS == false)
{
sPositionData PosZ;
if (target == eWorkPort.Left)
{
PosZ = MOT.GetLZPos(eLZLoc.READY);
}
else
{
PosZ = MOT.GetRZPos(eRZLoc.READY);
}
if (MOT.CheckMotionPos(seqTime, PosZ, funcName) == false) return false;
}
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//###
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
//air off
if (target == eWorkPort.Left)
{
DIO.SetPrintLAir(false);
if (OPT_BYPASS == false)
VAR.I32[eVarInt32.LPickOnCount] += 1;
PUB.flag.set(eVarBool.FG_PL_ITEMON, true, funcName);
}
else
{
DIO.SetPrintRAir(false);
if (OPT_BYPASS == false)
VAR.I32[eVarInt32.RPickOnCount] += 1;
PUB.flag.set(eVarBool.FG_PR_ITEMON, true, funcName);
}
PUB.sm.seq.Update(cmdIndex);
return false;
}
return true;
}
}
}

View File

@@ -0,0 +1,574 @@

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using AR;
namespace Project
{
public partial class FMain
{
public Boolean PRINTER_OFF(eWorkPort target, eSMStep cmdIndex)
{
UInt16 idx = 1;
var mv = PUB.Result.vModel;
var mc = PUB.Result.mModel;
var funcName = System.Reflection.MethodBase.GetCurrentMethod().Name;
var seqTime = PUB.sm.seq.GetTime(cmdIndex);
var msgType = (Class.eStatusMesage)target;
var item = target == eWorkPort.Left ? PUB.Result.ItemDataL : PUB.Result.ItemDataR;
var CVMode = VAR.BOOL[eVarBool.Use_Conveyor];
//option check
var OPT_PrinterOff = PUB.OPT_PRINTEROFF(target);
var OPT_CameraOff = PUB.OPT_CAMERA();
//var OPT_BYPASS = PUB.OPT_BYPASS(target);
//####################################################
//### 인터락 확인
//####################################################
Boolean MotMoveM, MotMoveZ;
AR.CInterLock iLockM, iLockZ;
eAxis axisM = target == eWorkPort.Left ? eAxis.PL_MOVE : eAxis.PR_MOVE;
eAxis axisZ = target == eWorkPort.Left ? eAxis.PL_UPDN : eAxis.PR_UPDN;
if (target == eWorkPort.Left)
{
MotMoveM = PUB.mot.IsMotion((int)eAxis.PL_MOVE);
MotMoveZ = PUB.mot.IsMotion((int)eAxis.PL_UPDN);
iLockM = PUB.iLock[(int)eAxis.PL_MOVE];
iLockZ = PUB.iLock[(int)eAxis.PL_UPDN];
}
else
{
MotMoveM = PUB.mot.IsMotion((int)eAxis.PR_MOVE);
MotMoveZ = PUB.mot.IsMotion((int)eAxis.PR_UPDN);
iLockM = PUB.iLock[(int)eAxis.PR_MOVE];
iLockZ = PUB.iLock[(int)eAxis.PR_UPDN];
}
if (iLockM.IsEmpty() == false && MotMoveM)
{
var locklistX = MOT.GetActiveLockList(axisM, iLockM);
PUB.mot.MoveStop("ILock(" + string.Join(",", locklistX) + ")", (short)axisM);
}
if (iLockZ.IsEmpty() == false && MotMoveZ)
{
var locklistZ = MOT.GetActiveLockList(axisZ, iLockZ);
PUB.mot.MoveStop("ILock(" + string.Join(",", locklistZ) + ")", (short)axisZ);
}
//####################################################
//### 작업시작
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
//PUB.log.Add($"[{target}] 프린트 OFF 작업 시작");
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### 피커Y축 위치 확인
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
var PosX = MOT.GetPXPos(ePXLoc.PICKON);
var OffX = MOT.getPositionOffset(PosX);
if (target == eWorkPort.Left)
{
if (OffX < -1) return false; //충돌조건이므로 Y축을 움직이면 안된다
}
else
{
if (OffX > 1) return false;//충돌조건이므로 Y축을 움직이면 안된다
}
//PUB.log.Add($"[{target}] 프린트 OFF 작업 시작");
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### 프린터Z축 위치 확인
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
if (iLockZ.IsEmpty() == false) return false;
sPositionData Pos;
if (target == eWorkPort.Left)
{
Pos = MOT.GetLZPos(eLZLoc.READY);
}
else
{
Pos = MOT.GetRZPos(eRZLoc.READY);
}
if (MOT.CheckMotionPos(seqTime, Pos, funcName) == false) return false;
//PUB.log.Add($"[{target}] 프린트 OFF 작업 시작");
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### Y이동
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
sPositionData Pos;
if (OPT_PrinterOff == false)
{
//릴크기없으면 오류
var reelSize = item.VisionData.ReelSize;
if (reelSize == eCartSize.None)
{
PUB.Result.SetResultMessage(eResult.OPERATION, eECode.NOREELSIZE, eNextStep.PAUSE, target);
return false;
}
//부착위치
var PrintPutPos = item.VisionData.GetPrintPutPosition();
if (PrintPutPos == ePrintPutPos.None)
{
PUB.Result.SetResultMessage(eResult.OPERATION, eECode.NOPUTPOSITION, eNextStep.PAUSE, target);
return false;
}
if (target == eWorkPort.Left)
{
//위에 찍을지 아래에 찍을지 위치를 결정한다
if (reelSize == eCartSize.Inch13)
{
if (PrintPutPos == ePrintPutPos.Middle) Pos = MOT.GetLMPos(eLMLoc.PRINTM13);
else if (PrintPutPos == ePrintPutPos.Bottom) Pos = MOT.GetLMPos(eLMLoc.PRINTL13);
else Pos = MOT.GetLMPos(eLMLoc.PRINTH13);
}
else
{
if (PrintPutPos == ePrintPutPos.Middle) Pos = MOT.GetLMPos(eLMLoc.PRINTM07);
else if (PrintPutPos == ePrintPutPos.Bottom) Pos = MOT.GetLMPos(eLMLoc.PRINTL07);
else Pos = MOT.GetLMPos(eLMLoc.PRINTH07);
}
}
else //Right Move
{
//위에 찍을지 아래에 찍을지 위치를 결정한다
if (reelSize == eCartSize.Inch13)
{
if (PrintPutPos == ePrintPutPos.Middle) Pos = MOT.GetRMPos(eRMLoc.PRINTM13);
else if (PrintPutPos == ePrintPutPos.Bottom) Pos = MOT.GetRMPos(eRMLoc.PRINTL13);
else Pos = MOT.GetRMPos(eRMLoc.PRINTH13);
}
else
{
if (PrintPutPos == ePrintPutPos.Middle) Pos = MOT.GetRMPos(eRMLoc.PRINTM07);
else if (PrintPutPos == ePrintPutPos.Bottom) Pos = MOT.GetRMPos(eRMLoc.PRINTL07);
else Pos = MOT.GetRMPos(eRMLoc.PRINTH07);
}
}
if (iLockM.IsEmpty() == false) return false;
//if (iLockZ.IsEmpty() == false) return false;
//위치오류확인
if (Pos.isError == false)
{
if (MOT.CheckMotionPos(seqTime, Pos, funcName) == false) return false;
}
else
{
PUB.Result.SetResultMessage(eResult.OPERATION, eECode.POSITION_ERROR, eNextStep.PAUSE, "PRINTPOS");
return false;
}
}
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### 실린더 전/후진 상태를 전환한다 -- 210207
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
if (OPT_PrinterOff == false)
{
var Cylinder = item.VisionData.NeedCylinderForward;
if (Cylinder == true)
{
//전진이 필요하다
if (target == eWorkPort.Left)
DIO.SetOutput(eDOName.PRINTL_FWD, true);
else
DIO.SetOutput(eDOName.PRINTR_FWD, true);
}
else
{
//전진이 필요하지 않다.
if (target == eWorkPort.Left)
DIO.SetOutput(eDOName.PRINTL_FWD, false);
else
DIO.SetOutput(eDOName.PRINTR_FWD, false);
}
}
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### 카트모드에서는 추가 실린더 down 해야한다 230809
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
if (OPT_PrinterOff == false)
{
if (SETTING.Data.Enable_PickerCylinder)
{
//전진이 필요하다
if (target == eWorkPort.Left)
DIO.SetOutput(eDOName.L_CYLDN, true);
else
DIO.SetOutput(eDOName.R_CYLDN, true);
}
else
{
if (target == eWorkPort.Left)
DIO.SetOutput(eDOName.L_CYLDN, false);
else
DIO.SetOutput(eDOName.R_CYLDN, false);
}
}
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### 카트상태확인
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
if (OPT_PrinterOff == false)
{
eVarBool fg = target == eWorkPort.Left ? eVarBool.FG_RDY_PORT_PL : eVarBool.FG_RDY_PORT_PR;
if (PUB.flag.get(fg) == false) return false;
}
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### 실린더상태확인 -- 210207
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
if (OPT_PrinterOff == false)
{
var Cylinder = item.VisionData.NeedCylinderForward;
if (Cylinder == true)
{
//전진이 필요하다
if (target == eWorkPort.Left)
{
if (DIO.checkDigitalO(eDIName.L_PICK_FW, seqTime, true) != eNormalResult.True)
return false;
}
else
{
if (DIO.checkDigitalO(eDIName.R_PICK_FW, seqTime, true) != eNormalResult.True)
return false;
}
}
else
{
//전진이 필요하지 않다.
if (target == eWorkPort.Left)
{
if (DIO.checkDigitalO(eDIName.L_PICK_BW, seqTime, true) != eNormalResult.True)
return false;
}
else
{
if (DIO.checkDigitalO(eDIName.R_PICK_BW, seqTime, true) != eNormalResult.True)
return false;
}
}
}
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### 피커 down 실린더상태확인 -- 230809
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
if (OPT_PrinterOff == false && SETTING.Data.Enable_PickerCylinder)
{
//전진이 필요하다
if (target == eWorkPort.Left)
{
if (DIO.checkDigitalO(eDIName.L_CYLDN, seqTime, true, timeoutcode: eECode.PICKER_LCYL_NODOWN) != eNormalResult.True)
return false;
}
else
{
if (DIO.checkDigitalO(eDIName.R_CYLDN, seqTime, true, timeoutcode: eECode.PICKER_RCYL_NODOWN) != eNormalResult.True)
return false;
}
}
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### Z값을 내린다.
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
if (iLockZ.IsEmpty() == false) return false;
if (OPT_PrinterOff == false)
{
sPositionData Pos;
if (target == eWorkPort.Left)
Pos = MOT.GetLZPos(eLZLoc.PICKOFF);
else
Pos = MOT.GetRZPos(eRZLoc.PICKOFF);
if (MOT.CheckMotionPos(seqTime, Pos, funcName) == false) return false;
}
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### 진공파기
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
if (OPT_PrinterOff == false)
{
if (target == eWorkPort.Left)
{
DIO.SetPrintLVac(ePrintVac.exhaust);
}
else
{
DIO.SetPrintRVac(ePrintVac.exhaust);
}
}
if (target == eWorkPort.Left)
{
VAR.BOOL[eVarBool.LEFT_ITEM_PICKOFF] = true;
VAR.TIME[eVarTime.LEFT_ITEM_PICKOFF] = DateTime.Now;
VAR.DBL[eVarDBL.LEFT_ITEM_PICKOFF] = 0;
VAR.I32[eVarInt32.LEFT_ITEM_COUNT] += 1;
}
else
{
VAR.BOOL[eVarBool.RIGT_ITEM_PICKOFF] = true;
VAR.TIME[eVarTime.RIGT_ITEM_PICKOFF] = DateTime.Now;
VAR.DBL[eVarDBL.RIGT_ITEM_PICKOFF] = 0;
VAR.I32[eVarInt32.RIGT_ITEM_COUNT] += 1;
}
PUB.log.Add($"[{target}] Placing reel down");
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### 잠시대기
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
if (OPT_PrinterOff == false)
{
if (seqTime.TotalMilliseconds < AR.SETTING.Data.PrintVacOffPurgeMS) return false;
}
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### 저속으로올린다
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
if (iLockZ.IsEmpty() == false) return false;
if (OPT_PrinterOff == false)
{
sPositionData Pos;
if (target == eWorkPort.Left)
Pos = MOT.GetLZPos(eLZLoc.PICKOFF);
else
Pos = MOT.GetRZPos(eRZLoc.PICKOFF);
Pos.Position -= 30;
Pos.Speed = 30;
if (MOT.CheckMotionPos(seqTime, Pos, funcName) == false) return false;
}
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### 카트모드에서는 추가 실린더 down 해야한다 230809
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
//if (ByPassMode == false)
//{
// if (CVMode == false)
//{
//전진이 필요하다
if (target == eWorkPort.Left)
DIO.SetOutput(eDOName.L_CYLDN, false);
else
DIO.SetOutput(eDOName.R_CYLDN, false);
//}
// }
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### Z값 대기위치로
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
if (iLockZ.IsEmpty() == false) return false;
if (OPT_PrinterOff == false)
{
sPositionData Pos;
if (target == eWorkPort.Left)
Pos = MOT.GetLZPos(eLZLoc.READY);
else
Pos = MOT.GetRZPos(eRZLoc.READY);
if (MOT.CheckMotionPos(seqTime, Pos, funcName) == false) return false;
}
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### AIR해제
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
if (target == eWorkPort.Left)
DIO.SetPrintLVac(ePrintVac.off);
else
DIO.SetPrintRVac(ePrintVac.off);
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### 실린더 복귀 확인 -- 230809
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
if (SETTING.Data.Enable_PickerCylinder)
{
//상승이 필요하다
if (target == eWorkPort.Left)
{
if (DIO.checkDigitalO(eDIName.L_CYLUP, seqTime, true, timeoutcode: eECode.PICKER_LCYL_NOUP) != eNormalResult.True)
return false;
}
else
{
if (DIO.checkDigitalO(eDIName.R_CYLUP, seqTime, true, timeoutcode: eECode.PICKER_RCYL_NOUP) != eNormalResult.True)
return false;
}
}
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//###
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
if (OPT_PrinterOff == false)
{
if (target == eWorkPort.Left)
{
if (DIO.checkDigitalO(eDIName.L_PICK_VAC, seqTime, false) != eNormalResult.True) return false;
VAR.I32[eVarInt32.LPickOfCount] += 1;
}
else
{
if (DIO.checkDigitalO(eDIName.R_PICK_VAC, seqTime, false) != eNormalResult.True) return false;
VAR.I32[eVarInt32.RPickOfCount] += 1;
}
//PUB.log.AddAT($"용지 떨어짐 확인 필요");
}
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//###
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
if (target == eWorkPort.Left)
{
PUB.flag.set(eVarBool.FG_PL_ITEMON, false, funcName);
}
else
{
PUB.flag.set(eVarBool.FG_PR_ITEMON, false, funcName);
}
//프린터 사용여부 확인
if (OPT_PrinterOff == false)
{
item.PrintAttach = true;
item.Attachtime = DateTime.Now;
}
PUB.sm.seq.Update(cmdIndex);
return false;
}
return true;
}
}
}

View File

@@ -0,0 +1,147 @@
using AR;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
namespace Project
{
public partial class FMain
{
delegate void savedataeehandler(Class.JobData item, string Loc, string inboundok, string reason);
public void SaveData_EE(Class.JobData item, string Loc, string inboundok, string reason)
{
if (this.InvokeRequired)
{
//이자료를 복사해서 데이터를 넘겨줘야한다.
var a = new Class.JobData(999);
item.CopyTo(ref a);
this.BeginInvoke(new savedataeehandler(SaveData_EE), a, Loc, inboundok, reason);
return;
}
var retval = false;
if (AR.SETTING.Data.OnlineMode == false)
{
PUB.log.AddAT($"[SAVE-EE] Not saving in offline mode");
return;
}
DateTime savestart = DateTime.Now;
try
{
var save_month = DateTime.Now.ToString("YY") + DateTime.Now.Month.ToString("X");
var save_sn = string.Empty;
if (item.VisionData.RID.Length == 15)
{
save_month = item.VisionData.RID.Substring(8, 3); //21A 식으로 년도와 월이 나온다
save_sn = item.VisionData.RID.Substring(item.VisionData.RID.Length - 4); //뒷에서 4자리 끊는다
}
//var Jobtype = VAR.STR[eVarString.JOB_TYPE];
//var ByPassMode = Jobtype == "BP";
var CVMode = VAR.BOOL[eVarBool.Use_Conveyor];
//option check
//var OPT_PrinterOff = PUB.OPT_PRINTEROFF(target);
//var OPT_CameraOff = PUB.OPT_CAMERA(target);
var OPT_BYPASS = SETTING.Data.SystemBypass;// PUB.OPT_BYPASS(target);
using (var taResult = new DataSet1TableAdapters.K4EE_Component_Reel_ResultTableAdapter())
{
//QTY 0값은 없을 수도있다(해당 값은 서버조회여부에다라 다르다)
int? qtyorg = null;
if (int.TryParse(item.VisionData.QTY0, out int vqty0))
qtyorg = vqty0;
string remark = string.Empty;
if (item.VisionData.ConfirmAuto) remark = "[자동]" + remark; //자동확인문구
else if (item.VisionData.ConfirmUser) remark = "[확인]" + remark; //사용자 확인데이터 비고에 추가
if (OPT_BYPASS) remark = "(BYPASS)" + remark;
DataSet1.K4EE_Component_Reel_ResultRow newdr = this.dataSet1.K4EE_Component_Reel_Result.Where(t => t.JGUID.Equals(item.guid)).FirstOrDefault();
if (newdr == null) newdr = this.dataSet1.K4EE_Component_Reel_Result.NewK4EE_Component_Reel_ResultRow();
//else newdr = dt.Rows[0] as DataSet1.Component_Reel_ResultRow;
if (item.JobStart.Year != 1982) newdr.STIME = item.JobStart;
else newdr.STIME = DateTime.Now;
if (item.JobEnd.Year != 1982) newdr.ETIME = item.JobEnd;
if (item.PrintTime.Year != 1982) newdr.PTIME = item.PrintTime;
newdr.ATIME = item.Attachtime;
newdr.PDATE = save_month;
newdr.JTYPE = PUB.Result.vModel.Title;// PUB.Result.JobType2;
if (newdr.JTYPE.Length > 10) newdr.JTYPE = newdr.JTYPE.Substring(0, 9);
newdr.SID = item.VisionData.SID;
newdr.SID0 = item.VisionData.SID0;
newdr.RID = item.VisionData.RID;
newdr.RID0 = item.VisionData.RID0;
newdr.RSN = save_sn;
newdr.QR = item.VisionData.PrintQRData;
newdr.ZPL = item.VisionData.ZPL;
newdr.POS = item.VisionData.PrintPositionData;
newdr.LOC = Loc;
newdr.ANGLE = item.VisionData.ApplyAngle;
if (int.TryParse(item.VisionData.QTY, out int oqty))
newdr.QTY = oqty;
else
newdr.QTY = 0;
newdr.MFGDATE = item.VisionData.MFGDATE;//210326 날짜도 추가함
if (qtyorg != null) newdr.QTY0 = (int)qtyorg;
newdr.VNAME = item.VisionData.VNAME;
newdr.VLOT = item.VisionData.VLOT; ///210326
newdr.PRNATTACH = item.PrintAttach;
newdr.PRNVALID = item.PrintQRValid;
newdr.REMARK = remark;
if (inboundok.isEmpty() == false) newdr.iNBOUND = inboundok;//230622
newdr.MC = AR.SETTING.Data.McName;
newdr.PARTNO = item.VisionData.PARTNO;
newdr.CUSTCODE = item.VisionData.CUSTCODE;
newdr.MCN = item.VisionData.MCN;
newdr.target = item.VisionData.Target;
//220921 - batch qtymax
newdr.BATCH = item.VisionData.BATCH;
if (int.TryParse(item.VisionData.QTYMAX, out int qtymax))
newdr.qtymax = qtymax;
else newdr.qtymax = -1;
//new mode
if (newdr.RowState == System.Data.DataRowState.Detached)
{
newdr.GUID = PUB.Result.guid; //220921
newdr.JGUID = item.guid;
newdr.wdate = DateTime.Now;
this.dataSet1.K4EE_Component_Reel_Result.AddK4EE_Component_Reel_ResultRow(newdr);
}
else newdr.EndEdit();
var ta = new DataSet1TableAdapters.K4EE_Component_Reel_ResultTableAdapter();
var cnt = ta.Update(newdr);
newdr.AcceptChanges();
if (cnt == 0) PUB.log.AddE("Save Error");
}
retval = true;
}
catch (Exception ex)
{
PUB.log.AddE($"[EE-SAVE] {ex.Message}");
retval = false;
}
var ts = DateTime.Now - savestart;
PUB.log.AddI($"data save time : {ts.TotalSeconds:N2}");
ListFormmatData();
}
}
}

View File

@@ -0,0 +1,175 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using AR;
namespace Project
{
public partial class FMain
{
public Boolean QR_VALIDATION(eWorkPort target, eSMStep cmdIndex)
{
UInt16 idx = 1;
var mv = PUB.Result.vModel;
var mc = PUB.Result.mModel;
var funcName = System.Reflection.MethodBase.GetCurrentMethod().Name;
var seqTime = PUB.sm.seq.GetTime(cmdIndex);
var msgType = (Class.eStatusMesage)target;
var item = target == eWorkPort.Left ? PUB.Result.ItemDataL : PUB.Result.ItemDataR;
var WS = target == eWorkPort.Left ? PUB.wsL : PUB.wsR;
//####################################################
//### 작업시작
//####################################################
var CIDX = PUB.sm.seq.Get(cmdIndex);
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
//작업 플래그 설정
if (target == eWorkPort.Left)
{
VAR.BOOL[eVarBool.VisionL_Retry] = false;
PUB.flag.set(eVarBool.FG_END_VISIONL, false, funcName);
PUB.flag.set(eVarBool.FG_PRC_VISIONL, true, funcName);
//PUB.iLockCVL.set((int)eILockCV.VISION, true, funcName);
}
else
{
VAR.BOOL[eVarBool.VisionR_Retry] = false;
PUB.flag.set(eVarBool.FG_END_VISIONR, false, funcName);
PUB.flag.set(eVarBool.FG_PRC_VISIONR, true, funcName);
//PUB.iLockCVR.set((int)eILockCV.VISION, true, funcName);
}
PUB.sm.seq.Update(cmdIndex);
return false;
}
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
//카메라 트리거 전송
var sendok = WS_Send(target, WS, item.guid, "TRIG", item.VisionData.PrintQRData);
PUB.log.Add($"Send QR Vision trigger ({target}) = {sendok} CMD=TRIG,DATA={item.VisionData.PrintQRData}");
if(sendok==false) //230512 전송실패시 오류로 한다
{
PUB.Result.SetResultMessage(eResult.HARDWARE, eECode.VISION_TRIGERROR, eNextStep.PAUSE);
return false;
}
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### 수신된 바코드 값을 기다린다.
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
//타임아웃시간을 넘어서면 오류처리한다
if (seqTime.TotalMilliseconds >= AR.SETTING.Data.Timeout_VisionProcessU)
{
//
if (target == eWorkPort.Left)
{
if (VAR.BOOL[eVarBool.VisionL_Retry] == false)
{
PUB.log.AddAT("Vision (L) failed once, retrying");
VAR.BOOL[eVarBool.VisionL_Retry] = true;
PUB.sm.seq.Update(cmdIndex, -1);
return false;
}
if (item.VisionData.RID2.isEmpty() == false && item.VisionData.MatchValidation == false)
{
PUB.Result.SetResultMessage(eResult.OPERATION, eECode.QRDATAMISSMATCHL, eNextStep.PAUSE, target, item.VisionData.RID, item.VisionData.RID2);
}
else
{
PUB.Result.SetResultMessage(eResult.OPERATION, eECode.VISION_NORECV, eNextStep.PAUSE, target);
}
}
else
{
if (VAR.BOOL[eVarBool.VisionR_Retry] == false)
{
PUB.log.AddAT("Vision (R) failed once, retrying");
VAR.BOOL[eVarBool.VisionR_Retry] = true;
PUB.sm.seq.Update(cmdIndex, -1);
return false;
}
if (item.VisionData.RID2.isEmpty() == false && item.VisionData.MatchValidation == false)
{
PUB.Result.SetResultMessage(eResult.OPERATION, eECode.QRDATAMISSMATCHR, eNextStep.PAUSE, target, item.VisionData.RID, item.VisionData.RID2);
}
else
{
PUB.Result.SetResultMessage(eResult.OPERATION, eECode.VISION_NORECV, eNextStep.PAUSE, target);
}
}
PUB.sm.seq.Update(cmdIndex, -1); // 재시작시 트리거 전송할 수 있게 위로 옮김
return false;
}
else
{
//타임아웃되지 않은 조건
if (target == eWorkPort.Left)
{
if (PUB.flag.get(eVarBool.FG_END_VISIONL)) //종료신호가 설정되어있다면 완료된 경우다
{
PUB.log.AddI($"{target} Completed processing due to vision end signal");
item.PrintQRValid = true;
}
else if (PUB.flag.get(eVarBool.FG_PRC_VISIONL) == false) //사용자가 취소했다면 넘어간다
{
PUB.log.AddAT($"{target} Skip QR verification due to user cancellation");
item.PrintQRValid = false;
}
else return false; //아직 완료전이므로 리턴한다
}
else
{
if (PUB.flag.get(eVarBool.FG_END_VISIONR))
{
PUB.log.AddI($"{target} Completed processing due to vision end signal");
item.PrintQRValid = true;
}
else if (PUB.flag.get(eVarBool.FG_PRC_VISIONR) == false) //사용자가 취소했다면 넘어간다
{
PUB.log.AddAT($"{target} Skip QR verification due to user cancellation");
item.PrintQRValid = false;
}
else return false; //아직 완료전이므로 리턴한다
}
}
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//###
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
PUB.log.Add($"{target} Vision verification completed (Result: {item.PrintQRValid})");
if (target == eWorkPort.Left)
PUB.flag.set(eVarBool.FG_PRC_VISIONL, false, funcName);
else
PUB.flag.set(eVarBool.FG_PRC_VISIONR, false, funcName);
PUB.sm.seq.Update(cmdIndex);
return false;
}
return true;
}
}
}

View File

@@ -0,0 +1,324 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using AR;
namespace Project
{
public partial class FMain
{
/// <summary>
/// 로더용 포트 조작
/// </summary>
/// <param name="idx"></param>
/// <param name="isFirst"></param>
/// <param name="StepTime"></param>
void _SM_RUN_MOT_PORT(int idx, Boolean isFirst, TimeSpan StepTime)
{
//포트 비활성 체크
eVarBool FG_RDY_PORT;
eDIName DI_LIMUP, DI_DETUP;
eDOName DO_PORTRUN;
Boolean PORT_DISABLE;
//인덱스에 맞는 플래그와 DI값 설정
if (idx == 0)
{
PORT_DISABLE = AR.SETTING.Data.Disable_PortL || AR.SETTING.Data.Disable_Left;
FG_RDY_PORT = eVarBool.FG_RDY_PORT_PL; DI_DETUP = eDIName.PORTL_DET_UP;
DI_LIMUP = eDIName.PORTL_LIM_UP; DO_PORTRUN = eDOName.PORTL_MOT_RUN;
}
else if (idx == 1)
{
PORT_DISABLE = AR.SETTING.Data.Disable_PortC;
FG_RDY_PORT = eVarBool.FG_RDY_PORT_PC; DI_DETUP = eDIName.PORTC_DET_UP;
DI_LIMUP = eDIName.PORTC_LIM_UP; DO_PORTRUN = eDOName.PORTC_MOT_RUN;
}
else
{
PORT_DISABLE = AR.SETTING.Data.Disable_PortR || AR.SETTING.Data.Disable_Right;
FG_RDY_PORT = eVarBool.FG_RDY_PORT_PR; DI_DETUP = eDIName.PORTR_DET_UP;
DI_LIMUP = eDIName.PORTR_LIM_UP; DO_PORTRUN = eDOName.PORTR_MOT_RUN;
}
//포트가 비활성화되어있다면 DETECT ON하고 , LIMIT는 해제한다 -201224
if (PORT_DISABLE)
{
if (PUB.flag.get(FG_RDY_PORT) == false)
PUB.flag.set(FG_RDY_PORT, true, "DISABLE PORT");
this.hmi1.arVar_Port[idx].AlignOK = 1;
hmi1.arVar_Port[idx].errorCount = 0;
return;
}
//비활성화(좌/우 기능사용여부확인)
//if (idx == 0 && COMM.SETTING.Data.Disable_Left == true)
//{
// this.hmi1.arVar_Port[idx].AlignOK = 1;
// return;
//}
//else if (idx == 2 && COMM.SETTING.Data.Disable_Right == true)
//{
// this.hmi1.arVar_Port[idx].AlignOK = 1;
// return;
//}
//오류가 일정횟수 발생하면 RDY를 풀어준다(이경우에는 오류처리를 해서 알림을 해야할듯함!)
if (hmi1.arVar_Port[idx].errorCount > 5)
{
if (hmi1.arVar_Port[idx].AlignOK != 1) hmi1.arVar_Port[idx].AlignOK = 1;
if (PUB.flag.get(FG_RDY_PORT) == true) PUB.flag.set(FG_RDY_PORT, false, "RUN_MOT_P");
return;
}
//동작중에 X가 pICK 위치에 있다면. Z축이 홈인지 체크한다.
if (PUB.sm.Step == eSMStep.RUN)
{
var PKZ_UNSAFE = MOT.getPositionOffset(eAxis.PZ_PICK, MOT.GetPZPos(ePZLoc.READY).Position) > 2;
//var PKX_POS = MOT.GetPKX_PosName();
var BSTOP = false;
//Z축이 Ready 위치보다 낮게 있다면 멈추게한다
if (idx == 0 && MOT.getPositionMatch(MOT.GetPXPos(ePXLoc.PICKOFFL)) && PKZ_UNSAFE) BSTOP = true;
else if (idx == 1 && MOT.getPositionMatch(MOT.GetPXPos(ePXLoc.PICKON)) && PKZ_UNSAFE) BSTOP = true;
else if (idx == 2 && MOT.getPositionMatch(MOT.GetPXPos(ePXLoc.PICKOFFR)) && PKZ_UNSAFE) BSTOP = true;
if (BSTOP)
{
if (DIO.GetIOOutput(DO_PORTRUN) == true) DIO.SetPortMotor(idx, eMotDir.CCW, false, "Z-NOTREADY");
return;
}
}
var PORTALIGN_OK = hmi1.arVar_Port[idx].AlignOK;
if (PORTALIGN_OK != 1) //align이 진행되지 않았다면 align을 잡기위해 처리를 해줘야한다
{
if (idx != 1)
{
//
}
//안전센서동작여부 확인
var BSafty = DIO.isSaftyDoorF(idx, true);
//안전이 확보된 경우에만 얼라인 ok를한다 - 임시로 해제를 한다? 상단리밋에 걸리것을 처리안하려는 코드인듯!
//if (isPortDetUp(idx) == false && isPortLimUP(idx) == true && BSafty == true) PORTALIGN_OK = 1;
if (PORTALIGN_OK == 0) //얼라인이 완료되지 않은상태라면 모터 하강
{
//모터하강시작시간
PUB.Result.PortAlignTime[idx] = DateTime.Now.Ticks;
//리밋이 감지된 상태에서 작업하는거면 좀더 오래 내린다
//if (isPortLimUP(idx))
//{
if (idx == 1) PUB.Result.PortAlignWaitSec[idx] = AR.SETTING.Data.PortAlignDownTimeL;
else PUB.Result.PortAlignWaitSec[idx] = AR.SETTING.Data.PortAlignDownTimeU;
//좌우측음 좀 덜 내려간다
//}
//else Pub.Result.PortAlignWaitSec[idx] = 1.2f;
//Pub.Result.PortAlignWaitSec[idx] -= 1.0f; //1초제거 210108
//모터하강
if (DIO.GetPortMotorDir(idx) != eMotDir.CCW && DIO.GetPortMotorRun(idx) == true)
{
DIO.SetPortMotor(idx, eMotDir.CCW, false, "하강전멈춤");
System.Threading.Thread.Sleep(100);
}
DIO.SetPortMotor(idx, eMotDir.CCW, true, "얼라인(DN)");
//하강검사시작
hmi1.arVar_Port[idx].AlignOK = 2;
//Pub.log.AddAT($"포트({idx}) 얼라인(DOWN) 작업 시작");
//포트가 이제 안정화하지 않았으니 안정화를 풀어준다
PUB.flag.set(FG_RDY_PORT, false, "MOT_PORT_ALIGNSTART");
}
else if (PORTALIGN_OK == 2) //하강해서 찾는중
{
//자재감지센서가 감지안되고 일정시간이 지나면 정방향으로 전환한다
if (isPortDetUp(idx) == false)
{
var waitSec = PUB.Result.PortAlignWaitSec[idx];
var ts = new TimeSpan(DateTime.Now.Ticks - PUB.Result.PortAlignTime[idx]);
if (ts.TotalSeconds >= waitSec)
{
if (DIO.GetPortMotorDir(idx) != eMotDir.CW && DIO.GetPortMotorRun(idx) == true)
{
DIO.SetPortMotor(idx, eMotDir.CW, false, "상승전멈춤");
System.Threading.Thread.Sleep(100);
}
DIO.SetPortMotor(idx, eMotDir.CW, true, "얼라인(UP)");
hmi1.arVar_Port[idx].AlignOK = 9; //올린다
//Pub.log.AddAT($"포트({idx}) 얼라인(UP) 작업 시작");
}
}
else
{
//하강하는데 자재가 감지되고있네? - 하강상태가이면 하강한다
if (DIO.GetIOOutput(DO_PORTRUN) == false)
{
if (DIO.GetPortMotorDir(idx) != eMotDir.CCW && DIO.GetPortMotorRun(idx) == true)
{
DIO.SetPortMotor(idx, eMotDir.CCW, false, "하강전멈춤");
System.Threading.Thread.Sleep(100);
}
DIO.SetPortMotor(idx, eMotDir.CCW, true, "얼라인(DN)");
PUB.log.Add("PORT", "Force port to descend");
}
//자재가 감지되면 시간을 다시 초기화해서 충분히 내려가도록 한다 210402
PUB.Result.PortAlignTime[idx] = DateTime.Now.Ticks;
}
//하단 리밋에 걸렷다면 반전시켜준다. 200708
if (isPortLimDN(idx) == true)
{
if (DIO.GetPortMotorDir(idx) != eMotDir.CW && DIO.GetPortMotorRun(idx) == true)
{
DIO.SetPortMotor(idx, eMotDir.CW, false, "리밋전환전멈춤");
System.Threading.Thread.Sleep(100);
}
DIO.SetPortMotor(idx, eMotDir.CW, true, "얼라인(LIM)");
hmi1.arVar_Port[idx].AlignOK = 9;
//Pub.log.AddAT($"포트({idx}) 얼라인(UP-LIM) 작업 시작");
}
}
else if (PORTALIGN_OK == 9) //상승해서 찾는중
{
if (isPortDetUp(idx) || isPortLimUP(idx))
{
hmi1.arVar_Port[idx].AlignOK = 1; //정렬완료로처리
//Pub.log.AddAT($"포트({idx}) 얼라인 작업 완료");
}
else if (isPortDetUp(idx) == false || isPortLimUP(idx) == false)
{
//둘다 켜지 않은 상태에서 모터가 멈춰있다면 올려준다
if (DIO.GetIOOutput(DO_PORTRUN) == false)
{
if (DIO.GetPortMotorDir(idx) != eMotDir.CW && DIO.GetPortMotorRun(idx) == true)
{
DIO.SetPortMotor(idx, eMotDir.CW, false, "강제상승전멈춤");
System.Threading.Thread.Sleep(100);
}
DIO.SetPortMotor(idx, eMotDir.CW, true, "MOT_PORT");
PUB.log.Add("PORT", "Force ascend (stopped at position 9)");
}
}
}
else if (PORTALIGN_OK == 1)
{
//정렬완료로처리 - 201229
hmi1.arVar_Port[idx].AlignOK = 1;
}
else
hmi1.arVar_Port[idx].AlignOK = 0; //알수없는 상태이므로 처음부터 시작하게 한다
}
else
{
//여기코드는 PORT ALIGN 이 완료된상태(=1) 일 때 동작하는 코드이다
if (PUB.flag.get(FG_RDY_PORT) == false)
{
if(idx != 1)
{
}
if (hmi1.arVar_Port[idx].errorCount > 5)
{
//5회이상 오류 발생햇으니 처리하지 않음
}
else if (isPortLimUP(idx) == true)
{
//상단 리밋이 확인됨(자재가 없는 경우임)
if (idx != 1)
{
//언로더 포트는 리밋에 걸리더라도 사용해야한다(놓는것은 가능 함)
//최초 상태에서는 반드시 이 상태가 된다
PUB.flag.set(FG_RDY_PORT, true, "MOT_PORT_UNLOADER ON");
}
else
{
if (isPortDetUp(idx))
{
PUB.flag.set(FG_RDY_PORT, true, "MOT_PORT_UNLOADER ON");
}
}
}
else if (isPortDetUp(idx) == true)
{
//자재감지가 완료되었다?
PUB.flag.set(FG_RDY_PORT, true, "RUN_MOT_P");
}
else
{
//모터를 올리는 작업을 진행해서 P-LIMIT를 찾아야 한다
Boolean runMot = DIO.GetPortMotorDir(idx) == eMotDir.CCW;
if (runMot == false)
{
if (DIO.GetIOOutput(DO_PORTRUN) == false) runMot = true;
}
if (runMot)
{
if (DIO.GetPortMotorDir(idx) != eMotDir.CW && DIO.GetPortMotorRun(idx) == true)
{
DIO.SetPortMotor(idx, eMotDir.CW, false, "얼라인(#1)전멈춤");
System.Threading.Thread.Sleep(100);
}
DIO.SetPortMotor(idx, eMotDir.CW, true, "얼라인(#1)");
}
}
}
else //포트가 준비되면 아무것도 안한다
{
//LIMIT이 들어와있는데 DETECT 센서도 들어와 있다면 다시 얼라인 잡게한다.
if (DIO.GetIOInput(DI_LIMUP) == true)
{
//언로더포트 0,2번은 Ready 를 풀지 않는다.
//그것은 P-LIM 상태라도 작업이 가능해야 한다
if (idx == 1)
{
if (isPortDetUp(idx) == false)
PUB.flag.set(FG_RDY_PORT, false, "RUN_MOT_P");
}
}
//자재가 감지되지 않았는데. LIMIT 가 아니라면 up을 시켜준다.
if (DIO.GetIOInput(DI_DETUP) == false && DIO.GetIOInput(DI_LIMUP) == false)
{
//RDY를 해제 해준다
PUB.flag.set(FG_RDY_PORT, false, "RUN_MOT_P");
if (DIO.GetIOOutput(DO_PORTRUN) == false)
{
if (DIO.GetPortMotorDir(idx) != eMotDir.CW && DIO.GetPortMotorRun(idx) == true)
{
DIO.SetPortMotor(idx, eMotDir.CW, false, "얼라인(#2)전멈춤");
System.Threading.Thread.Sleep(100);
}
DIO.SetPortMotor(idx, eMotDir.CW, true, "얼라인(#2)");
}
}
}
}
if (idx == 0)
PUB.sm.seq.UpdateTime(eSMStep.RUN_COM_PT0);
else if (idx == 1)
PUB.sm.seq.UpdateTime(eSMStep.RUN_COM_PT1);
else
PUB.sm.seq.UpdateTime(eSMStep.RUN_COM_PT2);
}
}
}

View File

@@ -0,0 +1,127 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using arDev;
using AR;
namespace Project
{
public partial class FMain
{
private void SM_StateProgress(object sender, AR.StateMachine.StateProgressEventArgs e)
{
arCtl.arLabel lbl = lbMsg;
lbl.BeginInvoke(new Action(() =>
{
var title = e.Message;
var max = e.MaxProgress;
var value = e.Progress;
if (lbl.ProgressEnable == false) lbl.ProgressEnable = true;
if (lbl.ProgressValue != value) lbl.ProgressValue = (float)value;
if (lbl.Text != title) lbl.Text = title;
if (max != 0)
{
if (lbl.ProgressMax != max) lbl.ProgressMax = (float)max;
}
if (e.ForeColor != null)
{
if (lbl.ProgressForeColor != e.ForeColor) lbl.ProgressForeColor = (Color)e.ForeColor;
}
if (e.ShadowColor != null)
{
if (lbl.ShadowColor != e.ShadowColor) lbl.ShadowColor = (Color)e.ShadowColor;
}
if (e.ProgressBackColor1 != null)
{
if (lbl.ProgressColor1 != e.ProgressBackColor1) lbl.ProgressColor1 = (Color)e.ProgressBackColor1;
}
if (e.ProgressBackColor2 != null)
{
if (lbl.ProgressColor2 != e.ProgressBackColor2) lbl.ProgressColor1 = (Color)e.ProgressBackColor2;
}
if (e.BackColor1 != null)
{
if (lbl.BackColor != e.BackColor1) lbl.BackColor = (Color)e.BackColor1;
}
if (e.BackColor2 != null)
{
if (lbl.BackColor2 != e.BackColor2) lbl.BackColor2 = (Color)e.BackColor2;
}
}));
}
private void SM_StepCompleted(object sender, EventArgs e)
{
PUB.log.Add($"Step completed({PUB.sm.Step})");
//초기화가 완료되면 컨트롤 글자를 변경 해준다.
if (PUB.sm.Step == eSMStep.INIT)
SM_InitControl(null, null);
}
private void SM_StepStarted(object sender, EventArgs e)
{
switch (PUB.sm.Step)
{
case eSMStep.IDLE:
//IDLE의 시작작업이 완료되었다면 각 버튼을 사용할 수 있도록 한다
this.Invoke(new Action(() =>
{
btStart.Enabled = true;
btStop.Enabled = true;
btReset.Enabled = true;
}));
break;
}
}
private void SM_InitControl(object sender, EventArgs e)
{
//작업시작전 컨트롤 초기화 코드
var mc = PUB.Result.mModel;
var mv = PUB.Result.vModel;
this.Invoke(new Action(() =>
{
//진행 중 표시되는 상태값 초기화
lbCntRight.ProgressValue = 0;
lbCntRight.Text = "--";
lbCntLeft.Text = "--";
}));
}
void SM_Message(object sender, StateMachine.StateMachineMessageEventArgs e)
{
//상태머신에서 발생한 메세지
PUB.log.Add(e.Header, e.Message);
}
void SM_StepChanged(object sender, StateMachine.StepChangeEventArgs e)
{
var o = (eSMStep)e.Old;
var n = (eSMStep)e.New;
PUB.log.AddI($"Step transition({o} >> {n})");
//230313
//EEMStatus.AddStatusSQL(n);
}
}
}

View File

@@ -0,0 +1,246 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using arDev;
using AR;
namespace Project
{
public partial class FMain
{
DateTime lastDeleteTime = DateTime.Now;
DateTime HomeSuccessTime;
DateTime HomeChkTime;
void SM_Loop(object sender, StateMachine.RunningEventArgs e)
{
//main loop
var step = (eSMStep)e.Step;
var obj = this.GetType();
var stepName = step.ToString();
var methodName = $"_STEP_{stepName}";
var methodNameStart = $"_STEP_{stepName}_START";
var runMethodName = $"_{stepName}";
var method = obj.GetMethod(methodName);
var methodS = obj.GetMethod(methodNameStart);
switch (step)
{
case eSMStep.NOTSET:
PUB.log.Add("S/M Initialize Start");
PUB.sm.SetNewStep(eSMStep.INIT);
break;
case eSMStep.WAITSTART:
if (e.isFirst) PUB.log.Add("EVENT WAITSTART");
break;
case eSMStep.PAUSE:
case eSMStep.EMERGENCY:
case eSMStep.ERROR:
if (e.isFirst)
_SM_MAIN_ERROR(e.isFirst, (eSMStep)e.Step, e.StepTime);
break;
default:
if (e.isFirst)
{
//시작명령은 반드시 구현할 필요가 없다
if (methodS != null) methodS.Invoke(this, new object[] { step });
else
{
hmi1.ClearMessage();
PUB.log.Add($"Undefined STEP({step}) started");
}
if (step == eSMStep.HOME_QUICK || step == eSMStep.HOME_FULL || PUB.sm.getOldStep == eSMStep.IDLE || PUB.sm.getOldStep == eSMStep.FINISH)
{
PUB.sm.seq.ClearData(step);
PUB.sm.seq.Clear(step);
}
PUB.sm.seq.ClearTime();
PUB.sm.RaiseStepStarted();
}
if (PUB.popup.needClose) System.Threading.Thread.Sleep(10);
else
{
//스텝번호값 보정 220313
if (PUB.sm.seq.Get(step) < 1) PUB.sm.seq.Update(step, 1);
if (method == null)
{
var runMethod = obj.GetMethod(runMethodName);
if (runMethod == null)
{
PUB.log.AddE($"The following command is not implemented {methodName}/{runMethodName}");
PUB.Result.SetResultMessage(eResult.DEVELOP, eECode.NOFUNCTION, eNextStep.ERROR, methodName, runMethodName);
}
else
{
var stepName2 = step.ToString();
//실행코드는 있으니 처리한다.
if (PUB.popup.needClose) System.Threading.Thread.Sleep(10); //팝업이 닫힐때까지 기다린다.
else
{
//실행가능여부를 확인 합니다
if (CheckSystemRunCondition() == true)
{
//동작상태가 아니라면 처리하지 않는다.
if (PUB.sm.Step == step && PUB.sm.getNewStep == step)
{
var param = new object[] { step };
var rlt = (bool)runMethod.Invoke(this, param);
if (rlt == true)
{
PUB.log.AddI("User step(automatic) execution completed, switching to idle state");
PUB.sm.SetNewStep(eSMStep.IDLE, true);
}
}
}
}
}
}
else
{
var param = new object[] { step, e.StepTime, PUB.sm.seq.GetTime(step) };
var rlt = (StepResult)method.Invoke(this, param);
if (rlt == StepResult.Complete) PUB.sm.RaiseStepCompleted();
else
{
//사용자 스텝이 설정되어있다면 자동으로 멈춘다 220223
if (rlt == StepResult.Error)
{
if (PUB.sm.getNewStep != eSMStep.ERROR)
PUB.sm.SetNewStep(eSMStep.ERROR);
}
if (PUB.flag.get(eVarBool.FG_USERSTEP) == true)
{
if (PUB.sm.Step >= eSMStep.RUN && PUB.sm.getNewStep >= eSMStep.RUN &&
PUB.sm.Step < eSMStep.FINISH && PUB.sm.getNewStep < eSMStep.FINISH)
{
//유저스텝에 걸려있지 않다면 자동으로 멈춘다
if (LockUserL.WaitOne(10) && LockUserR.WaitOne(10))
{
//Pub.Result.SetResultMessage(eResult.OPERATION, eECode.USER_STOP)
PUB.Result.ResultMessage = string.Empty;
PUB.sm.SetNewStep(eSMStep.PAUSE);
}
}
}
}
}
}
break;
}
}
void DeleteFile(string path)
{
var basetime = DateTime.Now.AddDays(-1 * AR.SETTING.Data.AutoDeleteDay);
var di = new System.IO.DirectoryInfo(path);
if (di.Exists)
{
var dirYear = di.GetDirectories().OrderBy(t => t.Name).FirstOrDefault();
if (dirYear != null)
{
var dirMon = dirYear.GetDirectories().OrderBy(t => t.Name).FirstOrDefault();
if (dirMon != null)
{
var dirDay = dirMon.GetDirectories().OrderBy(t => t.Name).FirstOrDefault();
if (dirDay != null)
{
var curDay = DateTime.Parse(string.Format("{0}-{1}-{2} 00:00:00", dirYear.ToString(), dirMon.ToString(), dirDay.ToString()));
if (curDay < basetime)
{
var dirLot = dirDay.GetDirectories().OrderBy(t => t.Name).FirstOrDefault();
if (dirLot != null)
{
var delfile = dirLot.GetFiles().FirstOrDefault();
if (delfile != null)
{
try
{
PUB.log.AddI("Remove Fle : " + delfile.FullName + ",time=" + delfile.LastWriteTime.ToString());
delfile.Delete();
}
catch (Exception ex)
{
PUB.log.AddE("deleete error : " + ex.Message);
}
}
else
{
string delpath = dirLot.FullName;
try
{
dirLot.Delete(true);
}
catch (Exception ex)
{
PUB.log.AddE("remove dir" + ex.Message + "," + delpath);
}
}
}
else
{
//이 폴더아래에 다른 폴더가 하나도 없다 즉 비어 있따.
string delpath = dirDay.FullName;
try
{
dirDay.Delete(true);
}
catch (Exception ex)
{
PUB.log.AddE("remove dir" + ex.Message + "," + delpath);
}
}
}
}
else
{
//날짜에 해당하는 폴더가 하나도 없다. 월 폴더를 제거한다.
string delpath = dirMon.FullName;
try
{
dirMon.Delete(true);
}
catch (Exception ex)
{
PUB.log.AddE("remove dir" + ex.Message + "," + delpath);
}
}
}
else
{
//이 달에 해당하는 데이터가 없다. 이 년도를 삭제한다.
string delpath = dirYear.FullName;
try
{
dirYear.Delete(true);
}
catch (Exception ex)
{
PUB.log.AddE("remove dir" + ex.Message + "," + delpath);
}
}
}
//년도별폴더목록을 정리함
//가장작은 년도를 기준으로 파일을 검색해서 1개씩 삭제함
}
}
}
}

View File

@@ -0,0 +1,122 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using AR;
namespace Project
{
public partial class FMain
{
private void Dio_IOValueChanged(object sender, arDev.DIO.IOValueEventArgs e)
{
if (e.Direction == arDev.DIO.eIOPINDIR.INPUT)
{
var diPin = DIO.Pin.input.Where(t=>t.terminalno == e.ArrIDX).FirstOrDefault();
if(diPin == null)
{
PUB.log.AddE($"No terminal target found for DI INDEX:{e.ArrIDX}");
}
else
{
var pin = (eDIName)diPin.idx;
if (AR.SETTING.Data.Log_DI)
{
PUB.log.Add("DIO", String.Format("DI:IDX={0},DIR={1},VAL={2},NM={3}", e.ArrIDX, e.Direction, e.NewValue, diPin));
}
var value = DIO.GetIOInput(pin);
_DIO_INPUT_VALUE_CHANGED(pin, value);
}
}
else
{
var doPin = DIO.Pin.output.Where(t => t.terminalno == e.ArrIDX).FirstOrDefault();
if (doPin == null)
{
PUB.log.AddE($"No terminal target found for DO INDEX:{e.ArrIDX}");
}
else
{
var pin = (eDOName)doPin.idx;
if (AR.SETTING.Data.Log_DO)
{
//타워램프는 제외하낟.
if (e.ArrIDX != (byte)eDOName.TWR_GRNF &&
e.ArrIDX != (byte)eDOName.TWR_REDF &&
e.ArrIDX != (byte)eDOName.TWR_YELF &&
e.ArrIDX != (byte)eDOName.BUT_STARTF &&
e.ArrIDX != (byte)eDOName.BUT_STOPF &&
e.ArrIDX != (byte)eDOName.BUT_RESETF)
PUB.log.Add("DIO", String.Format("DO:IDX={0},DIR={1},VAL={2}", e.ArrIDX, e.Direction, e.NewValue));
}
_DIO_OUTPUT_VALUE_CHANGED(pin, e.NewValue);
}
}
}
void _DIO_IOMessage(object sender, arDev.DIO.MessageEventArgs e)
{
if (e.IsError)
{
if (e.Message.ToLower().IndexOf("inposi") != -1 || e.Message.ToLower().IndexOf("동일위치") != -1)
{
PUB.log.AddAT("DIO:" + e.Message);
}
else
{
PUB.log.AddE("DIO:" + e.Message);
}
}
else PUB.log.Add("DIO:" + e.Message);
}
//void IO_SaftySensor_Changed(eDIName pin, eFlag flag, eVar_Date varDt_On, eVar_Date varDt_Off, bool value)
//{
// //안전센서는 일정 시간 동작하는것을 체크한다
// Pub.log.AddAT(string.Format("{0} Sensor : {1}", pin, value));
// if (value) Pub.Var_dateTime[(int)varDt_On] = DateTime.Now;
// else Pub.Var_dateTime[(int)varDt_Off] = DateTime.Now;
//}
void IncCount(int seq, int port, int value = 1)
{
if (SETTING.Counter.DateStr != DateTime.Now.ToShortDateString())
{
if (port == 0) SETTING.Counter.CountDP1 = value;
if (port == 1) SETTING.Counter.CountDP2 = value;
if (port == 2) SETTING.Counter.CountDP3 = value;
if (port == 3) SETTING.Counter.CountDP4 = value;
SETTING.Counter.DateStr = DateTime.Now.ToShortDateString();
}
else
{
if (port == 0) SETTING.Counter.CountDP1 += value;
if (port == 1) SETTING.Counter.CountDP2 += value;
if (port == 2) SETTING.Counter.CountDP3 += value;
if (port == 3) SETTING.Counter.CountDP4 += value;
}
//각 포트별 수량은 차수별 작업이므로 차수가 변경되면 리셋됨
//리셋되는 코드 필요함
if (port == 0) SETTING.Counter.CountP0 += value;
if (port == 1) SETTING.Counter.CountP1 += value;
if (port == 2) SETTING.Counter.CountP2 += value;
if (port == 3) SETTING.Counter.CountPrintR += value;
else
{
PUB.log.AddAT(string.Format("[{0}] Cannot increase quantity as it is an unspecified port", seq));
}
//Pub.log.AddI("수량정보가 저장 되었습니다");
SETTING.Counter.Save();
}
}
}

View File

@@ -0,0 +1,43 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
namespace Project
{
public partial class FMain
{
#region "Common Utility"
/// <summary>
/// 지정된 시간만큼 대기하며 완료되면 true를 반환합니다.
/// </summary>
/// <param name="time"></param>
/// <returns></returns>
Boolean WaitForSeconds(eWaitType wait, double timems)
{
var idx = (byte)wait;
if (PUB.Result.WaitForVar[idx] == null || PUB.Result.WaitForVar[idx].Year == 1982)
{
PUB.Result.WaitForVar[idx] = PUB.Result.WaitForVar[idx] = DateTime.Now;
//Pub.log.Add(string.Format("Wait for [{0}], Wait Time:{1}ms", wait, timems));
}
var ts = DateTime.Now - PUB.Result.WaitForVar[idx];
if (ts.TotalSeconds >= timems) return true;
else return false;
}
void ResetWaitForSeconds(eWaitType wait)
{
var idx = (byte)wait;
PUB.Result.WaitForVar[idx] = DateTime.Parse("1982-11-23");
}
#endregion
}//cvass
}

View File

@@ -0,0 +1,265 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text.RegularExpressions;
using AR;
namespace Project
{
public partial class FMain
{
void SM_SPS(object sender, EventArgs e)
{
//명령어 가져오기 7:3개의 데이터 확인
if (PUB.plc != null && PUB.plc.Init)
{
if (PUB.plc.ReadBytes(0, 16, out byte[] plcbuffer))
{
//내부버퍼에 상태를 기록한다
Array.Copy(plcbuffer, 0, PUB.swPLCBuffer, 0, plcbuffer.Length);
}
}
//인터락설정(공용)
Set_InterLock();
//230905
hmi1.CVLeftBusy = PUB.iLockCVL.get((int)eILockCV.BUSY);
hmi1.CVLeftReady = PUB.iLockCVL.get((int)eILockCV.EXTBUSY);
hmi1.CVRightBusy = PUB.iLockCVR.get((int)eILockCV.BUSY);
hmi1.CVRightReady = PUB.iLockCVR.get((int)eILockCV.EXTBUSY);
//XMOVE 시에 RESET 키를 이용한 장치 초기화 작업
if (PUB.sm.Step == eSMStep.IDLE)
if (PUB.mot.HasHomeSetOff == true)
if (DIO.GetIOInput(eDIName.BUT_RESETF) == true)
if (DIO.GetIOInput(eDIName.PICKER_SAFE) == true)
if (PUB.Result.ResetButtonDownTime.Year != 1982)
if ((DateTime.Now - PUB.Result.ResetButtonDownTime).TotalSeconds >= 5)
Func_sw_initialize();
//비상정지체크
if (PUB.dio.IsInit == true)
{
if (DIO.IsEmergencyOn() == true)
{
//모터에 비상정지신호를 바로 전송한다
//Util_DO.SetMotEmergency(true);
DIO.SetMotPowerOn(false);
DIO.SetMotEmergency(true);
if (PUB.sm.Step > eSMStep.IDLE)
{
string EmgButtonState = string.Empty;
if (DIO.GetIOInput(eDIName.BUT_EMGF)) EmgButtonState = "EMG-FRONT";
if (PUB.sm.Step != eSMStep.EMERGENCY &&
PUB.sm.getNewStep != eSMStep.EMERGENCY)
{
PUB.mot.MoveStop("EmgBut", true); //모든 축 강제정지 (물리시그널에 의해 미리 정지 된 상태임)
//비상상태가 아니라면 비상으로 전환해준다.
PUB.Result.ResultCode = eResult.EMERGENCY;
PUB.Result.ResultMessage = string.Format("EMERGENCY\n" +
"Emergency stop button ({0}) has been pressed\n" +
"All motions are forced to stop\n" +
"Please check the emergency stop button and initialize the system", EmgButtonState);
PUB.log.AddI("SPS:Reserve Emergency Step");
PUB.sm.SetNewStep(eSMStep.EMERGENCY);
}
}
}
else
{
//이머전시가 해제되었으므로 파워를 복원한다.
DIO.SetMotPowerOn(true);
DIO.SetMotEmergency(false);
}
}
//룸조명(자동)
if (PUB.dio.IsInit)
Func_AutoRoomLight();
//부저확인
if (PUB.dio.IsInit)
Func_BuzzerControl();
//충돌검사()
if (PUB.dio.IsInit && PUB.mot.IsInit)
CheckCollision();
//포트의 UP/DN 모터
PortZMotorAutoOff();
//포트의 마그넷 작동
PortMagnet();
//동작중에 데이터가 reset 되는 코드 임시로 모니터링한다.
if (PUB.sm.Step != eSMStep.IDLE && PUB.sm.Step != eSMStep.HOME_FULL && PUB.sm.Step != eSMStep.HOME_QUICK)
{
var currid = PUB.Result.ItemDataC.VisionData.RID;
if (currid.Equals(lastridv1) == false)
{
PUB.AddDebugLog("[SPS] RID값 변경 감지 :" + currid);
lastridv1 = currid;
}
}
//process barcode
BarcodeProcess();
AutoOutConveyor();
}
string lastridv1 = string.Empty;
System.Diagnostics.Stopwatch UnloaderWatch = new System.Diagnostics.Stopwatch();
void PortMagnet()
{
if (PUB.flag.get(eVarBool.FG_WAT_MAGNET0) && DIO.GetIOOutput(eDOName.PORTL_MAGNET) == false)
{
var ts = DateTime.Now - VAR.TIME[(int)eVarTime.MAGNET0];
if (ts.TotalMilliseconds > AR.SETTING.Data.WaitTime_Magnet0)
{
DIO.SetPortMagnet(0, true); //Util_DO.SetOutput(eDOName.CART_MAG0, true);
PUB.flag.set(eVarBool.FG_WAT_MAGNET0, false, "SPS-MAGON");
}
}
if (PUB.flag.get(eVarBool.FG_WAT_MAGNET0) == true && DIO.GetIOOutput(eDOName.PORTL_MAGNET) == true)
{
PUB.flag.set(eVarBool.FG_WAT_MAGNET0, false, "SPS-MAGOFF");
}
if (PUB.flag.get(eVarBool.FG_WAT_MAGNET1) && DIO.GetIOOutput(eDOName.PORTC_MAGNET) == false)
{
var ts = DateTime.Now - VAR.TIME[(int)eVarTime.MAGNET1];
if (ts.TotalMilliseconds > AR.SETTING.Data.WaitTime_Magnet1)
{
DIO.SetPortMagnet(1, true); // Util_DO.SetOutput(eDOName.CART_MAG1, true);
PUB.flag.set(eVarBool.FG_WAT_MAGNET1, false, "SPS-MAGON");
}
}
if (PUB.flag.get(eVarBool.FG_WAT_MAGNET1) == true && DIO.GetIOOutput(eDOName.PORTC_MAGNET) == true)
{
PUB.flag.set(eVarBool.FG_WAT_MAGNET1, false, "SPS-MAGOFF");
}
if (PUB.flag.get(eVarBool.FG_WAT_MAGNET2) && DIO.GetIOOutput(eDOName.PORTR_MAGNET) == false)
{
var ts = DateTime.Now - VAR.TIME[(int)eVarTime.MAGNET2];
if (ts.TotalMilliseconds > AR.SETTING.Data.WaitTime_Magnet2)
{
DIO.SetPortMagnet(2, true); // Util_DO.SetOutput(eDOName.CART_MAG2, true);
PUB.flag.set(eVarBool.FG_WAT_MAGNET2, false, "SPS-MAGON");
}
}
if (PUB.flag.get(eVarBool.FG_WAT_MAGNET2) == true && DIO.GetIOOutput(eDOName.PORTR_MAGNET) == true)
{
PUB.flag.set(eVarBool.FG_WAT_MAGNET2, false, "SPS-MAGOFF");
}
}
int intlockcnt = 0;
/// <summary>
/// 이 기능은 DIO 에서도 처리된다. - 해당 위치가 더 빠를듯 하여 ,그곳에서도 처리되고 이곳에서도 추가 처리를 한다
/// </summary>
private void PortZMotorAutoOff()
{
//dir 이 켜져있다면 Up/ 꺼져있다면 down
var P0DirUp = DIO.GetPortMotorDir(0) == eMotDir.CW;
var P1DirUp = DIO.GetPortMotorDir(1) == eMotDir.CW;
var P2DirUp = DIO.GetPortMotorDir(2) == eMotDir.CW;
var P0Run = DIO.GetIOOutput(eDOName.PORTL_MOT_RUN);
var P1Run = DIO.GetIOOutput(eDOName.PORTC_MOT_RUN);
var P2Run = DIO.GetIOOutput(eDOName.PORTR_MOT_RUN);
var P0LimUp = DIO.GetIOInput(eDIName.PORTL_LIM_UP);
var P1LimUp = DIO.GetIOInput(eDIName.PORTC_LIM_UP);
var P2LimUp = DIO.GetIOInput(eDIName.PORTR_LIM_UP);
var P0DetUp = DIO.GetIOInput(eDIName.PORTL_DET_UP);
var P1DetUp = DIO.GetIOInput(eDIName.PORTC_DET_UP);
var P2DetUp = DIO.GetIOInput(eDIName.PORTR_DET_UP);
var P0LimDn = DIO.GetIOInput(eDIName.PORTL_LIM_DN);
var P1LimDn = DIO.GetIOInput(eDIName.PORTC_LIM_DN);
var P2LimDn = DIO.GetIOInput(eDIName.PORTR_LIM_DN);
//현재 출력중이고, 상단이 켜져있는데 상단 센서가 들어와잇다면 OFF 한다
if (P0Run && P0DirUp && (P0LimUp || P0DetUp)) DIO.SetPortMotor(0, eMotDir.CCW, false, "SPS");
if (P1Run && P1DirUp && (P1LimUp || P1DetUp)) DIO.SetPortMotor(1, eMotDir.CCW, false, "SPS");
if (P2Run && P2DirUp && (P2LimUp || P2DetUp)) DIO.SetPortMotor(2, eMotDir.CCW, false, "SPS");
//현재 출력중이고, 하단이 켜져있는데. 하단 센서가 들어와 있다면 Off 한다
if (P0Run && P0DirUp == false && P0LimDn) DIO.SetPortMotor(0, eMotDir.CW, false, "SPS");
if (P1Run && P1DirUp == false && P1LimDn) DIO.SetPortMotor(1, eMotDir.CW, false, "SPS");
if (P2Run && P2DirUp == false && P2LimDn) DIO.SetPortMotor(2, eMotDir.CW, false, "SPS");
//작업이 종료되어서 포트가 내려가고 있다면 5초뒤에 멈춘다 - 210405
if (PUB.flag.get(eVarBool.FG_PORT1_ENDDOWN) && AR.SETTING.Data.Port1FisnishDownTime > 0)
{
var runtime = DateTime.Now - VAR.TIME[(int)eVarTime.PORT1];
if (runtime.TotalMilliseconds >= AR.SETTING.Data.Port1FisnishDownTime)
{
if (P1Run && PUB.sm.isRunning == false && DIO.GetPortMotorDir(1) == eMotDir.CCW)
{
DIO.SetPortMotor(1, eMotDir.CW, false, "SPS");
}
PUB.flag.set(eVarBool.FG_PORT1_ENDDOWN, false, "SPS");
VAR.TIME.Update(eVarTime.PORT1);
}
}
}
DateTime CollCheckTime = DateTime.Now;
private void CheckCollision()
{
//충돌검검사 (홈 이 완료안된 모터에는 처리하지 않는다)
if (PUB.sm.Step != eSMStep.RUN || PUB.sm.getNewStep != eSMStep.RUN) return;
//초당 20번 검사하게 함
var ts = DateTime.Now - CollCheckTime;
if (ts.TotalMilliseconds < 50) return;
//현재 시간으로 설정
CollCheckTime = DateTime.Now;
}
private void Func_AutoRoomLight()
{
if (AR.SETTING.Data.Enable_AutoLight == false) return;
}
private void Func_BuzzerControl()
{
//if (AR.SETTING.Data.Disable_Buzzer == false) return;
if (PUB.BuzzerTime.Year == 1982) return; //시간설정이없으면 out
if (DIO.GetIOOutput(eDOName.BUZZER) == false) return; //부저가 꺼져있다면 out
if (AR.SETTING.Data.buzz_run_ms != 0) //시간이 설정된 경우에만 작동190509
{
if (PUB.BuzzerTime.Year == 1982) PUB.BuzzerTime = DateTime.Now;
else
{
var ts = DateTime.Now - PUB.BuzzerTime;
if (ts.TotalMilliseconds >= AR.SETTING.Data.buzz_run_ms) //지정시간이 초과된경우에만 OFF
{
PUB.log.Add("Auto Buzzer Off by SPS");
DIO.SetBuzzer(false); //지정시간초과로 부저를 OFF 한다.
}
}
}
}
}
}

View File

@@ -0,0 +1,87 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text.RegularExpressions;
using AR;
namespace Project
{
public partial class FMain
{
//컨베이어 배출신호를 자동 해제한다.(지정시간-초)
DateTime AutoConvOutTimeL = new DateTime(1982, 11, 23);
DateTime AutoConvOutTimeR = new DateTime(1982, 11, 23);
void AutoOutConveyor()
{
//동작중에만 사용한다
if (PUB.sm.Step != eSMStep.RUN) return;
//컨베이어 사용시에만.
if (VAR.BOOL[eVarBool.Use_Conveyor] == false) return;
//모델정보 필수
if (PUB.Result.vModel == null || PUB.Result.isSetvModel == false) return;
//자동 해제 시간확인 (0=비활성)
var AutoReleaseSecond = PUB.Result.vModel.AutoOutConveyor;
if (AutoReleaseSecond < 1) return;
//현재 모델의 사용여부 확인 (UI상단에서 버튼으로 클릭가능하다)
if (PUB.Result.AutoReelOut == false) return;
//외부신호 대기중일때만 사용
if (PUB.iLockCVL.get((int)eILockCV.EXTBUSY) && DIO.GetIOInput(eDIName.L_CONV4))
{
if (VAR.BOOL[eVarBool.FG_AUTOOUTCONVL] == false)
{
if (AutoConvOutTimeL.Year == 1982) AutoConvOutTimeL = DateTime.Now;
var ts = DateTime.Now - AutoConvOutTimeL;
if (ts.TotalSeconds > AutoReleaseSecond)
{
PUB.log.AddI($"Auto Conveyor(L) Output - On");
VAR.BOOL[eVarBool.FG_AUTOOUTCONVL] = true;
AutoConvOutTimeL = DateTime.Now;
}
}
}
else if (VAR.BOOL[eVarBool.FG_AUTOOUTCONVL] == true)
{
var ts = DateTime.Now - AutoConvOutTimeL;
if (ts.TotalSeconds > SETTING.Data.Timeout_AutoOutConvSignal)
{
PUB.log.Add($"Auto Conveyor(L) Output - Off");
VAR.BOOL[eVarBool.FG_AUTOOUTCONVL] = false;
AutoConvOutTimeL = new DateTime(1982, 11, 23);
}
}
//외부신호 대기중일때만 사용
if (PUB.iLockCVR.get((int)eILockCV.EXTBUSY) && DIO.GetIOInput(eDIName.R_CONV4))
{
if (VAR.BOOL[eVarBool.FG_AUTOOUTCONVR] == false)
{
if (AutoConvOutTimeR.Year == 1982) AutoConvOutTimeR = DateTime.Now;
var ts = DateTime.Now - AutoConvOutTimeR;
if (ts.TotalSeconds > AutoReleaseSecond)
{
PUB.log.AddI($"Auto Conveyor(R) Output - On");
VAR.BOOL[eVarBool.FG_AUTOOUTCONVR] = true;
AutoConvOutTimeR = DateTime.Now;
}
}
}
else if (VAR.BOOL[eVarBool.FG_AUTOOUTCONVR] == true)
{
var ts = DateTime.Now - AutoConvOutTimeR;
if (ts.TotalSeconds > SETTING.Data.Timeout_AutoOutConvSignal)
{
PUB.log.Add($"Auto Conveyor(R) Output - Off");
VAR.BOOL[eVarBool.FG_AUTOOUTCONVR] = false;
AutoConvOutTimeR = new DateTime(1982, 11, 23);
}
}
}
}
}

View File

@@ -0,0 +1,266 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text.RegularExpressions;
using AR;
namespace Project
{
public partial class FMain
{
Tuple<int, List<string>> BarcodeRegExProcess(
List<Class.RegexPattern> patterns,
List<Class.RegexPattern> patternsEx,
Class.VisionData vdata, string barcodeSymbol,
string bcd, out bool IgnoreBarcode, out bool findregex)
{
//var patterns = PUB.Result.BCDPattern;
IgnoreBarcode = false;
findregex = false;
if (barcodeSymbol == "6") barcodeSymbol = "11"; //250930
//get : same symbol data
List<Class.RegexPattern> pats;
if (patterns != null)
{
if (barcodeSymbol.isEmpty() == false) pats = patterns.Where(t => t.IsEnable == true && (string.IsNullOrEmpty(t.Symbol) || t.Symbol == barcodeSymbol)).OrderBy(t => t.Seq).ToList();
else pats = patterns.Where(t => t.IsEnable == true).OrderBy(t => t.Seq).ToList();
}
else pats = new List<Class.RegexPattern>();
List<Class.RegexPattern> patsEx;
if (patternsEx == null) patsEx = new List<Class.RegexPattern>();
else
{
if (barcodeSymbol.isEmpty() == false) patsEx = patternsEx.Where(t => string.IsNullOrEmpty(t.Symbol) || t.Symbol == barcodeSymbol).OrderBy(t => t.Seq).ToList();
else patsEx = patternsEx.Where(t => t.IsEnable == true).OrderBy(t => t.Seq).ToList();
}
//모델정보의 허용 심볼인지 확인한다 221017
var vm = PUB.Result.vModel;
if (vm != null)
{
if (vm.BCD_DM == false && barcodeSymbol == "2")
{
PUB.log.AddAT($"Inactive in model Symbol Setting(DM):{bcd}");
IgnoreBarcode = true;
return new Tuple<int, List<string>>(0, new List<string>());
}
else if (vm.BCD_1D == false && (barcodeSymbol == "6" || barcodeSymbol == "11"))
{
PUB.log.AddAT($"Inactive in model Symbol Setting(1D):{bcd}");
IgnoreBarcode = true;
return new Tuple<int, List<string>>(0, new List<string>());
}
else if (vm.BCD_QR == false && (barcodeSymbol == "1"))
{
PUB.log.AddAT($"Inactive in model Symbol Setting(QR):{bcd}");
IgnoreBarcode = true;
return new Tuple<int, List<string>>(0, new List<string>());
}
}
//check barcode pattern
if (pats.Any() == false)
{
PUB.log.AddAT($"No registered pattern(SYM={barcodeSymbol}) Model:{vm.Title}");
return new Tuple<int, List<string>>(0, new List<string>());
}
//이 바코드가 무시바코드에 있는지 먼저 검사한다 220718
foreach (var pt in patsEx)
{
//skip disable item
if (pt.IsEnable == false) continue;
//check regex
var regx = new Regex(pt.Pattern, RegexOptions.IgnoreCase, new TimeSpan(0, 0, 10));
if (regx.IsMatch(bcd))
{
PUB.log.AddAT($"Ignore barcode:{bcd},PAT:{pt.Pattern},SYM:{pt.Symbol}");
IgnoreBarcode = true;
break;
}
}
if (IgnoreBarcode)
{
return new Tuple<int, List<string>>(0, new List<string>());
}
//동작중에 들어오는 바코드의 자동처리코드 추가 250926
if (PUB.sm.Step == eSMStep.RUN || PUB.sm.Step == eSMStep.PAUSE || PUB.sm.Step == eSMStep.WAITSTART)
{
var OPT_PrinterOff = VAR.BOOL[eVarBool.Opt_DisablePrinter];
var OPT_CameraOff = PUB.OPT_CAMERA();
var OPT_BYPASS = PUB.OPT_BYPASS();
if (OPT_BYPASS == false)
{
//기본 벤더이름
if (PUB.Result.vModel.Def_Vname.isEmpty() == false)
{
if (vdata.VNAME.Equals(PUB.Result.vModel.Def_Vname) == false)
{
vdata.VNAME = PUB.Result.vModel.Def_Vname;
vdata.VNAME_Trust = true;
PUB.log.Add($"Defaul V.Name Set to {PUB.Result.vModel.Def_Vname}");
}
}
//기본 MFG
if (PUB.Result.vModel.Def_MFG.isEmpty() == false)
{
if (vdata.MFGDATE.Equals(PUB.Result.vModel.Def_MFG) == false)
{
vdata.MFGDATE = PUB.Result.vModel.Def_MFG;
vdata.MFGDATE_Trust = true;
PUB.log.Add($"Defaul MFGDATE Set to {PUB.Result.vModel.Def_MFG}");
}
}
//파트넘버무시
if (PUB.Result.vModel.IgnorePartNo)
{
vdata.PARTNO_Trust = true;
}
//배치무시
if (PUB.Result.vModel.IgnoreBatch)
{
}
//프린트를 하지 않는 경우에는 프린트 위치를 자동으로 처리한다.
if (OPT_PrinterOff == true)
{
vdata.PrintPositionData = "0";
vdata.PrintPositionCheck = true;
}
}
else
{
if (vdata.VNAME_Trust == false)
{
vdata.VNAME = "BYPASS";
vdata.VNAME_Trust = true;
}
}
}
var ValueApplyCount = 0;
ValueApplyCount = 0;
List<string> list = new List<string>();
findregex = false;
foreach (var pt in pats)
{
//skip disable item
if (pt.IsEnable == false) continue;
var regx = new Regex(pt.Pattern, RegexOptions.IgnoreCase, new TimeSpan(0, 0, 5));
try
{
if (regx.IsMatch(bcd))
{
findregex = true;
//find data
var matchs = regx.Matches(bcd);
foreach (System.Text.RegularExpressions.Match mat in matchs)
{
if (vdata == null) ValueApplyCount += 1;
else
{
foreach (var matchdata in pt.Groups)
{
if (matchdata.GroupNo <= mat.Groups.Count)
{
var data = mat.Groups[matchdata.GroupNo];
if (PUB.SetBCDValue(vdata, matchdata.TargetPos, data.Value, pt.IsTrust))
ValueApplyCount += 1;
}
}
}
}
if (vdata != null && pt.IsAmkStd)// && bcdObj.barcodeSymbol == "1")
{
vdata.QRInputRaw = bcd;
}
if (vdata != null)
PUB.log.AddI($"[{pt.Description}]=>{bcd}");
list.Add(pt.Customer + "|" + pt.Description);
}
else
{
//PUB.log.AddAT($"(X)Match ({pt.Pattern}) Data={bcd}");
}
}
catch (Exception ex)
{
PUB.log.AddE($"BarcodeRegEx Error : {ex.Message}");
}
}
return new Tuple<int, List<string>>(ValueApplyCount, list);
}
/// <summary>
/// barcod eprocess
/// </summary>
void BarcodeProcess()
{
var itemC = PUB.Result.ItemDataC;
var vdata = itemC.VisionData;
//No Run - Confirm Data
if (vdata.Confirm) return;
var vm = PUB.Result.vModel;
lock (vdata.barcodelist)
{
foreach (var item in vdata.barcodelist)
{
//var src = item.Value.barcodeSource;
var bcd = item.Value.Data;
var bcdObj = item.Value;
//already checked
if (bcdObj.RegExConfirm) continue;
lock (PUB.Result.BCDPatternLock)
{
var ValueApplyCount = BarcodeRegExProcess(PUB.Result.BCDPattern, PUB.Result.BCDIgnorePattern, vdata, bcdObj.barcodeSymbol, bcd, out bool IgnoreBcd, out bool findregex);
bcdObj.Ignore = IgnoreBcd;
//기타바코드 무시기능 적용 221018
if (vm != null && vm.IgnoreOtherBarcode == true && findregex == false)
bcdObj.Ignore = true;
bcdObj.RefExApply = (ValueApplyCount?.Item1 ?? 0);
bcdObj.RegExConfirm = true;
}
}
}
//all process sequence
if (BCDProcess_ALL(itemC, "SPS", PUB.sm.Step == eSMStep.RUN) != EResultKeyence.Nothing)
{
//nothing : multisid condition
}
}
}
}

View File

@@ -0,0 +1,147 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text.RegularExpressions;
using Newtonsoft.Json.Linq;
namespace Project
{
public partial class FMain
{
bool RecvQRProcess(List<string> qrdatas, eWorkPort vIdx)
{
//데이터가없으면 처리하지 않는다.
if (qrdatas == null || qrdatas.Count < 1) return false;
bool FindData = false;
var idata = vIdx == eWorkPort.Left ? PUB.Result.ItemDataL : PUB.Result.ItemDataR;
//표준바코드라면 그 값을 표시해준다
lock (PUB.Result.BCDPatternLock)
{
var patterns = PUB.Result.BCDPattern;
foreach (var datas in qrdatas)
{
// JSON 구조에서 "data" 필드 추출
string barcodeData = datas;
try
{
var jobj = JObject.Parse(datas);
if (jobj["data"] != null)
{
barcodeData = jobj["data"].ToString();
}
}
catch
{
// JSON 파싱 실패 시 원본 데이터 사용
barcodeData = datas;
}
//원본자료를 체크한다
if (barcodeData.Equals(idata.VisionData.PrintQRData))
{
//인쇄한 자료와 동일한 자료이다
FindData = true;
}
//표준 바코드 형태만 취한다
var pats = patterns.Where(t => t.IsAmkStd && t.IsEnable).OrderBy(t => t.Seq).ToList();
if (pats.Any())
{
//패턴을 확인하여 값을 표시해준다
//var ValueApplyCount = 0;
foreach (var pt in pats)
{
var regx = new Regex(pt.Pattern, RegexOptions.IgnoreCase, new TimeSpan(0, 0, 10));
if (regx.IsMatch(barcodeData)) //패턴이 일치하다면 이것만 사용한다
{
//find data
var matchs = regx.Matches(barcodeData);
foreach (System.Text.RegularExpressions.Match mat in matchs)
{
foreach (var matchdata in pt.Groups)
{
if (matchdata.GroupNo <= mat.Groups.Count)
{
var data = mat.Groups[matchdata.GroupNo];
switch (matchdata.TargetPos.ToUpper())
{
case "SID":
idata.VisionData.SID2 = data.Value;
break;
case "RID":
idata.VisionData.RID2 = data.Value;
break;
case "VLOT":
idata.VisionData.VLOT2 = data.Value;
break;
case "VNAME":
idata.VisionData.VNAME2 = data.Value;
break;
case "MFG":
idata.VisionData.MFGDATE2 = data.Value;
break;
case "QTY":
idata.VisionData.QTY2 = data.Value;
break;
case "PART":
idata.VisionData.PARTNO2 = data.Value;
break;
}
}
}
}
break;
}
}
}
}
}
//자료는 있었지만 바코드검증이 실패된 경우이다
//타임아웃까지 기다리지 않고 바로 오류처리를 한다.
if (FindData == true)
{
//데이터를 찾았다면 완료처리를 해준다
idata.VisionData.Complete = true;
//PUB.Result.ItemData[vIdx].VisionData.Complete = true;
return true;
}
return false;
//else
//{
// var item = Pub.Result.ItemData[vIdx];
// var tsGrab = DateTime.Now - Pub.GetVarTime(VAR_LIVEVIEW);
// var timeoutVision = vIdx == 1 ? COMM.SETTING.Data.Timeout_VisionProcessL : COMM.SETTING.Data.Timeout_VisionProcessU;
// if (tsGrab.TotalMilliseconds >= timeoutVision)
// {
// //다음 바코드가 있다면 추가 진행을 위해서 남겨준다
// _SM_SAVEIMAGE(vIdx, DateTime.Now, "Images(QRValid)");
// WS_Send((idx == 0 ? 0 : 1), Pub.wsL, Pub.Result.ItemData[idx].guid, "OFF");
// var barcodepos = vIdx == 0 ? "LEFT" : "RIGHT";
// Pub.log.AddE("(" + barcodepos + ")바코드를 검증했지만 일치하지 않습니다");
// Pub.Result.SetResultMessage(eResult.OPERATION, eECode.BARCODEVALIDERR, eNextStep.pause,
// vIdx, Pub.Result.ItemData[vIdx].VisionData.RID, Pub.Result.ItemData[vIdx].VisionData.RID2,
// Pub.Result.ItemData[vIdx].VisionData.QTY, Pub.Result.ItemData[vIdx].VisionData.QTY2,
// Pub.Result.ItemData[vIdx].VisionData.SID, Pub.Result.ItemData[vIdx].VisionData.SID2,
// Pub.Result.ItemData[vIdx].VisionData.MFGDATE, Pub.Result.ItemData[vIdx].VisionData.MFGDATE2,
// barcodepos);
// return;
// }
//}
}
}
}

View File

@@ -0,0 +1,49 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using AR;
namespace Project
{
public partial class FMain
{
public void _STEP_FINISH_START(eSMStep step)
{
//포트1번을 아래로 이동한다(모든포트를 내린다)
DIO.SetPortMotor(1, eMotDir.CCW, true, "FINISH"); //210326
var cvMODE = VAR.BOOL[eVarBool.Use_Conveyor];
if(cvMODE==false)
{
if (AR.SETTING.Data.Disable_Left == false) DIO.SetPortMotor(0, eMotDir.CCW, true, "FINISH"); //210326
if (AR.SETTING.Data.Disable_Right == false) DIO.SetPortMotor(2, eMotDir.CCW, true, "FINISH"); //210326
}
//picker move to center
if (DIO.GetIOInput(eDIName.PICKER_SAFE) == false)
{
var PosX = MOT.GetPXPos(ePXLoc.PICKON);
MOT.Move(PosX);
}
PUB.Result.JobEndTime = DateTime.Now;
//컨베어OFF
DIO.SetOutput(eDOName.LEFT_CONV, false);
DIO.SetOutput(eDOName.RIGHT_CONV, false);
DIO.SetBuzzer(true, AR.SETTING.Data.Force_JobEndBuzzer);
PUB.log.AddI("Work has been completed");
needShowSummary = true;
}
public StepResult _STEP_FINISH(eSMStep step, TimeSpan stepTime, TimeSpan seqTime)
{
return StepResult.Wait;
}
}
}

View File

@@ -0,0 +1,150 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using AR;
namespace Project
{
public partial class FMain
{
public void _STEP_HOME_CONFIRM_START(eSMStep step)
{
PUB.sm.seq.Clear(step);
}
public StepResult _STEP_HOME_CONFIRM(eSMStep step, TimeSpan stepTime, TimeSpan seqTime)
{
byte idx = 1;
var cmdIndex = step;
if (PUB.sm.seq.Get(cmdIndex) < idx) PUB.sm.seq.Set(cmdIndex, idx);
//*********************
//** 하드웨어 조건 확인
//*********************
if (CheckHomeProcess_HW_Available(false) == false)
{
return StepResult.Error;
}
// 전체 홈 시간을 체크한다.
if (stepTime.TotalSeconds >= AR.SETTING.Data.Timeout_HomeSearch)
{
PUB.Result.SetResultMessage(eResult.TIMEOUT, eECode.HOME_TIMEOUT, eNextStep.NOTHING, AR.SETTING.Data.Timeout_HomeSearch); //, eECode.(eResult.HomeTimeout,msg ,false);
return StepResult.Error;
}
//모든축의 완료여부 확인
if (PUB.sm.seq.Get(step) == idx++)
{
//모든축이 완료되었다면 완료처리를 한다.
if (
PUB.mot.IsHomeSet((short)eAxis.PX_PICK) &&
PUB.mot.IsHomeSet((short)eAxis.PZ_PICK) &&
PUB.mot.IsHomeSet((short)eAxis.Z_THETA) &&
PUB.mot.IsHomeSet((short)eAxis.PL_MOVE) &&
PUB.mot.IsHomeSet((short)eAxis.PR_MOVE) &&
PUB.mot.IsHomeSet((short)eAxis.PL_UPDN) &&
PUB.mot.IsHomeSet((short)eAxis.PR_UPDN))
{
//완료처리
hmi1.Scean = UIControl.HMI.eScean.Nomal;
PUB.sm.seq.Update(cmdIndex);
}
return StepResult.Wait;
}
//X축을 안전위치로 보낸다
if (PUB.sm.seq.Get(step) == idx++)
{
var Pos = MOT.GetPXPos(ePXLoc.PICKON);
Pos.Speed = 200;
if (MOT.CheckMotionPos(seqTime, Pos, "HOME_SEARCH", false) == false) return StepResult.Wait;
PUB.sm.seq.Update(cmdIndex);
return StepResult.Wait;
}
//자재를 들고 있는가(왼쪽)
if (PUB.sm.seq.Get(step) == idx++)
{
if (DIO.isVacOKL() > 0)
{
//로더에 다시 놓아야 한다
var Pos = MOT.GetPXPos(ePXLoc.PICKON);
if (MOT.CheckMotionPos(seqTime, Pos, "#6") == false) return 0;
//피커의Z축은 가져오는 위치에서 +10mm 에서 처리한다
var PosZ = MOT.GetPZPos(ePZLoc.PICKON);
PosZ.Position -= 60;
//theta 는 0으로 원복한다
if (MOT.CheckMotionPos(eAxis.Z_THETA, seqTime, 0, 400, 1000, 1000, "QUICK") == false) return 0;
if (MOT.CheckMotionPos(seqTime, PosZ, "QUICK") == false) return 0;
//진공끈다(진공이꺼지면 감지 센서도 같이 꺼진다 - 이 프로젝트에는 감지 센서가 없고 , 출력센서를 그대로 감지로 이용한다)
DIO.SetPickerVac(false, true);
//로더의 얼라인을 해제해준다.
hmi1.arVar_Port[1].AlignReset();// = 0; loader1.arVar_Port[1].errorCount = 0;
}
PUB.sm.seq.Update(cmdIndex);
return StepResult.Wait;
}
//피커 Z축 정렬 후 Y축을 준비위치로 옮긴다
if (PUB.sm.seq.Get(step) == idx++)
{
var PosZ = MOT.GetPZPos(ePZLoc.READY);
if (MOT.CheckMotionPos(seqTime, PosZ, "#7") == false) return StepResult.Wait;
PUB.sm.seq.Update(cmdIndex);
return StepResult.Wait;
}
//중앙포트(로더)를 아래로 내림
if (PUB.sm.seq.Get(step) == idx++)
{
//if (DIO.GetIOInput(eDIName.PORTC_LIM_UP) == true)
DIO.SetPortMotor(1, eMotDir.CCW, true, "FINISH", true); //210326
PUB.sm.seq.Update(cmdIndex);
return StepResult.Wait;
}
//연관플래그 소거
if (PUB.sm.seq.Get(step) == idx++)
{
//진공상태를 초기화 해준다.
DIO.SetPrintLVac(ePrintVac.off, true);
DIO.SetPrintRVac(ePrintVac.off, true);
DIO.SetOutput(eDOName.PRINTL_AIRON, false);
DIO.SetOutput(eDOName.PRINTR_AIRON, false);
PUB.Result.Clear("home");
FlagClear(false);
//트리거 OFF작업
WS_Send(eWorkPort.Left, PUB.wsL, "", "OFF","");
WS_Send(eWorkPort.Right, PUB.wsR, "", "OFF","");
//컨베어off
DIO.SetOutput(eDOName.LEFT_CONV, false);
DIO.SetOutput(eDOName.RIGHT_CONV, false);
if (PUB.keyenceF != null && PUB.keyenceF.IsConnect)
PUB.keyenceF.Trigger(false);
if (PUB.keyenceR != null && PUB.keyenceR.IsConnect)
PUB.keyenceR.Trigger(false);
PUB.sm.seq.Update(cmdIndex);
return StepResult.Wait;
}
PUB.sm.SetNewStep(eSMStep.IDLE);
return StepResult.Complete;
}
}
}

View File

@@ -0,0 +1,55 @@
using AR;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
namespace Project
{
public partial class FMain
{
public void _STEP_HOME_DELAY_START(eSMStep step)
{
//각 파트의 초기 값을 설정해준다.
DIO.SetBuzzer(false);
//홈이완료되었으므로 3초정도 기다려준다.
PUB.log.AddAT("Timer started for home completion confirmation");
HomeSuccessTime = DateTime.Now;
}
public StepResult _STEP_HOME_DELAY(eSMStep step, TimeSpan stepTime, TimeSpan seqTime)
{
//*********************
//** 하드웨어 조건 확인
//*********************
if (CheckHomeProcess_HW_Available(false) == false)
{
return StepResult.Error;
}
var tsHome = DateTime.Now - HomeSuccessTime;
if (tsHome.TotalSeconds >= 3.0)
{
if (PUB.mot.HasMoving == false)
{
//모든축의 위치를 0으로 한다
//Pub.mot.ClearPosition();
//각 파트의 초기 값을 설정해준다.
DIO.SetBuzzer(false);
PUB.flag.set(eVarBool.FG_USERSTEP, false, "SM_HOME");
PUB.log.AddI("Moving to home verification code due to home operation completion");
HomeChkTime = DateTime.Now;
PUB.sm.SetNewStep(eSMStep.HOME_CONFIRM);
}
}
return StepResult.Wait;
}
}
}

View File

@@ -0,0 +1,564 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using Project.Commands;
using AR;
namespace Project
{
public partial class FMain
{
public void _STEP_HOME_FULL_START(eSMStep step)
{
//ClearBarcode();
//Pub.popup.needClose = true; // Pub.popup.CloseAll();
//181225
if (PUB.dio.IsInit)
DIO.SetBuzzer(false);
if (PUB.mot.IsInit)
{
//알람클리어작업
if (PUB.mot.HasServoAlarm)
{
PUB.mot.SetAlarmClearOn();
System.Threading.Thread.Sleep(200);
PUB.mot.SetAlarmClearOff();
}
}
HomeSuccessTime = DateTime.Parse("1982-11-23");
//홈모드로 전환
hmi1.Scean = UIControl.HMI.eScean.MotHome;
hmi1.arHomeProgress[0] = 0;
hmi1.arHomeProgress[1] = 0;
hmi1.arHomeProgress[2] = 0;
hmi1.arHomeProgress[3] = 0;
hmi1.arHomeProgress[4] = 0;
hmi1.arHomeProgress[5] = 0;
hmi1.arHomeProgress[6] = 0;
//실린더 상태 복귀
DIO.SetOutput(eDOName.PRINTL_FWD, false);
DIO.SetOutput(eDOName.PRINTR_FWD, false);
DIO.SetOutput(eDOName.L_CYLDN, false);
DIO.SetOutput(eDOName.R_CYLDN, false);
}
public StepResult _STEP_HOME_FULL(eSMStep step, TimeSpan stepTime, TimeSpan seqTime)
{
//전체 홈 시간을 체크한다.
if (stepTime.TotalSeconds >= AR.SETTING.Data.Timeout_HomeSearch)
{
PUB.Result.SetResultMessage(eResult.TIMEOUT, eECode.HOME_TIMEOUT, eNextStep.NOTHING, AR.SETTING.Data.Timeout_HomeSearch); //, eECode.(eResult.HomeTimeout,msg ,false);
return StepResult.Error;
}
//*********************
//** 하드웨어 조건 확인
//*********************
if (CheckHomeProcess_HW_Available(false) == false)
{
return StepResult.Error;
}
int idx = 1;
var cmdIndex = step;
//Check X Safty Area
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
//안전위치 센서가 안들어와잇으면 오류 처리한다
if (DIO.GetIOInput(eDIName.PICKER_SAFE) == false)
{
PUB.Result.SetResultMessage(eResult.MOTION,
eECode.MOTX_SAFETY,
eNextStep.ERROR,
eAxis.PL_MOVE, PUB.mot.ErrorMessage);
return StepResult.Error;
}
//포트 모두내리기(221013 - 박형철)
if (VAR.BOOL[eVarBool.Use_Conveyor] == false && AR.SETTING.Data.Disable_HomePortDown == false)
{
DIO.SetPortMotor(0, eMotDir.CCW, true, "HOME");
DIO.SetPortMotor(1, eMotDir.CCW, true, "HOME");
DIO.SetPortMotor(2, eMotDir.CCW, true, "HOME");
}
PUB.sm.seq.Update(cmdIndex);
return StepResult.Wait;
}
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
//홈 설정여부플래그 OFF
for (short i = 0; i < PUB.mot.DeviceCount; i++)
{
if (PUB.mot.IsUse(i) == false) continue;
PUB.mot.SetHomeSet(i, false);
}
//부저 OFF
DIO.SetBuzzer(false);
//프린터부착헤드 후진
if (DIO.GetIOInput(eDIName.L_PICK_BW) == false)
DIO.SetOutput(eDOName.PRINTL_FWD, false);
if (DIO.GetIOInput(eDIName.R_PICK_BW) == false)
DIO.SetOutput(eDOName.PRINTR_FWD, false);
if (DIO.GetIOInput(eDIName.L_CYLUP) == false)
DIO.SetOutput(eDOName.L_CYLDN, false);
if (DIO.GetIOInput(eDIName.R_CYLUP) == false)
DIO.SetOutput(eDOName.R_CYLDN, false);
PUB.sm.seq.Update(cmdIndex);
return StepResult.Wait;
}
//피커실린더 상승
if (PUB.sm.seq.Get(step) == idx++)
{
DIO.SetOutput(eDOName.L_CYLDN, false);
DIO.SetOutput(eDOName.R_CYLDN, false);
PUB.sm.seq.Update(cmdIndex);
return StepResult.Wait;
}
if (PUB.sm.seq.Get(step) == idx++)
{
if (AR.SETTING.Data.Enable_PickerCylinder)
{
if (DIO.checkDigitalO(eDIName.L_CYLUP, seqTime, true, timeoutcode: eECode.PICKER_LCYL_NOUP) != eNormalResult.True) return StepResult.Wait;
if (DIO.checkDigitalO(eDIName.R_CYLUP, seqTime, true, timeoutcode: eECode.PICKER_RCYL_NOUP) != eNormalResult.True) return StepResult.Wait;
}
PUB.sm.seq.Update(cmdIndex);
return StepResult.Wait;
}
//프린터 부착헤드 후진 검사
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
//프린터부착헤드 후진
if (DIO.GetIOInput(eDIName.L_PICK_BW) == false)
{
if (stepTime.TotalSeconds > 5)
{
PUB.Result.SetResultMessage(eResult.MOTION, eECode.PRINTER_LPICKER_NOBW, eNextStep.PAUSE);
}
return StepResult.Wait;
}
if (DIO.GetIOInput(eDIName.R_PICK_BW) == false)
{
if (stepTime.TotalSeconds > 5)
{
PUB.Result.SetResultMessage(eResult.MOTION, eECode.PRINTER_RPICKER_NOBW, eNextStep.PAUSE);
}
return StepResult.Wait;
}
PUB.sm.seq.Update(cmdIndex);
return StepResult.Wait;
}
//프린터 부착헤드 후진 검사
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
//프린터부착헤드 후진
if (AR.SETTING.Data.Enable_PickerCylinder)
{
if (DIO.GetIOInput(eDIName.L_CYLUP) == false)
{
if (stepTime.TotalSeconds > 5)
{
PUB.Result.SetResultMessage(eResult.MOTION, eECode.PRINTER_LPRINTER_NOUP, eNextStep.PAUSE);
}
return StepResult.Wait;
}
if (DIO.GetIOInput(eDIName.R_CYLUP) == false)
{
if (stepTime.TotalSeconds > 5)
{
PUB.Result.SetResultMessage(eResult.MOTION, eECode.PRINTER_RPRINTER_NOUP, eNextStep.PAUSE);
}
return StepResult.Wait;
}
}
else
{
//전진이 들어와 있다면 오류 로한다
if (DIO.GetIOInput(eDIName.L_CYLDN))
{
PUB.Result.SetResultMessage(eResult.MOTION, eECode.PRINTER_LPRINTER_NOUP, eNextStep.PAUSE);
return StepResult.Wait;
}
if (DIO.GetIOInput(eDIName.R_CYLDN))
{
PUB.Result.SetResultMessage(eResult.MOTION, eECode.PRINTER_RPRINTER_NOUP, eNextStep.PAUSE);
return StepResult.Wait;
}
}
PUB.sm.seq.Update(cmdIndex);
return StepResult.Wait;
}
//피커의 Z축을 우선 진행
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
var rlt1 = MOT.Home("RUN_SAFTY_HOME", eAxis.PZ_PICK);
if (rlt1 == false)
{
PUB.Result.SetResultMessage(eResult.MOTION,
eECode.MOT_HSEARCH,
eNextStep.ERROR,
eAxis.PL_UPDN, PUB.mot.ErrorMessage);
return StepResult.Error;
}
PUB.sm.seq.Update(cmdIndex);
return StepResult.Wait;
}
//Z축 안전위치 대기
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
if (PUB.mot.IsHomeSet((short)eAxis.PZ_PICK) == false && PUB.mot.IsLimitN((short)eAxis.PZ_PICK) == false && PUB.mot.IsOrg((short)eAxis.PZ_PICK) == false)
{
System.Threading.Thread.Sleep(10);
return StepResult.Wait;
}
PUB.sm.seq.Update(cmdIndex);
return StepResult.Wait;
}
//프린터의 Z축을 먼저 한다 221013
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
var rlt1 = MOT.Home("RUN_SAFTY_HOME", eAxis.PL_UPDN);
var rlt2 = MOT.Home("RUN_SAFTY_HOME", eAxis.PR_UPDN);
PUB.sm.seq.Update(cmdIndex);
return StepResult.Wait;
}
//Z축 안전위치 대기
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
if (PUB.mot.IsHomeSet((short)eAxis.PL_UPDN) == false && PUB.mot.IsLimitN((short)eAxis.PL_UPDN) == false && PUB.mot.IsOrg((short)eAxis.PL_UPDN) == false)
{
System.Threading.Thread.Sleep(10);
return StepResult.Wait;
}
PUB.sm.seq.Update(cmdIndex);
return StepResult.Wait;
}
//Z축 안전위치 대기
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
if (PUB.mot.IsHomeSet((short)eAxis.PR_UPDN) == false && PUB.mot.IsLimitN((short)eAxis.PR_UPDN) == false && PUB.mot.IsOrg((short)eAxis.PR_UPDN) == false)
{
System.Threading.Thread.Sleep(10);
return StepResult.Wait;
}
PUB.sm.seq.Update(cmdIndex);
return StepResult.Wait;
}
//각 프린터의 Y,Z 축의 홈을 진행한다.
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
//유효성 검사를 하지 않는다.. 하게되면 오류남 201208
var rlt1 = MOT.Home("RUN_SAFTY_HOME", eAxis.PL_MOVE, false);
var rlt2 = MOT.Home("RUN_SAFTY_HOME", eAxis.PR_MOVE, false);
//var rlt3 = MOT.Home("RUN_SAFTY_HOME", eAxis.PL_UPDN, false);
//var rlt4 = MOT.Home("RUN_SAFTY_HOME", eAxis.PR_UPDN, false);
if (rlt1 == false)
{
PUB.Result.SetResultMessage(eResult.MOTION,
eECode.MOT_HSEARCH,
eNextStep.ERROR,
eAxis.PL_MOVE, PUB.mot.ErrorMessage);
return StepResult.Error;
}
if (rlt2 == false)
{
PUB.Result.SetResultMessage(eResult.MOTION,
eECode.MOT_HSEARCH,
eNextStep.ERROR,
eAxis.PR_MOVE, PUB.mot.ErrorMessage);
return StepResult.Error;
}
//if (rlt3 == false)
//{
// PUB.Result.SetResultMessage(eResult.MOTION,
// eECode.MOT_HSEARCH,
// eNextStep.ERROR,
// eAxis.PL_UPDN, PUB.mot.ErrorMessage);
// return StepResult.Error;
//}
//if (rlt4 == false)
//{
// PUB.Result.SetResultMessage(eResult.MOTION,
// eECode.MOT_HSEARCH,
// eNextStep.ERROR,
// eAxis.PR_UPDN, PUB.mot.ErrorMessage);
// return StepResult.Error;
//}
PUB.sm.seq.Update(cmdIndex);
return StepResult.Wait;
}
//프린터축의 Y,Z축이 완료되기를 기다린다.
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
if (PUB.mot.IsHomeSet((short)eAxis.PL_MOVE) &&
PUB.mot.IsHomeSet((short)eAxis.PR_MOVE) &&
PUB.mot.IsHomeSet((short)eAxis.PL_UPDN) &&
PUB.mot.IsHomeSet((short)eAxis.PR_UPDN))
{
//현재위치를 0으로 설정한다.
PUB.mot.ClearPosition((int)eAxis.PL_MOVE);
PUB.mot.ClearPosition((int)eAxis.PR_MOVE);
//var p1 = MOT.GetLMPos(eLMLoc.READY);
//MOT.Move(eAxis.PL_MOVE, p1.Position, 200, 500, false, false, false);
//var p2 = MOT.GetRMPos(eRMLoc.READY);
//p2.Speed = 100;
//MOT.Move(eAxis.PR_MOVE, p2.Position, 200, 500, false, false, false);
PUB.sm.seq.Update(cmdIndex);
}
return StepResult.Wait;
}
//실린더를OFF한다 - 210207
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
DIO.SetOutput(eDOName.PRINTL_FWD, false);
DIO.SetOutput(eDOName.PRINTR_FWD, false);
PUB.sm.seq.Update(cmdIndex);
return StepResult.Wait;
}
//실린더 OFF 확인 - 210207
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
//IO가 완료되지 안항ㅆ다면 대기한다
if (DIO.checkDigitalO(eDIName.L_PICK_BW, seqTime, true) != eNormalResult.True) return StepResult.Wait;
if (DIO.checkDigitalO(eDIName.R_PICK_BW, seqTime, true) != eNormalResult.True) return StepResult.Wait;
PUB.sm.seq.Update(cmdIndex);
return StepResult.Wait;
}
//프린터 move 축 안전지대로이동
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
var PosLM = MOT.GetLMPos(eLMLoc.READY);
var PosRM = MOT.GetRMPos(eRMLoc.READY);
PosLM.Speed = 200;
PosRM.Speed = 200;
MOT.Move((eAxis)PosLM.Axis, PosLM.Position, PosLM.Speed, PosLM.Acc, false, false, false);
MOT.Move((eAxis)PosRM.Axis, PosRM.Position, PosRM.Speed, PosRM.Acc, false, false, false);
PUB.sm.seq.Update(cmdIndex);
return StepResult.Wait;
}
//프린터 move 축 안전지대로이동
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
var PosLM = MOT.GetLMPos(eLMLoc.READY);
var PosRM = MOT.GetRMPos(eRMLoc.READY);
PosLM.Speed = 250;
PosRM.Speed = 250;
if (MOT.CheckMotionPos(seqTime, PosLM, "MOT_HOME", false) == false) return StepResult.Wait;
if (MOT.CheckMotionPos(seqTime, PosRM, "MOT_HOME", false) == false) return StepResult.Wait;
PUB.sm.seq.Update(cmdIndex);
return StepResult.Wait;
}
//Theta 홈
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
//회전축은 잡지 않는다
PUB.mot.SetHomeSet((int)eAxis.Z_THETA, true);
PUB.mot.ClearPosition((int)eAxis.Z_THETA);
PUB.sm.seq.Update(cmdIndex);
return StepResult.Wait;
}
//피커-X축 홈
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
var rlt1 = MOT.Home("RUN_SAFTY_HOME", eAxis.PX_PICK, false);
if (rlt1 == false)
{
PUB.Result.SetResultMessage(eResult.MOTION,
eECode.MOT_HSEARCH,
eNextStep.ERROR,
eAxis.PX_PICK, PUB.mot.ErrorMessage);
return StepResult.Error;
}
PUB.sm.seq.Update(cmdIndex);
return StepResult.Wait;
}
//모든축의 완료여부 확인
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
//모든축이 완료되었다면 완료처리를 한다.
if (PUB.mot.IsHomeSet((short)eAxis.PX_PICK))
{
//완료처리
PUB.mot.ClearPosition((int)eAxis.PX_PICK);
PUB.sm.seq.Update(cmdIndex);
}
return StepResult.Wait;
}
//X축 값 초기화확인
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
//모든축이 완료되었다면 완료처리를 한다.
var ts = PUB.sm.seq.GetTime(cmdIndex);
if (ts.TotalSeconds >= 5)
{
PUB.Result.SetResultMessage(eResult.MOTION,
eECode.MOT_HSEARCH,
eNextStep.ERROR,
eAxis.PX_PICK, PUB.mot.ErrorMessage);
return StepResult.Error;
}
else
{
var XPos = PUB.mot.GetActPos((int)eAxis.PX_PICK);
if (Math.Abs(XPos) <= 0.1 && PUB.mot.IsMotion((int)eAxis.PX_PICK) == false)
{
PUB.sm.seq.Update(cmdIndex);
}
}
return StepResult.Wait;
}
//완료됨
if (PUB.sm.seq.Get(step) == idx++)
{
//진공상태를 초기화 해준다.
DIO.SetPrintLVac(ePrintVac.off, true);
DIO.SetPrintRVac(ePrintVac.off, true);
DIO.SetOutput(eDOName.PRINTL_AIRON, false);
DIO.SetOutput(eDOName.PRINTR_AIRON, false);
FlagClear(true);
PUB.sm.SetNewStep(eSMStep.HOME_DELAY);
return StepResult.Complete;
}
return StepResult.Complete;
}
void FlagClear(bool ClearItemOn)
{
PUB.log.AddAT($"Flag initialization({ClearItemOn})");
//연관플래그 소거
if (ClearItemOn)
{
PUB.flag.set(eVarBool.FG_PK_ITEMON, false, "POSRESET");
PUB.flag.set(eVarBool.FG_PL_ITEMON, false, "POSRESET");
PUB.flag.set(eVarBool.FG_PR_ITEMON, false, "POSRESET");
PUB.flag.set(eVarBool.FG_PORTL_ITEMON, false, "POSRESET");
PUB.flag.set(eVarBool.FG_PORTR_ITEMON, false, "POSRESET");
}
PUB.flag.set(eVarBool.FG_OK_PRINTL, false, "POSRESET");
PUB.flag.set(eVarBool.FG_OK_PRINTR, false, "POSRESET");
PUB.flag.set(eVarBool.FG_RUN_PRINTL, false, "POSRESET");
PUB.flag.set(eVarBool.FG_RUN_PRINTR, false, "POSRESET");
PUB.flag.set(eVarBool.FG_RDY_PORT_PC, false, "POSRESET");
PUB.flag.set(eVarBool.FG_RDY_PORT_PL, false, "POSRESET");
PUB.flag.set(eVarBool.FG_RDY_PORT_PR, false, "POSRESET");
PUB.flag.set(eVarBool.FG_RDY_PX_LPICKOF, false, "POSRESET");
PUB.flag.set(eVarBool.FG_RDY_PX_RPICKOF, false, "POSRESET");
PUB.flag.set(eVarBool.FG_RDY_PX_PICKONWAITL, false, "POSRESET");
PUB.flag.set(eVarBool.FG_RDY_PX_PICKONWAITR, false, "POSRESET");
PUB.flag.set(eVarBool.FG_SET_DATA_PORT0, false, "POSRESET");
PUB.flag.set(eVarBool.FG_SET_DATA_PORT2, false, "POSRESET");
//PUB.flag.set(eVarBool.SCR_JOBFINISH, false, "POSRESET");
PUB.flag.set(eVarBool.FG_WAIT_PAPERDETECTL, false, "POSRESET");
PUB.flag.set(eVarBool.FG_WAIT_PAPERDETECTR, false, "POSRESET");
PUB.flag.set(eVarBool.FG_END_VISIONL, false, "POSRESET");
PUB.flag.set(eVarBool.FG_END_VISIONR, false, "POSRESET");
PUB.flag.set(eVarBool.FG_PRC_VISIONL, false, "POSRESET");
PUB.flag.set(eVarBool.FG_PRC_VISIONR, false, "POSRESET");
PUB.flag.set(eVarBool.FG_CMD_YP_LPICKON, false, "POSRESET");
PUB.flag.set(eVarBool.FG_CMD_YP_LPICKOF, false, "POSRESET");
PUB.flag.set(eVarBool.FG_CMD_YP_RPICKOF, false, "POSRESET");
PUB.flag.set(eVarBool.FG_CMD_YP_RPICKON, false, "POSRESET");
PUB.flag.set(eVarBool.FG_RDY_PZ_LPICKOF, false, "POSRESET");
PUB.flag.set(eVarBool.FG_RDY_PZ_RPICKOF, false, "POSRESET");
PUB.flag.set(eVarBool.FG_RDY_PZ_PICKON, false, "POSRESET");
PUB.flag.set(eVarBool.FG_RUN_PLM_PICKOF, false, "POSRESET");
PUB.flag.set(eVarBool.FG_RUN_PRM_PICKOF, false, "POSRESET");
PUB.flag.set(eVarBool.FG_RUN_PLM_PICKON, false, "POSRESET");
PUB.flag.set(eVarBool.FG_RUN_PRM_PICKON, false, "POSRESET");
PUB.flag.set(eVarBool.FG_RUN_PLZ_PICKOF, false, "POSRESET");
PUB.flag.set(eVarBool.FG_RUN_PRZ_PICKOF, false, "POSRESET");
PUB.flag.set(eVarBool.FG_RUN_PLZ_PICKON, false, "POSRESET");
PUB.flag.set(eVarBool.FG_RUN_PRZ_PICKON, false, "POSRESET");
PUB.flag.set(eVarBool.FG_RUN_LEFT, false, "POSREST");
PUB.flag.set(eVarBool.FG_RUN_RIGHT, false, "POSREST");
//VAR.BOOL[eVarBool.JOB_BYPASS_LEFT] = false;
//VAR.BOOL[eVarBool.JOB_BYPASS_RIGHT] = false;
//VAR.STR[eVarString.JOB_BYPASS_SID] = string.Empty;
//VAR.STR[eVarString.JOB_TYPE] = string.Empty;
//retry소거 230510
VAR.BOOL[eVarBool.JOB_PickON_Retry] = false;
VAR.BOOL[eVarBool.VisionL_Retry] = false;
VAR.BOOL[eVarBool.VisionR_Retry] = false;
VAR.BOOL[eVarBool.wait_for_keyence] = false;
VAR.BOOL[eVarBool.wait_for_keyenceL] = false;
VAR.BOOL[eVarBool.wait_for_keyenceR] = false;
VAR.BOOL[eVarBool.JOB_Empty_SIDConvertInfo] = false;
//busy 플래그 제거
PUB.iLockCVL.set((int)eILockCV.BUSY, false, "POSREST");
PUB.iLockCVR.set((int)eILockCV.BUSY, false, "POSREST");
PUB.iLockCVL.set((int)eILockCV.VISION, false, "POSREST");
PUB.iLockCVR.set((int)eILockCV.VISION, false, "POSREST");
VAR.I32[eVarInt32.RIGT_ITEM_COUNT] = 0;
VAR.I32[eVarInt32.LEFT_ITEM_COUNT] = 0;
}
}
}

View File

@@ -0,0 +1,215 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using Project.Commands;
using AR;
namespace Project
{
public partial class FMain
{//홈 맞춰
public void _STEP_HOME_QUICK_START(eSMStep step)
{
//모든 홈이 되어야 가능하다
if (PUB.mot.IsInit && PUB.mot.HasHomeSetOff == true)
{
PUB.Result.SetResultMessage(eResult.MOTION, eECode.MOT_HSET, eNextStep.ERROR);
return;
}
if (DIO.IsEmergencyOn() == true)
{
PUB.Result.SetResultMessage(eResult.HARDWARE, eECode.EMERGENCY, eNextStep.ERROR);
return;
}
if (DIO.isSaftyDoorF() == false || DIO.isSaftyDoorR() == false)
{
PUB.Result.SetResultMessage(eResult.HARDWARE, eECode.DOORSAFTY, eNextStep.ERROR);
return;
}
//실린더 상태 복귀
DIO.SetOutput(eDOName.PRINTL_FWD, false);
DIO.SetOutput(eDOName.PRINTR_FWD, false);
DIO.SetOutput(eDOName.L_CYLDN, false);
DIO.SetOutput(eDOName.R_CYLDN, false);
}
CommandBuffer cmds = new CommandBuffer();
public StepResult _STEP_HOME_QUICK(eSMStep step, TimeSpan stepTime, TimeSpan seqTime)
{
byte idx = 1;
var cmdIndex = eSMStep.HOME_QUICK;
if (PUB.sm.seq.Get(step) < idx) PUB.sm.seq.Set(cmdIndex, idx);
//사용자 스텝처리가 아닌경우에만 동작 중지를 검사 한다
//중단조건 검사는 0번 축에만 동작하게 한다
if (PUB.flag.get(eVarBool.FG_USERSTEP) == false && CheckPauseCondition(true) == false)
{
//가동불가 조건 확인
if (PUB.Result.ResultCode == eResult.EMERGENCY)
PUB.sm.SetNewStep(eSMStep.ERROR);
else
PUB.sm.SetNewStep(eSMStep.PAUSE);
return StepResult.Wait;
}
//동작상태가 아니라면 처리하지 않는다.
var userStep = PUB.flag.get(eVarBool.FG_USERSTEP);
//*********************
//** 하드웨어 조건 확인
//*********************
if (CheckHomeProcess_HW_Available(true) == false)
{
return StepResult.Error;
}
//시작정보
if (PUB.sm.seq.Get(step) == idx++)
{
//210415
if (DIO.GetPortMotorDir(0) == eMotDir.CW) DIO.SetPortMotor(0, eMotDir.CW, false, "POSRESET");
if (DIO.GetPortMotorDir(1) == eMotDir.CW) DIO.SetPortMotor(1, eMotDir.CW, false, "POSRESET");
if (DIO.GetPortMotorDir(2) == eMotDir.CW) DIO.SetPortMotor(2, eMotDir.CW, false, "POSRESET");
PUB.sm.seq.Update(cmdIndex);
return StepResult.Wait;
}
//피커 Z축을 0으로 이동한다
if (PUB.sm.seq.Get(step) == idx++)
{
var Pos = MOT.GetPZPos(ePZLoc.READY);
if (MOT.CheckMotionPos(seqTime, Pos, "#7") == false) return 0;
PUB.sm.seq.Update(cmdIndex);
return StepResult.Wait;
}
//피커 Y축을 안전지대로 이동한다
if (PUB.sm.seq.Get(step) == idx++)
{
var Pos = MOT.GetPXPos(ePXLoc.PICKON);
if (MOT.CheckMotionPos(seqTime, Pos, "#7", false) == false) return 0;
PUB.sm.seq.Update(cmdIndex);
return StepResult.Wait;
}
//PRINT-Z축을 0으로이동한다
if (PUB.sm.seq.Get(step) == idx++)
{
var spdinfo = MOT.GetLZPos(eLZLoc.READY);
MOT.Move(eAxis.PL_UPDN, spdinfo.Position, spdinfo.Speed, spdinfo.Acc, false, true, false);
spdinfo = MOT.GetRZPos(eRZLoc.READY);
MOT.Move(eAxis.PR_UPDN, spdinfo.Position, spdinfo.Speed, spdinfo.Acc, false, true, false);
PUB.sm.seq.Update(cmdIndex);
return StepResult.Wait;
}
//PRINT-Z축 완료대기
if (PUB.sm.seq.Get(step) == idx++)
{
var PosL = MOT.GetLZPos(eLZLoc.READY);
var PosR = MOT.GetRZPos(eRZLoc.READY);
if (MOT.CheckMotionPos(seqTime, PosL, "#7", false) == false) return StepResult.Wait;
if (MOT.CheckMotionPos(seqTime, PosR, "#8", false) == false) return StepResult.Wait;
PUB.sm.seq.Update(cmdIndex);
return StepResult.Wait;
}
//피커실린더 상승
if (PUB.sm.seq.Get(step) == idx++)
{
DIO.SetOutput(eDOName.L_CYLDN, false);
DIO.SetOutput(eDOName.R_CYLDN, false);
PUB.sm.seq.Update(cmdIndex);
return StepResult.Wait;
}
if (PUB.sm.seq.Get(step) == idx++)
{
if (AR.SETTING.Data.Enable_PickerCylinder)
{
if (DIO.checkDigitalO(eDIName.L_CYLUP, seqTime, true) != eNormalResult.True) return StepResult.Wait;
if (DIO.checkDigitalO(eDIName.R_CYLUP, seqTime, true) != eNormalResult.True) return StepResult.Wait;
}
PUB.sm.seq.Update(cmdIndex);
return StepResult.Wait;
}
//프린터부착헤드 후진
if (PUB.sm.seq.Get(step) == idx++)
{
DIO.SetOutput(eDOName.PRINTL_FWD, false);
DIO.SetOutput(eDOName.PRINTR_FWD, false);
PUB.sm.seq.Update(cmdIndex);
return StepResult.Wait;
}
//프린터헤드후진 확인
if (PUB.sm.seq.Get(step) == idx++)
{
if (DIO.checkDigitalO(eDIName.L_PICK_BW, seqTime, true) != eNormalResult.True) return StepResult.Wait;
if (DIO.checkDigitalO(eDIName.R_PICK_BW, seqTime, true) != eNormalResult.True) return StepResult.Wait;
PUB.sm.seq.Update(cmdIndex);
return StepResult.Wait;
}
//프린터 Y축 이동
if (PUB.sm.seq.Get(step) == idx++)
{
var spdinfo = MOT.GetLMPos(eLMLoc.READY);
MOT.Move(eAxis.PL_MOVE, spdinfo.Position, spdinfo.Speed, spdinfo.Acc, false, true, false);
spdinfo = MOT.GetRMPos(eRMLoc.READY);
MOT.Move(eAxis.PR_MOVE, spdinfo.Position, spdinfo.Speed, spdinfo.Acc, false, true, false);
PUB.sm.seq.Update(cmdIndex);
return StepResult.Wait;
}
//프린터 Y축 완료대기
if (PUB.sm.seq.Get(step) == idx++)
{
var PosL = MOT.GetLMPos(eLMLoc.READY);
var PosR = MOT.GetRMPos(eRMLoc.READY);
if (MOT.CheckMotionPos(seqTime, PosL, "#7") == false) return 0;
if (MOT.CheckMotionPos(seqTime, PosR, "#8") == false) return 0;
PUB.sm.seq.Update(cmdIndex);
return StepResult.Wait;
}
//연관플래그 소거
if (PUB.sm.seq.Get(step) == idx++)
{
//진공상태를 초기화 해준다.
DIO.SetPrintLVac(ePrintVac.off, true);
DIO.SetPrintRVac(ePrintVac.off, true);
DIO.SetOutput(eDOName.PRINTL_AIRON, false);
DIO.SetOutput(eDOName.PRINTR_AIRON, false);
FlagClear(true);
PUB.sm.SetNewStep(eSMStep.HOME_CONFIRM);
return StepResult.Wait;
}
PUB.sm.seq.Clear(step);
PUB.sm.SetNewStep(eSMStep.HOME_CONFIRM);
return StepResult.Complete;
}
}
}

View File

@@ -0,0 +1,82 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using AR;
namespace Project
{
public partial class FMain
{
DateTime IdleStartTime = DateTime.Now;
bool IdleSleep = false;
public void _STEP_IDLE_START(eSMStep step)
{
PUB.flag.set(eVarBool.FG_USERSTEP, false, "SM_IDLE");
//lbMsgR.ProgressEnable = false;
IdleStartTime = DateTime.Now;
//초기화완료되면 버튼을 활성화한다
if (PUB.sm.getOldStep == eSMStep.INIT)
{
this.BeginInvoke(new Action(() =>
{
panTopMenu.Enabled = true;
btStart.Enabled = true;
btStop.Enabled = true;
btReset.Enabled = true;
}));
//Pub.sm.setNewStep(eSMStep.XMOVE); //홈을 위해서 바로 이동 모션으로 가게한다
if (PUB.mot.HasHomeSetOff == true && DIO.GetIOInput(eDIName.PICKER_SAFE) == false)
{
//피커의 이동이 필요한 상황
this.BeginInvoke(new Action(() => { btManage.PerformClick(); }));
}
else
{
//리셋이 필요한 상황
if (AR.SETTING.Data.OnlineMode == true)
this.BeginInvoke(new Action(() => { btMReset.PerformClick(); }));
}
}
}
public StepResult _STEP_IDLE(eSMStep step, TimeSpan stepTime, TimeSpan seqTime)
{
//대기상태에서 조명 자동으로 끄기
if (IdleSleep == false && IdleStartTime.Year != 1982)
{
var ts = DateTime.Now - IdleStartTime;
if (ts.TotalMinutes > AR.SETTING.Data.AutoOffRoomLightMin)
{
PUB.log.Add("Turning off lights due to idle state transition");
IdleSleep = true;
DIO.SetRoomLight(false);
}
}
//자동소거기능
if (AR.SETTING.Data.AutoDeleteDay > 0)
{
if (PUB.flag.get(eVarBool.FG_MINSPACE) == true)
{
var ts = DateTime.Now - lastDeleteTime;
if (ts.TotalSeconds > 1)
{
//파일을 찾아서 소거한다.
var delpath = System.IO.Path.Combine(AR.SETTING.Data.GetDataPath(), "Images");
if (delpath != "") DeleteFile(delpath);
lastDeleteTime = DateTime.Now;
}
}
}
return StepResult.Wait;
}
}
}

View File

@@ -0,0 +1,195 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using AR;
namespace Project
{
public partial class FMain
{
//Int32[] _hDevice = new Int32[] { 0, 0, 0 };
//Int32[] _width = new Int32[] { 0, 0, 0 };
//Int32[] _height = new Int32[] { 0, 0, 0 };
//Int32[] _stride = new Int32[] { 0, 0, 0 };
//Int32[] _bufferSize = new Int32[] { 0, 0, 0 };
//Boolean[] _isCrevisOpen = new bool[] { false, false, false };
//Boolean[] _isCrevisACQ = new bool[] { false, false, false };
// IntPtr[] _pImage = new IntPtr[] { IntPtr.Zero, IntPtr.Zero, IntPtr.Zero };
public void _STEP_INIT_START(eSMStep step)
{
int progress = 0;
var ProgressMax = 13;
Color fColor = Color.DarkViolet;
PUB.sm.RaiseStateProgress(++progress, "Motion Initialize", ProgressMax, fColor); System.Threading.Thread.Sleep(5);
if (PUB.mot.Init() == false)
{
PUB.log.AddE(string.Format("MOT INIT ERROR : {0}", PUB.mot.ErrorMessage));
PUB.log.AddE("Motion initialization error, retrying shortly");
System.Threading.Thread.Sleep(1000);
if (PUB.mot.Init() == false)
{
PUB.log.AddE("Motion initialization retry failed " + PUB.mot.ErrorMessage);
}
}
_SM_RUN_INIT_MOTION();
PUB.sm.RaiseStateProgress(++progress, "DIO Initialize", ProgressMax, fColor); System.Threading.Thread.Sleep(5);
if (PUB.dio.Init())
{
DIO.InitDIOSensitive();
PUB.log.Add("DIO RUN MONITOR");
PUB.dio.RunMonitor();
//포트동작을 멈춘다
DIO.SetPortMotor(0, eMotDir.CW, false, "init");
DIO.SetPortMotor(1, eMotDir.CW, false, "init");
DIO.SetPortMotor(2, eMotDir.CW, false, "init");
}
else PUB.log.AddE(string.Format("DIO INIT ERROR : {0}", PUB.dio.ErrorMessage));
TowerLamp.Init(PUB.dio,
DIO.Pin[eDOName.TWR_REDF].terminalno,
DIO.Pin[eDOName.TWR_GRNF].terminalno,
DIO.Pin[eDOName.TWR_YELF].terminalno);
TowerLamp.Enable = !SETTING.Data.Disable_TowerLamp;
PUB.sm.RaiseStateProgress(++progress, "Set DIO Names", ProgressMax, fColor); System.Threading.Thread.Sleep(5);
_SM_RUN_INIT_SETDIONAME();
PUB.log.AddI("Motion initialization flag setup complete");
PUB.flag.set(eVarBool.FG_INIT_MOTIO, true, "INIT");
//230504
hmi1.SetDIO(PUB.dio);
hmi1.SetMOT(PUB.mot);
//남은 공간
PUB.sm.RaiseStateProgress(++progress, "Space Check", ProgressMax, fColor); System.Threading.Thread.Sleep(5);
CheckFreeSpace(); //181225
//프린터설정
PUB.sm.RaiseStateProgress(++progress, "Printer Setup", ProgressMax, fColor); System.Threading.Thread.Sleep(5);
PUB.PrinterL = new Device.SATOPrinterAPI();
PUB.PrinterL.PortName = AR.SETTING.Data.PrintL_Port;
PUB.PrinterL.BaudRate = AR.SETTING.Data.PrintL_Baud;
PUB.PrinterR = new Device.SATOPrinterAPI();
PUB.PrinterR.PortName = AR.SETTING.Data.PrintR_Port;
PUB.PrinterR.BaudRate = AR.SETTING.Data.PrintR_Baud;
PUB.flag.set(eVarBool.FG_INIT_PRINTER, true, "INIT");
//모델자동선택 181206
PUB.sm.RaiseStateProgress(++progress, "Previous Model Check", ProgressMax, fColor); System.Threading.Thread.Sleep(5);
//
if (SETTING.User.LastModelV != "") PUB.SelectModelV(SETTING.User.LastModelV, false);
var motionmodel = SETTING.User.LastModelM;
if (motionmodel.isEmpty()) motionmodel = PUB.Result.vModel.Motion ?? string.Empty;
if (motionmodel.ToUpper().StartsWith("CONV")) PUB.flag.set(eVarBool.Use_Conveyor, true, "load");
else PUB.flag.set(eVarBool.Use_Conveyor, false, "load");
PUB.SelectModelM(motionmodel, false);
PUB.sm.RaiseStateProgress(ProgressMax, "Initialization Complete", ProgressMax, Color.Gold); System.Threading.Thread.Sleep(5);
PUB.log.Add("init finish");
//조명 ON
DIO.SetRoomLight(true);
}
public StepResult _STEP_INIT(eSMStep step, TimeSpan stepTime, TimeSpan seqTime)
{
PUB.sm.SetNewStep(eSMStep.IDLE);
return StepResult.Complete;
}
public void _SM_RUN_INIT_SETDIONAME()
{
//DIO 이름설정
Console.WriteLine("## SET DI NAME ##");
for (int i = 0; i < PUB.dio.GetDICount; i++)
{
var name = Enum.GetName(typeof(eDIName), i);
Console.WriteLine($"[{i}] {name}");
PUB.dio.SetDIName(i, name);
}
Console.WriteLine("## SET DO NAME ##");
for (int i = 0; i < PUB.dio.GetDOCount; i++)
{
var name = Enum.GetName(typeof(eDOName), i);
Console.WriteLine($"[{i}] {name}");
PUB.dio.SetDOName(i, name);
}
//Console.WriteLine("## SET FLAG NAME ##");
//for (int i = 0; i < PUB.flag.Length; i++)
//{
// var name = Enum.GetName(typeof(eFlag), i);
// PUB.flag.Name[i] = name;
// Console.WriteLine($"[{i}] {name}");
//}
}
private void _SM_RUN_INIT_MOTION()
{
PUB.mot.SetAlarmClearOn();
System.Threading.Thread.Sleep(5);
PUB.mot.SetAlarmClearOff();
//7개의 축을 사용한다
if (PUB.mot.IsInit == false)
{
PUB.log.AddE("Motion board initialization error, configuration will not proceed");
}
else
{
for (short i = 0; i < SETTING.System.MotaxisCount; i++)
{
//설정파일이 있다면 불러온다
var file = System.IO.Path.Combine(UTIL.CurrentPath, "Model", "axis" + i.ToString() + ".motaxt");
if (System.IO.File.Exists(file) == false)
{
PUB.log.AddAT($"Motion ({i}) configuration file not found!!");
PUB.mot.InitAxis(i, file);
}
else
{
if (PUB.mot.InitAxis((short)i, file) == false)
PUB.log.AddE("Motion setup failed axis:" + i.ToString());
else
PUB.log.AddI($"Motion ({i}) setup complete");
}
}
//EStop Disable
PUB.mot.SetEStopEnable(0, false);
PUB.mot.SetEStopEnable(1, false);
PUB.mot.SetEStopEnable(2, false);
PUB.mot.SetEStopEnable(3, false);
PUB.mot.SetEStopEnable(4, false);
PUB.mot.SetEStopEnable(5, false);
PUB.mot.SetEStopEnable(6, false);
//softlimit 적용 - 201214
UpdateSoftLimit();
PUB.log.Add("MOT RUN MONITOR");
PUB.mot.RunMonitor();
PUB.log.AddAT("ALL SERVO ON");
PUB.mot.SetServOn(true);
}
}
}
}

View File

@@ -0,0 +1,328 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using AR;
namespace Project
{
public partial class FMain
{
//System.Threading.ManualResetEvent LockLL = new System.Threading.ManualResetEvent(true);
//System.Threading.ManualResetEvent LockLR = new System.Threading.ManualResetEvent(true);
System.Threading.ManualResetEvent LockPK = new System.Threading.ManualResetEvent(true);
System.Threading.ManualResetEvent LockUserL = new System.Threading.ManualResetEvent(true);
System.Threading.ManualResetEvent LockUserR = new System.Threading.ManualResetEvent(true);
async public void _STEP_RUN_START(eSMStep step)
{
//새로시작하면 포트 얼라인을 해제 해준다
PUB.flag.set(eVarBool.FG_RDY_PORT_PL, false, "SM_RUN");
PUB.flag.set(eVarBool.FG_RDY_PORT_PC, false, "SM_RUN");
PUB.flag.set(eVarBool.FG_RDY_PORT_PR, false, "SM_RUN");
//작업완료기준시간 초기화
if (PUB.flag.get(eVarBool.FG_JOB_END) == true) VAR.TIME.Update(eVarTime.JOB_END);
//라이브뷰시간 초기화
VAR.TIME.Update(eVarTime.LIVEVIEW0);
VAR.TIME.Update(eVarTime.LIVEVIEW1);
VAR.TIME.Update(eVarTime.LIVEVIEW2);
//룸조명과, 타워램프 ON 한다 - 210402
//COMM.SETTING.Data.Disable_RoomLight = false;
//COMM.SETTING.Data.Disable_TowerLamp = false;
//얼라인상태 초기화
hmi1.arVar_Port[1].AlignReset();
hmi1.Scean = UIControl.HMI.eScean.Nomal;
//loader1.arVar_Port.ToList().ForEach(t => t.AlignReset());
//daycount 초기화
if (SETTING.Counter.DateStr != DateTime.Now.ToString("yyyy-MM-dd"))
{
SETTING.Counter.ClearDay();
SETTING.Counter.DateStr = DateTime.Now.ToString("yyyy-MM-dd");
SETTING.Counter.Save();
}
//키엔스 시작시간을 초기화한다.
VAR.TIME.Update(eVarTime.KEYENCEWAIT);
//조명켜기 - 201228
DIO.SetRoomLight(true); //조명은 켜는 것으로 한다 221107
//각스텝의 시작변수 초기화한다.
PUB.sm.seq.ClearTime();//.ClearRunStepSeqTime();
//대기메세지소거
PUB.WaitMessage = new string[] { "", "", "", "", "", "", "", "", "", "", "" };
if (PUB.flag.get(eVarBool.FG_PRC_VISIONL) && PUB.flag.get(eVarBool.FG_END_VISIONL) == false)
{
//작업을 재시작하면 카메라 트리거를 다시 보낸다
WS_Send(eWorkPort.Left, PUB.wsL, PUB.Result.ItemDataL.guid, "TRIG", PUB.Result.ItemDataL.VisionData.PrintQRData);
}
if (PUB.flag.get(eVarBool.FG_PRC_VISIONR) && PUB.flag.get(eVarBool.FG_END_VISIONR) == false)
{
//Pub.Result.ItemData[2].Clear("[0] RUN FIRST");
WS_Send(eWorkPort.Right, PUB.wsR, PUB.Result.ItemDataR.guid, "TRIG", PUB.Result.ItemDataR.VisionData.PrintQRData);
}
//재시작할때에는 이것이 동작하면 안됨
if (PUB.sm.getOldStep == eSMStep.IDLE)
{
//인쇄용지감지상태 초기화
PUB.flag.set(eVarBool.FG_WAIT_PAPERDETECTL, false, "");
PUB.flag.set(eVarBool.FG_WAIT_PAPERDETECTR, false, "");
PUB.flag.set(eVarBool.FG_PRC_VISIONL, false, "");
PUB.flag.set(eVarBool.FG_PRC_VISIONR, false, "");
PUB.flag.set(eVarBool.FG_END_VISIONL, false, "");
PUB.flag.set(eVarBool.FG_END_VISIONR, false, "");
PUB.flag.set(eVarBool.FG_OK_PRINTL, false, "");
PUB.flag.set(eVarBool.FG_OK_PRINTR, false, "");
PUB.flag.set(eVarBool.FG_RUN_PRINTL, false, "");
PUB.flag.set(eVarBool.FG_RUN_PRINTR, false, "");
PUB.flag.set(eVarBool.FG_RDY_PX_PICKON, false, "");
PUB.flag.set(eVarBool.FG_RDY_PX_LPICKOF, false, "");
PUB.flag.set(eVarBool.FG_RDY_PX_RPICKOF, false, "");
PUB.flag.set(eVarBool.FG_SET_DATA_PORT0, false, "");
PUB.flag.set(eVarBool.FG_SET_DATA_PORT2, false, "");
PUB.flag.set(eVarBool.FG_RDY_PX_PICKONWAITL, false, "");
PUB.flag.set(eVarBool.FG_RDY_PX_PICKONWAITR, false, "");
PUB.flag.set(eVarBool.FG_PORTL_ITEMON, false, "");
PUB.flag.set(eVarBool.FG_PORTR_ITEMON, false, "");
//PUB.flag.set(eVarBool.INPUT_LEFT, false, "SM_RUN");
//step seq 를 모두 소거해준다
PUB.sm.seq.Clear(eSMStep.RUN_PICK_RETRY);
//자료를 소거한다.
//PUB.Result.Clear("RUN_START");
//PUB.Result.JobStartTime = DateTime.Now; //200728
//신규실행이므로 작업차수별 수량을 초기화해준다
SETTING.Counter.ClearP(); //200711
PUB.flag.set(eVarBool.FG_JOB_END, false, "SM_RUN");
PUB.sm.seq.Clear(eSMStep.RUN_ROOT_SEQUENCE_L);
PUB.sm.seq.Clear(eSMStep.RUN_ROOT_SEQUENCE_R);
if (await _SM_RUN_STARTCHKSW(true, new TimeSpan(0)) == false) return;
if (_SM_RUN_STARTCHKHW(true, new TimeSpan(0)) == false) return;
//plc의 SID 데이터를 갱신하도록 한다
PUB.Result.ClearAllSID = true;
PUB.log.AddI("*** New job has started ***");
//PUB.flag.set(eVarBool.RDY_VISION1, true, "JOB START"); //최초 시작시에는 1번 비젼이 동작하게 한다
//새로시작할때에는 이 값을 초기화 해준다.
PUB.Result.LastSIDFrom = string.Empty;
PUB.Result.LastSIDTo = string.Empty;
//Pub.Result.LastSID103_2 = string.Empty;
PUB.Result.LastSIDCnt = -1;
PUB.Result.LastVName = string.Empty;
//릴아디이 221107
VAR.STR[eVarString.PrePick_ReelIDNew] = string.Empty;
VAR.STR[eVarString.PrePick_ReelIDOld] = string.Empty;
VAR.STR[eVarString.PrePick_ReelIDTarget] = string.Empty;
}
else
{
if (VAR.BOOL[eVarBool.wait_for_keyence])
{
PUB.log.Add($"Deleting existing values because barcode reception was waiting (CONF={PUB.Result.ItemDataC.VisionData.Confirm}, ID:{PUB.Result.ItemDataC.VisionData.RID})");
PUB.Result.ItemDataC.VisionData.Clear("RESTART", true);
}
PUB.log.AddI("*** Job has been restarted ***");
}
}
public StepResult _STEP_RUN(eSMStep step, TimeSpan stepTime, TimeSpan seqTime)
{
if (PUB.popup.needClose)
{
System.Threading.Thread.Sleep(10); //팝업이 닫힐때까지 기다린다.
return StepResult.Wait;
}
//사용자 스텝처리가 아닌경우에만 동작 중지를 검사 한다
//중단조건 검사는 0번 축에만 동작하게 한다
//if (PUB.flag.get(eVarBool.UserStepCheck) == false)
//{
// return false;
//}
if (CheckSystemRunCondition() == false)
{
return StepResult.Wait;
}
//동작상태가 아니라면 처리하지 않는다.
if (PUB.sm.Step == eSMStep.RUN && PUB.sm.getNewStep == eSMStep.RUN)
{
var RStepisFirst = runStepisFirst[0];
//릴포트 제어
_SM_RUN_MOT_PORT(0, false, PUB.sm.seq.GetTime(eSMStep.RUN_COM_PT0));
_SM_RUN_MOT_PORT(1, false, PUB.sm.seq.GetTime(eSMStep.RUN_COM_PT1));
_SM_RUN_MOT_PORT(2, false, PUB.sm.seq.GetTime(eSMStep.RUN_COM_PT2));
//컨베어 상시동작 - 230503
Boolean cvl = PUB.iLockCVL.IsEmpty();
Boolean cvr = PUB.iLockCVR.IsEmpty();
DIO.SetOutput(eDOName.LEFT_CONV, cvl);
DIO.SetOutput(eDOName.RIGHT_CONV, cvr);
//왼쪽작업
if (PUB.flag.get(eVarBool.FG_ENABLE_LEFT))
{
_RUN_ROOT_SEQUENCE(eWorkPort.Left, eSMStep.RUN_ROOT_SEQUENCE_L);
}
//오른쪽작업
if (PUB.flag.get(eVarBool.FG_ENABLE_RIGHT))
{
_RUN_ROOT_SEQUENCE(eWorkPort.Right, eSMStep.RUN_ROOT_SEQUENCE_R);
}
//작업완료조건확인
var PLReady = MOT.GetLMPos(eLMLoc.READY);
var PRReady = MOT.GetRMPos(eRMLoc.READY);
//최종이벤트시간에서 10초이상 기다려준다 230504
var tsEventTime = VAR.TIME.RUN((int)eVarTime.JOBEVENT);
//컨베이어모드
var CVMode = VAR.BOOL[eVarBool.Use_Conveyor];
if (tsEventTime.TotalSeconds > 10 &&
stepTime.TotalSeconds > 5.0 &&
DIO.isSaftyDoorF(false) == true &&
PUB.flag.get(eVarBool.FG_PK_ITEMON) == false &&
PUB.flag.get(eVarBool.FG_PL_ITEMON) == false &&
PUB.flag.get(eVarBool.FG_PR_ITEMON) == false &&
//신규로 추가된 컨베이어 센서이다
(CVMode == false || DIO.GetIOInput(eDIName.L_CONV1) == false) &&
// (CVMode == false || DIO.GetIOInput(eDIName.L_CONV3) == false) &&
(CVMode == false || DIO.GetIOInput(eDIName.L_CONV4) == false) &&
(CVMode == false || DIO.GetIOInput(eDIName.R_CONV1) == false) &&
// (CVMode == false || DIO.GetIOInput(eDIName.R_CONV3) == false) &&
(CVMode == false || DIO.GetIOInput(eDIName.R_CONV4) == false) &&
//작업진행중 확인
PUB.flag.get(eVarBool.FG_BUSY_LEFT) == false &&
PUB.flag.get(eVarBool.FG_BUSY_RIGHT) == false &&
//비전처리중 확인
//PUB.flag.get(eVarBool.FG_PRC_VISIONL) == false &&
//PUB.flag.get(eVarBool.FG_PRC_VISIONR) == false &&
//모든 모터는 멈춰있어야 한다
PUB.mot.HasMoving == false && //피커는 중앙에 있어야 한다
//좌,우측 프린터 Y축이 정위치에 있어야 한다
MOT.getPositionMatch(PLReady) &&
MOT.getPositionMatch(PRReady) &&
isPortDetUp(1) == false &&
isPortLimUP(1) &&
//드라이런 중에는 완료하지 않는다
PUB.Result.DryRun == false)
{
if (PUB.flag.get(eVarBool.FG_JOB_END) == false)
{
PUB.log.AddAT("Work completion condition execution");
VAR.TIME.Update(eVarTime.JOB_END);
PUB.flag.set(eVarBool.FG_JOB_END, true, "SM_RUN");
}
else
{
//10초가 지나면 최조 완료로 한다
var ts = VAR.TIME.RUN((int)eVarTime.JOB_END);
if (ts.TotalSeconds >= AR.SETTING.Data.Timeout_JOBEnd)
{
PUB.Result.JobEndTime = DateTime.Now;
PUB.log.AddI($"Switching to job completion state (wait time: {AR.SETTING.Data.Timeout_JOBEnd} seconds)");
PUB.sm.SetNewStep(eSMStep.FINISH);
PUB.flag.set(eVarBool.FG_JOB_END, false, "SM_RUN:FINISH");
}
}
}
else
{
//이조건일때에는 job_End 가 없어야한다
if (PUB.flag.get(eVarBool.FG_JOB_END) == true)
{
PUB.log.AddI("Work completion condition released");
PUB.flag.set(eVarBool.FG_JOB_END, false, "run");
//메인메세지를 제거 해준다.
PUB.StatusMessage.set(Class.eStatusMesage.Main, string.Empty);
}
}
}
return StepResult.Wait;
}
public Boolean CheckSystemRunCondition()
{
if (PUB.mot.IsInit == false)
{
PUB.Result.SetResultMessage(eResult.HARDWARE, eECode.AZJINIT, eNextStep.ERROR);
return false;
}
if (PUB.dio.IsInit == false)
{
PUB.Result.SetResultMessage(eResult.HARDWARE, eECode.AZJINIT, eNextStep.ERROR);
return false;
}
if (PUB.mot.HasHomeSetOff == true)
{
PUB.Result.SetResultMessage(eResult.HARDWARE, eECode.MOT_HSET, eNextStep.ERROR);
return false;
}
if (PUB.Result.vModel == null || PUB.Result.vModel.Title.isEmpty())
{
PUB.Result.SetResultMessage(eResult.SETUP, eECode.NOMODELV, eNextStep.ERROR);
return false;
}
if (PUB.Result.mModel == null || PUB.Result.mModel.Title.isEmpty())
{
PUB.Result.SetResultMessage(eResult.SETUP, eECode.NOMODELM, eNextStep.ERROR);
return false;
}
if (DIO.isSaftyDoorF() == false || DIO.isSaftyDoorR() == false)
{
PUB.Result.SetResultMessage(eResult.OPERATION, eECode.DOORSAFTY, eNextStep.PAUSE);
return false;
}
return true;
}
}
}

View File

@@ -0,0 +1,466 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using AR;
namespace Project
{
public partial class FMain
{
void _DIO_INPUT_VALUE_CHANGED(eDIName pin, Boolean value)
{
//카드사이즈 센서 적용
if (pin == eDIName.PORT0_SIZE_07 || pin == eDIName.PORT0_SIZE_13)
{
if (value)
{
//둘중하나가 들어오면 시작시간을 설정한다
if (VAR.BOOL[eVarBool.Use_Conveyor] == false)
{
VAR.TIME.Update(eVarTime.MAGNET0);
PUB.flag.set(eVarBool.FG_WAT_MAGNET0, true, "SENSOR");
}
}
else
{
var b1 = DIO.GetIOInput(eDIName.PORT0_SIZE_07);
var b2 = DIO.GetIOInput(eDIName.PORT0_SIZE_13);
if (b1 == false && b2 == false)
{
PUB.flag.set(eVarBool.FG_WAT_MAGNET0, false, "SENSOR");
DIO.SetPortMagnet(0, false);
//if (Util_DO.GetIOOutput(eDOName.CART_MAG0))
//Util_DO.SetOutput(eDOName.CART_MAG0, false);
}
}
}
else if (pin == eDIName.PORT1_SIZE_07 || pin == eDIName.PORT1_SIZE_13)
{
if (value)
{
//둘중하나가 들어오면 시작시간을 설정한다
//if (VAR.BOOL[eVarBool.Use_Conveyor] == false)
{
VAR.TIME.Update(eVarTime.MAGNET1);
PUB.flag.set(eVarBool.FG_WAT_MAGNET1, true, "SENSOR");
}
}
else
{
var b1 = DIO.GetIOInput(eDIName.PORT1_SIZE_07);
var b2 = DIO.GetIOInput(eDIName.PORT1_SIZE_13);
if (b1 == false && b2 == false)
{
PUB.flag.set(eVarBool.FG_WAT_MAGNET1, false, "SENSOR");
DIO.SetPortMagnet(1, false);
//if (Util_DO.GetIOOutput(eDOName.CART_MAG1))
//Util_DO.SetOutput(eDOName.CART_MAG1, false);
}
}
}
else if (pin == eDIName.PORT2_SIZE_07 || pin == eDIName.PORT2_SIZE_13)
{
if (value)
{
//둘중하나가 들어오면 시작시간을 설정한다
if (VAR.BOOL[eVarBool.Use_Conveyor] == false)
{
VAR.TIME.Update(eVarTime.MAGNET2);
PUB.flag.set(eVarBool.FG_WAT_MAGNET2, true, "SENSOR");
}
}
else
{
var b1 = DIO.GetIOInput(eDIName.PORT2_SIZE_07);
var b2 = DIO.GetIOInput(eDIName.PORT2_SIZE_13);
if (b1 == false && b2 == false)
{
PUB.flag.set(eVarBool.FG_WAT_MAGNET2, false, "SENSOR");
DIO.SetPortMagnet(2, false);
//if (Util_DO.GetIOOutput(eDOName.CART_MAG2))
// Util_DO.SetOutput(eDOName.CART_MAG2, false);
}
}
}
else if (pin == eDIName.DOORF1 || pin == eDIName.DOORF2 || pin == eDIName.DOORF3)
{
int PortIDX = 0;
eVarBool FG_RDY_PORT;
if (pin == eDIName.DOORF1) { PortIDX = 0; FG_RDY_PORT = eVarBool.FG_RDY_PORT_PL; }
else if (pin == eDIName.DOORF2) { PortIDX = 1; FG_RDY_PORT = eVarBool.FG_RDY_PORT_PC; }
else { PortIDX = 2; FG_RDY_PORT = eVarBool.FG_RDY_PORT_PR; }
//전면도어가 열렸다
if (DIO.GetIOInput(pin) == true)
{
if (PUB.flag.get(FG_RDY_PORT) == true)
{
PUB.flag.set(FG_RDY_PORT, false, "IOCHANGE");
if (PUB.sm.Step > eSMStep.IDLE)
PUB.log.AddAT("Releasing PORT_READY(L) due to safety sensor detection");
}
//도어가 열리면 포트를 멈춘다 210329
if (DIO.GetPortMotorRun(0)) DIO.SetPortMotor(0, DIO.GetPortMotorDir(0), false, "DOOR OPEN");
if (DIO.GetPortMotorRun(1)) DIO.SetPortMotor(1, DIO.GetPortMotorDir(1), false, "DOOR OPEN");
if (DIO.GetPortMotorRun(2)) DIO.SetPortMotor(2, DIO.GetPortMotorDir(2), false, "DOOR OPEN");
//210331
if (PUB.sm.Step != eSMStep.RUN)
{
PUB.mot.MoveStop("Dorr oopen");
}
if (PUB.sm.isRunning == false && AR.SETTING.Data.PickerAutoMoveForDoor)
{
var motSpeed = 300;
var motAcc = 500;
if (pin == eDIName.DOORF3) //좌측도어가 열렸다
{
var DoorF2 = DIO.GetIOInput(eDIName.DOORF2);
var DoorF1 = DIO.GetIOInput(eDIName.DOORF1);
if (DoorF2 == false && DoorF1 == false) //중앙도어가 닫혀있다
{
var PosPZ = MOT.getPositionMatch(MOT.GetPZPos(ePZLoc.READY));//.MOT.GetPKZ_PosName();
var PosLM = MOT.getPositionMatch(MOT.GetLMPos(eLMLoc.READY));//. MOT.GetPLM_PosName();
var PosRM = MOT.getPositionMatch(MOT.GetRMPos(eRMLoc.READY));//.MOT.GetPRM_PosName();
if (PosLM && PosRM && PosPZ)
{
//x위치가 pickon 보다 작으면 옴겨줘야 한다.
var xpos = MOT.getPositionOffset(MOT.GetPXPos(ePXLoc.PICKON));
if (xpos < 1)
{
var mPos = MOT.GetPXPos(ePXLoc.PICKON);
MOT.Move(eAxis.PX_PICK, mPos.Position, motSpeed, motAcc, false, false, false);
}
}
}
}
else if (pin == eDIName.DOORF2) //중앙도어가 열렸다
{
//좌우측 닫혀있고 프린트M 위치가 Ready 여아한다.
var PosPZ = MOT.getPositionMatch(MOT.GetPZPos(ePZLoc.READY));//.MOT.GetPKZ_PosName();
var PosLM = MOT.getPositionMatch(MOT.GetLMPos(eLMLoc.READY));//. MOT.GetPLM_PosName();
var PosRM = MOT.getPositionMatch(MOT.GetRMPos(eRMLoc.READY));//.MOT.GetPRM_PosName();
if (PosPZ)
{
var xpos = MOT.getPositionOffset(MOT.GetPXPos(ePXLoc.PICKON));
if (Math.Abs(xpos) < 100) //중앙근처 10 mm 안에 있다면
{
var DoorF1 = DIO.GetIOInput(eDIName.DOORF1);
var DoorF3 = DIO.GetIOInput(eDIName.DOORF3);
if (DoorF1 == false && DoorF3 == false)
{
if (PosLM)
{
var mPos = MOT.GetPXPos(ePXLoc.READYL);
MOT.Move(eAxis.PX_PICK, mPos.Position, motSpeed, motAcc, false, false, false);
}
else if (PosRM)
{
var mPos = MOT.GetPXPos(ePXLoc.READYR);
MOT.Move(eAxis.PX_PICK, mPos.Position, motSpeed, motAcc, false, false, false);
}
//}
}
}
}
}
else if (pin == eDIName.DOORF1) //우측도어가 열렸다
{
var DoorF2 = DIO.GetIOInput(eDIName.DOORF2);
var DoorF3 = DIO.GetIOInput(eDIName.DOORF3);
if (DoorF2 == false && DoorF3 == false) //중앙도어가 닫혀있다
{
var PosPZ = MOT.getPositionMatch(MOT.GetPZPos(ePZLoc.READY));//.MOT.GetPKZ_PosName();
var PosLM = MOT.getPositionMatch(MOT.GetLMPos(eLMLoc.READY));//. MOT.GetPLM_PosName();
var PosRM = MOT.getPositionMatch(MOT.GetRMPos(eRMLoc.READY));//.MOT.GetPRM_PosName();
if (PosLM && PosRM && PosPZ)
{
//x위치가 pickon 보다 작으면 옴겨줘야 한다.
var xpos = MOT.getPositionOffset(MOT.GetPXPos(ePXLoc.PICKON));
if (xpos > 1)
{
var mPos = MOT.GetPXPos(ePXLoc.PICKON);
MOT.Move(eAxis.PX_PICK, mPos.Position, motSpeed, motAcc, false, false, false);
}
}
}
}
}
//안전센서가 감지되었다면 얼라인을 초기화 해준다
hmi1.arVar_Port[PortIDX].AlignOK = 0;
hmi1.arVar_Port[PortIDX].errorCount = 0;
//동작중일경우 추가 작업
if (PUB.sm.Step > eSMStep.IDLE)
{
//안전센서가 들어와잇다면 이 값을 초기화 해준다
if (DIO.isSaftyDoorF(PortIDX, true) == false && PUB.flag.get(eVarBool.FG_JOB_END) == true)
VAR.TIME.Update(eVarTime.JOB_END);
}
//오류 혹은 Wait 상태일때에는 프린터 Z축을 올려준다
if (PUB.sm.Step == eSMStep.WAITSTART || PUB.sm.Step == eSMStep.PAUSE)
{
if (pin == eDIName.DOORF3)
{
var PosM = MOT.getPositionMatch(MOT.GetLMPos(eLMLoc.READY));//. MOT.GetPLM_PosName();
var PosZ = MOT.getPositionMatch(MOT.GetLZPos(eLZLoc.PICKON));//.MOT.GetPRM_PosName();
if (PosM && PosZ)
{
PUB.log.Add("Raising printer L Z-axis due to door opening");
var Pos = MOT.GetLZPos(eLZLoc.PICKON);
MOT.Move(Pos);
}
}
else if (pin == eDIName.DOORF1)
{
var PosM = MOT.getPositionMatch(MOT.GetRMPos(eRMLoc.READY));// MOT.GetPRM_PosName();
var PosZ = MOT.getPositionMatch(MOT.GetRZPos(eRZLoc.PICKON));// GetPRZ_PosName();
if (PosM && PosZ)
{
PUB.log.Add("Raising printer R Z-axis due to door opening");
MOT.Move(eAxis.PR_UPDN, 0, 100, 1000, false, false, false);
}
}
}
}
else
{
//도어를 다시 닫았을때처리해준다.
//오류 혹은 Wait 상태일때에는 프린터 Z축을 올려준다
if (PUB.sm.Step == eSMStep.WAITSTART || PUB.sm.Step == eSMStep.PAUSE)
{
if (pin == eDIName.DOORF3)
{
var PosM = MOT.getPositionMatch(MOT.GetLMPos(eLMLoc.READY));//. MOT.GetPLM_PosName();
var PosZ = MOT.getPositionMatch(MOT.GetLZPos(eLZLoc.READY));//.MOT.GetPRM_PosName();
if (PosM && PosZ)
{
var zpos = MOT.GetLZPos(eLZLoc.PICKON);
PUB.log.Add("Lowering printer L Z-axis due to door closing");
MOT.Move(eAxis.PL_UPDN, zpos.Position, 100, 1000, false, false, false);
}
}
else if (pin == eDIName.DOORF1)
{
var PosM = MOT.getPositionMatch(MOT.GetRMPos(eRMLoc.READY));//. MOT.GetPLM_PosName();
var PosZ = MOT.getPositionMatch(MOT.GetRZPos(eRZLoc.READY));//.MOT.GetPRM_PosName();
if (PosM && PosZ)
{
var zpos = MOT.GetRZPos(eRZLoc.PICKON);
PUB.log.Add("Lowering printer R Z-axis due to door closing");
MOT.Move(eAxis.PR_UPDN, zpos.Position, 100, 1000, false, false, false);
}
}
}
}
}
else if (pin == eDIName.BUT_AIRF) //여기서부터는 스위치 영역
{
//AIR버튼은 IDLE 이상일떄에 동작 한다
if (value == true && PUB.sm.Step >= eSMStep.IDLE)
{
var curState = DIO.GetIOOutput(eDOName.SOL_AIR);
if (curState == false)
{
DIO.SetAIR(!curState);
PUB.log.AddI("Air ON");
}
else
{
DIO.SetAIR(!curState);
PUB.log.AddAT("Air OFF");
}
}
//AIR의 LED는 실제 AIR 출력 상태와 동기화 한다 * output event 에서 처리함
}
else if (pin == eDIName.BUT_EMGF)
{
PUB.log.AddAT(string.Format("Emergency Status : {0} Value= {1}", pin, value));
if (value == false)
{
//로더컨트롤의 이머전시 상탤르 설정한다 (둘중 하나라도 꺼지면 비상값이다)
EmergencyTime = DateTime.Now; //한놈이라도 이머전시가 들어오면 강제 멈춘다
PUB.mot.MoveStop("emg", true);
//포트 모터 정지
DIO.SetPortMotor(0, eMotDir.CW, false, "EMG"); System.Threading.Thread.Sleep(1);
DIO.SetPortMotor(1, eMotDir.CW, false, "EMG"); System.Threading.Thread.Sleep(1);
DIO.SetPortMotor(2, eMotDir.CW, false, "EMG"); System.Threading.Thread.Sleep(1);
}
else
{
//둘다 ON 되어잇다면 비상을 해제한다
if (DIO.IsEmergencyOn() != true) hmi1.arDI_Emergency = false;
}
//Emg는 B접점이라서 LED상태를 반전시킨다
if (pin == eDIName.BUT_EMGF) DIO.SetOutput(eDOName.BUT_EMGF, !value);
}
else if (pin == eDIName.BUT_STARTF) //시작버튼
{
if (PUB.flag.get(eVarBool.FG_MOVE_PICKER))
{
if (value)
{
if (VAR.BOOL[eVarBool.Enable_PickerMoveX] && PUB.mot.IsMotion((int)eAxis.PX_PICK) == false)
PUB.mot.JOG((int)eAxis.PX_PICK, arDev.MOT.MOTION_DIRECTION.Negative, AR.SETTING.Data.JOG_Speed, AR.SETTING.Data.JOG_Acc);
}
else
{
PUB.mot.MoveStop("xmove", (int)eAxis.PX_PICK);
}
}
else
{
if (PUB.flag.get(eVarBool.FG_SCR_JOBSELECT) == false)
{
if (value && PUB.sm.Step >= eSMStep.IDLE)
{
PUB.log.AddI("START BUTTON");
this._BUTTON_START();
}
}
}
}
else if (pin == eDIName.BUT_STOPF) //중단버튼
{
if (PUB.flag.get(eVarBool.FG_MOVE_PICKER))
{
if (value)
{
if (VAR.BOOL[eVarBool.Enable_PickerMoveX] && PUB.mot.IsMotion((int)eAxis.PX_PICK) == false)
PUB.mot.JOG((int)eAxis.PX_PICK, arDev.MOT.MOTION_DIRECTION.Positive, AR.SETTING.Data.JOG_Speed, AR.SETTING.Data.JOG_Acc);
}
else
{
PUB.mot.MoveStop("xmove", (int)eAxis.PX_PICK);
}
}
else
{
if (PUB.flag.get(eVarBool.FG_SCR_JOBSELECT) == false)
{
if (value && PUB.sm.Step >= eSMStep.IDLE)
{
PUB.log.AddI("STOP BUTTON");
_BUTTON_STOP();
}
}
}
}
else if (pin == eDIName.BUT_RESETF) //리셋버튼
{
if (PUB.flag.get(eVarBool.FG_SCR_JOBSELECT) == false)
{
if (value && PUB.sm.Step >= eSMStep.IDLE)
{
if (value) PUB.Result.ResetButtonDownTime = DateTime.Now;
else PUB.Result.ResetButtonDownTime = new DateTime(1982, 11, 23);
PUB.log.AddI("RESET BUTTON");
_BUTTON_RESET();
}
}
//요약폼이 있었다면 해제 해준다. - 210329
if (PUB.sm.Step == eSMStep.FINISH)
HideSummary();
}
else if (pin == eDIName.PORTL_DET_UP || pin == eDIName.PORTC_DET_UP || pin == eDIName.PORTR_DET_UP)
{
var pidx = 0;
eVarBool FG_RDY_PORT = eVarBool.FG_RDY_PORT_PL;
var value1 = DIO.GetIOInput(pin);
if (pin == eDIName.PORTC_DET_UP)
{
pidx = 1;
FG_RDY_PORT = eVarBool.FG_RDY_PORT_PC;
if (value1 == true) //해당 제품이 검출되어 멈춘다면, 키엔스 데이터를 초기화 해준다.
{
//Pub.Result.ItemData[1].VisionData.Clear("DIO DET1");
//PUB.flag.set(eVarBool.END_VISION1, false, "DIO DET1");
//데이터 손실건이 나와서 처리하지 않게한다 210318
}
}
else if (pin == eDIName.PORTR_DET_UP) { pidx = 2; FG_RDY_PORT = eVarBool.FG_RDY_PORT_PR; }
if (PUB.sm.Step != eSMStep.RUN && value1 == false) //감지가 꺼지면 ready 를 해제한다
PUB.flag.set(FG_RDY_PORT, false, "IOCHANGE");
else if (hmi1.arVar_Port[pidx].AlignOK != 1)
PUB.Result.PortAlignTime[0] = DateTime.Now.Ticks; //시작시간을 초기화 해준다
//동작중에 들어오면 바로 멈추게한다. 이것은 SPS에서 적용되어야하지만 더 빠르게 반응하기 위해서 그렇게 한다 - 200813
if (value1 && DIO.GetPortMotorDir(pidx) == eMotDir.CW)
DIO.SetPortMotor(pidx, eMotDir.CW, false, "_DIO_DETECT");
}
if (pin == eDIName.PORTL_LIM_DN)
{
//좌측포트의 하단부리밋센서가 검출될경우 마그넷이 on 되어있다면 off한다.
if (DIO.GetIOInput(eDIName.PORTL_LIM_DN) == true && DIO.GetIOOutput(eDOName.PORTL_MAGNET) == true)
{
DIO.SetPortMagnet(0, false);
PUB.log.Add("Left port magnet OFF");
}
}
else if (pin == eDIName.PORTC_LIM_DN)
{
//좌측포트의 하단부리밋센서가 검출될경우 마그넷이 on 되어있다면 off한다.
if (DIO.GetIOInput(eDIName.PORTC_LIM_DN) == true && DIO.GetIOOutput(eDOName.PORTC_MAGNET) == true)
{
DIO.SetPortMagnet(1, false);
PUB.log.Add("Center port magnet OFF");
if(PUB.sm.Step == eSMStep.FINISH)
{
DIO.SetBuzzer(false); //부저종료 231005
}
}
}
else if (pin == eDIName.PORTR_LIM_DN)
{
//좌측포트의 하단부리밋센서가 검출될경우 마그넷이 on 되어있다면 off한다.
if (DIO.GetIOInput(eDIName.PORTR_LIM_DN) == true && DIO.GetIOOutput(eDOName.PORTR_MAGNET) == true)
{
DIO.SetPortMagnet(2, false);
PUB.log.Add("Right port magnet OFF");
}
}
else if (pin == eDIName.R_CONV4 || pin == eDIName.L_CONV1 || pin == eDIName.L_CONV4 || pin == eDIName.R_CONV1)
{
VAR.TIME[(int)eVarTime.JOBEVENT] = DateTime.Now;
}
}
}
}

View File

@@ -0,0 +1,98 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using AR;
namespace Project
{
public partial class FMain
{
void _DIO_OUTPUT_VALUE_CHANGED(eDOName pin, Boolean value)
{
if (pin == eDOName.PORTL_MOT_RUN)
{
VAR.TIME[(int)eVarTime.JOBEVENT] = DateTime.Now;
hmi1.arVar_Port[0].MotorRun = value;
}
else if (pin == eDOName.PORTC_MOT_RUN)
{
//VAR.TIME[(int)eVarTime.JOBEVENT] = DateTime.Now;
hmi1.arVar_Port[1].MotorRun = value;
}
else if (pin == eDOName.PORTR_MOT_RUN)
{
VAR.TIME[(int)eVarTime.JOBEVENT] = DateTime.Now;
hmi1.arVar_Port[2].MotorRun = value;
}
else if (pin == eDOName.PORTL_MOT_DIR)
{
hmi1.arVar_Port[0].MotorDir = !value;
}
else if (pin == eDOName.PORTC_MOT_DIR)
hmi1.arVar_Port[1].MotorDir = !value;
else if (pin == eDOName.PORTR_MOT_DIR)
{
hmi1.arVar_Port[2].MotorDir = !value;
}
//피커 백큠 동작 상태(front)
//else if (pin == eDOName.PICK_VAC1) loader1.arVar_Picker[0].VacOutput[0] = value;
//else if (pin == eDOName.PICK_VAC2) loader1.arVar_Picker[0].VacOutput[1] = value;
//else if (pin == eDOName.PICK_VAC3) loader1.arVar_Picker[0].VacOutput[2] = value;
//else if (pin == eDOName.PICK_VAC4) loader1.arVar_Picker[0].VacOutput[3] = value;
//출력상태에 따라서 버튼의 LED를 켠다
else if (pin == eDOName.SOL_AIR)
{
DIO.SetOutput(eDOName.BUT_AIRF, value);
if (value == false)
PUB.flag.set(eVarBool.FG_PK_ITEMON, false, "DO");
hmi1.arDIAir = value; //AIR상태를 표시
}
else if (pin == eDOName.LEFT_CONV)
{
VAR.TIME[(int)eVarTime.JOBEVENT] = DateTime.Now;
if (value)
{
VAR.TIME[eVarTime.CONVL_START] = DateTime.Now;
}
else
{
VAR.TIME[eVarTime.CONVL_START] = new DateTime(1982, 11, 23);
VAR.DBL[eVarDBL.CONVL_RUNTIME] = 0;
}
PUB.log.Add($"LEFT_CONV : {value}");
}
else if (pin == eDOName.RIGHT_CONV)
{
VAR.TIME[(int)eVarTime.JOBEVENT] = DateTime.Now;
PUB.log.Add($"RIGHT_CONV : {value}");
if (value)
{
VAR.TIME[eVarTime.CONVR_START] = DateTime.Now;
}
else
{
VAR.TIME[eVarTime.CONVR_START] = new DateTime(1982, 11, 23);
VAR.DBL[eVarDBL.CONVR_RUNTIME] = 0;
}
}
else if (pin == eDOName.BUZZER)
{
if (value)
PUB.BuzzerTime = DateTime.Now;
else
PUB.BuzzerTime = new DateTime(1982, 11, 23);
}
}
}
}

View File

@@ -0,0 +1,153 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using arDev;
using AR;
using AR;
namespace Project
{
public partial class FMain
{
void Set_InterLock()
{
if (PUB.sm.Step < eSMStep.IDLE) return;
intlockcnt += 1;
var CurrentSaftyDoor = DIO.isSaftyDoorF();//도어안전
var CurrentSaftyArea = true; //안전영역
var bEmg = DIO.IsEmergencyOn(); //비상정지
var bHSet = PUB.mot.IsInit && PUB.mot.HasHomeSetOff; //홈 설정이 완료되었는지 확인한다
PUB.flag.set(eVarBool.FG_DOORSAFTY, CurrentSaftyDoor, "COMMINTERLOCK");
PUB.flag.set(eVarBool.FG_AREASAFTY, CurrentSaftyArea, "COMMINTERLOCK");
for (int i = 0; i < PUB.iLock.Length; i++)
{
PUB.iLock[i].set((int)eILock.EMG, bEmg, "COMMINTERLOCK");
PUB.iLock[i].set((int)eILock.DOOR, !CurrentSaftyDoor, "COMMINTERLOCK");
if (i < 7)
{
PUB.iLock[i].set((int)eILock.HOMESET, bHSet, "COMMINTERLOCK");
}
}
//피커의 Z축이 움직이는 동안에는 Y축을 움직이지 못하게 한다
PUB.iLock[(int)eAxis.PX_PICK].set((int)eILock.ZMOVE, PUB.mot.IsMotion((int)eAxis.PZ_PICK), "COMMINTERLOCK");
PUB.iLock[(int)eAxis.PL_MOVE].set((int)eILock.ZMOVE, PUB.mot.IsMotion((int)eAxis.PL_UPDN), "COMMINTERLOCK");
PUB.iLock[(int)eAxis.PR_MOVE].set((int)eILock.ZMOVE, PUB.mot.IsMotion((int)eAxis.PR_UPDN), "COMMINTERLOCK");
//피커의 Y축이 움직이는 동안에는 Z축을 움직이지 못하게 한다
PUB.iLock[(int)eAxis.PZ_PICK].set((int)eILock.XMOVE, PUB.mot.IsMotion((int)eAxis.PX_PICK), "COMMINTERLOCK");
//외부컨베어 신호 인터락설정 (출구쪽센서가 인식되지 않았다면 멈추지 않는다)
var cvLBusy = DIO.GetIOInput(eDIName.L_CONV4) && DIO.GetIOInput(eDIName.L_EXT_READY) == false && VAR.BOOL[eVarBool.FG_AUTOOUTCONVL] == false;
var cvRBusy = DIO.GetIOInput(eDIName.R_CONV4) && DIO.GetIOInput(eDIName.R_EXT_READY) == false && VAR.BOOL[eVarBool.FG_AUTOOUTCONVR] == false;
PUB.iLockCVL.set((int)eILockCV.EXTBUSY, cvLBusy, "COMMINTERLOCK");
PUB.iLockCVR.set((int)eILockCV.EXTBUSY, cvRBusy, "COMMINTERLOCK");
//축을 사용하지 않는경우
PUB.iLockCVL.set((int)eILockCV.DISABLE, SETTING.Data.Disable_Left, "COMMINTERLOCK");
PUB.iLockCVR.set((int)eILockCV.DISABLE, SETTING.Data.Disable_Right, "COMMINTERLOCK");
//카트모드에서
PUB.iLockCVL.set((int)eILockCV.CARTMODE, !VAR.BOOL[eVarBool.Use_Conveyor], "COMMINTERLOCK");
PUB.iLockCVR.set((int)eILockCV.CARTMODE, !VAR.BOOL[eVarBool.Use_Conveyor], "COMMINTERLOCK");
//포트가동상태에따라서 비젼인터락
PUB.iLockVS0.set((int)eILockVS0.PORTRDY, !PUB.flag.get(eVarBool.FG_RDY_PORT_PL), "COMMINTERLOCK");
if (PUB.Result.DryRun == true)
PUB.iLockVS1.set((int)eILockVS1.PORTRDY, false, "COMMINTERLOCK");
else
PUB.iLockVS1.set((int)eILockVS1.PORTRDY, !PUB.flag.get(eVarBool.FG_RDY_PORT_PC), "COMMINTERLOCK");
PUB.iLockVS2.set((int)eILockVS2.PORTRDY, !PUB.flag.get(eVarBool.FG_RDY_PORT_PR), "COMMINTERLOCK");
//위치관련 인터락은 MODEL이 설정 되어있어야하며, MOTION도 정상이어야 한다
if (PUB.mot.IsInit && PUB.Result.mModel.isSet)
{
//if (PUB.LockModel.WaitOne(1) == true)
{
//PUB.LockModel.Reset();
//피커의 X축에 따라서 비젼의 촬영가능여부가 결정된다
PUB.iLockVS0.set((int)eILockVS0.PKXPOS, DIO.GetIOInput(eDIName.PICKER_SAFE) == false && MOT.getPositionOffset(MOT.GetPXPos(ePXLoc.PICKON)) < -2, "COMMINTERLOCK");
if (MOT.getPositionOffset(MOT.GetPXPos(ePXLoc.READYL)) <= 2 || MOT.getPositionOffset(MOT.GetPXPos(ePXLoc.READYR)) >= -2)
PUB.iLockVS1.set((int)eILockVS1.PKXPOS, false, "COMMINTERLOCK");
else
PUB.iLockVS1.set((int)eILockVS1.PKXPOS, true, "COMMINTERLOCK");
PUB.iLockVS2.set((int)eILockVS2.PKXPOS, DIO.GetIOInput(eDIName.PICKER_SAFE) == false && MOT.getPositionOffset(MOT.GetPXPos(ePXLoc.PICKON)) > 2, "COMMINTERLOCK");
//프린터Y축 위치에 따른 비젼촬영여부(기준위치보다 낮게 있다면 촬영이 안된다)
var PLMCmdPos = MOT.GetLMPos(eLMLoc.READY);
var PRMCmdPos = MOT.GetRMPos(eRMLoc.READY);
PUB.iLockVS0.set((int)eILockVS0.PRNYPOS, (MOT.getPositionOffset(PLMCmdPos) < -5), "COMMINTERLOCK");
PUB.iLockVS2.set((int)eILockVS2.PRNYPOS, (MOT.getPositionOffset(PRMCmdPos) < -5), "COMMINTERLOCK");
//피커의Z축이 안전위치가 아니면 Y축을 움직이지 않는다
var PKZ_POS_ERR = MOT.getPositionOffset(MOT.GetPZPos(ePZLoc.READY)) > 2;
PUB.iLock[(int)eAxis.PX_PICK].set((int)eILock.Z_POS, PKZ_POS_ERR, "COMMINTERLOCK");
PKZ_POS_ERR = (DIO.GetIOInput(eDIName.PICKER_SAFE) == false && MOT.getPositionOffset(MOT.GetPXPos(ePXLoc.PICKON)) <= 2);
PUB.iLock[(int)eAxis.PL_MOVE].set((int)eILock.X_POS, PKZ_POS_ERR, "COMMINTERLOCK"); ;
PKZ_POS_ERR = (DIO.GetIOInput(eDIName.PICKER_SAFE) == false && MOT.getPositionOffset(MOT.GetPXPos(ePXLoc.PICKON)) >= 2);
PUB.iLock[(int)eAxis.PR_MOVE].set((int)eILock.X_POS, PKZ_POS_ERR, "COMMINTERLOCK");
//프린터Z축 안전위치가 아니면 Y축을 멈춘다
var PLZ_POS_ERR = MOT.getPositionOffset(MOT.GetLZPos(eLZLoc.READY)) > 2.0;
var PRZ_POS_ERR = MOT.getPositionOffset(MOT.GetRZPos(eRZLoc.READY)) > 2.0;
PUB.iLock[(int)eAxis.PL_MOVE].set((int)eILock.PZ_POS, PLZ_POS_ERR, "COMMINTERLOCK");
PUB.iLock[(int)eAxis.PR_MOVE].set((int)eILock.PZ_POS, PRZ_POS_ERR, "COMMINTERLOCK");
//실린더가 전진해 잇다면 이동하지 않아야 한다 - 210207
var PLZ_CYL_FW = !DIO.GetIOInput(eDIName.L_PICK_BW);
var PRZ_CYL_FW = !DIO.GetIOInput(eDIName.R_PICK_BW);
PUB.iLock[(int)eAxis.PL_MOVE].set((int)eILock.CYL_FORWARD, PLZ_CYL_FW, "COMMINTERLOCK");
PUB.iLock[(int)eAxis.PR_MOVE].set((int)eILock.CYL_FORWARD, PRZ_CYL_FW, "COMMINTERLOCK");
//프린터Y축 안전위치가 아니면 Z축을 멈춘다
var PLM_YPOS_READY = MOT.getPositionMatch(MOT.GetLMPos(eLMLoc.READY)); //MOT.GetPLM_PosName();
var PRM_YPOS_READY = MOT.getPositionMatch(MOT.GetRMPos(eRMLoc.READY)); //MOT.GetPRM_PosName();
var PLM_YPOS_H07 = MOT.getPositionMatch(MOT.GetLMPos(eLMLoc.PRINTH07));
var PLM_YPOS_M07 = MOT.getPositionMatch(MOT.GetLMPos(eLMLoc.PRINTM07));
var PLM_YPOS_L07 = MOT.getPositionMatch(MOT.GetLMPos(eLMLoc.PRINTL07));
var PLM_YPOS_H13 = MOT.getPositionMatch(MOT.GetLMPos(eLMLoc.PRINTH13));
var PLM_YPOS_M13 = MOT.getPositionMatch(MOT.GetLMPos(eLMLoc.PRINTM13));
var PLM_YPOS_L13 = MOT.getPositionMatch(MOT.GetLMPos(eLMLoc.PRINTL13));
var PRM_YPOS_H07 = MOT.getPositionMatch(MOT.GetRMPos(eRMLoc.PRINTH07));
var PRM_YPOS_M07 = MOT.getPositionMatch(MOT.GetRMPos(eRMLoc.PRINTM07));
var PRM_YPOS_L07 = MOT.getPositionMatch(MOT.GetRMPos(eRMLoc.PRINTL07));
var PRM_YPOS_H13 = MOT.getPositionMatch(MOT.GetRMPos(eRMLoc.PRINTH13));
var PRM_YPOS_M13 = MOT.getPositionMatch(MOT.GetRMPos(eRMLoc.PRINTM13));
var PRM_YPOS_L13 = MOT.getPositionMatch(MOT.GetRMPos(eRMLoc.PRINTL13));
var = MOT.getPositionOffset(MOT.GetLMPos(eLMLoc.READY));
var = MOT.getPositionOffset(MOT.GetRMPos(eRMLoc.READY));
var = ( >= (AR.SETTING.Data.MoveYForPaperVaccumeValue - 0.5) && <= 0.5);
var = ( >= (AR.SETTING.Data.MoveYForPaperVaccumeValue - 0.5) && <= 0.5);
var PLM_POS_ERR = !( || PLM_YPOS_READY || PLM_YPOS_H07 || PLM_YPOS_M07 || PLM_YPOS_L07 || PLM_YPOS_H13 || PLM_YPOS_M13 || PLM_YPOS_L13);
var PRM_POS_ERR = !( || PRM_YPOS_READY || PRM_YPOS_H07 || PRM_YPOS_M07 || PRM_YPOS_L07 || PRM_YPOS_H13 || PRM_YPOS_M13 || PRM_YPOS_L13);
PUB.iLock[(int)eAxis.PL_UPDN].set((int)eILock.PY_POS, PLM_POS_ERR, "COMMINTERLOCK");
PUB.iLock[(int)eAxis.PR_UPDN].set((int)eILock.PY_POS, PRM_POS_ERR, "COMMINTERLOCK");
//PUB.LockModel.Set();
}
}
else
{
//모션사용불능은 그냥 해제한다
//Pub.LockPRL.set((int)eILockPRL.PYPOS, false, "COMMINTERLOCK");
//Pub.LockPRL.set((int)eILockPRR.PYPOS, false, "COMMINTERLOCK");
}
}
}
}

View File

@@ -0,0 +1,106 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using AR;
using arDev;
namespace Project
{
public partial class FMain
{
void Lock_ValueChanged(object sender, AR.InterfaceValueEventArgs e)
{
//인터락플래그 변경 이벤트
var iL = sender as AR.CInterLock;
var tagstr = (iL.Tag == null ? string.Empty : iL.Tag.ToString());
var fgstr = $"[{e.ArrIDX}]";
if (tagstr == "PKX") fgstr = ((eILock)e.ArrIDX).ToString();
else if (tagstr == "PKZ") fgstr = ((eILock)e.ArrIDX).ToString();
else if (tagstr == "PKT") fgstr = ((eILock)e.ArrIDX).ToString();
else if (tagstr == "PLM") fgstr = ((eILock)e.ArrIDX).ToString();
else if (tagstr == "PLZ") fgstr = ((eILock)e.ArrIDX).ToString();
else if (tagstr == "PRM") fgstr = ((eILock)e.ArrIDX).ToString();
else if (tagstr == "PRZ") fgstr = ((eILock)e.ArrIDX).ToString();
else if (tagstr == "PRL") fgstr = ((eILockPRL)e.ArrIDX).ToString();
else if (tagstr == "PRR") fgstr = ((eILockPRR)e.ArrIDX).ToString();
else if (tagstr == "VS0") fgstr = ((eILockVS0)e.ArrIDX).ToString();
else if (tagstr == "VS1") fgstr = ((eILockVS1)e.ArrIDX).ToString();
else if (tagstr == "VS2") fgstr = ((eILockVS2)e.ArrIDX).ToString();
else if (tagstr == "CVL") fgstr = ((eILockCV)e.ArrIDX).ToString();
else if (tagstr == "CVR") fgstr = ((eILockCV)e.ArrIDX).ToString();
//else fgstr = "?";
//최초생성시에는 값을 표시한다
if (PUB.sm.Step >= eSMStep.IDLE && PUB.sm.Step != eSMStep.HOME_FULL)
{
if (e.NewOn)
{
if (tagstr == "PKX" && PUB.mot.IsMotion(0) == true)
{
Console.WriteLine("ㅠㅠ");
}
if (AR.SETTING.Data.Log_ILock)
PUB.log.Add(string.Format("[IL-ON:{2}] {0}:{1}", fgstr, e.Reason, tagstr));
if (AR.SETTING.Data.Enable_Log_ILock)
PUB.logILock.Add("ON", $"{fgstr}:{e.Reason}");
}
else if (e.NewOff)
{
if (AR.SETTING.Data.Log_ILock)
PUB.log.Add(string.Format("[IL-OF:{2}] {0}:{1}", fgstr, e.Reason, tagstr));
if (AR.SETTING.Data.Enable_Log_ILock)
PUB.logILock.Add("OF", $"{fgstr}:{e.Reason}");
}
var logmsg = "#### ILOCK(" + tagstr + ")변경 : " + fgstr + "(" + e.ArrIDX.ToString() + ") 값:" + e.NewValue.ToString() + ",사유:" + e.Reason;
//ILOck 로그에 기록
if (AR.SETTING.Data.Enable_Log_ILock) PUB.logILock.Add(logmsg);
//메인로그에 기록
if (AR.SETTING.Data.Log_ILock) PUB.log.Add(logmsg);
}
}
private void Flag_ValueChanged(object sender, VarData<bool>.ValueEventArgs e)
{
var fg = (eVarBool)e.Idx;
if (fg == eVarBool.FG_PK_ITEMON)
{
// Pub.log.AddAT(string.Format("[FLAG:{0}] : {1}", fg, e.NewValue));
hmi1.arVar_Picker[0].ItemOn = e.Value;
}
else if (fg == eVarBool.FG_RDY_PZ_LPICKOF) hmi1.arFG_RDY_YP_FPICKOF = e.Value;
else if (fg == eVarBool.FG_RDY_PZ_RPICKOF) hmi1.arFG_RDY_YP_RPICKOF = e.Value;
else if (fg == eVarBool.FG_CMD_YP_LPICKON) hmi1.arFG_CMD_YP_FPICKON = e.Value;
else if (fg == eVarBool.FG_CMD_YP_RPICKON) hmi1.arFG_CMD_YP_RPICKON = e.Value;
else if (fg == eVarBool.FG_MINSPACE) hmi1.arFlag_Minspace = e.Value;
hmi1.arVar_Port[0].Ready = PUB.flag.get(eVarBool.FG_RDY_PORT_PL);
hmi1.arVar_Port[1].Ready = PUB.flag.get(eVarBool.FG_RDY_PORT_PC);
hmi1.arVar_Port[2].Ready = PUB.flag.get(eVarBool.FG_RDY_PORT_PR);
if (PUB.sm.Step >= eSMStep.IDLE && PUB.sm.Step != eSMStep.HOME_FULL)
{
var logmsg = string.Format("[{0}] {1} : {2} => {3}", e.Idx, fg, e.Value, e.Message);
//ILOck 로그에 기록
if (AR.SETTING.Data.Enable_Log_Flag) PUB.logFlag.Add(logmsg);
//메인로그에 기록
if (AR.SETTING.Data.Log_flag) PUB.log.Add(logmsg);
}
}
}
}

View File

@@ -0,0 +1,152 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using AR;
namespace Project
{
public partial class FMain
{
Dialog.fFinishJob fsum = null;
void HideSummary()
{
if (this.InvokeRequired)
{
this.BeginInvoke(new MethodInvoker(HideSummary), null);
}
else
{
if (fsum != null)
{
if (fsum.IsDisposed == false && fsum.Disposing == false)
{
fsum.Close();
fsum.Dispose();
}
fsum = null;
}
}
}
void ShowSummary()
{
if (fsum == null || fsum.IsDisposed || fsum.Disposing == true)
{
fsum = new Dialog.fFinishJob();
fsum.FormClosed += (s1, e1) =>
{
//해당 폼이 닫힐때 처리한다.
if (PUB.sm.Step == eSMStep.FINISH)
{
//완료상때일때 닫으면
Run_MotionPositionReset();
}
};
fsum.Show();
}
else
{
fsum.Show();
fsum.Activate();
}
}
void UserStepWait(eWorkPort target)
{
if (PUB.flag.get(eVarBool.FG_USERSTEP))
{
if (target == eWorkPort.Left)
{
if (LockUserL.WaitOne(1))
LockUserL.Reset();
}
else
{
if (LockUserR.WaitOne(1))
LockUserR.Reset();
}
}
}
/// <summary>
/// user step 상황에서 자동으로 멈추게 합니다.
/// </summary>
void UserStepRun(eWorkPort target)
{
if (PUB.flag.get(eVarBool.FG_USERSTEP))
{
if (target == eWorkPort.Right)
{
if (LockUserL.WaitOne(1) == false)
LockUserL.Set();
}
else
{
if (LockUserR.WaitOne(1) == false)
LockUserR.Set();
}
}
}
/// <summary>
/// 홈작업이 진행 가능한지 하드웨어 상태를 확인한다.
/// </summary>
/// <returns></returns>
bool CheckHomeProcess_HW_Available(Boolean needHomeSet)
{
//모션이 초기화되지 않았다면 오류로 한다
if (PUB.mot.IsInit == false)
{
PUB.Result.SetResultMessage(eResult.MOTION, eECode.AZJINIT, eNextStep.NOTHING);
return false;
}
//모든 홈이 되어야 가능하다
if (needHomeSet)
{
if (PUB.mot.IsInit && PUB.mot.HasHomeSetOff == true)
{
PUB.Result.SetResultMessage(eResult.MOTION, eECode.MOT_HSET, eNextStep.ERROR);
return false;
}
}
//안전센서가 작동했다면 중지한다.
if (DIO.isSaftyDoorF(true) == false || DIO.isSaftyDoorR() == false)
{
PUB.Result.SetResultMessage(eResult.SAFTY, eECode.DOORSAFTY, eNextStep.ERROR);
return false;
}
//모션모델이 반드시 설정되어있어야 한다
if (PUB.Result.isSetmModel == false)
{
PUB.Result.SetResultMessage(eResult.MOTION, eECode.NOMODELM, eNextStep.ERROR);
return false;
}
//AIR확인
if (DIO.GetIOOutput(eDOName.SOL_AIR) == false)
{
PUB.Result.SetResultMessage(eResult.SENSOR, eECode.AIRNOOUT, eNextStep.ERROR);
return false;
}
// 비상정지 확인
if (DIO.IsEmergencyOn() == true)
{
PUB.Result.SetResultMessage(eResult.SAFTY, eECode.EMERGENCY, eNextStep.ERROR);
return false;
}
return true;
}
}
}

View File

@@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
namespace Project
{
public partial class FMain
{
}
}

View File

@@ -0,0 +1,46 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
namespace Project
{
public partial class FMain
{
/// <summary>
/// 프로그램을 닫을때 1회 실행되는 함수
/// </summary>
private void _Close_Start()
{
//연결체크용 쓰레드 종료
bRunConnection = false;
this.thConnection.Abort();
//Light off 220714
DIO.SetRoomLight(false, true);
//Pub.dio.SetOutput((int)eDOName.ABRUN, false); //stop mgz loader a/c motor
PUB.log.Add("Program Close");
PUB.LogFlush();
//키엔트추가 210114
if(PUB.keyenceF != null)
{
PUB.keyenceF.ExecCommand("QUIT");
PUB.keyenceF.Dispose();
}
if(PUB.keyenceR != null)
{
PUB.keyenceR.ExecCommand("QUIT");
PUB.keyenceR.Dispose();
}
PUB.dio.StopMonitor();
PUB.mot.StopMonitor();
PUB.sm.Stop();
}
}
}

View File

@@ -0,0 +1,84 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using AR;
namespace Project
{
public partial class FMain
{
public Boolean[] DisableMotion;
private void Mot_PositionChanged(object sender, arDev.MOT.PositionChangeEventArgs e)
{
eAxis mot = (eAxis)e.Axis;
if (mot == eAxis.PX_PICK)
{
}
//모터 위치가 변경되면 로더 컨트롤에 입력한다
hmi1.arMotorPosition[e.Axis] = e.Actual;
}
void mot_StatusChanged(object sender, arDev.MOT.StatusChangeEventArags e)
{
if (e.Axis >= SETTING.System.MotaxisCount) return;
if (e.Status == arDev.MOT.MOTION_STATUS.SERVOALARM) hmi1.arMOT_Alm[e.Axis] = e.Value;
else if (e.Status == arDev.MOT.MOTION_STATUS.LIMITN) hmi1.arMOT_LimDn[e.Axis] = e.Value;
else if (e.Status == arDev.MOT.MOTION_STATUS.LIMITP) hmi1.arMOT_LimUp[e.Axis] = e.Value;
else if (e.Status == arDev.MOT.MOTION_STATUS.ORIGIN) hmi1.arMOT_Origin[e.Axis] = e.Value;
else if (e.Status == arDev.MOT.MOTION_STATUS.SERVROON) hmi1.arMOT_SVOn[e.Axis] = e.Value;
}
private void Mot_EndStatusChanged(object sender, arDev.MOT.EndStatusChangeEventArgs e)
{
if (AR.SETTING.Data.Enable_Log_MotStopReason == false) return; //210112
var bitstatus = Convert.ToString(e.Value, 2).PadLeft(16, '0');
List<FS_END_STATUS> lst = new List<FS_END_STATUS>();
for (byte i = 0; i < 15; i++)
{
var offset = (ushort)(Math.Pow(2, i));
if ((e.Value & offset) > 0) lst.Add((FS_END_STATUS)offset);
}
var reason = string.Join(",", lst);
PUB.log.Add("MOT", $"Motor stop reason ({e.axis}): {reason}: bit={bitstatus}");
}
void mot_HomeStatusChanged(object sender, arDev.MOT.HomeStatusChangeEventArgs e)
{
if (PUB.sm.Step == eSMStep.HOME_FULL)
{
hmi1.arHomeProgress[e.Axis] = e.Progress;
if (e.NewStatus == arDev.MOT.HOME_RESULT.HOME_ERR_NOT_DETECT)
{
//홈 검색시 오류가 발생했다 사용자에게 알림을 해야 함
PUB.Result.SetResultMessage(eResult.MOTION, eECode.MOT_HSET, eNextStep.ERROR, e.Axis);
}
else if (e.NewStatus == arDev.MOT.HOME_RESULT.HOME_SUCCESS)
{
PUB.log.AddI(string.Format("Home search completed for axis: {0}", e.Axis));
}
}
}
void mot_Message(object sender, arDev.MOT.MessageEventArgs e)
{
if (e.IsError)
{
if (e.Message.IndexOf("same position") != -1 || e.Message.IndexOf("inposition") != -1)
{ // Pub.log.AddAT("MOT:" + e.Message);
}
else PUB.log.AddE("MOT:" + e.Message);
}
else PUB.log.Add("MOT:" + e.Message);
}
}
}

View File

@@ -0,0 +1,202 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using AR;
namespace Project
{
public partial class FMain
{
bool[] runStepisFirst = new bool[] { false, false };
#region "Is Can Pick On/Off"
Boolean isCanPLPickOn()
{
//아이템을 가지고 있으면 안된다.
if (PUB.flag.get(eVarBool.FG_PL_ITEMON)) return false;
//Y축이 집는 위치가 아니면 빠져나감
var Pos = MOT.getPositionMatch(MOT.GetLMPos(eLMLoc.READY));// MOT.GetPLM_PosName();
if (Pos) return false;
return true;
}
Boolean isCanPRPickOn()
{
//아이템을 가지고 있으면 안된다.
if (PUB.flag.get(eVarBool.FG_PR_ITEMON)) return false;
//Y축이 집는 위치가 아니면 빠져나감
var Pos = MOT.getPositionMatch(MOT.GetRMPos(eRMLoc.READY));// MOT.GetPRM_PosName();
if (Pos) return false;
return true;
}
Boolean isCanPLPickOff()
{
//아이템이 없으면 불가
if (PUB.flag.get(eVarBool.FG_PL_ITEMON) == false) return false;
//Y축 위치 확인
var PosH07 = MOT.getPositionMatch(MOT.GetLMPos(eLMLoc.PRINTH07));
var PosM07 = MOT.getPositionMatch(MOT.GetLMPos(eLMLoc.PRINTM07));
var PosL07 = MOT.getPositionMatch(MOT.GetLMPos(eLMLoc.PRINTL07));
var PosH13 = MOT.getPositionMatch(MOT.GetLMPos(eLMLoc.PRINTH13));
var PosM13 = MOT.getPositionMatch(MOT.GetLMPos(eLMLoc.PRINTM13));
var PosL13 = MOT.getPositionMatch(MOT.GetLMPos(eLMLoc.PRINTL13));
if (PosH07 && PosM07 && PosL07 && PosH13 && PosM13 && PosL13) return false;
//포트가 준비되지않았거나, 감지가 안되었다면 진행 불가
if (PUB.flag.get(eVarBool.FG_RDY_PORT_PL) == false || hmi1.arVar_Port[0].AlignOK != 1) return false;
return true;
}
Boolean isCanPRPickOff()
{
//아이템이 없으면 불가
if (PUB.flag.get(eVarBool.FG_PR_ITEMON) == false) return false;
//Y축 위치 확인
var PosH07 = MOT.getPositionMatch(MOT.GetRMPos(eRMLoc.PRINTH07));
var PosM07 = MOT.getPositionMatch(MOT.GetRMPos(eRMLoc.PRINTM07));
var PosL07 = MOT.getPositionMatch(MOT.GetRMPos(eRMLoc.PRINTL07));
var PosH13 = MOT.getPositionMatch(MOT.GetRMPos(eRMLoc.PRINTH13));
var PosM13 = MOT.getPositionMatch(MOT.GetRMPos(eRMLoc.PRINTM13));
var PosL13 = MOT.getPositionMatch(MOT.GetRMPos(eRMLoc.PRINTL13));
if (PosH07 && PosM07 && PosL07 && PosH13 && PosM13 && PosL13) return false;
//포트가 준비되지않았거나, 감지가 안되었다면 진행 불가
if (PUB.flag.get(eVarBool.FG_RDY_PORT_PR) == false || hmi1.arVar_Port[2].AlignOK != 1) return false;
return true;
}
Boolean isCanPickOffL()
{
//아이템이 없으면 불가
if (PUB.flag.get(eVarBool.FG_PK_ITEMON) == false) return false;
//Y축 위치 확인
if (MOT.getPositionMatch(MOT.GetPXPos(ePXLoc.PICKOFFL)) == false) return false;
//포트가 준비되지않았거나, 감지가 안되었다면 진행 불가
if (PUB.flag.get(eVarBool.FG_RDY_PORT_PL) == false || hmi1.arVar_Port[0].AlignOK != 1) return false;
return true;
}
Boolean isCanPickOn()
{
//아이템을 가지고 있으면 안된다.
if (PUB.flag.get(eVarBool.FG_PK_ITEMON)) return false;
//Y축이 집는 위치가 아니면 빠져나감
if (MOT.getPositionMatch(MOT.GetPXPos(ePXLoc.PICKON)) == false) return false;
//포트가 준비되어 있지 않다면 가져갈수 없다
if (PUB.Result.DryRun == false && (PUB.flag.get(eVarBool.FG_RDY_PORT_PC) == false || hmi1.arVar_Port[1].AlignOK != 1)) return false;
return true;
}
Boolean isCanPickOffR()
{
//아이템이 없으면 불가
if (PUB.flag.get(eVarBool.FG_PK_ITEMON) == false) return false;
//Y축 위치 확인
if (MOT.getPositionMatch(MOT.GetPXPos(ePXLoc.PICKOFFR)) == false) return false;
//포트가 준비되지않았거나, 감지가 안되었다면 진행 불가
if (PUB.flag.get(eVarBool.FG_RDY_PORT_PR) == false || hmi1.arVar_Port[2].AlignOK != 1) return false;
return true;
}
#endregion
bool CheckPauseCondition(Boolean lightCheck)
{
//비상정지체크
if (DIO.IsEmergencyOn() == true || PUB.mot.HasEmergencyStop)
{
//이것은 SPS에서 추가로 처리된다
PUB.Result.SetResultMessage(eResult.EMERGENCY, eECode.EMERGENCY, eNextStep.NOTHING);// false);
return false;
}
//홈이 잡혀잇는지 체크한다
if (PUB.mot.HasHomeSetOff == true)
{
PUB.Result.SetResultMessage(eResult.MOTION, eECode.MOT_HSET, eNextStep.ERROR);
return false;
}
if (lightCheck == false)
{
//안전센서체크
if (DIO.isSaftyDoorF() == false)
{
PUB.Result.SetResultMessage(eResult.EMERGENCY, eECode.DOORSAFTY, eNextStep.PAUSE);// false);
PUB.mot.MoveStop("Safety issue", true);
if (DIO.isSaftyDoorF(0, false) == false) DIO.SetPortMotor(0, eMotDir.CW, false, "Safety error");
if (DIO.isSaftyDoorF(1, false) == false) DIO.SetPortMotor(1, eMotDir.CW, false, "Safety error");
if (DIO.isSaftyDoorF(2, false) == false) DIO.SetPortMotor(2, eMotDir.CW, false, "Safety error");
return false;
}
//에어공급출력체크
if (AR.SETTING.Data.DisableSensor_AIRCheck == false && DIO.GetIOOutput(eDOName.SOL_AIR) == false)
{
PUB.Result.SetResultMessage(eResult.HARDWARE, eECode.AIRNOOUT, eNextStep.PAUSE);//false);
return false;
}
//오버로드체크
if (hmi1.arVar_Port[0].OverLoad)
{
PUB.Result.SetResultMessage(eResult.SENSOR, eECode.PORTOVERLOAD, eNextStep.PAUSE, new object[] { "FRONT-LEFT" });
return false;
}
}
return true;
}
Boolean isPortLimDN(int idx)
{
if (idx < 0 || idx > 2) throw new Exception("Port number must be between (0~2)");
if (idx == 0) return DIO.GetIOInput(eDIName.PORTL_LIM_DN);
else if (idx == 1) return DIO.GetIOInput(eDIName.PORTC_LIM_DN);
else return DIO.GetIOInput(eDIName.PORTR_LIM_DN);
}
Boolean isPortLimUP(int idx)
{
if (idx < 0 || idx > 2) throw new Exception("Port number must be between (0~2)");
if (idx == 0) return DIO.GetIOInput(eDIName.PORTL_LIM_UP);
else if (idx == 1) return DIO.GetIOInput(eDIName.PORTC_LIM_UP);
else return DIO.GetIOInput(eDIName.PORTR_LIM_UP);
}
Boolean isPortDetUp(int idx)
{
if (idx < 0 || idx > 2) throw new Exception("Port number must be between (0~2)");
if (idx == 0) return DIO.GetIOInput(eDIName.PORTL_DET_UP);
else if (idx == 1) return DIO.GetIOInput(eDIName.PORTC_DET_UP);
else return DIO.GetIOInput(eDIName.PORTR_DET_UP);
}
}//cvass
}

View File

@@ -0,0 +1,381 @@
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WatsonWebsocket;
using AR;
namespace Project
{
public partial class FMain
{
//DateTime lastRecvWSL = new DateTime(1982, 11, 23);
//DateTime lastRecvWSR = new DateTime(1982, 11, 23);
string lastBarcodeRawL = string.Empty;
string lastBarcodeRawR = string.Empty;
void AttachCameraEventL()
{
//크레비스오픈 - 210203
//PUB.log.Add("카메라 이벤트 생성");
PUB.wsL.MessageReceived += Ws_DataArrivalL;
PUB.wsL.ServerConnected += Ws_ConnectedL;
PUB.wsL.ServerDisconnected += Ws_DisconnectedL;
}
void DetachCameraEventL()
{
//크레비스오픈 - 210203
//PUB.log.Add("카메라 이벤트 해제");
PUB.wsL.MessageReceived -= Ws_DataArrivalL;
PUB.wsL.ServerConnected -= Ws_ConnectedL;
PUB.wsL.ServerDisconnected -= Ws_DisconnectedL;
}
void AttachCameraEventR()
{
//크레비스오픈 - 210203
//if (COMM.SETTING.Data.Log_CameraConn) PUB.log.Add("카메라 이벤트 생성");
PUB.wsR.MessageReceived += Ws_DataArrivalR;
PUB.wsR.ServerConnected += Ws_ConnectedR;
PUB.wsR.ServerDisconnected += Ws_DisconnectedR;
}
void DetachCameraEventR()
{
//크레비스오픈 - 210203
//if (COMM.SETTING.Data.Log_CameraConn) PUB.log.Add("카메라 이벤트 해제");
PUB.wsR.MessageReceived -= Ws_DataArrivalR;
PUB.wsR.ServerConnected -= Ws_ConnectedR;
PUB.wsR.ServerDisconnected -= Ws_DisconnectedR;
}
private void Ws_DisconnectedL(object sender, EventArgs e)
{
var ws = sender as WatsonWebsocket.WatsonWsClient;
PUB.log.AddAT("Camera L connection terminated");
//_isCrevisOpen[0] = false;
PUB.flag.set(eVarBool.FG_RDY_CAMERA_L, false, "DISC");
}
private void Ws_ConnectedL(object sender, EventArgs e)
{
PUB.log.AddAT("Camera L connection successful");
//_isCrevisOpen[0] = true;
}
private void Ws_DisconnectedR(object sender, EventArgs e)
{
var ws = sender as WatsonWebsocket.WatsonWsClient;
PUB.log.AddAT("Camera R connection terminated");
//_isCrevisOpen[2] = false;
PUB.flag.set(eVarBool.FG_RDY_CAMERA_R, false, "DISC");
}
private void Ws_ConnectedR(object sender, EventArgs e)
{
PUB.log.AddAT("Camera R connection successful");
//_isCrevisOpen[2] = true;
}
private void Ws_DataArrivalL(object sender, MessageReceivedEventArgs e)
{
Ws_DataArrival(0, sender as WatsonWsClient, e);
}
private void Ws_DataArrivalR(object sender, MessageReceivedEventArgs e)
{
Ws_DataArrival(1, sender as WatsonWsClient, e);
}
private void Ws_DataArrival(int idx, WatsonWsClient ws, MessageReceivedEventArgs e)
{
//throw new NotImplementedException();
var data = Encoding.UTF8.GetString(e.Data);// Pub.ws.Get<String>();
if (idx == 0) VAR.TIME[eVarTime.lastRecvWSL] = DateTime.Now;
else VAR.TIME[eVarTime.lastRecvWSR] = DateTime.Now;
if (data.Contains("\"command\":\"status"))
{
//PUB.logVision.Add($"[{idx}]상태메세지수신");
//PUB.logVision.Flush();
try
{
var jsondata = JObject.Parse(data);
var msgdata = new
{
command = jsondata.Value<String>("command"),
camera = jsondata.Value<String>("camera"),
live = jsondata.Value<String>("live"),
stream = jsondata.Value<String>("stream"),
listen = jsondata.Value<String>("listen"),
trig = jsondata.Value<String>("trig"),
license = jsondata.Value<String>("license"),
reel = jsondata.Value<String>("reel"),
conv = jsondata.Value<String>("conv"),
};
if (idx == 0)
{
PUB.flag.set(eVarBool.VS_DETECT_REEL_L, (msgdata.reel == "1"), "WS");
PUB.flag.set(eVarBool.VS_DETECT_CONV_L, (msgdata.conv == "1"), "WS");
}
else
{
PUB.flag.set(eVarBool.VS_DETECT_REEL_R, (msgdata.reel == "1"), "WS");
PUB.flag.set(eVarBool.VS_DETECT_CONV_R, (msgdata.conv == "1"), "WS");
}
if (msgdata.license == "1" && msgdata.camera == "1")
{
if (idx == 0)
{
if(PUB.flag.get(eVarBool.FG_RDY_CAMERA_L)==false)
{
PUB.flag.set(eVarBool.FG_RDY_CAMERA_L, true, "WEBSOCKET");
PUB.log.Add("Left camera ready");
}
}
else
{
if (PUB.flag.get(eVarBool.FG_RDY_CAMERA_R) == false)
{
PUB.flag.set(eVarBool.FG_RDY_CAMERA_R, true, "WEBSOCKET");
PUB.log.Add("Right camera ready");
}
}
}
else
{
if (idx == 0) PUB.flag.set(eVarBool.FG_RDY_CAMERA_L, false, "WEBSOCKET");
else PUB.flag.set(eVarBool.FG_RDY_CAMERA_R, false, "WEBSOCKET");
}
}
catch (Exception ex)
{
PUB.log.AddE("Status message analysis failed: " + ex.Message);
}
}
else
{
//처리가능한 상황에서만 큐에 데이터를 넣는다
if (idx == 0 && PUB.flag.get(eVarBool.FG_PRC_VISIONL) == false)
{
PUB.log.AddAT("Left side vision not in verification state, deleting barcode data\n" + data);
return;
}
if (idx != 0 && PUB.flag.get(eVarBool.FG_PRC_VISIONR) == false)
{
PUB.log.AddAT("Right side vision not in verification state, deleting barcode data\n" + data);
return;
}
PUB.log.Add($"QR verification ({(idx == 0 ? "L" : "R")}) received: " + data);
var guid = idx == 0 ? PUB.Result.ItemDataL.guid : PUB.Result.ItemDataR.guid;
//BarcodeParsing(idx, guid, data, "WS");
var qrDataList = ProcessRecvBarcodeData(idx, data);
if (qrDataList.Count > 0) //바코드데이터가 존재 했다
{
//처리가 완료되지 않은경우엠ㄴ 사용한다.
if (idx == 0)
{
if (PUB.flag.get(eVarBool.FG_END_VISIONL) == false)
{
var Complete = RecvQRProcess(qrDataList, eWorkPort.Left);
if (Complete) PUB.flag.set(eVarBool.FG_END_VISIONL, true, "DATA_ARRIVAL");
}
else PUB.log.AddAT("Vision (L) previous task completed, not processing");
}
else
{
if (PUB.flag.get(eVarBool.FG_END_VISIONR) == false)
{
var Complete = RecvQRProcess(qrDataList, eWorkPort.Right);
if (Complete) PUB.flag.set(eVarBool.FG_END_VISIONR, true, "DATA_ARRIVAL");
}
else PUB.log.AddAT("Vision (R) previous task completed, not processing");
}
}
}
}
//바코드 원본의 데이터큐
//ConcurrentQueue<string> BarcodeQueL = new ConcurrentQueue<string>();
//ConcurrentQueue<string> BarcodeQueR = new ConcurrentQueue<string>();
//bool BarcodeParsing(int idx, string guid, string jsonstr, string source, Boolean force = false)
//{
// //값이있다면 바코드 큐에 집어 넣는다.
// if (idx == 0)
// {
// lastBarcodeRawL = jsonstr;
// lock (BarcodeQueL)
// BarcodeQueL.Enqueue(jsonstr);
// }
// else
// {
// lastBarcodeRawR = jsonstr;
// lock (BarcodeQueR)
// BarcodeQueR.Enqueue(jsonstr);
// }
// return true;
//}
//DateTime WSLLastRecv = DateTime.Now;
//DateTime WSRLastRecv = DateTime.Now;
bool WS_Send(eWorkPort idx, WatsonWebsocket.WatsonWsClient ws, string guid, string cmd,string data)
{
if (ws == null) return false;
//데이터 생성
var msg = new
{
guid = guid,
command = cmd,
data = data
};
var json = Newtonsoft.Json.JsonConvert.SerializeObject(msg);
Boolean sendok = false;
try
{
//PUB.log.Add($"전송({idx}),ID:{guid},명령:{cmd}");
ws.SendAsync(json);
sendok = true;
}
catch (Exception ex)
{
PUB.log.AddE($"Transmission {idx} failed {ex.Message}");
sendok = false;
}
if (sendok == false)
{
try
{
if (idx == 0) CameraConTimeL = DateTime.Now;
else CameraConTimeR = DateTime.Now;
if(ws != null)
{
PUB.log.AddAT($"Closing socket due to transmission {idx} failure");
ws.Stop();
}
}
catch (Exception ex)
{
PUB.log.AddE($"Socket {idx} termination failed: {ex.Message}");
}
}
return sendok;
}
//System.Diagnostics.Stopwatch wat = new System.Diagnostics.Stopwatch();
//System.Diagnostics.Stopwatch wat0 = new System.Diagnostics.Stopwatch();
//System.Diagnostics.Stopwatch wat1 = new System.Diagnostics.Stopwatch();
//System.Diagnostics.Stopwatch wat2 = new System.Diagnostics.Stopwatch();
/// <summary>
/// 바코드큐에있는 데이터를 분석하고 시작한다.
/// </summary>
/// <param name="Idx"></param>
/// <param name="Process"></param>
/// <returns></returns>
List<string> ProcessRecvBarcodeData(int vIdx, string JsonStr)
{
//PUB.logVision.Add($"[{vIdx}]ProcessBarcodeQue");
//PUB.logVision.Flush();
List<string> retval = new List<string>();
if (JsonStr.isEmpty())
{
PUB.log.AddE("Cannot proceed due to missing barcode receive value (JSON)");
return retval;
}
if (vIdx == 0)
lastBarcodeRawL = JsonStr;
else
lastBarcodeRawR = JsonStr;
try
{
//모델에서 고정값을 입력한게 있다면 그것을 사용한다
var itemC = PUB.Result.ItemDataC;
if (itemC.VisionData.VNAME.isEmpty() && PUB.Result.vModel.Def_Vname.isEmpty() == false)
{
itemC.VisionData.VNAME = PUB.Result.vModel.Def_Vname;
itemC.VisionData.VNAME_Trust = true;
PUB.log.Add($"Defaul V.Name Set to {PUB.Result.vModel.Def_Vname}");
}
if (itemC.VisionData.MFGDATE.isEmpty() && PUB.Result.vModel.Def_MFG.isEmpty() == false)
{
itemC.VisionData.MFGDATE = PUB.Result.vModel.Def_MFG;
itemC.VisionData.MFGDATE_Trust = true;
PUB.log.Add($"Defaul MFGDATE Set to {PUB.Result.vModel.Def_MFG}");
}
var jsondata = JObject.Parse(JsonStr);
var msgdata = new
{
guid = jsondata.Value<String>("guid"),
command = jsondata.Value<String>("command"),
data = jsondata.Value<String>("data[]"),
time = jsondata.Value<String>("time"),
file = jsondata.Value<String>("file")
};
var datas = jsondata.GetValue("data");
if (datas.Type == JTokenType.String)
{
var bcdstr = datas.ToString();
//새로운 바코드라면 추가한다
if (retval.Contains(bcdstr) == false)
retval.Add(bcdstr);
}
else
{
//데이터가 배열로 들어있는 경우이다
foreach (var data in datas)
{
var dataarr = new
{
barcode = data.ToString()
};
if (dataarr.barcode.isEmpty()) continue;
if (retval.Contains(dataarr.barcode) == false)
retval.Add(dataarr.barcode);
}
}
//입력된 바코드 데이터를 확인한다.
//각 데이터는 아래처럼 변수에 추가를 해줘야ㅏ한ㄷ.ㅏ
//ImageProcessResult[vIdx].Add(item.data);
}
catch (Exception ex)
{
PUB.logVision.Add($"Camera ({vIdx}) ProcessBarcodeQue failed {ex.Message}"); PUB.logVision.Flush();
}
return retval;
}
}
}