C# 机器视觉工控通讯------Panasonic松下PLC之串口上位机通讯
前言
本文以Panasonic松下PLC位列,介绍C#通过上位机串口访问松下PLC,可以使用串口助手协助调试。
一、松下PLC简介?
PLC (Programmable Logic Controller),可编程逻辑控制器,一种数字运算操作的电子系统,专为在工业环境应用而设计的。它采用一类可编程存储器,用于其内部 存储程序,执行 逻辑运算,顺序控制,定时,计数与算术操作等面向用户的指令,并通过数字或模拟式输入/输出控制各种类型的机械或生产过程,是工业控制的核心部分。松下公司的 PLC产品中,FPO为微型机,FP1为整体式 小型机,FP3为中型机,FP5/FP10、FP10S(FP10的改进型)、FP20为 大型机,其中FP20是最新产品。松下公司近几年PLC产品的主要特点是:指令系统功能强。
二、使用步骤
1.引入库
using System.IO.Ports;
2.设置串口参数
/// /// 设置串口参数/// /// Serialport类的名字/// 串口号/// 波特率/// 停止位/// 校验位/// 数据位public static void SetSerialPort(SerialPort SP_Panasonic, string portname, int baudrate, StopBits stopbits, Parity parity, int databits){SP_Panasonic.PortName = portname;SP_Panasonic.BaudRate = baudrate;SP_Panasonic.StopBits = stopbits;SP_Panasonic.Parity = parity;SP_Panasonic.DataBits = databits;if (SP_Panasonic.IsOpen){SP_Panasonic.Close();SP_Panasonic.Open();}else{SP_Panasonic.Open();}}
3. 读取松下PLC寄存器数据,支持X、Y、R、D
/// /// 3. 3/// /// Serialport类的名字/// 站号/// 寄存器类型/// 起始地址/// 地址位数/// public static string Read_Pan(SerialPort SP_Panasonic, int Station, string Memory, int Adress, int Count){string ReadData = "";switch (Memory){case "X":ReadData = ReadXYR(SP_Panasonic, Station, Memory, Adress, Count);//暂不支持读取多位break;case "Y":ReadData = ReadXYR(SP_Panasonic, Station, Memory, Adress, Count);break;case "R":ReadData = ReadXYR(SP_Panasonic, Station, Memory, Adress, Count);break;case "D":ReadData = ReadD(SP_Panasonic, Station, Memory, Adress, Count);//支持读取多位break;}if (ReadData == "读取失败"){String LogMSg = "串口通讯超时";cPublic.saveDataLog(LogMSg);cPublic.UpdateGUI((int)cPublic.UpdateItem.label_error, "label_error", "串口通讯超时,请检查!");}else{cPublic.UpdateGUI((int)cPublic.UpdateItem.label_error, "label_error", "");}return ReadData;}
4. 写入松下PLC寄存器数据,支持X、Y、R、D
/// /// 写入松下PLC寄存器数据,支持X、Y、R、D/// /// Serialport类的名字/// 站号/// 寄存器类型/// 起始地址/// 地址位数/// 写入的字符串/// public static bool Write_Pan(SerialPort SP_Panasonic, int Station, string Memory, int Adress, int Count, string Data){bool WriteData = false;switch (Memory){case "Y":WriteData = WriteXYR(SP_Panasonic, Station, Memory, Adress, Count, Data);//暂不支持读取多位break;case "R":WriteData = WriteXYR(SP_Panasonic, Station, Memory, Adress, Count, Data);break;case "D":WriteData = WriteD(SP_Panasonic, Station, Memory, Adress, Count, Data);//支持读取多位break;}return WriteData;}
5. 读取DT寄存器数据
/// /// 读取DT寄存器数据/// /// Serialport类的名字/// 站号/// 寄存器类型/// 起始地址/// 地址位数/// private static string ReadD(SerialPort SP_Panasonic, int station, string memory, int address, int addressCount){lock(Lock_Serial){send_count = 0;string strSendData;string strReceiveData = "";string[] arrstrReceiveData = new string[addressCount * 2];byte[] arrbyReceiveData = new byte[addressCount * 2];string strStartAddress = address.ToString("d5");string strEndAddress = (address + addressCount - 1).ToString("d5");// 生成发送数据字符串strSendData = "%0" + station.ToString() + "#RD" + memory.ToUpper() + strStartAddress + strEndAddress;// 字符添加校验码和回车结束符strSendData += GetCheckCode(strSendData) + "\r";send_count += strSendData.Length;if (SendData(SP_Panasonic, strSendData))strReceiveData = ReceiveData(SP_Panasonic, 300);receive_count += strReceiveData.Length;if (strReceiveData != "" && strReceiveData[3] == '$'){// 解析串口接收的数据for (int i = 0; i < addressCount * 2; i++){arrstrReceiveData[i] = strReceiveData.Substring(6 + 2 * i, 2);arrbyReceiveData[i] = Convert.ToByte(arrstrReceiveData[i], 16);}String s = BitConverter.ToString(arrbyReceiveData).Replace("-", "");return s;}else{return "读取失败";}}}
6. 读取X、Y、R寄存器数据
/// /// 读取X、Y、R寄存器数据/// /// Serialport类的名字/// 站号/// 寄存器类型/// 起始地址/// 地址位数/// private static string ReadXYR(SerialPort SP_Panasonic, int station, string memory, int address, int addressCount){lock (Lock_Serial){send_count = 0;string strSendData;string strReceiveData = "";string[] arrstrReceiveData = new string[addressCount];byte[] arrbyReceiveData = new byte[addressCount];string strStartAddress = address.ToString("d4");string strEndAddress = (address + addressCount - 1).ToString("d4");// 生成发送数据字符串strSendData = "%0" + station.ToString() + "#RCS" + memory.ToUpper() + strStartAddress;// 字符添加校验码和回车结束符strSendData += GetCheckCode(strSendData) + "\r";send_count += strSendData.Length;if (SendData(SP_Panasonic, strSendData))strReceiveData = ReceiveData(SP_Panasonic, 100);cPublic.strReceiveData_public = strReceiveData;receive_count += strReceiveData.Length;if (strReceiveData != "" && strReceiveData[3] == '$'){// 解析串口接收的数据for (int i = 0; i < addressCount; i++){arrstrReceiveData[i] = strReceiveData.Substring(6, 1);arrbyReceiveData[i] = Convert.ToByte(arrstrReceiveData[i], 16);}String s = BitConverter.ToString(arrbyReceiveData).Replace("-", "");return s;}else{return "读取失败";}}}
7. 写入DT寄存器
/// /// 写入DT寄存器/// /// Serialport类的名字/// 站号/// 寄存器类型/// 起始地址/// 地址位数/// 写入的字符串/// public static bool WriteD(SerialPort SP_Panasonic, int station, string memory, int address, int addressCount, string data){lock (Lock_Serial){send_count = 0;string strSendData;string strReceiveData = "";string[] arrstrReceiveData = new string[addressCount * 2];byte[] arrbyReceiveData = new byte[addressCount * 2];string strStartAddress = address.ToString("d5");string strEndAddress = (address + addressCount - 1).ToString("d5");// 生成发送数据字符串strSendData = "%0" + station.ToString() + "#WD" + memory.ToUpper() + strStartAddress + strEndAddress + data;// 字符添加校验码和回车结束符strSendData += GetCheckCode(strSendData) + "\r";send_count += strSendData.Length;if (SendData(SP_Panasonic, strSendData)){strReceiveData = ReceiveData(SP_Panasonic, 300);receive_count += strReceiveData.Length;if (strReceiveData != "" && strReceiveData[3] == '$'){return true;}else{return false;}}else{return false;}}}
8. 写入X、Y、R寄存器数据
/// /// 写入X、Y、R寄存器数据/// /// Serialport类的名字/// 站号/// 寄存器类型/// 起始地址/// 地址位数/// 写入的字符串/// public static bool WriteXYR(SerialPort SP_Panasonic, int station, string memory, int address, int addressCount, string data){lock (Lock_Serial){send_count = 0;string strSendData;string strReceiveData = "";string[] arrstrReceiveData = new string[addressCount * 2];byte[] arrbyReceiveData = new byte[addressCount * 2];string strStartAddress = address.ToString("d4");string strEndAddress = (address + addressCount - 1).ToString("d4");// 生成发送数据字符串strSendData = "%0" + station.ToString() + "#WCS" + memory.ToUpper() + strStartAddress + data;//strSendData = "%0" + station.ToString() + "#WCS" + memory.ToUpper() + strStartAddress + strEndAddress + data;// 字符添加校验码和回车结束符strSendData += GetCheckCode(strSendData) + "\r";send_count += strSendData.Length;if (SendData(SP_Panasonic, strSendData)){strReceiveData = ReceiveData(SP_Panasonic, 300);receive_count += strReceiveData.Length;//if (strReceiveData != "" && strReceiveData[3] == '$')if (strReceiveData != "" && strReceiveData[3] == '$'){return true;}else{return false;}}else{return false;}}}
9. 校验码计算
/// /// /// /// /// private static string GetCheckCode(string sendData){//将字符串转换成字节数组byte[] arrSendData = new byte[sendData.Length];arrSendData = Encoding.Default.GetBytes(sendData);byte sum = 0;// 进行校验码计算,异或求和后生成for (int i = 0; i < arrSendData.Length; i++){ sum = (byte)(sum ^ arrSendData[i]); }// 将计算结果转换成字符串string strCheck = Convert.ToString(sum, 16);return strCheck.ToUpper();}
10. 串口发送字符串
/// /// 往串口发送字符串/// /// Serialport类的名字/// 发送的字符串/// private static bool SendData(SerialPort SP_Panasonic, string sendData){// 将字符串转换成字节数组byte[] arrbySendBuffer = new byte[sendData.Length];arrbySendBuffer = Encoding.Default.GetBytes(sendData);// 通过串口发送数据try{//发送数据SP_Panasonic.Write(arrbySendBuffer, 0, arrbySendBuffer.Length);return true;}catch (Exception ex){//MessageBox.Show(ex.Message);return false;}}
11. 串口接收字符串
/// /// 从串口接收字符串/// /// Serialport类的名字/// 延时时间/// 返回接收的字符串 private static string ReceiveData(SerialPort SP_Panasonic, int time){int i = 0;Thread.Sleep(time);while (SP_Panasonic.BytesToRead == 0){i++;Thread.Sleep(20);if (i == 50) return "";}byte[] arrReceiveData = new byte[SP_Panasonic.BytesToRead];SP_Panasonic.Read(arrReceiveData, 0, SP_Panasonic.BytesToRead);return Encoding.ASCII.GetString(arrReceiveData);}
总结
例如:以上就是今天要讲的内容,本文仅仅简单介绍以松下PLC为列,使用C#上位机通过串口访问PLC所有寄存器,提供了大量能使我们快速便捷地处理数据的函数和方法。
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
