C#实现上位机与欧姆龙PLC的通信.docx

上传人:b****6 文档编号:3254951 上传时间:2022-11-21 格式:DOCX 页数:13 大小:404.90KB
下载 相关 举报
C#实现上位机与欧姆龙PLC的通信.docx_第1页
第1页 / 共13页
C#实现上位机与欧姆龙PLC的通信.docx_第2页
第2页 / 共13页
C#实现上位机与欧姆龙PLC的通信.docx_第3页
第3页 / 共13页
C#实现上位机与欧姆龙PLC的通信.docx_第4页
第4页 / 共13页
C#实现上位机与欧姆龙PLC的通信.docx_第5页
第5页 / 共13页
点击查看更多>>
下载资源
资源描述

C#实现上位机与欧姆龙PLC的通信.docx

《C#实现上位机与欧姆龙PLC的通信.docx》由会员分享,可在线阅读,更多相关《C#实现上位机与欧姆龙PLC的通信.docx(13页珍藏版)》请在冰豆网上搜索。

C#实现上位机与欧姆龙PLC的通信.docx

C#实现上位机与欧姆龙PLC的通信

本人最近做了一个上位机与欧姆龙PLC通信的系统。

与大家分享分享心得吧!

废话不多说,先看看实际的效果图吧!

由于本人能力有限,请大家多多指正吧!

要想做好上位机,就必须搞好通信问题。

欧姆龙PLC与上位机通信采用的是HostLink协议。

下面就先来介绍介绍HostLink协议。

使用HostLink协议要注意以下几点:

(1)通信线的连线,RS232口接线。

一般使用无握手信号连线,无握手信号连线仅需要3根线,1根地线,2根信号线:

发送线TXD,接受线RXD。

(2)通信参数的设置,一般我们VisualStdio中选用控件SerialPort,在其属性中选择波特率9600,数据位7位,偶检验,2个停止位。

在调试的时候可以用串口助手先进行调试,调试明白了再开始写上位机也不迟。

(3)HostLink协议的格式,一般包括起始符,单元号,正文,FCS检验码,结束符。

起始符都是@,一般你的上位机控制的只有一个下位机,那么你的单元号就是00,正文内容是举一个例子,比如说@00WD0100123456*CR,@是起始符,00是单元号,WD0100表示向DM区0100,写入数据,写入的就是1234(写的是字符,传入PLC中自动变成16进制的1234),56是FCS校验,FCS校验就是校验码前面所有的字符按其ASCII码异或,结果是两位的。

在写上位机之前你也可以现写一个FCS校验器,反正后续的代码总是要写的。

*CR是结束符,*比较容易打出来,CR就是回车键,程序中表现时可以用”\r”来表示。

再比如说@00RD0100000156*CR是向DM0100开始的数据区,连续读0001个数据,在这里也就是连续读一个数据。

当然你给PLC发一个数据,如果格式正确,PLC也会响应你一个数据,见下表。

在这里讲一下返回的状态码,根据状态码,我们可以知道发送的数据有没有出现错误。

正常情况下,返回的只能是00,如果不是00,请根据上表,自己修改错误。

下面我先把我写的FCS校验码贴出来吧,

代码如下:

usingSystem;

usingSystem.Collections.Generic;

usingSystem.ComponentModel;

usingSystem.Data;

usingSystem.Drawing;

usingSystem.Linq;

usingSystem.Text;

usingSystem.Threading.Tasks;

usingSystem.Windows.Forms;

namespace异或测试

