0:通讯的PLC中无须写任何程序;
1:需添加 http://S7.Net动态库(基本函数),此库可以在网上查找到库文件,下载到电脑中;
2:打开VS2019或者其它版本,新建一个WinForm程序,添加此动态库文件到程序中,
3:在头文件中引用此命名空间,using S7.Net;引用线程命名空间
using System.Threading;
效果展示 读取VB0-VB9内存的数据,写VB5-VB9的内存数据
浮点读的是VD0的数据;


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);
}
```