s7.net 写数据到plc_C#直接读写S7-200smartPLC的内存数据

0:通讯的PLC中无须写任何程序;

0:通讯的PLC中无须写任何程序;

1:需添加 http://S7.Net动态库(基本函数),此库可以在网上查找到库文件,下载到电脑中;

2:打开VS2019或者其它版本,新建一个WinForm程序,添加此动态库文件到程序中,

3:在头文件中引用此命名空间,using S7.Net;引用线程命名空间

using System.Threading;

效果展示 读取VB0-VB9内存的数据,写VB5-VB9的内存数据

浮点读的是VD0的数据;

![image](https://img2024.cnblogs.com/blog/128740/202504/128740-20250418143144789-809893807.png)

![image](https://img2024.cnblogs.com/blog/128740/202504/128740-20250418143152200-1264028953.jpg)

4:定义公共变量

```

bool status = false;//定义PLC连接状态字

bool bOK = true; //写数据地址只读一次标志位

Plc plcSmsrt200; //定义变PLC变量类型

Thread thRead = null; // 定义读写线程名

int readByteSum; // 定义读字节的总数变量名

int readByteStart; // 定义读字节的起始字节变量名

int writeByteSum; // 定义写字节的总数变量名

int writeByteStart; // 定义写字节的起始字节变量名

IniFile Initools = new IniFile(); //定义并实例化INI文件读写类

```

##### 5: //初始化程序段

```

public Form1()

{

InitializeComponent();

ReadINI(); //读取INI保存的文件

plcSmsrt200 = new Plc(CpuType.S71200, txtIPAddr.Text, 0, 1); //实例化PLC类

//*************************************************

CheckForIllegalCrossThreadCalls = false; //关闭跨线程访问

thRead = new Thread(plc_ThreadRead); // 实例化线程

thRead.IsBackground = true; // 确定线程为后台线程

thRead.Start(); // 启动线程

Thread threadConnectPLC = new Thread(IsConnectPLC); //实例化连接线程,用于状态栏显示

threadConnectPLC.IsBackground = true; // 打开后台执行变量

threadConnectPLC.Start(); // 启动线程

}

```

##### 6:在建立的连接按钮下面的程序代码

```

private void btn_connectPLC_Click(object sender, EventArgs e)

{

if (!plcSmsrt200.IsConnected)

{

plcSmsrt200.Close();

try

{

if (plcSmsrt200.IsAvailable)//发送ping +IP给PLC 如果连接上则返回true

{

plcSmsrt200.Open();

status = true;

}

else

{

MessageBox.Show("请检查网线和PLC的IP地址是否正确");

}

}

catch (Exception ex)

{

MessageBox.Show(ex.Message);

}

}

}

```

##### 7:在单击读取数据按钮下面的程序代码

```

private void btn_readByte_Click(object sender, EventArgs e)

{

if (status)

{

try

{

textBox1.Text = "";

List<byte> list1 = new List<byte>();

list1 = ReadMultipleBytes(readByteStart,readByteSum, 1 );

foreach (var readdata in list1)

{

textBox1.Text = textBox1.Text + readdata + " ";

}

//读浮点数据并显示

Single[] si = ReadMultipleReal(0, 3, 1);

txtReal.Text=si[0].ToString();

//把写数据的text的数据只刷新一次到窗口

if (bOK)

{

List<byte> list2 = new List<byte>();

list2 = ReadMultipleBytes(writeByteStart,writeByteSum, 1 );

for (int i = 2; i < list2.Count + 2; i++)

{

TextBox tb = this.Controls["TextBox" + i.ToString()] as TextBox;

if (tb != null)

{

tb.Text = list2[i - 2].ToString();

}

}

bOK = false;

}

}

catch (Exception)

{

MessageBox.Show("PLC读取数据错误");

}

}

}

```

##### 8:建立一读取字节的方法

```

private List<byte> ReadMultipleBytes(int startByteAdr = 0,int sumBytes=1, int DB = 1 )

{

List<byte> resultBytes = new List<byte>();

int index = startByteAdr;

try

{

if (status)

{

while (sumBytes > 0)

{

var maxToRead = (int)Math.Min(sumBytes, 200);

byte[] bytes = plcSmsrt200.ReadBytes(DataType.DataBlock, DB, index, (int)maxToRead);

if (bytes == null)

return new List<byte>();

resultBytes.AddRange(bytes);

sumBytes -= maxToRead;

index += maxToRead;

}

}

return resultBytes;

}

catch

{

return new List<byte>();

}

}

```

##### 9:建立一个用于判断PLC是否连接上一个方法,添加到线程里面,用于连接状态栏的显示

```

public void IsConnectPLC()

{

while (true)

{

if (plcSmsrt200.IsConnected)

{

toolStripStatusLabel2.ForeColor = Color.Green;

toolStripStatusLabel2.Text = plcSmsrt200.IP + " 已成功连接 ";

Thread.Sleep(500);

}

else

{

toolStripStatusLabel2.ForeColor = Color.Red;

toolStripStatusLabel2.Text = plcSmsrt200.IP + " 已断开";

Thread.Sleep(500);

}

}

}

```

##### 10:定义一个方法,去时时刷新读取的数据

```

private void plc_ThreadRead()

{

while (true)

{

if (status)

{

Thread.Sleep(1000);

btn_readByte_Click(null, null);

}

else

{

Thread.Sleep(1000);

Console.WriteLine(status);

}

}

}

```

##### 11:在断开PLC连接按钮下面的程序代码

```

private void btn_disConnect_Click(object sender, EventArgs e)

{

plcSmsrt200.Close();

status = false;

bOK = true;

}

```

##### 12:在写入按钮下面和程序代码

```

private void btn_writeByte_Click(object sender, EventArgs e)

{

if (status)

{

try

{ //写数据前先把文本框里的数据转存到数组中

Byte[] value = new Byte[0];

List<byte> ts = new List<byte>();

for (int i = 2; i < 7; i++)

{

TextBox tb = this.Controls["TextBox" + i.ToString()] as TextBox;

if (tb != null)

{

ts.Add((byte)Convert.ToByte(tb.Text));

}

}

value=ts.ToArray();

plcSmsrt200.WriteBytes(DataType.DataBlock, 1, writeByteStart, value);

//写入数据再次读入数据,以便显示刷新

List<byte> list2 = new List<byte>();

list2 = ReadMultipleBytes(writeByteStart,writeByteSum, 1 );

for (int i = 2; i < list2.Count+2; i++)

{

TextBox tb =this. Controls["TextBox" + i.ToString()] as TextBox;

if (tb!=null)

{

tb.Text = list2[i-2].ToString();

}

}

}

catch (Exception)

{

}

}

else

{

MessageBox.Show("PLC未连接");

}

}

```

##### 13:在写入INI按钮下面填定如下代码

```

private void btnWriteINI_Click(object sender, EventArgs e)

{

if (!status)

{

string strtemp = Application.StartupPath + "math";

string strFile = Application.StartupPath + "mathnumber.ini"; //得到参数的全路径

Initools.CreateAllDirectory(strFile);//创建文件夹和文件 //段落+抽屉+值(0表示没有读到的话,就返回0)+完全路径

Initools.WritePrivateProfileStringEx("number", "readSum", txtReadSum.Text, strFile);

Initools.WritePrivateProfileStringEx("number", "readStart", txtReadStart.Text, strFile);

Initools.WritePrivateProfileStringEx("number", "writeSum", txtWriteSum.Text, strFile);

Initools.WritePrivateProfileStringEx("number", "writeStart", txtwriteStart.Text, strFile);

Initools.WritePrivateProfileStringEx("number", "IPaddr", txtIPAddr.Text, strFile);

ReadINI();

plcSmsrt200 = new Plc(CpuType.S71200, txtIPAddr.Text, 0, 1);

}

else

{

MessageBox.Show("请先断开PLC连接");

}

}

```

##### 14:读保存的INI的方法 只在初始化时执行一次

```

private void ReadINI()

{

string strFile = Application.StartupPath + "mathnumber.ini"; //得到参数的全路径

Initools.CreateAllDirectory(strFile);//创建文件夹和文件 //段落+抽屉+值(0表示没有读到的话,就返回0)+完全路径

txtReadSum.Text = Initools.GetPrivateProfileString("number", "readSum", "1", strFile);

txtReadStart.Text = Initools.GetPrivateProfileString("number", "readStart", "1", strFile);

txtWriteSum.Text = Initools.GetPrivateProfileString("number", "writeSum", "1", strFile);

txtwriteStart.Text = Initools.GetPrivateProfileString("number", "writeStart", "1", strFile);

txtIPAddr.Text = Initools.GetPrivateProfileString("number", "IPaddr", "192.168.1.1", strFile);

readByteSum = Convert.ToInt32(txtReadSum.Text);

readByteStart = Convert.ToInt32(txtReadStart.Text);

writeByteSum = Convert.ToInt32(txtWriteSum.Text);

writeByteStart = Convert.ToInt32(txtwriteStart.Text);

}

```

LICENSED UNDER CC BY-NC-SA 4.0
Comment