{

publicpartialclassForm1:

Form

{

publicForm1()

{

InitializeComponent();

}

privatevoidbutton1_Click(objectsender,EventArgse)

{

stringstr=textBox1.Text;

Int16[]a=newInt16[str.Length];//将字符串中的一个个字符,分离出来,并保存

for(inti=0;i

{

a[i]=Convert.ToInt16(str[i]);

}

Int16FCS=0;

for(inti=0;i

{

FCS=(Int16)(FCS^a[i]);//异或计算FCS码

}

stringstr_FCS;//把计算出来的FCS码再转成字符串

str_FCS=FCS.ToString("x2");

textBox2.Text=str_FCS;

}

}

}

写的不太好,就当自己测试的时候用了。

特别要注意的是,PLC在运行状态是不能向DM区写数据的。

必要的时候我们可以通过向PLC发送不同指令来改变其工作模式。

指令如下:

模式的改变

PROGRAM@00SC0050*

MONITOR@00SC0252*

RUN@00SC0353*

"00"是站號

最基本的东西已经说得比较清楚了,下面把代码也贴出来吧,同样代码也写的比较乱,让内行人见笑了。

大体上看一共就用了这几个事件。

下面是其具体的代码:

本人做的是一个恒压供水的项目,这里只是一个产品的测试,故有很多地方还不严谨,思路不是很清楚,我感觉这也我一周弄出来的,还是比较不错的

usingSystem;

usingSystem.Collections.Generic;

usingSystem.ComponentModel;

usingSystem.Data;

usingSystem.Drawing;

usingSystem.Linq;

usingSystem.Text;

usingSystem.Threading.Tasks;

usingSystem.Windows.Forms;

usingSystem.IO.Ports;

namespaceWindowsFormsApplication2

{

publicpartialclassForm1:

Form

{

publicForm1()

{

InitializeComponent();

System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls=false;

//关闭线程检查

}

privatevoidForm1_Load(objectsender,EventArgse)

{//窗口载入时,自动搜索可用的串口

stringbuffer;

comboBox1.Items.Clear();

for(inti=0;i<20;i++)

{

try

{

buffer="COM"+i.ToString();

serialPort1.PortName=buffer;

serialPort1.Open();

comboBox1.Items.Add(buffer);

serialPort1.Close();

}

catch{}

}

serialPort1.WriteLine("MONITOR@00SC0252*"+"\r");//让PLC工作在监视模式下

//serialPort1.WriteLine("@00WD0201000050*"+"\r");

}

privatevoidserialPort1_DataReceived(objectsender,SerialDataReceivedEventArgse)

{

//串口接受事件所触发执行

if(radioButton1.Checked)

{

//如果处于运行状态,则接受的字符串只显示在接受数据去

//高级功能中的接受面板不予显示

stringstr=serialPort1.ReadExisting();//接受到的字符

stringstr1;//通道1的字符

//stringstr2;//通道2的字符//该设备没有外接

stringstr3;//通道3的字符

//stringstr4;//通道4的字符//该设备没有外接

stringstr_Z_S_PLC;//转速的字符PLC模块所采集的

try

{

str1=str.Substring(8,2);

}

catch

{

str1="";

}

S_Y_1.Text=str1;

Application.DoEvents();

//System.Threading.Thread.Sleep(100);

try

{

str3=str.Substring(12,2);

}

catch

{

str3="";

}

S_Y_3.Text=str3;

Application.DoEvents();/******************/

//System.Threading.Thread.Sleep(100);//让线程在此休眠100MS,以便处理

//其他线程的事情。

//这对刷屏,text属性用比较大的作用

S_Y_2.Text="60";

S_Y_4.Text="60";

Application.DoEvents();/******************/

try

{

str_Z_S_PLC=str.Substring(15,3);

}

catch

{

str_Z_S_PLC="";

//str_Z_S_PLC=str.Substring(15,3);

}

S_B_Z_S.Text=str_Z_S_PLC;

Application.DoEvents();/******************/

}

else

{

stringstr_gaoji=serialPort1.ReadExisting();//接受到的字符

textBox1.AppendText(str_gaoji);

}

}

privatevoidbutton2_Click(objectsender,EventArgse)

{

//高级功能中的发送按钮所执行的功能

if(serialPort1.IsOpen)

{

try

{

//若串口为打开状态则,发送命令

serialPort1.WriteLine(textBox2.Text);

}

catch

{

MessageBox.Show("数据写入有错","错误");

}

}

}

privatevoidbutton1_Click(objectsender,EventArgse)

{

//打开串口按钮执行的功能

if(serialPort1.IsOpen)

{

try

{

//若串口原状态是开,再按一次则关闭穿口

serialPort1.Close();

button1.Text="打开串口";

ovalShape1.FillColor=Color.Gray;

}

catch

{

MessageBox.Show("串口关闭错误","错误");

}

}

else

{

try

{

//若串口状态原先是关闭,则按一次打开串口

serialPort1.PortName=comboBox1.Text;

serialPort1.Open();

button1.Text="关闭串口";

ovalShape1.FillColor=Color.GreenYellow;

}

catch

{

MessageBox.Show("串口打开错误","错误");

}

}

}

privatevoidtimer1_Tick(objectsender,EventArgse)

{

//每隔1S,上位机给PLC发送一条指令

//PLC返回一条指令,用于刷新,各采集的数据

if(serialPor

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 小学教育 > 语文

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1