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", "")}"); ParseBarcode(e.RawData, 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; /// /// 키엔스로부터 받은 데이터를 분석한다. /// /// /// 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); } } } } }