目錄
一、PLC程序工程創(chuàng)建
1、硬件配置
2、程序編程
3、添加監(jiān)控表
二、C#程序工程創(chuàng)建
1、界面UI
2、代碼編寫
(1)創(chuàng)建本地Udp
(2)讀PLC的線程函數(shù)
(3)定時器
(4)上位機寫寄存器操作
(5)StringToByte()方法封裝
(6)窗口關(guān)閉
3、C#和PLC測試
(1)C#上位機寫操作1
(2)C#上位機寫操作2
(3)C#控制PLC中的繼電器輸出
(4)C#上位機讀操作
?(5)串口調(diào)試助手和PLC通信測試
三、工程合并下載連接
一、PLC程序工程創(chuàng)建
1、硬件配置
2、程序編程
Main程序
?
?
?"TSEND_C_DB"功能塊配置如下:
"TURCV_DB"功能塊不需要配置,ADDR地址和"TSEND_C_DB"相同即可
3、添加監(jiān)控表
?雙擊添加新監(jiān)控表,在監(jiān)控表中分別添加MB20-MB29、MB30-MB39寄存器。在監(jiān)控狀態(tài)下,可以實時的讀取、修改當前寄存器值
?
二、C#程序工程創(chuàng)建
1、界面UI
2、代碼編寫
(1)創(chuàng)建本地Udp
注意的是,本地Udp創(chuàng)建成功后,先給PLC寄存器發(fā)送0做數(shù)據(jù)測試。PLC只有在接收到到一次上位機發(fā)送的程序,PLC才會啟動對上位機發(fā)送功能,因為共用的功能塊ADDR中的地址。
private void btnConnect_Click(object sender, EventArgs e)
{
try
{
LocalIp = txtLocalIp.Text;
LocalPort = int.Parse(txtLocalPort.Text);
TargetIp = txtPlcIp.Text;
TargetPort = int.Parse(txtPlcPort.Text);
client = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
client.Bind(new IPEndPoint(IPAddress.Parse(LocalIp), LocalPort));
Thread.Sleep(50);
MessageBox.Show("本地Udp創(chuàng)建成功");
txtUdpState.Text = "本地Udp創(chuàng)建成功";
isUdpConnected = true;
//本地Udp創(chuàng)建成功后,先給PLC寄存器發(fā)送0做數(shù)據(jù)測試
byte[] sendBytes = new byte[10];
sendBytes[0] = 0x00;
sendBytes[1] = 0x00;
sendBytes[2] = 0x00;
sendBytes[3] = 0x00;
sendBytes[4] = 0x00;
sendBytes[5] = 0x00;
sendBytes[6] = 0x00;
sendBytes[7] = 0x00;
sendBytes[8] = 0x00;
sendBytes[9] = 0x00;
EndPoint point = new IPEndPoint(IPAddress.Parse(TargetIp), TargetPort);
client.SendTo(sendBytes, point);
threadRecv = new Thread(ReciveMsg);
threadRecv.Start();
timer1.Start();
}
catch
{
txtUdpState.Text = "本地Udp創(chuàng)建失敗";
}
}
(2)讀PLC的線程函數(shù)
void ReciveMsg()
{
while (true)
{
if(isUdpConnected)
{
EndPoint point = new IPEndPoint(IPAddress.Any, 0);//用來保存發(fā)送方的ip和端口號
byte[] buffer = new byte[1024];
int length = client.ReceiveFrom(buffer, ref point);//接收數(shù)據(jù)報
if(length>0)
{
for(int i=0;i<10;i++)
{
byteRecvs[i] = buffer[i];
}
}
}
}
}
(3)定時器
private void timer1_Tick(object sender, EventArgs e)
{
//將線程中接收到PLC的byte數(shù)據(jù),轉(zhuǎn)換成16進制的字符串顯示
txtReadMB20.Text = byteRecvs[0].ToString("X");
txtReadMB21.Text = byteRecvs[1].ToString("X");
txtReadMB22.Text = byteRecvs[2].ToString("X");
txtReadMB23.Text = byteRecvs[3].ToString("X");
txtReadMB24.Text = byteRecvs[4].ToString("X");
txtReadMB25.Text = byteRecvs[5].ToString("X");
txtReadMB26.Text = byteRecvs[6].ToString("X");
txtReadMB27.Text = byteRecvs[7].ToString("X");
txtReadMB28.Text = byteRecvs[8].ToString("X");
txtReadMB29.Text = byteRecvs[9].ToString("X");
}
(4)上位機寫寄存器操作
private void btnWriteValue_Click(object sender, EventArgs e)
{
try
{
if(isUdpConnected==false)
{
MessageBox.Show("請先創(chuàng)建本地Udp", "提示");
return;
}
byte[] sendBytes = new byte[10];
//sendBytes[0] = 0x10;
//sendBytes[1] = 0x10;
//sendBytes[2] = 0x10;
//sendBytes[3] = 0x10;
//sendBytes[4] = 0x10;
//sendBytes[5] = 0x10;
//sendBytes[6] = 0x10;
//sendBytes[7] = 0x10;
//sendBytes[8] = 0x10;
//sendBytes[9] = 0x10;
sendBytes[0] = StringToByte(txtWriteMB30.Text);
sendBytes[1] = StringToByte(txtWriteMB31.Text);
sendBytes[2] = StringToByte(txtWriteMB32.Text);
sendBytes[3] = StringToByte(txtWriteMB33.Text);
sendBytes[4] = StringToByte(txtWriteMB34.Text);
sendBytes[5] = StringToByte(txtWriteMB35.Text);
sendBytes[6] = StringToByte(txtWriteMB36.Text);
sendBytes[7] = StringToByte(txtWriteMB37.Text);
sendBytes[8] = StringToByte(txtWriteMB38.Text);
sendBytes[9] = StringToByte(txtWriteMB39.Text);
EndPoint point = new IPEndPoint(IPAddress.Parse(TargetIp), TargetPort);
client.SendTo(sendBytes, point);
MessageBox.Show("發(fā)送成功");
}
catch(Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
(5)StringToByte()方法封裝
封裝方法需要注意的是,PLC寄存器最大只能支持兩位的16進制FF。所以,需要將測寫入的字符串不能超過3兩位、同時也不能超過F。
/// <summary>
/// 字符串轉(zhuǎn)byte數(shù)據(jù)
/// </summary>
/// <param name="s"></param>
/// <returns></returns>
private byte StringToByte(string s)
{
if(s.Length>2)
{
throw new ArgumentNullException("超過兩位或者不是16進制字符!");
}
byte b;
try
{
string str;
str = "0x" + s;
b = Convert.ToByte(str, 16);
}
catch
{
throw new ArgumentNullException("不是指定的16進制字符");
}
return b;
}
(6)窗口關(guān)閉
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
System.Environment.Exit(0); //強制關(guān)閉所有線程
}
3、C#和PLC測試
(1)C#上位機寫操作1
?
(2)C#上位機寫操作2
(3)C#控制PLC中的繼電器輸出
(4)C#上位機讀操作
在PLC程序中,將M60.0強制TRUE
?PLC即將數(shù)據(jù)以0.5秒的時間周期發(fā)送上位機C#,時間可以調(diào)快一點比如50毫秒、100毫秒都可以
?
?(5)串口調(diào)試助手和PLC通信測試
對于不會C#上位機編程的電氣工程師來說,也可以使用網(wǎng)絡(luò)調(diào)試助手來做測試。測試方法參加另一篇博客西門子S7-1200 PLC和上位機通信_Big_潘大師的博客-CSDN博客_西門子1200與上位機s7通訊文章來源:http://www.zghlxwxcb.cn/news/detail-443044.html
三、工程合并下載連接
https://download.csdn.net/download/panjinliang066333/86508006文章來源地址http://www.zghlxwxcb.cn/news/detail-443044.html
到了這里,關(guān)于C#和西門子PLC使用Udp通信的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!