C#读取三菱FX PLC

.Net技术 码拜 8年前 (2017-04-27) 1852次浏览
这两天帮老爸干个活儿。写个程序去读PLC里面的数据
端口设置如下:
SerialPort com = new SerialPort(“COM4”, 9600, Parity.Even, 7, StopBits.One);
从D200开始读,读9个数据,感觉这东西还不算难。
在论坛里找了找,有收获,写了测试
发现,D200-D204读取正常,D205读取就会返回15H(接收错误),不知道为什么,求高手指点!
附程序

        SerialPort com = new SerialPort("COM4", 9600, Parity.Even, 7, StopBits.One);
        string[] po = new string[9];//读取指令
        string[] check = new string[9];//校验位
        public int[] apb = new int[9];//amount per box,每箱件数
private void FirstUse()
        {
            if (com.IsOpen)
            { 
                com.Close();
            }
            com.Open();
        }
        public static string Chr(int asciiCode)
        {
            if (asciiCode >= 0 && asciiCode <= 255)
            {
                System.Text.ASCIIEncoding asciiEncoding = new System.Text.ASCIIEncoding();
                byte[] byteArray = new byte[] { (byte)asciiCode };
                string strCharacter = asciiEncoding.GetString(byteArray);
                return (strCharacter);
            }
            else
            {
                throw new Exception("ASCII Code is not valid.");
            }
        }
private void Form1_Load(object sender, EventArgs e)
        {
            po[0] = "0119002";
            po[1] = "0119202";
            po[2] = "0119402";
            po[3] = "0119602";
            po[4] = "0119802";
            po[5] = "0119A02";
            po[6] = "0119C02";
            po[7] = "0119E02";
            po[8] = "011A002";
            check[0] = "60";
            check[1] = "62";
            check[2] = "64";
            check[3] = "66";
            check[4] = "68";
            check[5] = "6A";
            check[6] = "6C";
            check[7] = "6E";
            check[8] = "61";
            FirstUse();
        }        private void 刷新ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            //string sReadData = "";
            for (int i = 0; i <= 8; i++)
            {
                this.txtRead0.Text="";
                string sReadCmd = Chr(2) + po[i] + Chr(3) + check[i];
                //string sReadCmd = "2" + po[i] + "3" + check[i];
                com.Write(sReadCmd);
                //等待1秒钟
                System.Threading.Thread.Sleep(1000);
                // 从串口读数据
                byte[] data = new byte[1024];
                try
                {
                    int j=com.Read(data, 0, 1024);
                }
                catch (Exception eg)
                {
                    MessageBox.Show(eg.ToString());
                }
                //假如首位为2,则表示数据有效.这里有个问题,在第二次读,第2位才为"2",第三次又是首位为2,需要再测试
                if (data[0] == 2)
                {
                    string sReceiveData = System.Text.Encoding.ASCII.GetString(data);
                    //MessageBox.Show(sReceiveData);
                    //解析命令,将读到的字符解析成数字,注意高低位的转换
                    string sLow = sReceiveData.Substring(1, 2);
                    //string sHigh = sReceiveData.Substring(3, 2);
                    //int res = Convert.ToInt32(sHigh)+ Convert.ToInt32(sLow);
                    int res = Convert.ToInt32(sLow, 16); //+ Convert.ToInt32(sHigh, 16);
                    this.txtRead0.Text = res.ToString();
                    string temp=(int.Parse(txtRead0.Text)*apb[i]).ToString();
                    switch (i)
                    {
                        case 0:
                            {
                                tb13.Text = txtRead0.Text;
                                tb14.Text = temp;
                                break;
                            }
                        case 1:
                            {
                                tb23.Text = txtRead0.Text;
                                tb24.Text = temp;
                                break;
                            }
                        case 2:
                            {
                                tb33.Text = txtRead0.Text;
                                tb34.Text = temp;
                                break;
                            }
                        case 3:
                            {
                                tb43.Text = txtRead0.Text;
                                tb44.Text = temp;
                                break;
                            }
                        case 4:
                            {
                                tb53.Text = txtRead0.Text;
                                tb54.Text = temp;
                                break;
                            }
                        case 5:
                            {
                                tb63.Text = txtRead0.Text;
                                tb64.Text = temp;
                                break;
                            }
                        case 6:
                            {
                                tb73.Text = txtRead0.Text;
                                tb74.Text = temp;
                                break;
                            }
                        case 7:
                            {
                                tb83.Text = txtRead0.Text;
                                tb84.Text = temp;
                                break;
                            }
                        case 8:
                            {
                                tb93.Text = txtRead0.Text;
                                tb94.Text = temp;
                                break;
                            }
                    }
                }
                else 
                {
                    i--;
                    com.Close();
                    com.Open();
                }
            }
            
            
            
            
        }

求各位高手不吝指点!多谢!

解决方案

10

你得明白一点计算机的基础知识:
二进制才是全部数据的基础,不要随便转为字符串。
你收发的都是byte[], 你直接处理byte,不要用asciiEncoding.GetString();
这种 string check = “6C”肯定也不对,
应该是相似这样的:  byte c = 0x6c ;

30

引用:

昨天调试了一下,发现可能是跟16进制数的字母有关系,发送ABCDEF的时候就出错了,那么问题来了,怎么样发送16进制数中的字母?

所以先让你用串口调试助手测试,先把发什么,收什么,都代表什么意思,弄弄清楚
然后再研究怎么样用代码去实现这个过程
不要一开始就纠结代码
等调试代码的时候,完全可以抛开PLC了,只要你发送出去的跟用调试助手发出去的一样,接收到的也能正确解析,把代码直接连PLC保证也是好使的


CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明C#读取三菱FX PLC
喜欢 (0)
[1034331897@qq.com]
分享 (0)