小弟先在此謝過各位進來看過,小弟想問下怎麼通過serialport這個類來控制PLC節點的on和off,請問能給出解決方案麼?在綫等謝謝大家了!

解决方案 »

  1.   

     查询plc的命令,把命令sendto plc
      

  2.   

    三樓您好  我現在是這樣,有8個 label 依次為:X1 X2 X3 X4 Y1 Y2 Y3 Y4 然後相應對著 PLC的
    X1 X2 X3 X4 Y1 Y2 Y3 Y4 ,然後我用線觸碰PLC的X1 那X1的燈就會亮,跟著我這裡的label X1由黑色變為紅色,反之,如果斷開接觸,label X1由紅色變為黑色!請問我應該怎麼做  或者能給我一個連接上PLC的程式例子嗎?
      

  3.   

    串口通信编程,主要是根据产品说明书来就行了,波特率、数据位、停止位、校验位等参数设置正确
    如果有例子,可以研究例子的写法调试的时候用portmon软件监视,看读写数据是不是完全满足游戏规则
      

  4.   

    PLC应该要和计算机串口有通讯才行,PLC的灯亮了,但是同时如果没有通过串口发送数据给计算机的话,你的LABLE想变化是不可能的,需要联系PLC的开发人员,让他提供通讯协议给你。
      

  5.   

    我希望就是給我一個用C#來反映PLC的代碼!控制X和Y          protected int BytesToRead = 0;
            protected int ReadStart = 0;
            protected char[] ReadBuffer = new char[1000];        Port = new SerialPort(COMPort, BaudRate, Parity, DataBit, StopBit);
            Port.DataReceived += new SerialDataReceivedEventHandler(Port_DataReceived);        Port.Open();
            Port.Write(…);        protected virtual void Port_DataReceived(object sender,   SerialDataReceivedEventArgs e)
            {
                BytesToRead = Port.BytesToRead;
                Port.Read(ReadBuffer, ReadStart, BytesToRead);
            }
    就是不知道Write裏面寫什麼
      

  6.   

    參數是         public string COMPort = 3;
            public int BaudRate = 19200;
            public Parity Parity = Parity.Even;
            public int DataBit = 7;
            public StopBits StopBits = StopBits.One;
      

  7.   

    主要是看PLC的协议是如何定义的
    然后往COM定对应的指令就好了,
    以前干过,
    PLC那块是另外部门的同事做的,他让发什么指令就发什么
      

  8.   

    这个只是设COM口的参数,
    要往COM口写东西才行,至于写什么就看PLC上是如何定义的了
      

  9.   


    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;
    using System.IO.Ports;namespace TryPLC
    {
        public partial class Form1 : Form
        {
            SerialPort spcom;
            public string COMPort = "COM3";
            public int BaudRate = 9600;
            public Parity Parity = Parity.Even;
            public int DataBit = 7;
            public StopBits StopBits = StopBits.One;
            protected int BytesToRead = 0;
            protected int ReadStart = 0;
            private string b;
            private delegate void MydelegateShow();
            private MydelegateShow SerialDelegate;        public Form1()
            {
                InitializeComponent();
                this.Load += new EventHandler(Form1_Load);
                butsend.Click += new EventHandler(butsend_Click);
                butrev.Click += new EventHandler(butrev_Click);
            }        private void Form1_Load(object sender, EventArgs e)
            {
                spcom = new SerialPort(COMPort, BaudRate, Parity, DataBit, StopBits);
                SerialDelegate = new MydelegateShow(UpdateTextBox);
                spcom.DataReceived += new SerialDataReceivedEventHandler(spcom_DataReceived);
                spcom.ReceivedBytesThreshold = 1;            try
                {
                    if (spcom.IsOpen == false)
                    {
                        spcom.Open();
                    }
                    else
                    {
                        spcom.Close();
                        spcom.Open();
                    }
                }
                catch
                {
                    MessageBox.Show("沒有找到串口,請檢查後再試……", "警告");
                }
                if (spcom.IsOpen == true)
                {
                    spcom.DiscardInBuffer();
                }
            }        public void spcom_DataReceived(object sender, SerialDataReceivedEventArgs e)
            {
                if (spcom.BytesToRead == 0)
                {
                    return;
                }
                char[] buffer = new char[1000];
                spcom.Read(buffer, 0, buffer.Length);
                b = new string(buffer);
                this.Invoke(SerialDelegate);
            }        private void UpdateTextBox()
            {
                txtrev.Text += b;
            }        //發送數據
            private void butsend_Click(object sender, EventArgs e)
            {
                SendStringData(spcom);
            }        //發送字符串數據
            private void SendStringData(SerialPort serialPort)
            {
                try
                {
                    if (!spcom.IsOpen)
                    {
                        spcom.Open();
                    }
                    spcom.Write(txtSend.Text);
                }
                catch
                {
                    MessageBox.Show("沒有找到串口,請先打開串口", "警告");
                }
                spcom.Close();
            }        //發送二進制數據
            private void SendBytesData(SerialPort serialPort)
            {
                byte[] bytesSend = Encoding.Default.GetBytes(txtSend.Text);
                spcom.Write(bytesSend, 0, bytesSend.Length);
            }        private void butrev_Click(object sender, EventArgs e)
            {
                txtrev.Text = "";
            }        private void txtsend_TextChenged(object sender, EventArgs e)
            { 
                
            }        private void txtrev_TextChanged(object sender, EventArgs e)
            {
                txtrev.SelectionStart = txtrev.Text.Length;
                txtrev.SelectionLength = 0;
                txtrev.ScrollToCaret();
            }
        }
    }
    這是我已經可以連接串口了,但是怎麼用指令接收PLC的X的on和off的狀態呢?我的是永宏PLC
      

  10.   

    支持modbus嘛。
    在PLC中得有相应的程序来接受串口的数据。
    比如用modbus,你可以调用编程软件的modbus库,设置校验位,波特率等等,完成PLC编程。
    然后用电脑的232,加上232转485的转换器,一般PLC通信都是485的。(注意)
    然后通过发送串口数据,才能实现通讯。
      

  11.   

    关键问题的  你的PLC支持什么通信协议  你得按照它的通信协议来编程 
    不是简单的串口数据收发就完了。
      

  12.   

    19樓  您有QQ嗎?我這裡有份通信協議  您可以看下  我實在不太懂這個PLC.我只是一個C#初學者。。您能抽個時間和我講解一下嗎?很想學習!謝謝您了!
      

  13.   

    17楼的例子LZ应该好好看看,这是一个简单的RS232通讯的例子。
    只串口的打开和关闭这不重要,重要是你前面几位兄弟说的通讯协议,因为每个PLC的协议都是不一样的。先把协议吃透,起始符是什么,前几位代表什么,数据位在哪,是什么校验方式,结束符是什么等等等等,然后就是基本的发送和接收了。
    按照经验,这样的程序应该用多线程来实现,最简单的,一个UI,一个负责PLC的通讯。
    LZ首要解决的是:1)RS232或485的通讯实现 2)PLC协议的理解
      

  14.   

    抄别人的。转载的。
    通过MODBUS TCP读写PLC源码
    功能模块一:读写PLC主模块
    using System;
    using System.Net;
    using System.Net.Sockets;
    using System.Windows.Forms;
    /// <summary>
    /// 通过modbus TCP读写PLC数据,
    /// 
    /// 设计:张东启,2011.4.9
    /// 2011.5.13更新,加入Application.DoEvents();以防连续读写时引起前台反应迟顿,同时让PLC有处理等待时间
    /// 
    /// 
    /// 
    /// </summary>public class PLCFunction
    {    public static bool Connected = false;
        public static int trytimes = 0;
        //内部使用变量
        private static byte[] sendBuf = { 0, 0, 0, 0, 0, 06, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };  //共20个字节
        private static byte[] recBuf = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };  //共20个字节
        private static int hi, low, bytes, hi1, low1;
        private static Socket zdqSocket;
        private static string tiaoshi="N";
        private static string plcAddress = "127.0.0.1";
        public static int ReadWord(int mwAddress)
    {
            int rtValue = -99; 
            if (init_plc() == 0)
            {
                try
                {
                    hi = mwAddress / 256;
                    low = mwAddress - hi * 256;                sendBuf[7] = 3;
                    sendBuf[8] = (byte)hi;
                    sendBuf[9] = (byte)low;
                    sendBuf[10] = 0;
                    sendBuf[11] = 1;                //发送查询
                    zdqSocket.Send(sendBuf, 12, 0);
                    Application.DoEvents();
                    bytes = zdqSocket.Receive(recBuf, 11, 0);  //返回11个字节
                    if (bytes == 11)
                    {
                        hi = recBuf[9];
                        low = recBuf[10];
                        rtValue = hi * 256 + low;
                    }
                    trytimes = 0;
                }
                catch (Exception te)
                {
                    if (tiaoshi == "Y") MessageBox.Show(te.ToString());
                    trytimes++;
                }
            }
            return rtValue;
    }
        public static void WriteWord(int mwAddress,int mwValue)
        {
            if (init_plc() == 0)
            {
                try
                {
                    hi = mwAddress / 256;
                    low = mwAddress - hi * 256;
                    hi1 = mwValue / 256;
                    low1 = mwValue - hi * 256;
                    sendBuf[7] = 6;
                    sendBuf[8] = (byte)hi;
                    sendBuf[9] = (byte)low;
                    sendBuf[10] = (byte)hi1;
                    sendBuf[11] = (byte)low1;
                    zdqSocket.Send(sendBuf, 12, 0);
                    Application.DoEvents();
                    bytes = zdqSocket.Receive(recBuf, recBuf.Length, 0);  //写一个字返回几个?
                    trytimes = 0;
                }
                catch (Exception te)
                {
                    if (tiaoshi == "Y") MessageBox.Show(te.ToString());
                    trytimes++;
                }
            }
        }
        public static int GetMemory(int mwAddress)
        {
            int rtValue = -99;
            if (init_plc() == 0)
            {
                try
                {
                    hi = mwAddress / 256;
                    low = mwAddress - hi * 256;                sendBuf[7] = 2;
                    sendBuf[8] = (byte)hi;
                    sendBuf[9] = (byte)low;
                    sendBuf[10] = 0;
                    sendBuf[11] = 1;                //发送查询
                    zdqSocket.Send(sendBuf, 12, 0);
                    Application.DoEvents();
                    bytes = zdqSocket.Receive(recBuf, 10, 0);  //返回11个字节
                    if (bytes == 10)
                    {
                        hi = recBuf[9];
                        rtValue = hi;
                    }
                    trytimes = 0;
                }
                catch (Exception te)
                {
                    if (tiaoshi == "Y") MessageBox.Show(te.ToString());
                    trytimes++;
                }
            }
            return rtValue;
        }    public static void SetMemory(int mwAddress,int mFlag)
        {
            if (init_plc() == 0)
            {
                //线圈置位与复位
                int mBit = 0;
                if (mFlag == 1) mBit = 255; else mBit = 0;
                try
                {
                    hi = mwAddress / 256;
                    low = mwAddress - hi * 256;
                    sendBuf[7] = 5;
                    sendBuf[8] = (byte)hi;
                    sendBuf[9] = (byte)low;
                    sendBuf[10] = (byte)mBit;
                    sendBuf[11] = 0;
                    zdqSocket.Send(sendBuf, 12, 0);
                    Application.DoEvents();
                    bytes = zdqSocket.Receive(recBuf, recBuf.Length, 0);
                    trytimes = 0;            }
                catch (Exception te)
                {
                    if (tiaoshi == "Y") MessageBox.Show(te.ToString());
                    trytimes++;
                }
            }
        }
        private static int init_plc()
        {
            //初始化
            int zdqrt = 0;
            if (trytimes > 3) 
            {
                //超过3次自动恢复连接
                if (zdqSocket.Connected == true) zdqSocket.Disconnect(false);
                zdqSocket = null;
                trytimes = 0;
            }
            try
            {
                if (zdqSocket == null)
                {
                    zdqSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                    zdqSocket.ReceiveTimeout = int.Parse(zdqpro.WriteOrReadINI("系统设置", "接收超时"));
                    plcAddress = zdqpro.WriteOrReadINI("系统设置", "PLC地址");            }
                if (zdqSocket.Connected == false)
                {
                    //重新连接
                    tiaoshi = zdqpro.WriteOrReadINI("系统设置", "PLC调试");
                    zdqSocket.Connect(plcAddress, 502);
                }
            }
            catch (Exception te)
            {
                if (tiaoshi == "Y") MessageBox.Show(te.ToString());
                trytimes++;
                zdqrt = -1;
            }
            Connected = zdqSocket.Connected;//是否已经连接
            Application.DoEvents();
            return zdqrt;
        }
    }读写配置文件功能代码
        public static string WriteOrReadINI(string rootNod, string valueNod)
        {        //读取配置文件
            XmlDocument mydoc = new XmlDocument();
            mydoc.Load("zdqsys.ini");
            string str1 = rootNod + "/" + valueNod;
            string rt = mydoc.SelectSingleNode(str1).InnerText;
            return rt;
        }    public static void WriteOrReadINI(string rootNod, string valueNod, string valueStr)
        {
            //写入配置文件
            XmlDocument mydoc = new XmlDocument();
            mydoc.Load("zdqsys.ini");
            string str1 = rootNod + "/" + valueNod;
            XmlNode mynod = mydoc.SelectSingleNode(str1);
            mynod.InnerText = valueStr;
            mydoc.Save("zdqsys.ini");
    }

    配置文件zdqsys.ini内容如下:
    <?xml version="1.0" encoding="GB2312"?>
    <系统设置>
      <PLC地址>192.168.1.200</PLC地址>
      <接收超时>10</接收超时>
      <PLC调试>N</PLC调试>
    </系统设置>


    希望能与工控爱好者或相关开发人员相互交流切搓,不当之处敬请指教。
                                       张东启  2011.5.15
      

  15.   

    不好意思   我的是RS232的線來連接PLC的
      

  16.   

    起始符:STX    結尾字符是:ETX     都是ASCI I 码
      

  17.   

    LZ還沒解決麼???我也在找人  怎麼獲取PLC的X節點
      

  18.   

    X 输入接点 X0000~ X9999 WX0000~WX9984 DWX0000~ DWX9968
    Y 输出继电器 Y0000~ Y9999 WY0000~WY9984 DWY0000~ DWY9968
    本文信息中单点状态的表示是以一个字符来表示( 1 表示ON,0 表OFF),而
    16 位缓存器数据则以4 个字符来表示一个Word 的数值( 0000H~ FFFFH)。
      

  19.   

    這裡沒人PLC高手前來指點一下嗎?
      

  20.   

    各位高手  我這裡的問題還沒解決呢!!  怎麼獲取PLC的X位元