跳到主要内容

Siemens S7

Zeus 的 S7 模块支持 Siemens S7 TCP,也就是常见的 ISO-on-TCP / Read Var / Write Var 访问方式。当前覆盖 DB、I、Q、M 区的 BoolByteWordDWordIntDIntReal,并支持点表采集、按点名写回和虚拟 PLC 联调。

安装

dotnet add package Zeus.Communications
dotnet add package Zeus.Protocols.S7

连接真实 PLC

S7 TCP 通常使用端口 102。通道只负责 TCP 收发,S7 设备挂在通道之上:

await using var app = ZeusHost.Create(builder =>
{
builder.AddTcpClient("plc-link", "192.168.1.10", 102);
builder.AddSiemensS7("plc", "plc-link", new S7Options
{
Rack = 0,
Slot = 1
});
});

await app.StartAsync();

var plc = app.Devices.Get<S7Device>("plc");
var temperature = await plc.ReadRealAsync(S7Area.DataBlock, byteOffset: 0, dbNumber: 1);
await plc.WriteIntAsync(S7Area.DataBlock, byteOffset: 4, value: 120, dbNumber: 1);
var running = await plc.ReadBoolAsync(S7Area.Merkers, byteOffset: 10, bitOffset: 0);

如果现场使用 S7-300/400,槽号常见为 2;S7-1200/1500 项目常见为 1。Zeus 默认 Rack = 0Slot = 1,不匹配时请显式设置。

读写常用类型

var dbBytes = await plc.ReadDataBlockBytesAsync(dbNumber: 1, byteOffset: 0, length: 8);
await plc.WriteDataBlockBytesAsync(dbNumber: 1, byteOffset: 20, values: [1, 2, 3, 4]);

var word = await plc.ReadWordAsync(S7Area.DataBlock, 0, dbNumber: 1);
var dint = await plc.ReadDIntAsync(S7Area.DataBlock, 4, dbNumber: 1);
var real = await plc.ReadRealAsync(S7Area.DataBlock, 8, dbNumber: 1);
var bit = await plc.ReadBoolAsync(S7Area.DataBlock, 12, 3, dbNumber: 1);

await plc.WriteWordAsync(S7Area.Merkers, 0, 1234);
await plc.WriteBoolAsync(S7Area.Outputs, 2, 1, true);

S7 多字节数值按 PLC 常用的大端字节序编码。Bool 使用字节偏移加位偏移,例如 DB1.DBX12.3 对应 area: dbdb: 1address: 12bit: 3

点表采集与写回

await using var app = ZeusHost.Create(builder =>
{
builder.AddTcpClient("plc-link", "192.168.1.10", 102);
builder.AddSiemensS7("plc", "plc-link", points: map => map
.DbReal("temperature", dbNumber: 1, byteOffset: 0)
.DbInt("setpoint", dbNumber: 1, byteOffset: 4, scale: 0.1).Writable("setpoint")
.MarkerBool("running", byteOffset: 10, bitOffset: 0).Writable("running"));
});

await app.StartAsync();

var temperature = app.Points.Get<float>("temperature");
await app.Points.WriteAsync("setpoint", 12.3);
await app.Points.WriteAsync("running", true);

scale 用于整数寄存器的工程值换算。上例中写入 12.3 会反算为原始 123 再写入 DB1.DBW4

没硬件时先跑虚拟 PLC

var memory = new S7SlaveMemory();
await using var app = ZeusHost.Create(builder =>
{
builder.AddVirtualChannel("plc-link", new S7SlaveResponder(memory));
builder.AddSiemensS7("plc", "plc-link");
});

await app.StartAsync();

var plc = app.Devices.Get<S7Device>("plc");
await plc.WriteRealAsync(S7Area.DataBlock, 0, 25.5f, dbNumber: 1);
var value = await plc.ReadRealAsync(S7Area.DataBlock, 0, dbNumber: 1);

虚拟 PLC 支持 S7 握手、Read Var 和 Write Var,可用于测试主站逻辑、界面绑定和 JSON 配置。

可运行示例:samples/Zeus.Samples.Console.S7。该示例使用虚拟 S7 PLC,演示 DB/M 区点表采集、点名写回和直接协议读写。

JSON 配置

真实 PLC:

{
"channels": [
{ "name": "plc-link", "type": "tcp", "host": "192.168.1.10", "port": 102 }
],
"devices": [
{
"name": "plc",
"channel": "plc-link",
"type": "siemens-s7",
"rack": 0,
"slot": 1,
"points": [
{ "name": "temperature", "area": "db", "db": 1, "address": 0, "dataType": "real" },
{ "name": "setpoint", "area": "db", "db": 1, "address": 4, "dataType": "int", "scale": 0.1, "writable": true },
{ "name": "running", "area": "m", "address": 10, "bit": 0, "dataType": "bool", "writable": true }
]
}
]
}

无硬件联调:

{
"channels": [
{ "name": "plc-link", "type": "virtual", "responder": "s7" }
],
"devices": [
{
"name": "plc",
"channel": "plc-link",
"type": "siemens-s7",
"points": [
{ "name": "temperature", "area": "db", "db": 1, "address": 0, "dataType": "real" }
]
}
]
}

常见问题

现象常见原因处理
一直超时IP、端口 102、rack/slot 或 PLC 访问设置不对先用 S7SlaveResponder 跑通主站,再核对现场参数
DB 能读但值不对DB 偏移、数据类型或优化访问设置不匹配对照 TIA Portal 的实际地址,确认 DB 地址可被外部访问
Bool 点不对忘了 bit 偏移address 是字节偏移,bit 是 0–7
写输入区失败I 区由 PLC 输入映像驱动写 Q、M 或 DB 区;I 区只读

下一步:需要三菱 PLC 看 三菱 MC,需要标准仪表看 Modbus