基恩士 - Snet Docs

Keyence 协议驱动

包: Snet.Keyence | 类: KeyenceOperate | 类型: 5

提供通过以太网上的 Keyence 专用协议连接基恩士 PLC(KV 系列)的能力。

安装

dotnet add package Snet.Keyence

快速开始

using Snet.Keyence;

var op = await KeyenceOperate.InstanceAsync(new KeyenceData.Basics
{
    IpAddress = "192.168.1.100",
    Port = 8501
});

var address = new Address(new List<AddressDetails>
{
    new("读数", "DM100", DataType.Int16),
    new("读数2", "DM102", DataType.Int16)
});
var result = await op.ReadAsync(address);
if (result.Status)
{
    var data = result.GetSource<ConcurrentDictionary<string, AddressValue>>();
    foreach (var kv in data)
        Console.WriteLine($"{kv.Key} = {kv.Value.ResultValue}");
}
else
{
    Console.WriteLine($"读取失败: {result.Message}");
}

// 订阅之前 绑定数据事件
op.OnDataEventAsync += async (sender, e) =>
{
    if (e.Status)
    {
        var data = e.GetSource<ConcurrentDictionary<string, AddressValue>>();
        foreach (var kv in data)
            Console.WriteLine($"{kv.Key} = {kv.Value.ResultValue}");
    }
    else
    {
        Console.WriteLine($"{e.Message}");
    }
};

var subAddr = new Address(new List<AddressDetails>
{
    new("读数", "DM100", DataType.Int16)
});
await op.SubscribeAsync(subAddr);

// 后续:取消订阅
// await op.UnSubscribeAsync(subAddr);

await op.DisposeAsync();

配置

参数 类型 默认值 描述
IpAddress string 127.0.0.1 PLC IP 地址
Port int 6688 通信端口
ConnectTimeOut int 1000 连接超时(毫秒)
ReceiveTimeOut int 1000 接收超时(毫秒)
ProtocolType enum KeyenceMcNet 协议类型

支持的协议类型

类型 描述
KeyenceMcNet MC 协议二进制通过以太网 TCP(KV 系列)
KeyenceMcAsciiNet MC 协议 ASCII 通过以太网 TCP
KeyenceNanoSerial Nano 串行协议通过 RS-232/485
KeyenceNanoSerialOverTcp 通过 TCP 桥接的 Nano 串行协议
KeyenceKvOld KV 旧版协议

地址格式

MC Binary/ASCII(KV系列)

区域 地址格式 示例
X / Y / B (位, 十六进制) {类型}{十六进制} X0, Y10, Y1F
M / L / SM (位, 十进制) {类型}{编号} M100, L100, SM0
TS / TC / CS / CC (位, 十进制) {类型}{编号} TS0, TC1, CS5
MR/LR/CR 复合位号,映射M/L/SM MR100→16
D/DM/EM/FM/SD/CM/TN/CN(字) 十进制;EM偏移+100000 DM100, EM100
W/ZR(字)及ZF别名 W/ZR十六进制;ZF十进制映射ZR W1A0, ZF100
R(依操作类型) 字操作为十进制R;Bool操作为复合位号Y R100
MC说明

前缀逐字符接受大小写。W/ZR十六进制,ZF十进制别名;MR/LR/CR及Bool R按复合位号转换:数字字符串长度不超过2时按十进制保持,超过2时为十进制前段×16加末两位十进制数(MR100→16,MR015→15)。点号位的前段十进制,位号含A-F则十六进制,否则十进制。组包不优化点号输入、位区域的字访问及字区域的Bool访问;当前共享模型按转换后的六字符/24位线缆范围校验,EM输入≤899999,ZF使用十六进制线缆字段。

Nano独立地址模型

Nano有独立地址模型;旧KV也使用另一套实现。Nano前缀接受全大写或全小写,不承诺任意混合大小写;Nano客户端不接受裸数字地址,应写R100。

