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

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的数据;

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