最近在研究PLC\C#版本,做了个小Demo
你要连接PLC 用已经有的连接引用S7.Net

下面是代码分享
c
private Plc plc;
//连接plc
public bool Connect(string ip, short rack, short slot)
{
try
{
plc = new Plc(CpuType.S71200, ip, rack, slot);
plc.Open();
if (plc.IsConnected)
{
Console.WriteLine("成功连接到PLC");
return true;
}
else
{
Console.WriteLine("连接失败");
return false;
}
}
catch (Exception ex)
{
Console.WriteLine($"连接错误: {ex.Message}");
return false;
}
}
//断开plc连接
public void Disconnect()
{
if (plc != null && plc.IsConnected)
{
plc.Close();
Console.WriteLine("已断开PLC连接");
}
}
连接里面有什么
c
CpuType.S71200 连接类型
ip ip地址
port 端口号
rack 机架号
slot 槽位号
连接了之后就操作
先了解有哪些类型,你要学一个东西,建议多翻翻里面的源码(一点个人经验)

这些类型有我们知道的类型,有我们不知道的类型,第一时间做一下对照
c
word : ushort
dword : uint
int : float
dint : byte
real :float
其他类型大差不差
好了,对照了类型之后我们开始获取数据,想看看我们的引用给我们提供了什么些方法

