过程数据
先确认 诊断 里 Connected 与 IoStatus 正常,再读写过程数据。
数据获取用属性或返回错误码的方法,IO 路径不抛异常(未启动返回 InvalidHandle)。地址由公共解析器 PnSAddress.Parse 单源解析。
地址
西门子风格。字 / 双字偏移即字节偏移,不强制 2 / 4 对齐(IW3 合法)。字 / 双字为大端(PROFINET 网络序)。
| 区域 | 地址格式 | 方向 | 写 | 读 |
|---|---|---|---|---|
| I(输入面) | I0.0 / IB0 / IW2 / ID4 | 设备 → 控制器 | 发送 | 读回本地影子 |
| Q(输出面) | Q0.0 / QB0 / QW2 / QD4 | 控制器 → 设备 | 返回 NotSupported | 读控制器数据 |
| M | M0.0 / MB0 / MW0 / MD0 | 内部存储(映射输入面) | 本机可见 | 本机可见 |
| DB | DB1.DBX0.0 / DB1.DBB2 / DBW0 / DBD4 / DB1.0 | 槽位 1 数据块 | 按区 | 按区 |
服务会话是单一线性过程区:仅 DB1 有效,槽位大于 1 返回 NotFound。
地址化读写
| 成员 | 类型 | 类别 | 读写 | 说明 |
|---|---|---|---|---|
WriteBool(string address, bool value) | PnSErrorCode | IO | 写 | 写位。仅 I / M / DB;写 Q 返回 NotSupported |
WriteInt16(string address, short value) | PnSErrorCode | IO | 写 | 写字(IW2,大端) |
WriteInt32(string address, int value) | PnSErrorCode | IO | 写 | 写双字(ID4,大端) |
ReadBool(string address, out bool value) | PnSErrorCode | IO | 只读 | 读位(I 影子 / Q 控制器值) |
ReadInt16(string address, out short value) | PnSErrorCode | IO | 只读 | 读字(IW2 / QW0,大端) |
ReadInt32(string address, out int value) | PnSErrorCode | IO | 只读 | 读双字(ID4 / QD4,大端) |
ReadArea(PnSAddressArea area, out byte[] data) | PnSErrorCode | IO | 只读 | 整区快照。Input / Output / Memory |
WriteArea(PnSAddressArea area, byte[] data) | PnSErrorCode | IO | 写 | 整区写入。长度必须等于区长度。写 Q 返回 NotSupported |
Read(out byte[] fromPlc) | PnSErrorCode | IO | 只读 | 读当前 Q 区快照 |
Write(byte[] toPlc) | PnSErrorCode | IO | 写 | 从偏移 0 写 I 区(允许短写) |
this[int offset] | byte | IO | 读写 | get = 读 Q 绝对字节;set = 写 I 绝对字节。失败抛异常 |
device.WriteInt16("IW2", 123);
short q = 0;
PnSErrorCode rc = device.ReadInt16("QW0", out q);
if (rc != PnSErrorCode.Success)
Console.WriteLine(rc);
// device.WriteInt16("QW0", 5); // → NotSupported
ReadArea / WriteArea 一次整区,避免逐地址往返。WriteArea 的 data 长度必须与区长度一致,否则 LengthMismatch。
过程数据质量
读写之前先看 IoStatus。GOOD / BAD 语义、AllGood 等见 诊断 · 过程数据质量。
if (!device.IoStatus.InputDataGood)
Console.WriteLine("控制器数据当前不可用,先不要当有效值用");
辅助:结构体映射
辅助写法。 主路径是诊断 + 地址化 I / Q。结构体映射只是把同一过程区按字段排开,不是永久主叙事。
通过 device.PDO 访问(Pdo 是同一实例)。与地址化读写同源同区。
| 调用 | 方向 | 读写 |
|---|---|---|
PDO.Write(ref tx) | 结构体 → I(设备 → 控制器) | 只写 |
PDO.Read(ref rx) | Q → 结构体(控制器 → 设备) | 只读 |
PDO.Out[i] | 写 I 字节 | 可写 |
PDO.In[i] | 读 Q 字节 | 只读 |
PDO.Outputs | get = I 影子;set = 整段写 I | 读写 |
PDO.Inputs | 当前 Q 快照(每次新拷) | 只读 |
结构体必须 [StructLayout(LayoutKind.Sequential, Pack = 1)]。字段按声明顺序紧排;bool 占 1 字节;字 / 双字 / 8 字节大端。支持数值、bool、枚举、定长 byte[](MarshalAs(ByValArray, SizeConst=N))、嵌套结构体。
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct PdoData
{
public byte A; // 偏移 0
public short B; // 偏移 1(大端)
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public byte[] D; // 偏移 3
}
PdoData tx = new PdoData { A = 1, B = -2, D = new byte[] { 9, 8, 7, 6 } };
device.PDO.Write(ref tx);
PdoData rx = new PdoData();
device.PDO.Read(ref rx);
也可 device.WriteStruct(ref tx) / device.ReadStruct(ref rx),与上同义。
byte q0 = device.PDO.In[0].Content; // 读 Q
device.PDO.Out[0].Content = 0x11; // 写 I
short iw = device.PDO.Out[2].AsInt16; // 大端字
// device.PDO.In[0].Content = 1; // 抛 InvalidOperationException(In 只读)
In[i] / Out[i] 的 i 是过程映像字节偏移。PdoDataItem 另有 AsUInt16 / AsInt32 / AsFloat / GetBit / SetBit(SetBit 仅 Out)。
InputsMapping<T>() 把 Q 区映射为结构体快照(每次拷贝,无 live 指针)。可选内部轮询 OnChanged。OutputsMapping(ref T) 与 Write(ref T) 同义。
GetFieldAddress 把字段名翻成 I / Q 地址,供地址化读写按字段访问。无参重载默认 Q(与 Read 同向)。
string qAddr = device.PDO.GetFieldAddress<PdoData>("B"); // "QW1"
string iAddr = device.PDO.GetFieldAddress<PdoData>("B", PnSAddressArea.Input); // "IW1"
| 成员 | 类型 | 类别 | 读写 | 说明 |
|---|---|---|---|---|
PDO / Pdo | PnSPdo | 辅助 | 只读 | 同一实例 |
PDO.Write<T>(ref T data) | PnSErrorCode | 辅助 | 写 | 结构体 → I |
PDO.Read<T>(ref T data) | PnSErrorCode | 辅助 | 只读 | Q → 结构体 |
PDO.Out | PdoArrayInstance | 辅助 | 写 | Out[offset] 写 I |
PDO.In | PdoArrayInstance | 辅助 | 只读 | In[offset] 读 Q |
PDO.Outputs | byte[] | 辅助 | 读写 | get = I 影子;set = 写 I |
PDO.Inputs | byte[] | 辅助 | 只读 | 当前 Q 快照 |
PDO.InputsMapping<T>() | InputPdoInstance<T> | 辅助 | 只读 | Q → 结构体快照 |
PDO.GetFieldAddress<T>(name) | string | 辅助 | 只读 | 字段 → Q 区地址 |
WriteStruct<T>(ref T data) | PnSErrorCode | 辅助 | 写 | PDO.Write 转发 |
ReadStruct<T>(ref T data) | PnSErrorCode | 辅助 | 只读 | PDO.Read 转发 |