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

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

效果展示 读取VB0-VB9内存的数据,写VB5-VB9的内存数据
浮点读的是VD0的数据;

image
image

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);
}
posted @ 2025-04-18 14:34  零一の世界  阅读(230)  评论(0)    收藏  举报