using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using System.Threading; using System.IO; using ACS.SPiiPlusNET; // ACS .NET Library using System.Runtime.InteropServices; namespace ACS_DotNET_Library_Advanced_Demo { public partial class MainForm : Form { private Api _ACS; private const int MAX_AXIS_COUNT = 32; private const int MAX_BUFFER_CNT = 64; 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;//右限位 private Label[] m_lblInput; private Label[] m_lblOutput; private Button[] m_btnOutput; //定一个point结构体,用于存储点的坐标 public struct Point { public double x; public double y; public double z; } //定义一个point结构体的列表,用于存储多个点的坐标 public List pointList = new List(); //定一个point结构体的对象 public Point point = new Point(); // 记录标志位 private bool record = false; private bool record_last = false; //上一次的记录标志位 public MainForm() { InitializeComponent(); _ACS = new Api(); //初始化 ACS运动控制类 // Register Event 注册时间 _ACS.PHYSICALMOTIONEND += _ACS_PHYSICALMOTIONEND; _ACS.PROGRAMEND += _ACS_PROGRAMEND; } #region Initialize private void Form1_Load(object sender, EventArgs e) { rdoTCP.Checked = true; btnOpen.Enabled = true; btnClose.Enabled = false; m_lblLeftLimit = new Label[MAX_UI_LIMIT_CNT]; //左限位 m_lblLeftLimit[0] = lblLL0; m_lblLeftLimit[1] = lblLL1; m_lblLeftLimit[2] = lblLL2; m_lblLeftLimit[3] = lblLL3; m_lblLeftLimit[4] = lblLL4; m_lblLeftLimit[5] = lblLL5; m_lblLeftLimit[6] = lblLL6; m_lblLeftLimit[7] = lblLL7; m_lblRightLimit = new Label[MAX_UI_LIMIT_CNT];//有限位 m_lblRightLimit[0] = lblRL0; m_lblRightLimit[1] = lblRL1; m_lblRightLimit[2] = lblRL2; m_lblRightLimit[3] = lblRL3; m_lblRightLimit[4] = lblRL4; m_lblRightLimit[5] = lblRL5; m_lblRightLimit[6] = lblRL6; m_lblRightLimit[7] = lblRL7; m_lblInput = new Label[MAX_UI_IO_CNT]; m_lblInput[0] = lblIN0; m_lblInput[1] = lblIN1; m_lblInput[2] = lblIN2; m_lblInput[3] = lblIN3; m_lblInput[4] = lblIN4; m_lblInput[5] = lblIN5; m_lblInput[6] = lblIN6; m_lblInput[7] = lblIN7; m_lblOutput = new Label[MAX_UI_IO_CNT]; m_lblOutput[0] = lblOUT0; m_lblOutput[1] = lblOUT1; m_lblOutput[2] = lblOUT2; m_lblOutput[3] = lblOUT3; m_lblOutput[4] = lblOUT4; m_lblOutput[5] = lblOUT5; m_lblOutput[6] = lblOUT6; m_lblOutput[7] = lblOUT7; m_btnOutput = new Button[MAX_UI_IO_CNT]; m_btnOutput[0] = btnSW0; m_btnOutput[1] = btnSW1; m_btnOutput[2] = btnSW2; m_btnOutput[3] = btnSW3; m_btnOutput[4] = btnSW4; m_btnOutput[5] = btnSW5; m_btnOutput[6] = btnSW6; m_btnOutput[7] = btnSW7; //m_nFault = new int[MAX_AXIS_COUNT]; //Array.Clear(m_nFault, 0, MAX_AXIS_COUNT); m_nOutputState = 0; // Clear connection list from SPiiPlus UserMode-Driver (UMD) //TernminateUMD_Connection(); } private void rdoTCP_CheckedChanged(object sender, EventArgs e) { txtIP.Enabled = true; txtPort.Enabled = true; } private void rdoSimu_CheckedChanged(object sender, EventArgs e) { txtIP.Enabled = false; txtPort.Enabled = false; } #endregion #region Communication - Open / Close private void btnOpen_Click(object sender, EventArgs e) { string strTemp; int i; //double lfTemp = 0.0f; try { if (rdoTCP.Checked) { // TCP/IP (Ethernet) _ACS.OpenCommEthernetTCP( txtIP.Text, // IP Address (Default : 10.0.0.100) Convert.ToInt32(txtPort.Text.Trim())); // TCP/IP Port nubmer (default : 701) } else if (rdoSimu.Checked) { // Simmulation mode _ACS.OpenCommSimulator(); } m_bConnected = true; // Get Total number of axes // Using Transaction function : return string text from controller, we need to convert to integer value strTemp = _ACS.Transaction("?SYSINFO(13)"); m_nTotalAxis = Convert.ToInt32(strTemp.Trim()); // Using Sysinfo function //_ACS.GetSysInfo(_ACS.ACSC_SYS_NAXES_KEY, out lfTemp); // When we are using multi axes command (ex) ToPointM, HaltM, ...), we need to allocate the array size more 1. // Because of the last delimeter (-1) m_arrAxisList = new Axis[m_nTotalAxis + 1]; for (i = 0; i < m_nTotalAxis; i++) { cboAxisNo.Items.Add(i.ToString()); m_arrAxisList[i] = (Axis)i; } // Insert '-1' at the last m_arrAxisList[m_nTotalAxis] = Axis.ACSC_NONE; cboAxisNo.SelectedIndex = 0; // Update current motion paramter to UI. UpdateProfile(); strTemp = _ACS.Transaction("?SYSINFO(10)"); m_nTotalBuffer = Convert.ToInt32(strTemp.Trim()); for (i = 0; i < m_nTotalBuffer; i++) { cboBufferNo.Items.Add(i.ToString()); } cboBufferNo.SelectedIndex = 0; btnOpen.Enabled = false; btnClose.Enabled = true; // Set updating timer tmrMonitor.Interval = 50; tmrMonitor.Start(); } catch (COMException comex) { MessageBox.Show("Connection fail", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); System.Diagnostics.Debug.WriteLine("Connection fail" + comex.Message); m_bConnected = false; return; } catch (Exception ex) { MessageBox.Show(ex.Message, "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error); System.Diagnostics.Debug.WriteLine(ex.Message); } } private void btnClose_Click(object sender, EventArgs e) { if (m_bConnected) _ACS.CloseComm(); tmrMonitor.Stop(); btnOpen.Enabled = true; btnClose.Enabled = false; } /// /// Terminate connections from SPiiPlus User Mode Driver /// 终止来自 SPiiPlus 用户模式驱动程序的连接 /// - Maximum connections up to 10 in UMD /// private void TernminateUMD_Connection() { try { string terminateExceptionConnName = "ACS.Framework.exe"; ACSC_CONNECTION_DESC[] connectionList = _ACS.GetConnectionsList(); for (int index = 0; index < connectionList.Length; index++) { if (terminateExceptionConnName.CompareTo((string)connectionList[index].Application) != 0) _ACS.TerminateConnection(connectionList[index]); } } catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.ToString()); } } #endregion #region Update UI data from Controller /// /// Update Motion Profile from Controller /// private void UpdateProfile() { if (m_bConnected) { txtVel.Text = _ACS.GetVelocity((Axis)cboAxisNo.SelectedIndex).ToString(); txtAcc.Text = _ACS.GetAcceleration((Axis)cboAxisNo.SelectedIndex).ToString(); txtDec.Text = _ACS.GetDeceleration((Axis)cboAxisNo.SelectedIndex).ToString(); txtKdec.Text = _ACS.GetKillDeceleration((Axis)cboAxisNo.SelectedIndex).ToString(); txtJerk.Text = _ACS.GetJerk((Axis)cboAxisNo.SelectedIndex).ToString(); } } private void cboAxisNo_SelectedIndexChanged(object sender, EventArgs e) { UpdateProfile(); } private bool record_action = false; private void tmrMonitor_Tick(object sender, EventArgs e) { // Get selected axis number int iAxisNo = cboAxisNo.SelectedIndex; // Get selected buffer number int iBufferNo = cboBufferNo.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); txtFPOS.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); // Program State 运动状态 // State : Compiled, Running, Suspended, Autoroutine is running (ON syntax) // // ACSPL+ Variable : PST (integer) m_nProgramState = _ACS.GetProgramState((ProgramBuffer)iBufferNo); if ((m_nProgramState & ProgramStates.ACSC_PST_RUN) != 0) { lblPRG_Status_LED.Image = Properties.Resources.On; lblPRG_Status.Text = "Running"; } else { lblPRG_Status_LED.Image = Properties.Resources.Off; lblPRG_Status.Text = "Stop"; } // 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)); } } } // Read digital input/output (Port means all of bits) // If you want to read only 1 bit (not an integer), use "GetInput" function m_nValues = _ACS.GetInputPort(0); // _ACS.ReadVariableAsVector("IN", -1, 0, 0, -1, -1); UpdateIOState(m_nValues, true); m_nOutputState = _ACS.GetOutputPort(0); // _ACS.ReadVariableAsVector("OUT", -1, 0, 0, -1, -1); UpdateIOState(m_nOutputState, false); } catch (Exception ex) { MessageBox.Show(ex.Message, "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error); System.Diagnostics.Debug.WriteLine(ex.Message); } //编写代码,刷新0,1,8轴的位置 point.x = _ACS.GetRPosition((Axis)0); //参考位置 point.y = _ACS.GetRPosition((Axis)1); //参考位置 point.z = _ACS.GetRPosition((Axis)8); //参考位置 //对 point 保留3位小数 label54.Text = point.x.ToString("0.000"); label55.Text = point.y.ToString("0.000"); label56.Text = point.z.ToString("0.000"); if (record_action) { pointList.Add(point); } if (!record_last && record) //从未记录到记录 { lstLog.Items.Add("开始记录"); record_action = true; } //从记录到未记录 if (record_last && !record) { lstLog.Items.Add("停止记录"); record_action = false; //定义文件保存位置 D:/11.txt string path = "D:/11.txt"; { StreamWriter sw = new StreamWriter(path); foreach (Point p in pointList) { sw.WriteLine(p.x.ToString("0.000") + " " + p.y.ToString("0.000") + " " + p.z.ToString("0.000")); } sw.Close(); } pointList.Clear();//清空数据 lstLog.Items.Add("保存完成"); } //更新记录标志位 record_last = record; } } // Update limit state 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; } } // Update general I/O stae private void UpdateIOState(int value, bool isInput) { int bitUpCnt = 0x01; for (int i = 0; i < MAX_UI_IO_CNT; i++) { if (isInput) { // Input state if ((value & bitUpCnt) != 0) m_lblInput[i].Image = Properties.Resources.On; else m_lblInput[i].Image = Properties.Resources.Off; } else { // Output state if ((value & bitUpCnt) != 0) { m_btnOutput[i].Text = "OFF"; m_lblOutput[i].Image = Properties.Resources.On; } else { m_btnOutput[i].Text = "ON"; m_lblOutput[i].Image = Properties.Resources.Off; } } // 0x01 => 0x02 => 0x04 => 0x08 ... increase bit number bitUpCnt = (0x01) << (i + 1); } } #endregion #region Motor Enable / Disable private void btnEnable_Click(object sender, EventArgs e) { // Enable selected axis _ACS.Enable((Axis)cboAxisNo.SelectedIndex); // If you want to enable several axes, // // Ex) Eanble three axes (0, 1, 6) // // int[] AxisList = new int[] { 0, 1, 6, -1 }; !!!! Important !! Must insert '-1' at the last // _ACS.EnableM(AxisList); } private void btnDisable_Click(object sender, EventArgs e) { // Disable selected axis _ACS.Disable((Axis)cboAxisNo.SelectedIndex); // Disable multi axes : DisableM(int[] axisList) } private void btnDisableAll_Click(object sender, EventArgs e) { // Disable all of axes _ACS.DisableAll(); } #endregion private void btnSetZero_Click(object sender, EventArgs e) { // Change current poisition as you want // SetFPosition(Axis number, new position) _ACS.SetFPosition((Axis)cboAxisNo.SelectedIndex, 0); } #region Move to absolute position private void btnPTP_Click(object sender, EventArgs e) { double lfTargetPos = 0.0f; try { if (txtPTP_Pos.Text.Length > 0) { lfTargetPos = Convert.ToDouble(txtPTP_Pos.Text); _ACS.ToPoint( 0, // '0' - Absolute position (Axis)cboAxisNo.SelectedIndex, // Axis number lfTargetPos // Target position ); } } catch (Exception ex) { MessageBox.Show(ex.Message, "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error); System.Diagnostics.Debug.WriteLine(ex.Message); } } #endregion #region Move to relative position (from current position) private void btnPTP_R_Neg_Click(object sender, EventArgs e) { double lfTargetPos = 0.0f; try { if (txtPTP_Pos.Text.Length > 0) { lfTargetPos = Convert.ToDouble(txtPTP_Pos.Text); if (lfTargetPos > 0) lfTargetPos = lfTargetPos * (-1); // Target position (from current position, step move) _ACS.ToPoint( MotionFlags.ACSC_AMF_RELATIVE, // Flat (Axis)cboAxisNo.SelectedIndex, // Axis number lfTargetPos // Move distance ); } } catch (Exception ex) { MessageBox.Show(ex.Message, "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error); System.Diagnostics.Debug.WriteLine(ex.Message); } } private void btnPTP_R_Pos_Click(object sender, EventArgs e) { double lfTargetPos = 0.0f; try { if (txtPTP_Pos.Text.Length > 0) { lfTargetPos = Convert.ToDouble(txtPTP_Pos.Text); if (lfTargetPos < 0) lfTargetPos = lfTargetPos * (-1); _ACS.ToPoint(MotionFlags.ACSC_AMF_RELATIVE, (Axis)cboAxisNo.SelectedIndex, lfTargetPos); } } catch (Exception ex) { MessageBox.Show(ex.Message, "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error); System.Diagnostics.Debug.WriteLine(ex.Message); } } #endregion #region Stop motion using deceleration (halt command) private void btnHalt_Click(object sender, EventArgs e) { try { _ACS.Halt((Axis)cboAxisNo.SelectedIndex); //使用 halt 命令减速 } catch (Exception ex) { MessageBox.Show(ex.Message, "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error); System.Diagnostics.Debug.WriteLine(ex.Message); } } private void btnHallAll_Click(object sender, EventArgs e) { try { // There is no halt all command, so you need to user HaltM function // // ex) You want to stop 0, 2, 5 axis // int[] m_arrAxisList = new int[] { 0, 2, 5, -1 }; // if (m_arrAxisList != null) _ACS.HaltM(m_arrAxisList); } catch (Exception ex) { MessageBox.Show(ex.Message, "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error); System.Diagnostics.Debug.WriteLine(ex.Message); } } #endregion #region JOG Command private void btnJogNeg_MouseDown(object sender, MouseEventArgs e) { double lfVelocity = 0.0f; try { if (chkUseVel.Checked) { lfVelocity = Convert.ToDouble(txtJogVel.Text.Trim()); if (lfVelocity > 0) lfVelocity = lfVelocity * (-1); // Negative direction : Using - (minus) velocity _ACS.Jog( MotionFlags.ACSC_AMF_VELOCITY, // Velocity flag 速度标志 (Axis)cboAxisNo.SelectedIndex, // Axis number lfVelocity // Velocity ); } else { _ACS.Jog(0, (Axis)cboAxisNo.SelectedIndex, (double)GlobalDirection.ACSC_NEGATIVE_DIRECTION); } } catch (Exception ex) { MessageBox.Show(ex.Message, "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error); System.Diagnostics.Debug.WriteLine(ex.Message); } } private void btnJogPos_MouseDown(object sender, MouseEventArgs e) { double lfVelocity = 0.0f; try { if (chkUseVel.Checked) { lfVelocity = Convert.ToDouble(txtJogVel.Text.Trim()); if (lfVelocity < 0) lfVelocity = lfVelocity * (-1); _ACS.Jog(MotionFlags.ACSC_AMF_VELOCITY, (Axis)cboAxisNo.SelectedIndex, lfVelocity); } else { _ACS.Jog(0, (Axis)cboAxisNo.SelectedIndex, (double)GlobalDirection.ACSC_POSITIVE_DIRECTION); } } catch (Exception ex) { MessageBox.Show(ex.Message, "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error); System.Diagnostics.Debug.WriteLine(ex.Message); } } private void btnJog_MouseUp(object sender, MouseEventArgs e) { _ACS.Halt((Axis)cboAxisNo.SelectedIndex); } #endregion #region Run/Stop Buffer Program private void btnRunBuffer_Click(object sender, EventArgs e) { string temp; try { if (txtLabelName.Text.Length > 0) { temp = txtLabelName.Text.ToUpper(); // Allow _ (Under bar) or A ~ Z characters if (temp[0] != 0x5F && (temp[0] < 0x41 || temp[0] > 0x5A)) { MessageBox.Show("Wrong 'Label' name inputed.", "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Information); return; } // Run buffer program from label position _ACS.RunBuffer((ProgramBuffer)cboBufferNo.SelectedIndex, txtLabelName.Text.Trim()); } else { // Run buffer program from first line _ACS.RunBuffer((ProgramBuffer)cboBufferNo.SelectedIndex, null); } } catch (Exception ex) { MessageBox.Show(ex.Message, "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error); System.Diagnostics.Debug.WriteLine(ex.Message); } } private void btnStopBuffer_Click(object sender, EventArgs e) { // Stop program _ACS.StopBuffer((ProgramBuffer)cboBufferNo.SelectedIndex); } #endregion #region Change motion profile private void TextBoxes_KeyPress(object sender, KeyPressEventArgs e) { try { double lfTemp = 0.0f; TextBox textBox = sender as TextBox; if (textBox != null) { // Allow numbers (0 ~ 9), . (DOT), Backspace if ((e.KeyChar >= 0x30 && e.KeyChar <= 0x39) || e.KeyChar == 0x2E || e.KeyChar == 0x08 || e.KeyChar == (char)Keys.Return || e.KeyChar == (char)Keys.Enter) { if ((e.KeyChar == 0x2E) && (textBox.Text.Contains(Convert.ToString(0x2E)))) e.KeyChar = (char)0x00; if (e.KeyChar == (char)Keys.Return || e.KeyChar == (char)Keys.Enter) { e.Handled = true; lfTemp = Convert.ToDouble(textBox.Text.Trim()); switch (textBox.TabIndex) { // Immediately change value (On the fly) : SetVelocityImm() // Affect next motion : SetVelocity() case 0: _ACS.SetVelocityImm((Axis)cboAxisNo.SelectedIndex, lfTemp); break; case 1: _ACS.SetAccelerationImm((Axis)cboAxisNo.SelectedIndex, lfTemp); break; case 2: _ACS.SetDecelerationImm((Axis)cboAxisNo.SelectedIndex, lfTemp); break; case 3: _ACS.SetKillDecelerationImm((Axis)cboAxisNo.SelectedIndex, lfTemp); break; case 4: _ACS.SetJerkImm((Axis)cboAxisNo.SelectedIndex, lfTemp); break; } textBox.SelectAll(); } } else e.KeyChar = (char)0x00; } } catch (Exception ex) { System.Diagnostics.Debug.WriteLine("TextBoxes_KeyPress() Error\n" + ex.ToString()); } } private void TextBoxes_Enter(object sender, EventArgs e) { try { TextBox textBox = sender as TextBox; if (textBox != null) textBox.SelectAll(); } catch (Exception ex) { System.Diagnostics.Debug.WriteLine("TextBoxes_Enter() Error\n" + ex.ToString()); } } private void TextBoxes_Leave(object sender, EventArgs e) { try { double lfTemp = 0.0f; TextBox textBox = sender as TextBox; if (textBox == null) return; lfTemp = Convert.ToDouble(textBox.Text.Trim()); switch (textBox.TabIndex) { case 0: _ACS.SetVelocityImm((Axis)cboAxisNo.SelectedIndex, lfTemp); break; case 1: _ACS.SetAccelerationImm((Axis)cboAxisNo.SelectedIndex, lfTemp); break; case 2: _ACS.SetDecelerationImm((Axis)cboAxisNo.SelectedIndex, lfTemp); break; case 3: _ACS.SetKillDecelerationImm((Axis)cboAxisNo.SelectedIndex, lfTemp); break; case 4: _ACS.SetJerkImm((Axis)cboAxisNo.SelectedIndex, lfTemp); break; } textBox.SelectAll(); } catch (Exception ex) { System.Diagnostics.Debug.WriteLine("TextBoxes_Leave() Error\n" + ex.ToString()); } } #endregion #region On and Off General Output private void btnSW_Click(object sender, EventArgs e) { int nBitNo = 0x01; try { Button btn = sender as Button; if (btn == null) return; nBitNo = btn.TabIndex; nBitNo = (0x01) << nBitNo; //左移几位 if ((m_nOutputState & nBitNo) != 0) { // Set only 1 bit _ACS.SetOutput( 0, // Port number btn.TabIndex, // Bit number 0 // 0 = OFF, 1 = ON ); // If your I/O device is EtherCAT type, you cannot use this function // You can use WriteVariable function and Command function // // Ex) If EtherCAT mapped variable is 'EC_DOUT' // Want to ON bit '3' // _ACS.Command("EC_DOUT.3=1"); } else { _ACS.SetOutput(0, btn.TabIndex, 1); } } catch (Exception ex) { System.Diagnostics.Debug.WriteLine("btnSW_Click() Error\n" + ex.ToString()); } } #endregion #region Event private void btnEventMotionEnd_Click(object sender, EventArgs e) { //_ACS.PHYSICALMOTIONEND +=_ACS_PHYSICALMOTIONEND; _ACS.EnableEvent(Interrupts.ACSC_INTR_PHYSICAL_MOTION_END); lstLog.Items.Add("PHYSICAL_MOTION_END event enabled"); } void _ACS_PHYSICALMOTIONEND(AxisMasks axis) { int bit = 0x01; int axisNo = 0; // Param value is bit number // Bit Number = Axis Number for (int i = 0; i < 64; i++) { if ((int)axis == bit) { axisNo = i; break; } bit = bit << 1; } // Add log to ListBox this.Invoke((MethodInvoker)delegate { lstLog.Items.Add(String.Format(" - Axis {0}, Stoppped", axisNo)); lstLog.SelectedIndex = lstLog.Items.Count - 1; }); } private void btnEventProgramEnd_Click(object sender, EventArgs e) { //_ACS.PROGRAMEND += _ACS_PROGRAMEND; _ACS.EnableEvent(Interrupts.ACSC_INTR_PROGRAM_END); lstLog.Items.Add("PROGRAM_END event enabled"); } private void button8_Click(object sender, EventArgs e) { } private void button9_Click(object sender, EventArgs e) { } void _ACS_PROGRAMEND(BufferMasks buffer) { int bit = 0x01; int bufferNo = 0; // Param value is bit number // Bit Number = Axis Number for (int i = 0; i < 32; i++) { if ((int)buffer == bit) { bufferNo = i; break; } bit = bit << 1; } // Add log to ListBox this.Invoke((MethodInvoker)delegate { lstLog.Items.Add(String.Format(" - Buffer {0}, Stoppped", bufferNo)); lstLog.SelectedIndex = lstLog.Items.Count - 1; }); } #endregion #region Communication Termial - Using Transaction function private void txtCommand_KeyPress(object sender, KeyPressEventArgs e) { if (e.KeyChar == (char)Keys.Enter) btnSend.PerformClick(); } private void btnSend_Click(object sender, EventArgs e) { string temp = string.Empty; if (m_bConnected) { try { AppendTextToTextBox("> " + txtCommand.Text.Trim()); temp = _ACS.Transaction(txtCommand.Text.Trim()); } catch (ACS.SPiiPlusNET.ACSException ex) { temp = String.Format("?{0}", ex.ErrorCode); } finally { if (temp.Length > 0) { AppendTextToTextBox(temp); AppendTextToTextBox(":"); } } txtCommand.Focus(); txtCommand.SelectAll(); } } private void AppendTextToTextBox(string text) { rtxtTerminal.AppendText(text); rtxtTerminal.AppendText(Environment.NewLine); rtxtTerminal.ScrollToCaret(); } #endregion #region 三轴插补运动 private void button11_Click(object sender, EventArgs e) //MultiPointM 方法 { lstLog.Items.Add("MultiPointM"); int timeout = 5000; Axis[] axes = { Axis.ACSC_AXIS_0, Axis.ACSC_AXIS_1, Axis.ACSC_NONE }; double[] points = { 0, 0 }; _ACS.EnableM(axes); // Enable axis 0 and 1 // Wait axis 0 enabled during 5 sec _ACS.WaitMotorEnabled(Axis.ACSC_AXIS_0, 1, timeout); // Wait axis 1 enabled during 5 sec _ACS.WaitMotorEnabled(Axis.ACSC_AXIS_1, 1, timeout); // Create multi-point motion of axis 0 and 1 with default // velocity without // dwell in the points //_ACS.MultiPointM(MotionFlags.ACSC_NONE, axes, 0); // Add some points for (int index = 0; index < 5; index++) { points[0] = 100 * index; points[1] = 100 * index; //_ACS.AddPointM(axes, points); _ACS.ToPointM(MotionFlags.ACSC_AMF_VELOCITY,axes, points); //将点添加到 lstLog.Items lstLog.Items.Add("points[0]:" + points[0].ToString() + "points[1]:" + points[1].ToString()); } lstLog.Items.Add("结束添加"); // Finish the motion // End of the multi-point motion _ACS.EndSequenceM(axes); lstLog.Items.Add("执行"); record=true; } private void button12_Click(object sender, EventArgs e) //SplineM 方法 { lstLog.Items.Add("SplineM"); int timeout = 5000; Axis[] axes = { Axis.ACSC_AXIS_0, Axis.ACSC_AXIS_1,Axis.ACSC_AXIS_8, Axis.ACSC_NONE }; double[] points = { 0, 0 ,0}; _ACS.EnableM(axes); // Enable axes 0 and 1 _ACS.WaitMotorEnabled(Axis.ACSC_AXIS_0, 1, timeout); _ACS.WaitMotorEnabled(Axis.ACSC_AXIS_1, 1, timeout); _ACS.WaitMotorEnabled(Axis.ACSC_AXIS_8, 1, timeout); // Create the arbitrary path motion to axes 0 and 1 with // uniform interval 10 ms use a cubic interpolation // between the specified points _ACS.SplineM(MotionFlags.ACSC_AMF_CUBIC, axes, 1000); // Add some points // 定义三维点列表 int[,] pointsArray = new int[,] { { 0, 0, 0 }, { 10, 20, -10 }, { 20, 30, -40 }, { 30, 50, -20 }, { 40, 70, -30 }, { 50, 80, -50 }, { 60, 70, -60 }, { 70, 50, -70 }, { 80, 30, -80 }, { 90, 10, -90 } }; // 遍历列表并添加点 for (int index = 0; index < pointsArray.GetLength(0); index++) { double[] speed = { 100,100,100}; points[0] = pointsArray[index, 0]; points[1] = pointsArray[index, 1]; points[2] = pointsArray[index, 2]; // 使用AddPVPointM方法添加点 _ACS.AddPVPointM(axes, points, speed); // 将点信息添加到lstLog.Items lstLog.Items.Add($"points[0]: {points[0]} points[1]: {points[1]} points[2]: {points[2]}"); } //_ACS.GoM(axes); // Finish the motion // End of the multi-point motion _ACS.EndSequenceM(axes); //_ACS.GoM(axes); record = true; } private void button13_Click(object sender, EventArgs e) //AddPVTPointM 方法 { lstLog.Items.Add("AddPVTPointM"); int timeout = 5000; Axis[] axes = { Axis.ACSC_AXIS_0, Axis.ACSC_AXIS_1, Axis.ACSC_NONE }; double[] points = { 0, 0 }; _ACS.EnableM(axes); // Enable axes 0 and 1 // Wait axis 0 enabled during 5 sec _ACS.WaitMotorEnabled(Axis.ACSC_AXIS_0, 1, timeout); // Wait axis 1 enabled during 5 sec _ACS.WaitMotorEnabled(Axis.ACSC_AXIS_1, 1, timeout); // PVT motion and uniform interval is not used _ACS.SplineM(MotionFlags.ACSC_AMF_CUBIC | MotionFlags.ACSC_AMF_VARTIME, axes, 0); // Add some points for (int index = 0; index < 5; index++) { points[0] = 100 * index; // 0, 100, 200, 300, 400 points[1] = 50 * index; // 0, 200, 400, 600, 800 _ACS.AddPVTPointM(axes, points, points, 1000); } // Finish the motion // End of the multi-point motion _ACS.EndSequenceM(axes); record = true; } private void button14_Click(object sender, EventArgs e)//SegmentLine,平面内 { lstLog.Items.Add("SegmentLine"); int timeout = 5000; Axis[] axes = { Axis.ACSC_AXIS_1, Axis.ACSC_AXIS_8, Axis.ACSC_NONE }; double[] points = { 0, 0, 0 }; _ACS.EnableM(axes); // Enable axes 0 and 1 // Wait axis 0 enabled during 5 sec _ACS.WaitMotorEnabled(Axis.ACSC_AXIS_0, 1, timeout); // Wait axis 1 enabled during 5 sec _ACS.SegmentedMotion(MotionFlags.ACSC_AMF_VELOCITY, axes, points); lstLog.Items.Add("SegmentLine 1"); points[0] = 500; points[1] = -100; //points[2] = -100; _ACS.SegmentLine(MotionFlags.ACSC_NONE, axes, points, Api.ACSC_NONE, Api.ACSC_NONE, null, null, Api.ACSC_NONE, null); _ACS.Stopper(axes); //平滑 points[0] = 200; points[1] = -200; //points[2] = -200; _ACS.SegmentLine(MotionFlags.ACSC_NONE, axes, points, Api.ACSC_NONE, Api.ACSC_NONE, null, null, Api.ACSC_NONE, null); _ACS.EndSequenceM(axes); } private void button18_Click(object sender, EventArgs e) { record = true; } private void button19_Click(object sender, EventArgs e) { lstLog.Items.Add("停止记录"); record = false; } private void button10_Click(object sender, EventArgs e) { } private void button20_Click(object sender, EventArgs e)//MultiPointM { lstLog.Items.Add("MultiPointM"); int timeout = 5000; Axis[] axes = { Axis.ACSC_AXIS_0, Axis.ACSC_AXIS_1,Axis.ACSC_NONE }; double[] points = { 0, 0 }; _ACS.EnableM(axes); // Enable axes 0 and 1 // Wait axis 0 enabled during 5 sec _ACS.WaitMotorEnabled(Axis.ACSC_AXIS_0, 1, timeout); // Wait axis 1 enabled during 5 sec _ACS.WaitMotorEnabled(Axis.ACSC_AXIS_1, 1, timeout); // Create multi-point motion with default velocity without // dwell _ACS.MultiPointM(MotionFlags.ACSC_AMF_VELOCITY, axes, 0); // Add some points for (int index = 0; index < 5; index++) { // Position and velocity for each point points[0] = 100 * index; points[1] = 100 * index; _ACS.ExtAddPointM(axes, points, 5000); } // Finish the motion // End of the multi-point motion _ACS.EndSequenceM(axes); } private void button15_Click(object sender, EventArgs e) //ExtLine { int timeout = 5000; Axis[] axes = { Axis.ACSC_AXIS_0, Axis.ACSC_AXIS_1,Axis.ACSC_AXIS_8,Axis.ACSC_NONE }; double[] points = { 0, 0, 0 }; // Create segmented motion,coordinates of the initial point // are(1000, 1000) _ACS.EnableM(axes); // Wait axis 0 enabled during 5 sec _ACS.WaitMotorEnabled(Axis.ACSC_AXIS_0, 1, timeout); // Wait axis 1 enabled during 5 sec _ACS.WaitMotorEnabled(Axis.ACSC_AXIS_1, 1, timeout); // Wait axis 8 enabled during 5 sec _ACS.WaitMotorEnabled(Axis.ACSC_AXIS_8, 1, timeout); _ACS.Segment(MotionFlags.ACSC_NONE, axes, points); // Add line segment with final point (1000,-1000),vector // velocity 25000 points[0] = 100; points[1] = 100; points[2] = -10; _ACS.ExtLine(axes, points, 25000); _ACS.Stopper(axes); // Add line segment with final point (-1000,-1000),vector // velocity 25000 points[0] = 100; points[1] = 200; points[2] = -100; _ACS.ExtLine(axes, points, 25000); _ACS.Stopper(axes); // Add line segment with final point (-1000,1000),vector // velocity 25000 points[0] = 200; points[1] = 200; points[2] = -200; _ACS.ExtLine(axes, points, 25000); _ACS.Stopper(axes); // Add line segment with final point (1000,1000), vector // velocity 25000 points[0] = 200; points[1] = 100; points[2] = -100; _ACS.ExtLine(axes, points, 25000); // Finish the motion // End of the multi-point motion _ACS.EndSequenceM(axes); } private void button16_Click(object sender, EventArgs e) //BlendedLine { lstLog.Items.Add("BlendedLine "); int timeout = 5000; Axis[] Axes = { Axis.ACSC_AXIS_0, Axis.ACSC_AXIS_1, Axis.ACSC_NONE }; _ACS.EnableM(Axes); // Enable axes 0 and 1 _ACS.WaitMotorEnabled(Axis.ACSC_AXIS_0, 1, timeout); _ACS.WaitMotorEnabled(Axis.ACSC_AXIS_1, 1, timeout); _ACS.WaitMotorEnabled(Axis.ACSC_AXIS_8, 1, timeout); double[] Point = { 100, 100 }; _ACS.BlendedSegmentMotion(MotionFlags.ACSC_NONE, Axes, Point,//Starting point of motion 1000, // Segment time 500, // Segment Acceleration time 200, // Segment jerk time 0);// Waiting call double[] FinalPoint = { 300, 300}; _ACS.BlendedLine(MotionFlags.ACSC_NONE, Axes,FinalPoint, 10000, 200, 300, 0); //增加第二个点(500,400) double[] FinalPoint2 = { 500, 400 }; _ACS.BlendedLine(MotionFlags.ACSC_NONE, Axes, FinalPoint2, 10000, 200, 300, 0); //增加第三个点(600,100) double[] FinalPoint3 = { 600, 100 }; _ACS.BlendedLine(MotionFlags.ACSC_NONE, Axes, FinalPoint3, 10000, 200, 300, 0); _ACS.EndSequenceM(Axes); record =true; } private void button17_Click(object sender, EventArgs e) //ExtAddPointM 方法 { lstLog.Items.Add("ExtAddPointM "); int timeout = 5000; Axis[] axes = { Axis.ACSC_AXIS_0, Axis.ACSC_AXIS_1,Axis.ACSC_NONE }; double[] points = { 0, 0 }; _ACS.EnableM(axes); // Enable axes 0 and 1 // Wait axis 0 enabled during 5 sec _ACS.WaitMotorEnabled(Axis.ACSC_AXIS_0, 1, timeout); // Wait axis 1 enabled during 5 sec _ACS.WaitMotorEnabled(Axis.ACSC_AXIS_1, 1, timeout); // Create multi-point motion with default velocity without // dwell _ACS.MultiPointM(MotionFlags.ACSC_AMF_VELOCITY, axes, 0); // Add some points for (int index = 0; index < 5; index++) { // Position and velocity for each point points[0] = 100 * index; points[1] = 100 * index; _ACS.ExtAddPointM(axes, points, 5000); } // Finish the motion // End of the multi-point motion _ACS.EndSequenceM(axes); record = true; } private void button1_Click(object sender, EventArgs e) { } #endregion } }