using ACS.SPiiPlusNET; using HexcalMC.Hexcal; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using HexcalMC.Base; using HexcalMC.Form; namespace HexcalMC { public partial class MainFrom : Telerik.WinControls.UI.RadRibbonForm { #region hexcal变量区 private TcpIpServer m_tcpIpServer; //创建tcpserver,用于接收hexcal传来的指令,并解析传递平台 private bool m_bHexcalConnected = false; #endregion #region 运动平台变量区 private Api _ACS; private const int MAX_UI_LIMIT_CNT = 8; private const int MAX_UI_IO_CNT = 8; private int m_nTotalAxis = 0; private int m_nTotalBuffer = 0; private Axis[] m_arrAxisList = null; private bool m_bConnected = false; // For update values private MotorStates m_nMotorState; //运动状态 private ProgramStates m_nProgramState; //程序状态 private object m_objReadVar = null; private Array m_arrReadVector = null; private double m_lfRPos, m_lfFPos, m_lfPE, m_lfFVEL; //参考位置,反馈位置 位置误差 反馈速度 double类型 private int m_nValues, m_nOutputState; private Label[] m_lblLeftLimit; //左限位 private Label[] m_lblRightLimit; //右限位 #endregion public MainFrom() { InitializeComponent(); } private void MainFrom_Load(object sender, EventArgs e) { this.FormBorderStyle = FormBorderStyle.FixedSingle; // 设置窗体边框样式为固定大小 this.MaximizeBox = false; // 禁用窗体的最大化按钮 double[] dataX = new double[] { 1, 2, 3, 4, 5 }; double[] dataY = new double[] { 1, 4, 9, 16, 25 }; formsPlot1.Plot.AddScatter(dataX, dataY); formsPlot1.Refresh(); //启动界面刷新 timer_RefreshUI.Start(); } #region hexcal软件相关 private void StartServer() { //启动服务器,并获取数据,解析 m_tcpIpServer = new TcpIpServer("100.0.0.1", Convert.ToString(1234)); try { //启动监听 if (m_tcpIpServer.StartListen()) { //绑定两个事件 OnRaisedStatus 和OnRaisedMessage m_tcpIpServer.OnRaisedMessage += ReceiveMessage; m_tcpIpServer.OnRaisedStatus += ReceiveStatus; DebugDfn.AddLogText("TCP服务端启动成功 "); } else { MessageBox.Show("TCP服务端启动失败,请检查网络连接,重新打开软件", "异常", MessageBoxButtons.OK, MessageBoxIcon.Error); } } catch (Exception ex) { DebugDfn.AddLogText("启动TCP服务端异常" + ex.ToString()); } } private void ReceiveMessage(string ClientIP, string Msg) //接收的内容 { //打印ClientIP 和 Msg DebugDfn.AddLogText("接收到" + ClientIP + ": " + Msg); //根据源地址的不同,执行不同处理 //如果 ClientIP 来自L2系统的话,执行解析 switch (ClientIP) { case "172.19.153.80": //L2系统 //解析处理数据 ParseHexcalPacket(Msg); break; case "127.0.0.1": //模拟长宽系统 break; } } private void ParseHexcalPacket(string Msg) //编写一个Hexcal协议解析函数 { //根据不同的指令进行解析,3个层次,不合法,故障,最后是正常 //判断Msg的长度,如果不是指定长度,直接返回 if (Msg.Length != 8) return; //判断是否含有故障ERROR字样 if (Msg.Contains("ERROR")) return; //指令解析 string[] tokens = Msg.Split(','); foreach (string token in tokens) { Console.WriteLine(token); } //可能涉及到 将指令提取并单独处理的问题 if (string.Equals("CMMTYP", Msg)) { SendMsgToHexcal("CMMTYP MA 19617, FDC V15.00, 6 6 2 , 0"); } else if (string.Equals("VERSION", Msg)) //版本号 { SendMsgToHexcal("00-000-000-00000 FDC V51.04.0000 DATE: 12/21/22 TIME: 12:50:55"); } else if (string.Equals("^B", Msg)) //查询状态 { //todo 启动指令 } else if (string.Equals("SHOW MAXSTROKESW", Msg)) //最大行程 { SendMsgToHexcal("MAXSTROKESW 233.200000,346.500000,15.100000,0.000000,0.000000,0.000000,0.000000"); } else if (string.Equals("00000003", Msg)) //最小行程 { SendMsgToHexcal("MINSTROKESW -68.800000,-55.500000,-286.900000,0.000000,0.000000,0.000000,0.000000"); } else if (string.Equals("SHOW MAXVEL", Msg)) //最大速度 { SendMsgToHexcal("MAXVEL 300.000000,300.000000,300.000000,0.000000,0.000000,0.000000,0.000000,0.000000"); } else if (string.Equals("SHOW MAXACC", Msg)) //最大加速度 { SendMsgToHexcal( "MAXACC 300.000000,300.000000,300.000000,0.000000,0.000000,0.000000,0.000000,0.000000"); } else if (string.Equals("SHOW TEMPCOMPTYPE", Msg)) //温度补偿,温度补偿 >1 表示支持温度补偿 { SendMsgToHexcal("TEMPCOMPTYPE 1"); } else if (string.Equals("READTP", Msg)) { SendMsgToHexcal("READTP 0.000000"); } else if (string.Equals("SHOW SENSWKP", Msg)) { SendMsgToHexcal("X_ SENSWKP 4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0"); } else if (string.Equals("SHOW X_SENSAXIS", Msg)) { SendMsgToHexcal("X_SENSAXIS 6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0"); } else if (string.Equals("SHOW Y_SENSAXIS", Msg)) { SendMsgToHexcal("Y_SENSAXIS 2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0"); } else if (string.Equals("SHOW Z_SENSAXIS", Msg)) { SendMsgToHexcal("Z_SENSAXIS 7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0"); } else if (string.Equals("SHOW MOVPAR", Msg)) //获取速度 { SendMsgToHexcal( "MOVPAR 300.000000,300.000000,300.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.00000 0,0.000000"); } else if (string.Equals("MOVPAR 300.0,300.0,300.0,0.0,0.0,0.0", Msg)) //设置速度 xyz 轴的速度 { SendMsgToHexcal("%"); } else if (string.Equals("SHOW MAXVEL", Msg)) { SendMsgToHexcal("MAXVEL 300.000000,300.000000,300.000000,0.000000,0.000000,0.000000,0.000000,0.000000"); } else if (string.Equals("SHOW ACCEL", Msg)) //获取加速 { SendMsgToHexcal( "ACCEL 1000.000000,1000.000000,1000.000000,0.000000,0.000000,0.000000,0.000000,0.000000"); } else if (string.Equals("ACCEL 1000.0,1000.0,1000.0", Msg)) //设置加速度 { SendMsgToHexcal("%"); } else if (string.Equals( "PRBPIN 0.000000,0.000000,0.000000,0.000000,0.000000, 0.000000,0.000000,0.000000,0.000000,0.000000,0.000000, 0.000000", Msg)) { SendMsgToHexcal("%"); } else if (string.Equals("ENABLE TEMP", Msg)) { SendMsgToHexcal(""); } else if (string.Equals("WKPPAR 20,0.0000115,20", Msg)) { SendMsgToHexcal(""); } else if (string.Equals("SCLTMP", Msg)) { SendMsgToHexcal(""); } else if (string.Equals("MOVABS 167.553848,-55.400002,-208.548203,0.000000", Msg)) //移动指令 { SendMsgToHexcal("%"); } else if (string.Equals("GETPOS", Msg)) //获取位置 { SendMsgToHexcal("POS 167.553898,-55.400421,-208.548678,0.000000,0.000000,0.000000,0.000000"); } else if (string.Equals("SHOW ESTOP", Msg)) { SendMsgToHexcal("ESTOP FALSE"); } else if (string.Equals("", Msg)) { } else { //todo 未知指令 } } private void ReceiveStatus(TcpIpServer.EnumTcpIpServer iType, string Msg) { //记录到日志 DebugDfn.AddLogText(iType + " : " + Msg); } private void SendMsgToHexcal(string Msg) { //发送数据 m_tcpIpServer.SendMessageToAllClients(Msg); } #endregion #region ACS平台相关 private void btnEnable_Click(object sender, EventArgs e) //使能所有轴 { Axis[] AxisList = new Axis[] { Axis.ACSC_AXIS_0, Axis.ACSC_AXIS_1, Axis.ACSC_AXIS_4, Axis.ACSC_NONE }; //!!!! Important !! Must insert '-1' at the last _ACS.EnableM(AxisList); } private void btnDisable_Click(object sender, EventArgs e) //轴取消 { // Disable all of axes _ACS.DisableAll(); } private void tmrMonitor_Tick(object sender, EventArgs e) //用于刷新状态 { int iAxisNo = cboAxisNo.SelectedIndex; if (m_bConnected) { try { // Instruction 1. Using library functions - acsc_GetFPosition, acsc_GetRPosition, .... // Instruction 2. Read ACS variable - Already defined almost things (FPOS, RPOS, ...) // Motion parameters and state is array (Max length is total number of axes) // // * Library function can read only 1 axis information, so if you want to read several axes, you have to call the function many times. // (This may cause communication delay.) // Recommand (if you want to read many axes) : read/write variable using ReadVariable, ReadVariableScalar, ReadVariableVector, ReadVariableMatrix // // Get Motor State // ACSPL+ Variable : MST (integer) m_nMotorState = _ACS.GetMotorState((Axis)iAxisNo); // Returned value is integer, you need to use bitmaks if ((m_nMotorState & MotorStates.ACSC_MST_MOVE) != 0) lblMoving.Image = Properties.Resources.On; else lblMoving.Image = Properties.Resources.Off; // 运动中 if ((m_nMotorState & MotorStates.ACSC_MST_INPOS) != 0) lblInPos.Image = Properties.Resources.On; else lblInPos.Image = Properties.Resources.Off; // 就位 if ((m_nMotorState & MotorStates.ACSC_MST_ACC) != 0) lblAcc.Image = Properties.Resources.On; else lblAcc.Image = Properties.Resources.Off; // 加速 if ((m_nMotorState & MotorStates.ACSC_MST_ENABLE) != 0) lblEnable.Image = Properties.Resources.On; else lblEnable.Image = Properties.Resources.Off; // 使能 // Reference position // ACSPL+ Variable : RPOS (real) m_lfRPos = _ACS.GetRPosition((Axis)iAxisNo); // 参考位置 // Feedback position (Encoder value) // ACSPL+ Variable : FPO (real) m_lfFPos = _ACS.GetFPosition((Axis)iAxisNo); //反馈位置 // PE (Position Error) // There is no function in library. We need to use ReadVariable function m_lfPE = (double)_ACS.ReadVariable("PE", ProgramBuffer.ACSC_NONE, iAxisNo, iAxisNo); //位置误差 // Feedback Velocity m_lfFVEL = (double)_ACS.ReadVariable("FVEL", ProgramBuffer.ACSC_NONE, iAxisNo, iAxisNo); //实际速度 // txtRPOS.Text = String.Format("{0:0.0000}", m_lfRPos); //参考位置 rtb_xPos.Text = String.Format("{0:0.0000}", m_lfFPos); //反馈位置 // txtPE.Text = String.Format("{0:0.0000}", m_lfPE); //实际速度 // txtFVEL.Text = String.Format("{0:0.0000}", m_lfFVEL);//位置误差 // Read left/right hardware limits state // ACSPL+ Variable : FAULT (integer) m_objReadVar = _ACS.ReadVariableAsVector("FAULT", ProgramBuffer.ACSC_NONE, 0, m_nTotalAxis - 1, -1, -1); if (m_objReadVar != null) { m_arrReadVector = m_objReadVar as Array; if (m_arrReadVector != null) { for (int i = 0; i < m_nTotalAxis; i++) { UpdateLimitState(i, (int)m_arrReadVector.GetValue(i)); } } } } catch (Exception ex) { MessageBox.Show(ex.Message, "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error); System.Diagnostics.Debug.WriteLine(ex.Message); } } } private void btn_ACSStart_Click(object sender, EventArgs e) //连接 { btn_ACSStart.Enabled = false; btn_ACSStop.Enabled = true; // Set updating timer tmrMonitor.Interval = 50; tmrMonitor.Start(); } private void btn_ACSStop_Click(object sender, EventArgs e) //断开连接 { if (m_bConnected) _ACS.CloseComm(); tmrMonitor.Stop(); btn_ACSStart.Enabled = true; btn_ACSStop.Enabled = false; } private void MainFrom_FormClosed(object sender, FormClosedEventArgs e) { timer_RefreshUI.Stop(); } private void UpdateLimitState(int axisNo, int fault) //刷新限位 { if (axisNo < MAX_UI_LIMIT_CNT) { if ((fault & (int)SafetyControlMasks.ACSC_SAFETY_LL) != 0) m_lblLeftLimit[axisNo].Image = Properties.Resources.Error; else m_lblLeftLimit[axisNo].Image = Properties.Resources.Off; if ((fault & (int)SafetyControlMasks.ACSC_SAFETY_RL) != 0) m_lblRightLimit[axisNo].Image = Properties.Resources.Error; else m_lblRightLimit[axisNo].Image = Properties.Resources.Off; } } #endregion #region 菜单栏 private void rtb_motion_Click(object sender, EventArgs e) //ACS调试页面 { Motion motion = new Motion(); motion.Show(); } private void rtb_about_Click(object sender, EventArgs e) //关于界面 { AboutBox mAboutBox = new AboutBox(); mAboutBox.Show(); } private void timer_RefreshUI_Tick(object sender, EventArgs e) //UI刷新 { //状态灯刷新 lamp_acs.State = m_bConnected ? LampColor.Green : LampColor.Silver; lamp_hexcal.State = m_bHexcalConnected ? LampColor.Green : LampColor.Silver; //时间栏 //获取当前时间,构造形如 精确到秒,例如 2023-10-08 16:01:23 rle_timer.Text = "当前时间: " + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); } #endregion } }