Java API 参考
Darra Profinet Slave Java SDK(Maven 包 com.darra.pns)。单一入口是 PnSService。配置由 GUI / 服务完成,SDK 负责连接、启停、写 I、读 Q。周期自由配置,最低 1 ms。
connect() → start() → write / read / pdo() → stop()。不要把 Q 抄回 I。
运行前提:服务已启动,驱动已就绪。
import com.darra.pns.PDO;
import com.darra.pns.service.PnSService;
概览
| 类 | 包 | 职责 |
|---|---|---|
PnSService | com.darra.pns.service | 单一入口:无主机连接 / 启停 / 写 I / 读 Q / 地址化 |
PDO | com.darra.pns | ETH 式过程数据:in() 读 Q,out() 写 I |
PnSServiceException | com.darra.pns.service | 服务模式异常(Q 区只读、未连接、越界等) |
连接与生命周期
try (PnSService svc = new PnSService()) {
svc.connect();
svc.start();
// ... 写 I / 读 Q ...
svc.stop();
}
| 成员 | 类型 | 类别 | 读写 | 说明 |
|---|---|---|---|---|
PnSService() | PnSService | 设备 | 构造 | 未连接会话(AutoCloseable) |
connect() | void | 设备 | 写 | 本机会话 |
connect(String host) | void | 设备 | 写 | "127.0.0.1" = 指定本机服务 |
connect(host, port, apiKey) | void | 设备 | 写 | 完整形。只应填本机回环 |
DEFAULT_PORT | int | 设备 | 只读 | 本机服务默认端口 |
start() | void | 设备 | 写 | 启动会话。已启动则成功返回 |
stop() | void | 设备 | 写 | 停止本会话。主站在连时不要拆应用关系。停止路径不抛 |
close() | void | 设备 | 写 | 释放会话。空会话 / 重复调用安全 |
isConnected() / isStarted() | boolean | 设备 | 只读 | 会话是否已 connect / 本地是否已 start |
host() / port() | String / int | 设备 | 只读 | 服务主机 / 端口 |
生命周期:new → connect() → start() → 写 I / 读 Q → stop() → close()。
过程数据(写 I / 读 Q)
方向以控制器视角:
- I 区(设备 → 控制器):SDK 写。
write允许短写。 - Q 区(控制器 → 设备):SDK 读。写 Q 抛
PnSServiceException。
svc.write(new byte[]{0x01, 0x02, 0x03, 0x04}); // 写 I(允许短写)
byte[] q = svc.read(); // 读 Q
svc.setByte(4, 0x11); // 按偏移写 I
byte b = svc.getByte(0); // 按偏移读 Q
| 成员 | 类型 | 类别 | 读写 | 说明 |
|---|---|---|---|---|
write(byte[] data) | void | IO | 写 | 写 I 区前缀(设备 → 控制器)。空数组不写;超长 / 未启动抛异常 |
read() | byte[] | IO | 只读 | 读 Q 区副本(控制器 → 设备)。空数组 = 尚无过程数据 |
setByte(offset, v) | void | IO | 写 | 按绝对地址写 I 区单字节 |
getByte(offset) | byte | IO | 只读 | 按绝对地址读 Q 区单字节 |
getIo() | byte[][] | IO | 只读 | 过程映像快照:[0] = I 区,[1] = Q 区 |
writeArea(area, offset, data) | void | IO | 写 | 整区部分覆盖写。仅 INPUT / MEMORY;OUTPUT(Q)只读抛异常 |
readArea(area, offset, length) | byte[] | IO | 只读 | 整区按偏移读取 |
PDO(pdo().in() / pdo().out())
学 ETH Slave.PDO():in() 只读 Q,out() 可写 I。与 read() / write() 同区。无 live 指针,每次读写新拷。Java 无索引器:in().get(i) ≡ C# In[i]。
PDO pdo = svc.pdo();
byte q0 = pdo.in().get(0).getContent(); // 读 Q[0]
pdo.out().get(0).setContent((byte) 0x11); // 写 I[0]
short w = pdo.in().get(2).asInt16(); // 大端字
pdo.out().get(2).asInt16((short) -2);
byte[] q = new byte[16];
pdo.copyInputsTo(q); // 整段拷 Q
pdo.copyToOutputs(new byte[]{0x01, 0x02}); // 短写 I
| 成员 | 类型 | 类别 | 读写 | 说明 |
|---|---|---|---|---|
pdo() / getPdo() | PDO | PDO | 只读 | 同一会话上的 PDO 单例(懒初始化) |
in() | PdoArrayInstance | PDO | 只读 | 输入数组:读 Q(控制器 → 设备)。写抛 UnsupportedOperationException |
out() | PdoArrayInstance | PDO | 写 | 输出数组:写 I(设备 → 控制器) |
in().get(offset) / out().get(offset) | PdoDataItem | PDO | 只读 / 写 | 按字节偏移取项。偏移即过程映像地址 |
getContent() / setContent(byte) | byte / void | PDO | 只读 / 写 | 单字节。setContent 仅 out() |
asInt16() / asInt32() / asFloat() | 数值 | PDO | 读写 | 大端(PROFINET 网络序)。写仅 out() |
getBit(bit) / setBit(bit, value) | boolean / void | PDO | 读写 | 本字节第 0–7 位。写仅 out() |
copyInputsTo(dest) | int | PDO | 只读 | 整段拷 Q 到调用方缓冲(允许短拷) |
copyToOutputs(src) | int | PDO | 写 | 整段 / 短写 I |
readStruct / writeStruct | 结构 / void | PDO | 只读 / 写 | packed 大端结构 ↔ Q / I(PdoStruct 或 byte[]) |
地址化读写
西门子 / HSL 式地址,解析与 C# PnSAddress.Parse 对齐。字 / 双字大端,偏移即字节偏移,不强制 2 / 4 对齐(IW3 合法)。单一线性过程区,DB 仅槽位 1 有效(DB2 及以上抛 PnSServiceException)。
| 区域 | 地址格式 | 方向 | 写 |
|---|---|---|---|
| I 区 | I0.0 / IB0 / IW2 / ID4 | 设备 → 控制器 | 允许 |
| Q 区 | Q0.0 / QB0 / QW2 / QD4 | 控制器 → 设备 | 只读,写抛 PnSServiceException |
| M 区 | M0.0 / MB0 / MW100 / MD0 | 映射 I 面 | 允许 |
| DB 区 | DB1.DBX0.0 / DB1.DBB2 / DB1.DBW0 / DB1.DBD4 | 槽位 1 | 写走 I 面;仅 DB1 |
svc.writeBool("I0.0", true); // 写输入位
svc.writeInt16("IW2", (short) 0x1234); // 写输入字(大端)
boolean start = svc.readBool("Q0.0"); // 读输出位
short cmd = svc.readInt16("QW2"); // 读输出字
// svc.writeBool("Q0.0", true); // 抛 PnSServiceException:Q 区只读
| 成员 | 类型 | 类别 | 读写 | 说明 |
|---|---|---|---|---|
readBool(address) | boolean | IO | 只读 | 位:I0.0 / Q0.0 / M1.6 / DB1.DBX0.0 |
writeBool(address, value) | void | IO | 写 | 写位(I / M / DB)。Q 区只读,抛 PnSServiceException |
readInt16(address) | short | IO | 只读 | 字:IW2 / QW2 / MW0 / DB1.DBW0,大端 |
writeInt16(address, value) | void | IO | 写 | 写字(I / M / DB)。Q 区只读抛异常 |
readInt32(address) | int | IO | 只读 | 双字:ID4 / QD4 / MD0 / DB1.DBD4,大端 |
writeInt32(address, value) | void | IO | 写 | 写双字(I / M / DB)。Q 区只读抛异常 |
parseAddress(text) | Address | IO | 静态 | 解析地址。非法格式 / 位号越界抛异常 |
状态
状态来自运行态。
| 成员 | 类型 | 类别 | 读写 | 说明 |
|---|---|---|---|---|
status() / getState() | PnSState | 设备 | 只读 | 运行态枚举 |
statusEx() | ServiceStatus | 设备 | 只读 | 一次取回 state / connected / errorCode |
getErrorCode() | PnSRuntimeErrorCode | 设备 | 只读 | 最近错误码枚举。未识别 = UNKNOWN |
getErrorCodeRaw() | int | 设备 | 只读 | 错误码原值(0 = 无错误) |
ServiceStatus:getState() / connected() / getErrorCode() / getErrorCodeRaw()。connected() = 是否已与 IO 控制器建立周期数据交换。
PnSRuntimeErrorCode:OK=0 / ERR_INIT=-1 / ERR_CFG=-2 / ERR_THREAD=-3 / ERR_RUNNING=-4 / ERR_PDI=-5 / UNKNOWN=-10000。
完整示例
与仓库 examples/ServiceBasicExample.java 同口径。
import com.darra.pns.PDO;
import com.darra.pns.service.PnSService;
import com.darra.pns.service.PnSServiceException;
public class ServiceBasicExample {
public static void main(String[] args) {
PnSService svc = new PnSService();
try {
svc.connect();
svc.start();
byte[] q = svc.read(); // 读 Q
System.out.println("Q 长度 " + q.length);
svc.write(new byte[]{0x01, 0x02, 0x03, 0x04}); // 写 I
svc.writeBool("I0.0", true);
PDO pdo = svc.pdo();
System.out.printf("PDO In[0]=0x%02X%n", pdo.in().get(0).getContent() & 0xFF);
pdo.out().get(0).setContent((byte) 0x11);
svc.stop();
} catch (PnSServiceException e) {
System.err.println("错误: " + e.getMessage());
} finally {
svc.close();
}
}
}
Maven 依赖
<dependency>
<groupId>xyz.darra</groupId>
<artifactId>darra-pns-slave</artifactId>
<version>1.0.0</version>
</dependency>