Nano区域 基数/单位
R/MR/LR/CR 复合位号
B/VB/W 十六进制
DM/CM/TM/VM/EM/FM/ZF/Z 十进制
CTH/CTC/T/C/TS/TC/CS/CC/AT 十进制,每元素通常两个ushort字

AT字节写返回只读失败,模拟服务器报文写返回E0;Bool写仅R/B/MR/LR/CR/VB。定时器/计数器多字元素的WRS载荷现在输出全部组成字,不再丢后半;长度按元素宽度取整,未实现严格整除检查,不足一元素失败,余下不完整元素可能被忽略。

公开 Snet.Driver.Profinet.Keyence.KeyenceNanoHelper.IsWriteSupported(string dataCode) 按精确大写设备代码判断写能力,返回true不代表给定地址或载荷已经通过全部验证。Nano不在自动组包映射中。

支持的数据类型

所有读取按 AddressDetails.DataType 分发 — 别名(Short = Int16、Float = Single、Int = Int32 等)共用同一分支。

数据类型 支持 说明
Bool ✅ 位读取 — 线圈 / 字内位 Nano的Bool写仅R/B/MR/LR/CR/VB;AT只读。
Int16 / Short, UInt16 / Ushort ✅ 16 位整数
Int32 / Int, UInt32 / Uint ✅ 32 位整数
Int64 / Long, UInt64 / Ulong ✅ 64 位整数
Float / Single, Double ✅ 32 / 64 位浮点
String / Char ✅ 带 length + 编码读取
ByteArray + 全部 10 种 *Array ✅ 带 length 的数组读取
Byte ❌ ReadAsync 中有 case 但无底层读取 — "不支持该类型读取"
注意

None、Date、DateTime、Time 在 ReadAsync 中没有分支 — 不支持。

地址自动组包与解包

每个数采驱动都实现 IPacker,因此 KeyenceOperate 可直接将分散地址合并为最小批量读取,并直接解包结果——无需装配处理器(见 IPacker 接口):

// 组包:将分散地址合并为最少的批量读取
var packed = await op.PackerAsync(address, "KeyenceMcNet");
if (!packed.Status) return;                                  // 组包失败
var packedAddr = packed.GetSource<Address>();

// 一次往返读取组包后的批次
var result = await op.ReadAsync(packedAddr);
if (!result.Status) return;                                  // 读取失败
var data = result.GetSource<ConcurrentDictionary<string, AddressValue>>();

// 解包:将每个批次的原始字节解析回各地址的值
var unpacked = await op.UnPackerAsync(data);
if (!unpacked.Status) return;                                // 解包失败
var values = unpacked.GetSource<List<ConcurrentDictionary<string, AddressValue>>>();
foreach (var dict in values)
    foreach (var v in dict)
        Console.WriteLine($"{v.Key} = {v.Value.ResultValue}");

仅 KeyenceMcNet / KeyenceMcAsciiNet 支持组包——KeyenceNanoSerial(及其 TCP 桥接)与 KeyenceKvOld 使用不同地址模型,原样返回地址集合。引擎细节:地址自动组包。

位批采用位流布局(批内偏移=位号差)。

订阅

先绑定数据事件,再通过 SubscribeAsync 添加地址;数据通过 OnDataEventAsync 到达:

op.OnDataEventAsync += async (sender, e) =>
{
    if (e.Status)
    {
        var data = e.GetSource<ConcurrentDictionary<string, AddressValue>>();
        foreach (var kv in data)
            Console.WriteLine($"{kv.Key} = {kv.Value.ResultValue}");
    }
    else
    {
        Console.WriteLine($"订阅错误: {e.Message}");
    }
};

var subAddr = new Address(new List<AddressDetails>
{
    new("读数", "DM100", DataType.Int16)
});
await op.SubscribeAsync(subAddr);

// 后续:停止监视
// await op.UnSubscribeAsync(subAddr);

支持的操作

操作 方法
连接 OnAsync()
断开 OffAsync()
读取 ReadAsync(address)
写入 WriteAsync(values)
订阅 SubscribeAsync(address)
组包 / 解包 PackerAsync(address, protocolTypeKey) / UnPackerAsync(data)

参见