 9a7d1d27c7
			
		
	
	9a7d1d27c7
	
	
	
		
			
			- UIControl 프로젝트 구조 변경 (CapCleaningControl → Sub/UIControl) - arAjinextek 라이브러리 통합 및 구조 개선 - 새로운 arAjinextek_Union 프로젝트 추가 - 솔루션 파일에 README.md 추가 - QR 모드에서 WMS RCV 태그 인식 기능 강화 - 데이터베이스 스키마 업데이트 및 관련 클래스 수정 - 프린터 및 바코드 장치 연동 로직 개선 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
		
			
				
	
	
		
			349 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			349 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| using System;
 | |
| using System.Collections.Generic;
 | |
| using System.ComponentModel;
 | |
| using System.Data;
 | |
| using System.Drawing;
 | |
| using System.Linq;
 | |
| using System.Security.Cryptography.X509Certificates;
 | |
| using System.Text;
 | |
| using System.Windows.Forms;
 | |
| using AR;
 | |
| 
 | |
| namespace Project.Dialog
 | |
| {
 | |
|     public partial class fswPLC : Form
 | |
|     {
 | |
|       
 | |
|      //   byte[] buffer = new byte[16];
 | |
| 
 | |
|         public fswPLC()
 | |
|         {
 | |
|             InitializeComponent();
 | |
|             this.Text = $"{Application.ProductName} ver {Application.ProductVersion}";
 | |
|             PUB.log.RaiseMsg += (p1, p2, p3) => { this.logTextBox1.AddMsg(p1, p2, p3); };
 | |
|             this.FormClosing += (s1, e2) =>
 | |
|             {
 | |
|                 timer1.Stop();
 | |
|             };
 | |
| 
 | |
|             this.logTextBox1.ColorList = new arCtl.sLogMessageColor[] {
 | |
|                 new arCtl.sLogMessageColor("NORM",Color.Yellow),
 | |
|                 new arCtl.sLogMessageColor("ERR",Color.Red),
 | |
|                 new arCtl.sLogMessageColor("WARN",Color.Tomato),
 | |
|                 new arCtl.sLogMessageColor("INFO",Color.LightSkyBlue)
 | |
|             };
 | |
| 
 | |
|             List<string> piname = new List<String>();
 | |
|             List<string> titles = new List<String>();
 | |
|             List<bool> values = new List<bool>();
 | |
| 
 | |
|             titles.AddRange(new string[] {
 | |
|                 "Upper Limit","Reel Detect","Lower Limit",
 | |
|                 "Motor Direction(1=DN,0=UP)","Motor Run","Emergency",
 | |
|             });
 | |
|             piname.AddRange(new string[] {
 | |
|                 "X"+((int)eDIName.PORTL_LIM_UP).ToString("X2"),
 | |
|                 "X"+((int)eDIName.PORTL_DET_UP).ToString("X2"),
 | |
|                 "X"+((int)eDIName.PORTL_LIM_DN).ToString("X2"),
 | |
|                 "Y"+((int)eDOName.PORTL_MOT_DIR).ToString("X2"),
 | |
|                 "Y"+((int)eDOName.PORTL_MOT_RUN).ToString("X2"),"--"
 | |
|             });
 | |
| 
 | |
|             titles.AddRange(new string[] {
 | |
|                 "Upper Limit","Reel Detect","Lower Limit",
 | |
|                 "Motor Direction(1=DN,0=UP)","Motor Run","--",
 | |
|             });
 | |
|             piname.AddRange(new string[] {
 | |
|                 "X"+((int)eDIName.PORTC_LIM_UP).ToString("X2"),
 | |
|                 "X"+((int)eDIName.PORTC_DET_UP).ToString("X2"),
 | |
|                 "X"+((int)eDIName.PORTC_LIM_DN).ToString("X2"),
 | |
|                 "Y"+((int)eDOName.PORTC_MOT_DIR).ToString("X2"),
 | |
|                 "Y"+((int)eDOName.PORTC_MOT_RUN).ToString("X2"),"--"
 | |
|             });
 | |
| 
 | |
| 
 | |
|             titles.AddRange(new string[] {
 | |
|                 "Upper Limit","Reel Detect","Lower Limit",
 | |
|                 "Motor Direction(1=DN,0=UP)","Motor Run","--"
 | |
|             });
 | |
|             piname.AddRange(new string[] {
 | |
|                 "X"+((int)eDIName.PORTR_LIM_UP).ToString("X2"),
 | |
|                 "X"+((int)eDIName.PORTR_DET_UP).ToString("X2"),
 | |
|                 "X"+((int)eDIName.PORTR_LIM_DN).ToString("X2"),
 | |
|                 "Y"+((int)eDOName.PORTR_MOT_DIR).ToString("X2"),
 | |
|                 "Y"+((int)eDOName.PORTR_MOT_RUN).ToString("X2"),"--"
 | |
|             });
 | |
| 
 | |
|             for (int i = 0; i < titles.Count; i++)
 | |
|                 values.Add(false);
 | |
| 
 | |
|             ioPanel1.ColorList = new arDev.AjinEXTEK.UI.ColorListItem[] {
 | |
|                 new arDev.AjinEXTEK.UI.ColorListItem{ BackColor1 = Color.DimGray, BackColor2 = Color.FromArgb(30,30,30), Remark="False" },
 | |
|                 new arDev.AjinEXTEK.UI.ColorListItem{ BackColor1 = Color.Lime, BackColor2 = Color.Green, Remark="True" },
 | |
|             };
 | |
| 
 | |
|             this.ioPanel1.setTitle(titles.ToArray());
 | |
|             this.ioPanel1.setNames(piname.ToArray());
 | |
|             this.ioPanel1.setValue(values.ToArray());
 | |
|             this.ioPanel1.Invalidate();
 | |
| 
 | |
|             //내부버퍼확인
 | |
|             titles.Clear();
 | |
|             piname.Clear();
 | |
|             var valueb = new List<ushort>();
 | |
|             for (int i = 0; i < 16; i++)
 | |
|             {
 | |
|                 var addr = (eswPLCAddr)i;
 | |
|                 piname.Add(i.ToString("X2"));
 | |
|                 titles.Add(addr.ToString());
 | |
|                 valueb.Add(0);
 | |
|             }
 | |
| 
 | |
|             gridView1.ColorList = new arCtl.GridView.ColorListItem[] {
 | |
|                 new arCtl.GridView.ColorListItem{ BackColor1 = Color.DimGray, BackColor2 = Color.FromArgb(30,30,30), Remark="False" },
 | |
|                 new arCtl.GridView.ColorListItem{ BackColor1 = Color.Lime, BackColor2 = Color.Green, Remark="True" },
 | |
|             };
 | |
|             this.gridView1.setTitle(titles.ToArray());
 | |
|             this.gridView1.setNames(piname.ToArray());
 | |
|             this.gridView1.setValue(valueb.ToArray());
 | |
|             this.gridView1.ShowValueString = true;
 | |
|             this.gridView1.ShowNameString = true;
 | |
|             this.gridView1.ShowIndexString = false;
 | |
|             this.gridView1.Invalidate();
 | |
| 
 | |
|         }
 | |
| 
 | |
|         private void Form1_Load(object sender, EventArgs e)
 | |
|         {
 | |
|             PUB.log.AddI("프로그램시작");
 | |
|             PUB.plc.ValueChanged += Plc_ValueChanged;
 | |
|             ioPanel1.ItemClick += IoPanel1_ItemClick;
 | |
|             timer1.Start();
 | |
|         }
 | |
| 
 | |
|         private void Plc_ValueChanged(object sender, AR.MemoryMap.Core.monitorvalueargs e)
 | |
|         {
 | |
| 
 | |
|         }
 | |
|         private void Dio_IOValueChanged(object sender, arDev.DIO.IOValueEventArgs e)
 | |
|         {
 | |
|             if (e.Direction == arDev.DIO.eIOPINDIR.INPUT)
 | |
|             {
 | |
|                 var pin = (eDIName)e.ArrIDX;
 | |
| 
 | |
|                 //센서가 활성화될때는 이값을 설정해준다
 | |
|                 //나머지조건은 autocontrol 에서 처리된다.
 | |
|                 if (e.NewValue)
 | |
|                 {
 | |
|                     if (pin == eDIName.PORTL_LIM_DN) WriteBuffer(eswPLCAddr.LPort, 1);
 | |
|                     else if (pin == eDIName.PORTL_DET_UP) WriteBuffer(eswPLCAddr.LPort, 2);
 | |
|                     else if (pin == eDIName.PORTL_LIM_UP) WriteBuffer(eswPLCAddr.LPort, 3);
 | |
| 
 | |
|                     else if (pin == eDIName.PORTC_LIM_DN) WriteBuffer(eswPLCAddr.CPort, 1);
 | |
|                     else if (pin == eDIName.PORTC_DET_UP) WriteBuffer(eswPLCAddr.CPort, 2);
 | |
|                     else if (pin == eDIName.PORTC_LIM_UP) WriteBuffer(eswPLCAddr.CPort, 3);
 | |
| 
 | |
|                     else if (pin == eDIName.PORTR_LIM_DN) WriteBuffer(eswPLCAddr.RPort, 1);
 | |
|                     else if (pin == eDIName.PORTR_DET_UP) WriteBuffer(eswPLCAddr.RPort, 2);
 | |
|                     else if (pin == eDIName.PORTR_LIM_UP) WriteBuffer(eswPLCAddr.RPort, 3);
 | |
|                 }
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 var pin = (eDOName)e.ArrIDX;
 | |
| 
 | |
|                 if (pin == eDOName.PORTL_MOT_RUN)
 | |
|                 {
 | |
|                     if (e.NewValue == false) WriteBuffer(eswPLCAddr.LMotor, 3);
 | |
|                     else
 | |
|                     {
 | |
|                         //방향을 확인해야한다
 | |
|                         var value = GetDOValue(eDOName.PORTL_MOT_DIR) ? 2 : 1;
 | |
|                         WriteBuffer(eswPLCAddr.LMotor, (byte)value);
 | |
|                     }
 | |
|                 }
 | |
|                 else if (pin == eDOName.PORTC_MOT_RUN)
 | |
|                 {
 | |
|                     if (e.NewValue == false) WriteBuffer(eswPLCAddr.CMotor, 3);
 | |
|                     else
 | |
|                     {
 | |
|                         //방향을 확인해야한다
 | |
|                         var value = GetDOValue(eDOName.PORTC_MOT_DIR) ? 2 : 1;
 | |
|                         WriteBuffer(eswPLCAddr.CMotor, (byte)value);
 | |
|                     }
 | |
|                 }
 | |
|                 else if (pin == eDOName.PORTR_MOT_RUN)
 | |
|                 {
 | |
|                     if (e.NewValue == false) WriteBuffer(eswPLCAddr.RMotor, 3);
 | |
|                     else
 | |
|                     {
 | |
|                         //방향을 확인해야한다
 | |
|                         var value = GetDOValue(eDOName.PORTR_MOT_DIR) ? 2 : 1;
 | |
|                         WriteBuffer(eswPLCAddr.RMotor, (byte)value);
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
|         private void IoPanel1_ItemClick(object sender, arDev.AjinEXTEK.UI.IOPanel.ItemClickEventArgs e)
 | |
|         {
 | |
|             var name = this.ioPanel1.Names[e.idx];
 | |
|             if (name.StartsWith("Y"))
 | |
|             {
 | |
|                 var pinno = Convert.ToInt32(name.Substring(1), 16);
 | |
|                 var pin = (eDOName)pinno;
 | |
|                 var cur = GetDOValue(pin);
 | |
|                 DIO.SetOutput(pin, !cur);
 | |
|                 PUB.log.Add($"value change [X{pinno:X2}] {pin} to {!cur}");
 | |
|             }
 | |
|         }
 | |
|         bool GetDOValue(eDOName pin)
 | |
|         {
 | |
|             return PUB.dio.GetDOValue((int)pin);
 | |
|         }
 | |
|         bool GetDIValue(eDIName pin)
 | |
|         {
 | |
|             if (pin == eDIName.PORTL_LIM_DN || pin == eDIName.PORTC_LIM_DN || pin == eDIName.PORTR_LIM_DN)
 | |
|             {
 | |
|                 return !PUB.dio.GetDIValue((int)pin);
 | |
|             }
 | |
|             else if (pin == eDIName.PORTL_LIM_UP || pin == eDIName.PORTC_LIM_UP || pin == eDIName.PORTR_LIM_UP)
 | |
|             {
 | |
|                 return !PUB.dio.GetDIValue((int)pin);
 | |
|             }
 | |
|             else if (pin == eDIName.PORTL_DET_UP || pin == eDIName.PORTC_DET_UP || pin == eDIName.PORTR_DET_UP)
 | |
|             {
 | |
|                 return !PUB.dio.GetDIValue((int)pin);
 | |
|             }
 | |
|             else if (pin == eDIName.BUT_EMGF)
 | |
|             {
 | |
|                 return !PUB.dio.GetDIValue((int)pin);
 | |
|             }
 | |
|             else return PUB.dio.GetDIValue((int)pin);
 | |
|         }
 | |
| 
 | |
|         public enum eMotList
 | |
|         {
 | |
|             Left = 0,
 | |
|             Center,
 | |
|             Right,
 | |
|         }
 | |
|         public enum eMotControl
 | |
|         {
 | |
|             Stop,
 | |
|             Down,
 | |
|             Up,
 | |
| 
 | |
|         }
 | |
|     
 | |
|         void MotorControl(eMotList mot, eMotControl cmd)
 | |
|         {
 | |
|             if (cmd == eMotControl.Stop)
 | |
|             {
 | |
|                 eDOName pin = eDOName.PORTL_MOT_RUN;
 | |
|                 if (mot == eMotList.Center) pin = eDOName.PORTC_MOT_RUN;
 | |
|                 else if (mot == eMotList.Right) pin = eDOName.PORTR_MOT_RUN;
 | |
| 
 | |
|                 //출력이켜져있다면 끈다
 | |
|                 if (GetDOValue(pin)) SetOutput(pin, false);
 | |
|             }
 | |
|             else if (cmd == eMotControl.Down || cmd == eMotControl.Up)
 | |
|             {
 | |
|                 var dir = cmd == eMotControl.Down ? false : true;
 | |
|                 eDOName pinDir = eDOName.PORTL_MOT_DIR;
 | |
|                 if (mot == eMotList.Center) pinDir = eDOName.PORTC_MOT_DIR;
 | |
|                 else if (mot == eMotList.Right) pinDir = eDOName.PORTR_MOT_DIR;
 | |
| 
 | |
|                 eDOName pinRun = eDOName.PORTL_MOT_RUN;
 | |
|                 if (mot == eMotList.Center) pinRun = eDOName.PORTC_MOT_RUN;
 | |
|                 else if (mot == eMotList.Right) pinRun = eDOName.PORTR_MOT_RUN;
 | |
| 
 | |
|                 if (GetDOValue(pinDir) != dir) SetOutput(pinDir, dir);
 | |
|                 if (GetDOValue(pinRun) == false) SetOutput(pinRun, true);
 | |
|             }
 | |
| 
 | |
|         }
 | |
|         bool SetOutput(eDOName pin, bool value)
 | |
|         {
 | |
|             return PUB.dio.SetOutput((int)pin, value);
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// 내부임시버퍼의 값을 확인합니다
 | |
|         /// </summary>
 | |
|         /// <param name="addr"></param>
 | |
|         /// <returns></returns>
 | |
|         byte ReadBuffer(eswPLCAddr addr)
 | |
|         {
 | |
|             return PUB.swPLCBuffer[(int)addr];
 | |
|         }
 | |
|         void WriteBuffer(eswPLCAddr addr, byte value)
 | |
|         {
 | |
|             PUB.swPLCBuffer[(int)addr] = value;
 | |
|         }
 | |
| 
 | |
|         private void timer1_Tick(object sender, EventArgs e)
 | |
|         {
 | |
|             //io상태 ㅍ시
 | |
| 
 | |
|             var idx = 0;
 | |
|             if (PUB.dio != null && PUB.dio.IsInit)
 | |
|             {
 | |
|                 ioPanel1.setValue(idx++, GetDIValue(eDIName.PORTL_LIM_UP));
 | |
|                 ioPanel1.setValue(idx++, GetDIValue(eDIName.PORTL_DET_UP));
 | |
|                 ioPanel1.setValue(idx++, GetDIValue(eDIName.PORTL_LIM_DN));
 | |
|                 ioPanel1.setValue(idx++, PUB.dio.GetDOValue((int)eDOName.PORTL_MOT_DIR));
 | |
|                 ioPanel1.setValue(idx++, PUB.dio.GetDOValue((int)eDOName.PORTL_MOT_RUN));
 | |
|                 ioPanel1.setValue(idx++, GetDIValue(eDIName.BUT_EMGF));
 | |
| 
 | |
|                 ioPanel1.setValue(idx++, GetDIValue(eDIName.PORTC_LIM_UP));
 | |
|                 ioPanel1.setValue(idx++, GetDIValue(eDIName.PORTC_DET_UP));
 | |
|                 ioPanel1.setValue(idx++, GetDIValue(eDIName.PORTC_LIM_DN));
 | |
|                 ioPanel1.setValue(idx++, PUB.dio.GetDOValue((int)eDOName.PORTC_MOT_DIR));
 | |
|                 ioPanel1.setValue(idx++, PUB.dio.GetDOValue((int)eDOName.PORTC_MOT_RUN));
 | |
|                 ioPanel1.setValue(idx++, false);
 | |
| 
 | |
|                 ioPanel1.setValue(idx++, GetDIValue(eDIName.PORTR_LIM_UP));
 | |
|                 ioPanel1.setValue(idx++, GetDIValue(eDIName.PORTR_DET_UP));
 | |
|                 ioPanel1.setValue(idx++, GetDIValue(eDIName.PORTR_LIM_DN));
 | |
|                 ioPanel1.setValue(idx++, PUB.dio.GetDOValue((int)eDOName.PORTR_MOT_DIR));
 | |
|                 ioPanel1.setValue(idx++, PUB.dio.GetDOValue((int)eDOName.PORTR_MOT_RUN));
 | |
|                 ioPanel1.setValue(idx++, false);
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 ioPanel1.setValue(idx++, false);
 | |
|                 ioPanel1.setValue(idx++, false);
 | |
|                 ioPanel1.setValue(idx++, false);
 | |
|                 ioPanel1.setValue(idx++, false);
 | |
|                 ioPanel1.setValue(idx++, false);
 | |
|                 ioPanel1.setValue(idx++, false);
 | |
| 
 | |
|                 ioPanel1.setValue(idx++, false);
 | |
|                 ioPanel1.setValue(idx++, false);
 | |
|                 ioPanel1.setValue(idx++, false);
 | |
|                 ioPanel1.setValue(idx++, false);
 | |
|                 ioPanel1.setValue(idx++, false);
 | |
|                 ioPanel1.setValue(idx++, false);
 | |
| 
 | |
|                 ioPanel1.setValue(idx++, false);
 | |
|                 ioPanel1.setValue(idx++, false);
 | |
|                 ioPanel1.setValue(idx++, false);
 | |
|                 ioPanel1.setValue(idx++, false);
 | |
|                 ioPanel1.setValue(idx++, false);
 | |
|                 ioPanel1.setValue(idx++, false);
 | |
|             }
 | |
|             ioPanel1.Invalidate();
 | |
| 
 | |
|             //내부버퍼표시
 | |
|             for (int i = 0; i < 16; i++)
 | |
|             {
 | |
|                 gridView1.setValue(i, ReadBuffer((eswPLCAddr)i));
 | |
|             }
 | |
|             gridView1.Invalidate();
 | |
| 
 | |
|             toolStripStatusLabel2.Text = PUB.plc.Init ? "Connected" : "Disconnected";
 | |
|             toolStripStatusLabel2.ForeColor = PUB.plc.Init ? Color.Black : Color.Red;
 | |
|             toolStripStatusLabel3.Text = $"Loop({PUB.sm.Loop_ms:N0}ms)";
 | |
|         }
 | |
|     }
 | |
| } |