不吹不黑,我是觉得写这些dll 的人是真的非常厉害,好了,我这边决定先用 ReadBytes
先贴代码,有的没的先贴上去,带坏你们我不管哈哈哈
重点:传出参数有哪些
c
DataType.DataBlock 块类型
db 块号
startByteAdr 开始的偏移地址
count 字节数
c
public Task<List<DataItem>> ReadMultipleVarsAsync(List<DataItem> Datlist)
{
Task<List<DataItem>> bytes = plc.ReadMultipleVarsAsync(Datlist);
return bytes;
}
public float ReadReal(int pyl, int kh)
{
byte[] bytes = plc.ReadBytes(DataType.DataBlock, kh, pyl, 4);
float value = S7.Net.Types.Real.FromByteArray(bytes);
return value;
}
public float ReadInt(int pyl, int kh)
{
byte[] bytes = plc.ReadBytes(DataType.DataBlock, kh, pyl, 2);
float value = S7.Net.Types.Int.FromByteArray(bytes);
return value;
}
// 读取DINT(32位有符号)
public int ReadDInt(int pyl, int kh)
{
byte[] bytes = plc.ReadBytes(DataType.DataBlock, kh, pyl, 4);
return (bytes[0] << 24) | (bytes[1] << 16) | (bytes[2] << 8) | bytes[3];
}
public ushort ReadWord(int pyl, int kh)
{
byte[] bytes = plc.ReadBytes(DataType.DataBlock, kh, pyl, 2);
ushort value = (ushort)((bytes[0] << 8) | bytes[1]);
return value;
}
public uint ReadWord2_DWord(int pyl, int kh)
{
byte[] bytes = plc.ReadBytes(DataType.DataBlock, kh, pyl, 4);
uint result = BitConverter.ToUInt32(bytes.Reverse().ToArray(), 0);
//uint result = (uint)((bytes[0] << 24) | (bytes[1] << 16) | (bytes[2] << 8) | bytes[3]);
return result;
}
public int ReadTime(int pyl, int kh)
{
byte[] bytes = plc.ReadBytes(DataType.DataBlock, kh, pyl, 4);
int milliseconds = S7.Net.Types.DInt.FromByteArray(bytes);
return milliseconds;
}
public bool ReadBool(string pyl, int kh)
{
string[] pdbs = pyl.Split('.');
byte[] bytes = plc.ReadBytes(DataType.DataBlock, kh, int.Parse(pdbs[0]), 1);
bool judge = false;
if (pdbs.Length > 1)
{
judge = (bytes[0] & (1 << int.Parse(pdbs[1]))) != 0;
}
else
{
judge = (bytes[0] & (1 << 0)) != 0;
}
return judge;
}
public int ReadArray(int pyl, int kh)
{
byte[] bytes = plc.ReadBytes(DataType.DataBlock, kh, pyl, 4);
return (bytes[0] << 24) | (bytes[1] << 16) | (bytes[2] << 8) | bytes[3];
}
ReadBytes 一般般,不太好用,实际上不符合我想要的东西
我要大批量传输 ReadMultipleVarsAsync
c
/// <summary>
/// 获取类型
/// </summary>
/// <param name="plc_sjlx"></param>
/// <returns></returns>
public VarType setVarType(string plc_sjlx)
{
if (plc_sjlx == "real")
{
return VarType.Real;
}
else if (plc_sjlx == "word")
{
return VarType.Word;
}
else if (plc_sjlx == "dint")
{
return VarType.DInt;
}
else if (plc_sjlx == "dword")
{
return VarType.DWord;
}
else if (plc_sjlx == "int")
{
return VarType.Int;
}
return VarType.Real;
}
/// <summary>
/// 添加到集合
/// </summary>
/// <param name="currentTime">当前时间</param>
/// <param name="listsj">运行次序</param>
private async Task ExecuteTasks(long currentTime, List<int> listsj)
{
List<PlcBlzdbCs> tasksToExecute = new List<PlcBlzdbCs>();//记录组合的地址
int remainingCapacity = _maxTasksPerExecution;//剩余请求地址数量
foreach (var interval in listsj)
{
//返回值
TaskGroup group;
//获取返回值
if (!_taskGroups.TryGetValue(interval, out group)) continue;
//当前时间减去上次运行时间大于你的优先级时间则加入
if (currentTime - group.LastRunTime >= interval)
{
int availableTasks = group.Tasks.Count;
int tasksToTake = Math.Min(availableTasks, remainingCapacity);//判断
if (tasksToTake > 0)
{
List<PlcBlzdbCs> tasks = group.Tasks;
tasks.Sort((p1, p2) => p1.Scheduler.CompareTo(p2.Scheduler));
tasksToExecute.AddRange(tasks.GetRange(0, tasksToTake));
remainingCapacity -= tasksToTake;
if (availableTasks <= tasksToTake)
{
group.LastRunTime = currentTime;
}
if (remainingCapacity == 0) break;
}
}
}
if (tasksToExecute.Count > 0)
{
List<S7.Net.Types.DataItem> datas = new List<S7.Net.Types.DataItem>();
var s7 = new S7Communication();
string ipdz = "";
foreach (PlcBlzdbCs task in tasksToExecute)
{
task.Scheduler += 1;
if (ipdz == "") { ipdz = task.plc_ip; }
VarType type = setVarType(task.plc_sjlx);
datas.Add(new S7.Net.Types.DataItem
{
DataType = S7.Net.DataType.DataBlock,
VarType = type,
DB = int.Parse(task.plc_cck),
StartByteAdr = int.Parse(task.plc_pydz),
Count = 1,
});
}
if (s7.Connect(ipdz, 0, 1))
{
try
{
var task = s7.ReadMultipleVarsAsync(datas);
List<S7.Net.Types.DataItem> taskresult = await task;
foreach (var item in taskresult)
{
PlcBlzdbCs zdb = tasksToExecute.Where(m => m.plc_pydz == item.StartByteAdr.ToString()).FirstOrDefault();
PlcBlfhz fhz = new PlcBlfhz();
fhz.plc_uuid = zdb.plc_uuid;
fhz.plc_delete = "1";
PlcBlfhzManager plcblfhzmanager = new PlcBlfhzManager();
int xznr = plcblfhzmanager.insertData(fhz);
}
return;
}
catch (Exception ex)
{
Console.WriteLine($"读取数据时发生异常: {ex.Message}");
CommonMethods.AddLog(1, "读取数据时发生异常");
return; // 直接返回,避免后续代码执行
}
}
}
重点 ReadMultipleVarsAsync 这个返回的是一个 Task ,我代码是没贴全的,你要用这个方法你得处理这个异步任务,具体怎么处理就看你的业务需求了,只是代码片段就是想你不要拿来直接用,多学习学习,你说是吧