资讯详情

基于台达PLC的步进电机控制续一>

一、控制和使用步进电机LD语言实现

涉及程序段X、Y轴动作包括单相对位置运动、点动、回零、当前位置为零、停止等。

二、按预设路径行动

在路径控制程序段中,回字运动。XY双轴交替关联。

三、基于台达触摸屏程序进行仿真

四、基于C# GDI 绘制步进电机动作路径

通过C#读取PLC请参考数据

基于C# 读写PLC数据

使用C# GDI 请参考绘图和擦除功能

基于C# GDI 绘图及擦除

这里不再赘述。

using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading.Tasks; using System.Windows.Forms;  namespace readPLCData {     public partial class Form1 : Form     {         public Form1()         {             InitializeComponent();               ///解决跨线程访问问题             CheckForIllegalCrossThreadCalls = false;                       }          private void DrwaAxis()         {             ///绘制坐标轴             Graphics gr = panel1.CreateGraphics();             Pen pen1 = new Pen(Color.Black);             gr.DrawLine(pen1, new Point(0, 500), new Point(1000, 500));             gr.DrawLine(pen1, new Point(500, 0), new Point(500, 1000));         }          Modbus.Device.ModbusIpMaster ipMaster;         TcpClient tcpClient;         Graphics g;          bool start;         private void Button1_Click(object sender, EventArgs e)         {             if (button1.Text == "开始")             {                 button1.Text = "停止";                 DrwaAxis();                 start = true;                  //打开线程,读取数据                 Task.Run(() =>                 {                     DrawLine();                 });                  //连接PLC                 try                 {                     tcpClient = new TcpClient();                     tcpClient.Connect(IPAddress.Parse("192.168.1.5"), 502);                     ipMaster = Modbus.Device.ModbusIpMaster.CreateIp(tcpClient);                 }                 catch (Exception)                 {                     MessageBox.Show("连接PLC失败");                 }               }             else if (button1.Text == "停止")             {                 button1.Text = "开始";                 start = false;                  //关闭PLC连接                 tcpClient.Close();                 ipMaster.Dispose();              }          }          bool[] draw = new bool[2];         bool xStep, yStep;         Point p1 = new Point(500, 500);         Point p2 = new Point();          int i =1;         private void DrawLine()         {             while (start)             {                 try                 {                     draw = ipMaster.ReadCoils(125, 2);                     lbl_Step.Text = draw[0].ToString()   "-"   draw[1].ToString();                  }                 catch (Exception)                 {                     txtb_Message.AppendText("读取单个状态失败");                 }                  if (draw[0] || draw[1])                 {                     try                     {                         var res = ipMaster.ReadHoldingRegisters(1000, 9);                         if (res.Length == 9)                         {                             float x = GetIntFromUshortArray(new ushort[] { res[1], res[0] });                             float y = GetIntFromUshortArray(new ushort[] { res[3], res[2] });                             p2.X = (int)(x / 100)   500;                             p2.Y = (int)(y / 100)   500;                                                                                      lbl_X.Text = x.ToString();                             lbl_Y.Text = y.ToString();                             txtb_Message.AppendText(i.ToString()   ":  "   "X:"   x.ToString()   "   "   "Y:"   y.ToString()   "\r\n");                             i  = 1;                         }                     }                     catch (Exception)                     {                         txtb_Message.AppendText("读取x、y失败");                     }                      Pen pen = new Pen(Color.Red);                     g = panel1.CreateGraphics();//CreateGraphics();                     g.DrwLine(pen, p1, p2);
                    p1 = p2;

                    
                }
            }
        }


        #region ***定义功能函数   GetFloatFromUshortArray***
        private int GetIntFromUshortArray(ushort[] p)
        {
            List<byte> result = new List<byte>();
            result.AddRange(BitConverter.GetBytes(p[0]));
            result.AddRange(BitConverter.GetBytes(p[1]));
            byte[] b = new byte[4];
            b[0] = result[2];
            b[1] = result[3];
            b[2] = result[0];
            b[3] = result[1];
            //高位在后,低位在前
            //  float aa = BitConverter.ToSingle(b, 0);
            //  string str = FloatToHex(aa).ToString();
            //  float bb = HexToFloat(str);
            //return BitConverter.ToSingle(b, 0);
            return BitConverter.ToInt32(b, 0);
        }
        #endregion
        private void Btn_ClearPanel_Click(object sender, EventArgs e)
        {
            i = 1;
            p1.X = 500;
            p1.Y = 500;
            Graphics grap = panel1.CreateGraphics();
            SolidBrush sb = new SolidBrush(this.BackColor);
            Rectangle r = new Rectangle(0, 0, 1000, 1000);
            grap.FillRectangle(sb, r);


            DrwaAxis();

        }

 
    }
}

 运行起来即可捕捉双轴路径。

如下图:

 右侧文本框中使用村村错误信息以及每次划线时的X Y坐标。

注:若在路径图中出现斜线时,并非双轴联动出现问题,而是因为X轴或Y轴完成时,触发(M125和M126)时间太短,上位机未检测到该状态变为True。请自行调试。

所有资源已打包,基于台达PLC的步进电机控制方案,欢迎下载。

五、自动路径功能中添加限位功能

        例如:当X轴正限位触发时,需得停止正向的动作,且此时不允许进行正向的动作,同理反向一样。此时,将自动路劲功能拆分为X轴正向--------Y轴正向---------X反向--------Y反向到的动作。循环往复,完成设定的圈数后停止。

        自动路劲控制段程序修改如下:

 

 

 

 

 

 该部分的PLC程序加上位机程序已打包,基于台达PLC的步进电机控制方案<续>欢迎下载调试。

标签: m125dc2labb继电器

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台