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 { public partial class Form1 : Form { AR.Log log; arDev.DIO.IDIO dio; StateMachine sm; AR.MemoryMap.Server swplc; bool exitforce = false; byte[] buffer = new byte[16]; public Form1() { InitializeComponent(); this.Text = $"{Application.ProductName} ver {Application.ProductVersion}"; log = new AR.Log(); log.RaiseMsg += (p1, p2, p3) => { this.logTextBox1.AddMsg(p1, p2, p3); }; this.FormClosing += Form1_FormClosing; 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 piname = new List(); List titles = new List(); List values = new List(); 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" }, new arDev.AjinEXTEK.UI.ColorListItem{ BackColor1 = Color.Magenta, BackColor2 = Color.Green, Remark="True" }, new arDev.AjinEXTEK.UI.ColorListItem{ BackColor1 = Color.SkyBlue, BackColor2 = Color.LightSkyBlue, 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(); 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" }, new arCtl.GridView.ColorListItem{ BackColor1 = Color.Magenta, BackColor2 = Color.Green, Remark="True" }, new arCtl.GridView.ColorListItem{ BackColor1 = Color.SkyBlue, BackColor2 = Color.LightSkyBlue, 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_FormClosing(object sender, FormClosingEventArgs e) { if (exitforce == false) { this.WindowState = FormWindowState.Minimized; e.Cancel = true; return; } timer1.Stop(); dio.Dispose(); sm.Stop(); log.AddI("Program terminated"); log.Flush(); } private void Form1_Load(object sender, EventArgs e) { log.AddI("Program started"); dio = new arDev.AjinEXTEK.DIO(arDev.AjinEXTEK.ELibraryType.AXT);// arDev.AjinEXTEK.DIO(); if (dio.Init()) { dio.IOValueChanged += Dio_IOValueChanged; dio.RunMonitor(); log.Add($"DI:{dio.GetDICount}/DO:{dio.GetDOCount}"); } else log.AddE($"DIO initialization failed"); swplc = new AR.MemoryMap.Server(PUB.Setting.swplc_name, PUB.Setting.swplc_size); swplc.ValueChanged += Plc_ValueChanged; swplc.Start(); ioPanel1.ItemClick += IoPanel1_ItemClick; sm = new AR.StateMachine(); sm.StepChanged += Sm_StepChanged; sm.Running += Sm_Running; sm.SPS += Sm_SPS; if (dio.IsInit == false) log.AddE($"DIO initialization failed"); log.Add($"State machine started"); sm.Start(); sm.SetNewStep((byte)eSMStep.RUN); this.starttime = DateTime.Now; 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 에서 처리된다. var value = GetDIValue(pin); if (value) { if (pin == eDIName.PORTL_LIM_DN) WriteBuffer(eswPLCAddr.LPort, 1); if (pin == eDIName.PORTL_DET_UP) WriteBuffer(eswPLCAddr.LPort, 2); if (pin == eDIName.PORTL_LIM_UP) WriteBuffer(eswPLCAddr.LPort, 3); if (pin == eDIName.PORTC_LIM_DN) WriteBuffer(eswPLCAddr.CPort, 1); if (pin == eDIName.PORTC_DET_UP) WriteBuffer(eswPLCAddr.CPort, 2); if (pin == eDIName.PORTC_LIM_UP) WriteBuffer(eswPLCAddr.CPort, 3); if (pin == eDIName.PORTR_LIM_DN) WriteBuffer(eswPLCAddr.RPort, 1); if (pin == eDIName.PORTR_DET_UP) WriteBuffer(eswPLCAddr.RPort, 2); 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) { if (dio != null && dio.IsInit == false) return; 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 = dio.GetDOValue(pinno); dio.SetOutput(pinno, !cur); log.Add($"value change [X{pinno:X2}] {pin} to {!cur}"); } } bool GetDOValue(eDOName pin) { return 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 !dio.GetDIValue((int)pin); } else if (pin == eDIName.PORTL_LIM_UP || pin == eDIName.PORTC_LIM_UP || pin == eDIName.PORTR_LIM_UP) { return !dio.GetDIValue((int)pin); } else if (pin == eDIName.PORTL_DET_UP || pin == eDIName.PORTC_DET_UP || pin == eDIName.PORTR_DET_UP) { return !dio.GetDIValue((int)pin); } else if (pin == eDIName.BUT_EMGF) { return !dio.GetDIValue((int)pin); } else return dio.GetDIValue((int)pin); } private void Sm_SPS(object sender, EventArgs e) { //limit 센서에 의해 자동 멈춤 if (swplc.Init) { AutoStop(); WriteBuffer(); CommandProcess(); } } void CommandProcess() { //시스템 상태값 0:7 기록 swplc.Write(0, buffer, 0, 12); //명령어 가져오기 7:3개의 데이터 확인 if (swplc.ReadBytes(12, 3, out byte[] plcbuffer)) { //내부버퍼에 상태를 기록한다 Array.Copy(plcbuffer, 0, this.buffer, 12, plcbuffer.Length); } //command value var lcmd = ReadBuffer(eswPLCAddr.LCmd); var ccmd = ReadBuffer(eswPLCAddr.CCmd); var rcmd = ReadBuffer(eswPLCAddr.RCmd); //left command check if (lcmd == 1) MotorControl(eMotList.Left, eMotControl.Down); else if (lcmd == 2) MotorControl(eMotList.Left, eMotControl.Up); else if (lcmd == 3) MotorControl(eMotList.Left, eMotControl.Stop); else if (lcmd == 4) MotorRefresh(eMotList.Left); if (lcmd < 4 && ReadBuffer(eswPLCAddr.LSts) != 0) WriteBuffer(eswPLCAddr.LSts, 0); //center command check if (ccmd == 1) MotorControl(eMotList.Center, eMotControl.Down); else if (ccmd == 2) MotorControl(eMotList.Center, eMotControl.Up); else if (ccmd == 3) MotorControl(eMotList.Center, eMotControl.Stop); else if (ccmd == 4) MotorRefresh(eMotList.Center); if (ccmd < 4 && ReadBuffer(eswPLCAddr.CSts) != 0) WriteBuffer(eswPLCAddr.CSts, 0); //right command check if (rcmd == 1) MotorControl(eMotList.Right, eMotControl.Down); else if (rcmd == 2) MotorControl(eMotList.Right, eMotControl.Up); else if (rcmd == 3) MotorControl(eMotList.Right, eMotControl.Stop); else if (rcmd == 4) MotorRefresh(eMotList.Right); if (rcmd < 4 && ReadBuffer(eswPLCAddr.RSts) != 0) WriteBuffer(eswPLCAddr.RSts, 0); } /// /// 모터를 down -> up 합니다. /// /// /// void MotorRefresh(eMotList mot) { eswPLCAddr address = (eswPLCAddr)((int)eswPLCAddr.LSts + (int)mot); var Sts = ReadBuffer(address); //상태값을 변경한다 if (Sts == 0) //처음시작하는경우이다 { motortime[(int)mot] = DateTime.Now; MotorControl(mot, eMotControl.Down); WriteBuffer(address, 1); log.Add($"Motor[{mot}] Refresh #1 : Down,Addr={address}"); } else if (Sts == 1) //3초간 내린다. 센서가 감지되면 계속 내려야 한다 { //low limit check if (mot == eMotList.Left && GetDIValue(eDIName.PORTL_LIM_DN)) { log.Add($"Motor[{mot}] Refresh #2 : Down Limit,Addr={address}"); MotorControl(mot, eMotControl.Stop); WriteBuffer(address, 2); } else if (mot == eMotList.Center && GetDIValue(eDIName.PORTC_LIM_DN)) { log.Add($"Motor[{mot}] Refresh #2 : Down Limit,Addr={address}"); MotorControl(mot, eMotControl.Stop); WriteBuffer(address, 2); } else if (mot == eMotList.Right && GetDIValue(eDIName.PORTR_LIM_DN)) { log.Add($"Motor[{mot}] Refresh #2 : Down Limit,Addr={address}"); MotorControl(mot, eMotControl.Stop); WriteBuffer(address, 2); } else if (mot == eMotList.Left && GetDIValue(eDIName.PORTL_DET_UP)) { return; } else if (mot == eMotList.Center && GetDIValue(eDIName.PORTC_DET_UP)) { return; } else if (mot == eMotList.Right && GetDIValue(eDIName.PORTR_DET_UP)) { return; } else { var ts = DateTime.Now - motortime[(int)mot]; if (ts.TotalSeconds > 3) { log.Add($"Motor[{mot}] Refresh #2 : Down Time Over,Addr={address}"); MotorControl(mot, eMotControl.Stop); WriteBuffer(address, 2); } } } else if (Sts == 2) //다시 올린다 { log.Add($"Motor[{mot}] Refresh #3 : Up Addr={address}"); MotorControl(mot, eMotControl.Up); motortime[(int)mot] = DateTime.Now; WriteBuffer(address, 3); } else if (Sts == 3) //올라가는건 { WriteBuffer(address, 0); eswPLCAddr addressCmd = (eswPLCAddr)((int)eswPLCAddr.LCmd + (int)mot); if (addressCmd == eswPLCAddr.CCmd) { } log.Add($"Refresh[{mot}] Complete Addr={address}/{addressCmd} Reset"); swplc.Write((int)addressCmd, 0); } } int[] motorseq = new int[] { 0, 0, 0 }; DateTime[] motortime = new DateTime[] { DateTime.Now, DateTime.Now, DateTime.Now }; 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 ? true : false; 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 dio.SetOutput((int)pin, value); } /// /// Check the value of internal temporary buffer /// /// /// byte ReadBuffer(eswPLCAddr addr) { return buffer[(int)addr]; } void WriteBuffer(eswPLCAddr addr, byte value) { if (addr >= eswPLCAddr.LCmd) throw new Exception("Command must be written directly to swplc"); buffer[(int)addr] = value; } void WriteBuffer() { var idx = 0; //현재상태를 기록합니다 var bReady = dio != null && dio.IsInit; buffer[idx++] = bReady ? (byte)1 : (byte)2; //모터상태값3개는 동작시 발생한다 idx++; idx++; idx++; } /// /// Automatically stops when limit sensor and detect are detected. /// void AutoStop() { if (dio == null || dio.IsInit == false || autocontrol == false) return; //모터가 동작중에만 처리한다. var motrunL = dio.GetDOValue((int)eDOName.PORTL_MOT_RUN); var motrunC = dio.GetDOValue((int)eDOName.PORTC_MOT_RUN); var motrunR = dio.GetDOValue((int)eDOName.PORTR_MOT_RUN); if (motrunL) { if (GetDIValue(eDIName.BUT_EMGF)) { dio.SetOutput((int)eDOName.PORTL_MOT_RUN, false); } else { var dirDn = dio.GetDOValue((int)eDOName.PORTL_MOT_DIR); var limUp = GetDIValue(eDIName.PORTL_LIM_UP); var detect = GetDIValue(eDIName.PORTL_DET_UP); var limDn = GetDIValue(eDIName.PORTL_LIM_DN); if (dirDn == false) { if (detect) dio.SetOutput((int)eDOName.PORTL_MOT_RUN, false); else if (limUp) dio.SetOutput((int)eDOName.PORTL_MOT_RUN, false); } else { if (limDn) dio.SetOutput((int)eDOName.PORTL_MOT_RUN, false); } } } if (motrunC) { if (GetDIValue(eDIName.BUT_EMGF)) { dio.SetOutput((int)eDOName.PORTC_MOT_RUN, false); } else { var dirDn = dio.GetDOValue((int)eDOName.PORTC_MOT_DIR); var limUp = GetDIValue(eDIName.PORTC_LIM_UP); var detect = GetDIValue(eDIName.PORTC_DET_UP); var limDn = GetDIValue(eDIName.PORTC_LIM_DN); if (dirDn == false) { if (detect) dio.SetOutput((int)eDOName.PORTC_MOT_RUN, false); else if (limUp) dio.SetOutput((int)eDOName.PORTC_MOT_RUN, false); } else { if (limDn) dio.SetOutput((int)eDOName.PORTC_MOT_RUN, false); } } } if (motrunR) { if (GetDIValue(eDIName.BUT_EMGF)) { dio.SetOutput((int)eDOName.PORTR_MOT_RUN, false); } else { var dirDn = dio.GetDOValue((int)eDOName.PORTR_MOT_DIR); var limUp = GetDIValue(eDIName.PORTR_LIM_UP); var detect = GetDIValue(eDIName.PORTR_DET_UP); var limDn = GetDIValue(eDIName.PORTR_LIM_DN); if (dirDn == false) { if (detect) dio.SetOutput((int)eDOName.PORTR_MOT_RUN, false); else if (limUp) dio.SetOutput((int)eDOName.PORTR_MOT_RUN, false); } else { if (limDn) dio.SetOutput((int)eDOName.PORTR_MOT_RUN, false); } } } } private void Sm_Running(object sender, AR.StateMachine.RunningEventArgs e) { //throw new NotImplementedException(); var step = (eSMStep)e.Step; switch (step) { case eSMStep.RUN: break; } } private void Sm_StepChanged(object sender, AR.StateMachine.StepChangeEventArgs e) { var step = (eSMStep)e.New; log.Add($"Step Changed : {step}"); } DateTime starttime; bool startminimize = false; private void timer1_Tick(object sender, EventArgs e) { //io상태표시 시작시 최소한한다 230823 if (startminimize == false && this.IsDisposed == false && this.Disposing == false) { var ts = DateTime.Now - starttime; if (ts.TotalSeconds > 3) { this.WindowState = FormWindowState.Minimized; startminimize = true; } } var idx = 0; if (dio != null && 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++, GetDOValue(eDOName.PORTL_MOT_DIR)); ioPanel1.setValue(idx++, GetDOValue(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++, GetDOValue(eDOName.PORTC_MOT_DIR)); ioPanel1.setValue(idx++, GetDOValue(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++, GetDOValue(eDOName.PORTR_MOT_DIR)); ioPanel1.setValue(idx++, GetDOValue(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++) { var addr = (eswPLCAddr)i; var val = ReadBuffer(addr); var title = addr.ToString(); if (addr == eswPLCAddr.LCmd || addr == eswPLCAddr.CCmd || addr == eswPLCAddr.RCmd) { if (val == 0) title += "(--)"; else if (val == 1) title += "(up)"; else if (val == 2) title += "(up)"; else if (val == 3) title += "(stop)"; else if (val == 4) title += "(refresh)"; gridView1.setTitle(i, title); } else if (addr == eswPLCAddr.LSts || addr == eswPLCAddr.CSts || addr == eswPLCAddr.RSts) { if (val == 0) title += "(--)"; else title += "(~run~)"; gridView1.setTitle(i, title); } else if (addr == eswPLCAddr.LMotor || addr == eswPLCAddr.CMotor || addr == eswPLCAddr.RMotor) { if (val == 0) title += "(--)"; else if (val == 1) title += "(Down)"; else if (val == 2) title += "(up)"; else if (val == 3) title += "(stop)"; gridView1.setTitle(i, title); } else if (addr == eswPLCAddr.LPort || addr == eswPLCAddr.CPort || addr == eswPLCAddr.RPort) { if (val == 0) title += "(--)"; else if (val == 1) title += "(Limit -)"; else if (val == 2) title += "(Reel Detect)"; else if (val == 3) title += "(Limit +)"; gridView1.setTitle(i, title); } gridView1.setValue(i, val); } gridView1.Invalidate(); toolStripStatusLabel1.ForeColor = autocontrol ? Color.Green : Color.Black; toolStripStatusLabel2.Text = swplc.Init ? "Connected" : "Disconnected"; toolStripStatusLabel2.ForeColor = swplc.Init ? Color.Black : Color.Red; toolStripStatusLabel3.Text = $"Loop({sm.Loop_ms:N0}ms)"; } bool autocontrol = true; private void toolStripStatusLabel1_Click(object sender, EventArgs e) { this.autocontrol = !this.autocontrol; } private void button1_Click(object sender, EventArgs e) { var but = sender as Button; var butno = int.Parse(but.Tag.ToString()); swplc.Write((int)eswPLCAddr.LCmd + butno, 4); //refresh port } private void button4_Click(object sender, EventArgs e) { var but = sender as Button; var butno = int.Parse(but.Tag.ToString()); if (butno == 0) MotorControl(eMotList.Left, eMotControl.Up); else if (butno == 1) MotorControl(eMotList.Center, eMotControl.Up); else if (butno == 2) MotorControl(eMotList.Right, eMotControl.Up); } private void button9_Click(object sender, EventArgs e) { var but = sender as Button; var butno = int.Parse(but.Tag.ToString()); if (butno == 0) MotorControl(eMotList.Left, eMotControl.Down); else if (butno == 1) MotorControl(eMotList.Center, eMotControl.Down); else if (butno == 2) MotorControl(eMotList.Right, eMotControl.Down); } private void button11_Click(object sender, EventArgs e) { } private void button12_Click(object sender, EventArgs e) { var but = sender as Button; var butno = int.Parse(but.Tag.ToString()); if (butno == 0) MotorControl(eMotList.Left, eMotControl.Stop); else if (butno == 1) MotorControl(eMotList.Center, eMotControl.Stop); else if (butno == 2) MotorControl(eMotList.Right, eMotControl.Stop); } private void button13_Click(object sender, EventArgs e) { var dlg =UTIL.MsgQ("Do you want to exit the program?\nThis is a program that monitors I/O malfunction.It is recommended to run at all times"); if (dlg != DialogResult.Yes) return; this.exitforce = true; this.Close(); } } }