基于台达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.DrawLine(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的步进电机控制方案<续>欢迎下载调试。

  • 2
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值