Skip to content
切换导航条
切换导航条
当前项目
正在载入...
登录
顾剑亮
/
AIOBOX
转到一个项目
切换导航栏
切换导航栏固定状态
项目
群组
代码片段
帮助
项目
活动
版本库
流水线
图表
问题
0
合并请求
0
维基
网络
创建新的问题
作业
提交
问题看板
文件
提交
网络
比较
分支
标签
Commit f7630a88
由
顾剑亮
编写于
2020-05-12 11:48:13 +0800
浏览文件
选项
浏览文件
标签
下载
电子邮件补丁
差异文件
删除 AIOBOX - 副本.cs
1 个父辈
00438b6f
隐藏空白字符变更
内嵌
并排
正在显示
1 个修改的文件
包含
0 行增加
和
1149 行删除
AIOBOX - 副本.cs
AIOBOX - 副本.cs
deleted
100644 → 0
查看文件 @
00438b6
using
System
;
using
System.Net
;
using
System.Net.Sockets
;
using
System.Threading
;
using
System.Collections.Generic
;
namespace
Asa.IOModule
{
/// <summary>
/// AIOBOX操作类
/// </summary>
public
class
AIOBOX
{
private
Socket
_client
;
//客户端
private
bool
_loop
;
private
string
_logPath
;
//日志的文件夹路径
private
LogFile
_log
;
//日志的类
private
LogType
_logType
;
//日志输出类型
private
bool
_frontInputOutput
;
//True:Input False:Output
private
int
countInput
;
//输入总数
private
int
countOutput
;
//输出总数
private
int
sleepInput
;
//自动读取DI间隔
private
int
sleepOutput
;
//自动读取DO间隔
private
Box_Type
_typeInput
;
//输入类型
private
Box_Type
_typeOutput
;
//输出类型
private
byte
[]
_addressInput
;
//输入地址
private
byte
[]
_addressOutput
;
//输出地址
private
bool
_autoReadInput
;
//自动读取DI
private
bool
_autoReadOutput
;
//自动读取DO
private
bool
_manualReadOutput
;
//手动读取DO
private
bool
_changeDI
;
//DI收到数据触发事件
private
bool
_changeDO
;
//DO收到数据触发事件
private
bool
_changeAI
;
//AI收到数据触发事件
private
bool
_changeAO
;
//AO收到数据触发事件
private
Box_Sta
[]
_stateDI
;
//状态
private
Box_Sta
[]
_stateDO
;
//状态
private
int
[]
_valueAI
;
//模拟量
private
int
[]
_valueAO
;
//模拟量
private
System
.
Collections
.
Concurrent
.
ConcurrentQueue
<
ushort
>
_flag
;
private
System
.
Collections
.
Concurrent
.
ConcurrentQueue
<
byte
[
]>
_send
;
private
System
.
Collections
.
Concurrent
.
ConcurrentQueue
<
byte
[
]>
_receive
;
private
Thread
tSend
;
//发送命令处理
private
Thread
tReceive
;
//接收信息处理
private
Thread
tListen
;
//监听网络
private
Thread
tTrigger
;
//触发DI、DO改变事件
private
Thread
tReadInput
;
//自动读取DI线程
private
Thread
tReadOutput
;
//自动读取DO线程
private
Thread
tFlag
;
//ModBusTCP标识
private
UdpClient
broadcastClient
;
//广播客户端
private
IPEndPoint
broadcastEndPoint
;
//广播远程节点
private
byte
[]
broadcastBuffer
;
//远程返回数据
/// <summary>
/// 每条命令发送的间隔
/// 不能小于15,会出现IO接收不到的情况
/// 小于30时,会出现接收数据连包的情况
/// </summary>
private
const
int
SEND_SLEEP
=
30
;
/// <summary>
/// ModBus端口
/// </summary>
public
const
int
PORT
=
502
;
/// <summary>
/// 自动读取DI委托
/// </summary>
/// <param name="box">AIOBOX</param>
/// <param name="sta">所有DI状态</param>
public
delegate
void
DIO_Changed
(
AIOBOX
box
,
Box_Sta
[]
sta
);
/// <summary>
/// 自动读取DI事件触发
/// </summary>
public
event
DIO_Changed
DI_Changed_Event
;
/// <summary>
/// 自动读取DO事件触发
/// </summary>
public
event
DIO_Changed
DO_Changed_Event
;
/// <summary>
/// 自动读取AI委托
/// </summary>
/// <param name="box">AIOBOX</param>
/// <param name="val">所有AI的值</param>
public
delegate
void
AIO_Changed
(
AIOBOX
box
,
int
[]
val
);
/// <summary>
/// 自动读取AI事件触发
/// </summary>
public
event
AIO_Changed
AI_Changed_Event
;
/// <summary>
/// 自动读取AO事件触发
/// </summary>
public
event
AIO_Changed
AO_Changed_Event
;
/// <summary>
/// AIOBOX
/// </summary>
public
AIOBOX
()
{
_log
=
null
;
_logPath
=
null
;
_autoReadInput
=
false
;
_autoReadOutput
=
false
;
_manualReadOutput
=
false
;
sleepInput
=
100
;
sleepOutput
=
100
;
}
/// <summary>
/// IP地址
/// </summary>
public
string
IP
{
set
;
get
;
}
=
"192.168.1.100"
;
/// <summary>
/// 是否连接
/// </summary>
public
bool
IsConn
{
get
;
private
set
;
}
=
false
;
/// <summary>
/// 错误信息
/// </summary>
public
string
ErrInfo
{
get
;
private
set
;
}
=
""
;
/// <summary>
/// 日志路径,连接前设置路径会自动保存日志
/// </summary>
/// <param name="path">文件夹路径</param>
/// <param name="type">输出类型</param>
public
void
LogPath
(
string
path
,
LogType
type
)
{
_logPath
=
path
;
_logType
=
type
;
}
/// <summary>
/// 设置输入端
/// </summary>
/// <param name="type">类型</param>
/// <param name="count">数量</param>
public
void
SetInput
(
Box_Type
type
,
int
count
)
{
_typeInput
=
type
;
countInput
=
count
;
_frontInputOutput
=
false
;
}
/// <summary>
/// 设置输出端
/// </summary>
/// <param name="type">类型</param>
/// <param name="count">数量</param>
public
void
SetOutput
(
Box_Type
type
,
int
count
)
{
_typeOutput
=
type
;
countOutput
=
count
;
_frontInputOutput
=
true
;
}
/// <summary>
/// 自动获取IP地址,未连接前使用,必须在同一网段
/// </summary>
/// <param name="localIP">本地IP地址</param>
/// <returns></returns>
public
bool
AutoIP
(
string
localIP
)
{
try
{
IPEndPoint
local
=
new
IPEndPoint
(
IPAddress
.
Parse
(
localIP
),
55654
);
broadcastClient
=
new
UdpClient
(
local
);
broadcastBuffer
=
null
;
Thread
tTemp
=
new
Thread
(
new
ThreadStart
(
GetIP
));
tTemp
.
Start
();
broadcastEndPoint
=
new
IPEndPoint
(
IPAddress
.
Parse
(
"255.255.255.255"
),
1024
);
byte
[]
dgram
=
new
byte
[]
{
0x05
,
0x00
,
0x07
,
0x00
,
0x00
,
0xC1
,
0x59
};
broadcastClient
.
Send
(
dgram
,
dgram
.
Length
,
broadcastEndPoint
);
Thread
.
Sleep
(
1000
);
tTemp
.
Abort
();
broadcastClient
.
Close
();
ErrInfo
=
"无法访问"
;
if
(
broadcastBuffer
==
null
)
return
false
;
if
(
broadcastBuffer
[
0
]
!=
0x3B
)
return
false
;
byte
[]
buff
=
new
byte
[
broadcastBuffer
[
7
]];
Array
.
Copy
(
broadcastBuffer
,
9
,
buff
,
0
,
buff
.
Length
);
IP
=
buff
[
buff
.
Length
-
12
]
+
"."
+
buff
[
buff
.
Length
-
11
]
+
"."
+
buff
[
buff
.
Length
-
10
]
+
"."
+
buff
[
buff
.
Length
-
9
];
ErrInfo
=
"OK"
;
return
true
;
}
catch
(
Exception
ex
)
{
ErrInfo
=
ex
.
Message
;
return
false
;
}
}
/// <summary>
/// 检查IP地址
/// </summary>
/// <param name="ip"></param>
/// <returns></returns>
public
bool
CheckIP
(
string
ip
)
{
//IP合法
string
pattern
=
@"^((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)$"
;
bool
rtn
=
System
.
Text
.
RegularExpressions
.
Regex
.
IsMatch
(
ip
,
pattern
);
if
(!
rtn
)
{
ErrInfo
=
"非法的IP地址"
;
return
false
;
}
//Ping服务端
System
.
Net
.
NetworkInformation
.
Ping
ping
=
new
System
.
Net
.
NetworkInformation
.
Ping
();
System
.
Net
.
NetworkInformation
.
PingReply
result
=
ping
.
Send
(
ip
,
1000
);
ping
.
Dispose
();
if
(
result
.
Status
!=
System
.
Net
.
NetworkInformation
.
IPStatus
.
Success
)
{
ErrInfo
=
"Ping "
+
ip
+
" 请求没有响应"
;
return
false
;
}
return
true
;
}
/// <summary>
/// 连接
/// </summary>
/// <returns></returns>
public
bool
Connect
()
{
try
{
//初始化地址
InitAddr
();
//检查IP地址
bool
rtn
=
CheckIP
(
IP
);
if
(!
rtn
)
return
false
;
_send
=
new
System
.
Collections
.
Concurrent
.
ConcurrentQueue
<
byte
[
]>
();
_receive
=
new
System
.
Collections
.
Concurrent
.
ConcurrentQueue
<
byte
[
]>
();
_flag
=
new
System
.
Collections
.
Concurrent
.
ConcurrentQueue
<
ushort
>();
//建立连接
_client
=
new
Socket
(
AddressFamily
.
InterNetwork
,
SocketType
.
Stream
,
ProtocolType
.
Tcp
);
_client
.
SetSocketOption
(
SocketOptionLevel
.
Socket
,
SocketOptionName
.
SendTimeout
,
500
);
_client
.
SetSocketOption
(
SocketOptionLevel
.
Socket
,
SocketOptionName
.
ReceiveTimeout
,
500
);
_client
.
SetSocketOption
(
SocketOptionLevel
.
Socket
,
SocketOptionName
.
NoDelay
,
1
);
_client
.
Connect
(
IPAddress
.
Parse
(
IP
),
PORT
);
Thread
.
Sleep
(
100
);
//需要等待一会才能获取连接状态
tFlag
=
new
Thread
(
new
ThreadStart
(
Flag
));
tFlag
.
Start
();
Thread
.
Sleep
(
10
);
if
(
_logPath
==
null
)
_log
=
null
;
else
_log
=
new
LogFile
(
_logPath
,
IP
);
tSend
=
new
Thread
(
new
ThreadStart
(
Send
));
tReceive
=
new
Thread
(
new
ThreadStart
(
Receive
));
tListen
=
new
Thread
(
new
ThreadStart
(
Listen
));
tTrigger
=
new
Thread
(
new
ThreadStart
(
TriggerDIO
));
tReadInput
=
new
Thread
(
new
ThreadStart
(
AutoReadInput
));
tReadOutput
=
new
Thread
(
new
ThreadStart
(
AutoReadOutput
));
tListen
.
Start
();
tTrigger
.
Start
();
tSend
.
Start
();
tReceive
.
Start
();
tReadInput
.
Start
();
tReadOutput
.
Start
();
IsConn
=
true
;
ErrInfo
=
""
;
if
(
_log
!=
null
)
_log
.
OutData
(
"Connect OK"
);
return
true
;
}
catch
(
Exception
ex
)
{
IsConn
=
false
;
ErrInfo
=
ex
.
Message
;
if
(
_log
!=
null
)
_log
.
OutError
(
ex
.
Message
);
return
false
;
}
}
/// <summary>
/// 关闭连接
/// </summary>
public
void
Close
()
{
IsConn
=
false
;
if
(
tListen
!=
null
)
tListen
.
Abort
();
tListen
=
null
;
if
(
tReadInput
!=
null
)
tReadInput
.
Abort
();
tReadInput
=
null
;
if
(
tReadOutput
!=
null
)
tReadOutput
.
Abort
();
tReadOutput
=
null
;
if
(
tTrigger
!=
null
)
tTrigger
.
Abort
();
tTrigger
=
null
;
if
(
tSend
!=
null
)
tSend
.
Abort
();
tSend
=
null
;
if
(
tReceive
!=
null
)
tReceive
.
Abort
();
tReceive
=
null
;
if
(
tFlag
!=
null
)
tFlag
.
Abort
();
tFlag
=
null
;
if
(
_client
!=
null
)
{
_client
.
Shutdown
(
SocketShutdown
.
Both
);
_client
.
Close
();
}
_client
=
null
;
if
(
_log
!=
null
)
{
_log
.
OutData
(
"Close OK"
);
_log
.
Close
();
_log
=
null
;
}
}
/// <summary>
/// 自动读取输入端并触发事件(主动上传数据 = 禁止)
/// </summary>
/// <param name="read">是否自动读取</param>
/// <param name="sleep">间隔,必须大于等于15ms</param>
public
void
AutoReadInput
(
bool
read
,
int
sleep
)
{
if
(
countInput
<
1
)
_autoReadInput
=
false
;
else
if
(
sleep
<
15
)
_autoReadInput
=
false
;
else
if
(
read
)
{
_autoReadInput
=
true
;
sleepInput
=
sleep
;
}
else
_autoReadInput
=
false
;
}
/// <summary>
/// 自动读取输入端并触发事件(主动上传数据 = 使能)
/// </summary>
/// <param name="read">是否自动读取</param>
public
void
AutoReadInput
(
bool
read
)
{
if
(
countInput
<
1
)
_autoReadInput
=
false
;
else
if
(
read
)
{
_autoReadInput
=
true
;
sleepInput
=
8000
;
//IO模块最大10s,避免超过时间,每8秒发送一次心跳包
}
else
_autoReadInput
=
false
;
}
/// <summary>
/// 自动读取输出端,触发事件
/// </summary>
/// <param name="read">是否自动读取</param>
/// <param name="sleep">间隔,必须大于等于15ms</param>
public
void
AutoReadOutput
(
bool
read
,
int
sleep
)
{
if
(
countOutput
<
1
)
{
_autoReadOutput
=
false
;
sleepOutput
=
100
;
}
else
if
(
sleep
<
15
)
{
_autoReadOutput
=
false
;
sleepOutput
=
100
;
}
else
if
(
read
)
{
_autoReadOutput
=
true
;
sleepOutput
=
sleep
;
}
else
{
_autoReadOutput
=
false
;
_manualReadOutput
=
true
;
//用于第一次连接的时候读取一次状态
sleepOutput
=
sleep
;
}
}
/// <summary>
/// 相反状态(ON/OFF)
/// </summary>
/// <param name="sta"></param>
/// <returns></returns>
public
Box_Sta
ReverseStatus
(
Box_Sta
sta
)
{
return
sta
==
Box_Sta
.
On
?
Box_Sta
.
Off
:
Box_Sta
.
On
;
}
/// <summary>
/// 相反状态(ON/OFF)
/// </summary>
/// <param name="sta"></param>
public
void
ReverseStatus
(
ref
Box_Sta
sta
)
{
if
(
sta
==
Box_Sta
.
On
)
sta
=
Box_Sta
.
Off
;
else
sta
=
Box_Sta
.
On
;
}
/// <summary>
/// 读取单个DI输入状态(ON/OFF)
/// </summary>
/// <param name="add">输入地址,从0开始</param>
/// <returns></returns>
public
Box_Sta
ReadDI
(
int
add
)
{
return
_stateDI
[
add
];
}
/// <summary>
/// 读取多个DI输入状态(ON/OFF)
/// </summary>
/// <param name="add">起始地址,从0开始</param>
/// <param name="count">数量</param>
/// <returns></returns>
public
Box_Sta
[]
ReadDI
(
int
add
,
int
count
)
{
Box_Sta
[]
sta
=
new
Box_Sta
[
count
];
Array
.
Copy
(
_stateDI
,
add
,
sta
,
0
,
count
);
return
sta
;
}
/// <summary>
/// 读取单个AI模拟量的值
/// </summary>
/// <param name="add">模拟量地址,从0开始</param>
/// <returns></returns>
public
int
ReadAI
(
int
add
)
{
return
_valueAI
[
add
];
}
/// <summary>
/// 读取多个AI模拟量的值
/// </summary>
/// <param name="add">起始地址,从0开始</param>
/// <param name="count">数量</param>
/// <returns></returns>
public
int
[]
ReadAI
(
int
add
,
int
count
)
{
int
[]
sta
=
new
int
[
count
];
Array
.
Copy
(
_valueAI
,
add
,
sta
,
0
,
count
);
return
sta
;
}
/// <summary>
/// 读取单个DO输出状态(ON/OFF)
/// </summary>
/// <param name="add">输出地址,从0开始</param>
/// <returns></returns>
public
Box_Sta
ReadDO
(
int
add
)
{
return
_stateDO
[
add
];
}
/// <summary>
/// 读取多个DO输出状态(ON/OFF)
/// </summary>
/// <param name="add">起始地址,从0开始</param>
/// <param name="count">数量</param>
/// <returns></returns>
public
Box_Sta
[]
ReadDO
(
int
add
,
int
count
)
{
Box_Sta
[]
sta
=
new
Box_Sta
[
count
];
Array
.
Copy
(
_stateDO
,
add
,
sta
,
0
,
count
);
return
sta
;
}
/// <summary>
/// 读取单个AO模拟量的值
/// </summary>
/// <param name="add">输出地址,从0开始</param>
/// <returns></returns>
public
int
ReadAO
(
int
add
)
{
return
_valueAO
[
add
];
}
/// <summary>
/// 读取多个AO模拟量的值
/// </summary>
/// <param name="add">起始地址,从0开始</param>
/// <param name="count">数量</param>
/// <returns></returns>
public
int
[]
ReadAO
(
int
add
,
int
count
)
{
int
[]
sta
=
new
int
[
count
];
Array
.
Copy
(
_valueAO
,
add
,
sta
,
0
,
count
);
return
sta
;
}
/// <summary>
/// 写入单个DO输出状态(ON/OFF)
/// </summary>
/// <param name="add">输出地址,从0开始</param>
/// <param name="sta"></param>
/// <returns></returns>
public
bool
WriteDO
(
int
add
,
Box_Sta
sta
)
{
try
{
byte
[]
data
=
Command
();
byte
[]
buff
=
new
byte
[
12
];
Array
.
Copy
(
data
,
0
,
buff
,
0
,
data
.
Length
);
buff
[
7
]
=
5
;
//功能码
buff
[
9
]
=
_addressOutput
[
add
];
//地址
buff
[
10
]
=
(
byte
)
sta
;
//写入值
_send
.
Enqueue
(
buff
);
if
(!
_autoReadOutput
)
_manualReadOutput
=
true
;
return
true
;
}
catch
(
Exception
ex
)
{
ErrInfo
=
ex
.
Message
;
return
false
;
}
}
/// <summary>
/// 获取本地IPv4地址
/// </summary>
/// <returns></returns>
public
string
[]
GetLocalIP
()
{
List
<
string
>
str
=
new
List
<
string
>();
IPAddress
[]
add
=
Dns
.
GetHostEntry
(
Dns
.
GetHostName
()).
AddressList
;
foreach
(
IPAddress
ip
in
add
)
{
if
(
ip
.
AddressFamily
.
ToString
()
==
"InterNetwork"
)
str
.
Add
(
ip
.
ToString
());
}
return
str
.
ToArray
();
}
/// <summary>
/// 发送命令
/// </summary>
private
void
Send
()
{
while
(
_loop
)
{
bool
rtn
=
_send
.
TryDequeue
(
out
byte
[]
result
);
if
(
rtn
)
{
try
{
_client
.
Send
(
result
);
if
(
_log
!=
null
)
{
if
(
_logType
==
LogType
.
All
)
_log
.
OutData
(
"Send "
,
result
);
}
}
catch
(
Exception
ex
)
{
if
(
_log
!=
null
)
_log
.
OutError
(
ex
.
Message
);
}
}
Thread
.
Sleep
(
SEND_SLEEP
);
}
}
/// <summary>
/// 接收命令
/// </summary>
private
void
Receive
()
{
while
(
_loop
)
{
if
(
_receive
.
TryDequeue
(
out
byte
[]
buff
))
{
if
(
_log
!=
null
)
{
if
(
_logType
==
LogType
.
All
)
_log
.
OutData
(
"Receive "
,
buff
);
}
if
(
buff
.
Length
<
7
)
continue
;
if
(
buff
[
7
]
==
1
)
{
ReadDO
(
buff
);
_changeDO
=
true
;
}
else
if
(
buff
[
7
]
==
2
)
{
ReadDI
(
buff
);
_changeDI
=
true
;
}
else
if
(
buff
[
7
]
==
4
)
{
ReadAI
(
buff
);
_changeAI
=
true
;
}
else
if
(
buff
[
7
]
==
5
)
{
//ReadSingle(buff);
}
}
Thread
.
Sleep
(
10
);
}
}
/// <summary>
/// 读取写入单个DO,功能码5
/// </summary>
/// <param name="buff"></param>
private
void
ReadSingle
(
byte
[]
buff
)
{
string
s
;
//if (LogOut)
//{
// byte[] bb = new byte[2];
// bb[0] = buff[1];
// bb[1] = buff[0];
// ushort flag = BitConverter.ToUInt16(bb, 0);
// s = string.Format("{0:HH:mm:ss:fff} WriteDO {1} fun={2} len={3}", DateTime.Now, flag, buff[7], buff.Length);
// _log.Add(s);
//}
// int n = 0;
// int move = 0;
// byte val = _receive[0][9];
// for (int i = 0; i < 8; i++)
// {
// n = (val & Convert.ToInt32(Math.Pow(2, move))) >> move;
// _sta[i + 16] = n == 1 ? Box_Sta.On : Box_Sta.Off;
// move++;
// }
// if (_receive[0][8] == 2)
// {
// move = 0;
// val = _receive[0][10];
// for (int i = 8; i < 16; i++)
// {
// n = (val & Convert.ToInt32(Math.Pow(2, move))) >> move;
// _sta[i + 16] = n == 1 ? Box_Sta.On : Box_Sta.Off;
// move++;
// }
// }
// ErrInfo = "OK";
//}
//catch (Exception ex)
//{
// ErrInfo = ex.Message;
//}
}
/// <summary>
/// 读取所有DO状态,功能码1
/// </summary>
/// <param name="buff"></param>
private
void
ReadDO
(
byte
[]
buff
)
{
try
{
int
idx
=
0
;
int
count
=
buff
[
8
];
for
(
int
i
=
1
;
i
<=
count
;
i
++)
{
int
n
=
0
;
int
move
=
0
;
byte
val
=
buff
[
8
+
i
];
for
(
int
j
=
0
;
j
<
8
;
j
++)
{
n
=
(
val
&
Convert
.
ToInt32
(
Math
.
Pow
(
2
,
move
)))
>>
move
;
_stateDO
[
idx
++]
=
n
==
1
?
Box_Sta
.
On
:
Box_Sta
.
Off
;
move
++;
}
}
if
(
_log
!=
null
)
{
if
(
_logType
==
LogType
.
All
)
_log
.
OutData
(
"Read All DO"
);
}
}
catch
(
Exception
ex
)
{
if
(
_log
!=
null
)
_log
.
OutError
(
ex
.
Message
);
}
}
/// <summary>
/// 读取所有DI状态,功能码2
/// </summary>
private
void
ReadDI
(
byte
[]
buff
)
{
try
{
int
idx
=
0
;
int
count
=
buff
[
8
];
for
(
int
i
=
1
;
i
<=
count
;
i
++)
{
int
n
=
0
;
int
move
=
0
;
byte
val
=
buff
[
8
+
i
];
for
(
int
j
=
0
;
j
<
8
;
j
++)
{
n
=
(
val
&
Convert
.
ToInt32
(
Math
.
Pow
(
2
,
move
)))
>>
move
;
_stateDI
[
idx
++]
=
n
==
1
?
Box_Sta
.
On
:
Box_Sta
.
Off
;
move
++;
}
}
if
(
_log
!=
null
)
{
if
(
_logType
==
LogType
.
All
)
_log
.
OutData
(
"Read All DI"
);
}
}
catch
(
Exception
ex
)
{
if
(
_log
!=
null
)
_log
.
OutError
(
ex
.
Message
);
}
}
/// <summary>
/// 读取所有AI的值,功能码4
/// </summary>
/// <param name="buff"></param>
private
void
ReadAI
(
byte
[]
buff
)
{
try
{
if
(
countInput
*
2
==
buff
[
8
])
{
_valueAI
[
0
]
=
buff
[
9
]
*
256
+
buff
[
10
];
_valueAI
[
1
]
=
buff
[
11
]
*
256
+
buff
[
12
];
_valueAI
[
2
]
=
buff
[
13
]
*
256
+
buff
[
14
];
_valueAI
[
3
]
=
buff
[
15
]
*
256
+
buff
[
16
];
}
if
(
_log
!=
null
)
{
if
(
_logType
==
LogType
.
All
)
_log
.
OutData
(
"Read All AI"
);
}
}
catch
(
Exception
ex
)
{
if
(
_log
!=
null
)
_log
.
OutError
(
ex
.
Message
);
}
}
/// <summary>
/// 命令,前7个字节
/// </summary>
/// <returns></returns>
private
byte
[]
Command
()
{
_flag
.
TryDequeue
(
out
ushort
result
);
byte
[]
flag
=
BitConverter
.
GetBytes
(
result
);
byte
[]
data
=
new
byte
[
7
];
data
[
0
]
=
flag
[
1
];
data
[
1
]
=
flag
[
0
];
data
[
2
]
=
0
;
data
[
3
]
=
0
;
data
[
4
]
=
0
;
data
[
5
]
=
0
;
data
[
6
]
=
255
;
return
data
;
}
/// <summary>
/// 触发DIO改变事件
/// </summary>
private
void
TriggerDIO
()
{
Box_Sta
[]
sta
=
null
;
int
[]
val
=
null
;
while
(
_loop
)
{
//if (_autoReadInput)
//{
if
(
_typeInput
==
Box_Type
.
DI
&&
DI_Changed_Event
!=
null
)
{
if
(
_changeDI
)
{
sta
=
new
Box_Sta
[
countInput
];
Array
.
Copy
(
_stateDI
,
0
,
sta
,
0
,
sta
.
Length
);
if
(
_log
!=
null
)
{
if
(
_logType
==
LogType
.
All
)
_log
.
OutData
(
"Trigger DI Event"
);
}
DI_Changed_Event
.
Invoke
(
this
,
sta
);
_changeDI
=
false
;
}
}
else
if
(
_typeInput
==
Box_Type
.
AI
&&
AI_Changed_Event
!=
null
)
{
if
(
_changeAI
)
{
val
=
new
int
[
countInput
];
Array
.
Copy
(
_valueAI
,
0
,
val
,
0
,
val
.
Length
);
if
(
_log
!=
null
)
{
if
(
_logType
==
LogType
.
All
)
_log
.
OutData
(
"Trigger AI Event"
);
}
AI_Changed_Event
.
Invoke
(
this
,
val
);
_changeAI
=
false
;
}
}
//}
//if (_autoReadOutput)
//{
if
(
_typeOutput
==
Box_Type
.
DO
&&
DO_Changed_Event
!=
null
)
{
if
(
_changeDO
)
{
sta
=
new
Box_Sta
[
countOutput
];
Array
.
Copy
(
_stateDO
,
0
,
sta
,
0
,
sta
.
Length
);
if
(
_log
!=
null
)
{
if
(
_logType
==
LogType
.
All
)
_log
.
OutData
(
"Trigger DO Event"
);
}
DO_Changed_Event
.
Invoke
(
this
,
sta
);
_changeDO
=
false
;
}
}
else
if
(
_typeOutput
==
Box_Type
.
AO
&&
AO_Changed_Event
!=
null
)
{
if
(
_changeAO
)
{
val
=
new
int
[
countOutput
];
Array
.
Copy
(
_valueAO
,
0
,
val
,
0
,
val
.
Length
);
if
(
_log
!=
null
)
{
if
(
_logType
==
LogType
.
All
)
_log
.
OutData
(
"Trigger AO Event"
);
}
AO_Changed_Event
.
Invoke
(
this
,
val
);
_changeAO
=
false
;
}
}
//}
Thread
.
Sleep
(
10
);
}
}
/// <summary>
/// 自动读取输入端线程
/// </summary>
private
void
AutoReadInput
()
{
while
(
_loop
)
{
if
(
IsConn
&&
_autoReadInput
)
{
//if (suspendDI && suspend > 0)
//{
// suspendDI = false;
// suspend--;
//}
//else
//{
byte
[]
data
=
Command
();
byte
[]
buff
=
new
byte
[
12
];
Array
.
Copy
(
data
,
0
,
buff
,
0
,
data
.
Length
);
buff
[
5
]
=
6
;
//后面字节数
//功能码
if
(
_typeInput
==
Box_Type
.
DI
)
buff
[
7
]
=
2
;
else
if
(
_typeInput
==
Box_Type
.
AI
)
buff
[
7
]
=
4
;
buff
[
9
]
=
_addressInput
[
0
];
//地址
buff
[
11
]
=
(
byte
)
countInput
;
//个数
_send
.
Enqueue
(
buff
);
//suspendDI = true;
//}
}
Thread
.
Sleep
(
sleepInput
);
}
}
/// <summary>
/// 自动读取输出端线程
/// </summary>
private
void
AutoReadOutput
()
{
while
(
_loop
)
{
Thread
.
Sleep
(
sleepOutput
);
if
(!
IsConn
)
continue
;
if
(!
_autoReadOutput
)
{
if
(
_manualReadOutput
)
_manualReadOutput
=
false
;
else
continue
;
}
byte
[]
data
=
Command
();
byte
[]
buff
=
new
byte
[
12
];
Array
.
Copy
(
data
,
0
,
buff
,
0
,
data
.
Length
);
buff
[
5
]
=
6
;
//后面字节数
buff
[
7
]
=
1
;
//功能码
buff
[
9
]
=
_addressOutput
[
0
];
//地址
buff
[
11
]
=
(
byte
)
countOutput
;
//个数
_send
.
Enqueue
(
buff
);
}
}
/// <summary>
/// 监听结果线程
/// </summary>
private
void
Listen
()
{
byte
[]
temp
=
new
byte
[
200
];
int
start
,
len
;
while
(
_loop
)
{
try
{
if
(
_client
.
Available
>
0
)
{
start
=
0
;
int
count
=
_client
.
Receive
(
temp
);
while
(
count
-
start
>
6
)
{
len
=
temp
[
start
+
5
];
len
+=
6
;
if
(
start
+
len
>
count
)
break
;
byte
[]
aa
=
new
byte
[
len
];
Array
.
Copy
(
temp
,
start
,
aa
,
0
,
len
);
_receive
.
Enqueue
(
aa
);
start
+=
len
;
}
}
}
catch
(
Exception
ex
)
{
if
(
_log
!=
null
)
_log
.
OutError
(
ex
.
Message
);
}
Thread
.
Sleep
(
10
);
}
}
private
void
InitAddr
()
{
byte
n
=
0
;
if
(
_frontInputOutput
)
{
_addressInput
=
new
byte
[
countInput
];
for
(
int
i
=
0
;
i
<
countInput
;
i
++)
_addressInput
[
i
]
=
n
++;
_addressOutput
=
new
byte
[
countOutput
];
for
(
int
i
=
0
;
i
<
countOutput
;
i
++)
_addressOutput
[
i
]
=
n
++;
}
else
{
_addressOutput
=
new
byte
[
countOutput
];
for
(
int
i
=
0
;
i
<
countOutput
;
i
++)
_addressOutput
[
i
]
=
n
++;
_addressInput
=
new
byte
[
countInput
];
for
(
int
i
=
0
;
i
<
countInput
;
i
++)
_addressInput
[
i
]
=
n
++;
}
_stateDI
=
new
Box_Sta
[
countInput
];
_stateDO
=
new
Box_Sta
[
countOutput
];
_valueAI
=
new
int
[
countInput
];
_valueAO
=
new
int
[
countOutput
];
}
private
void
GetIP
()
{
broadcastBuffer
=
broadcastClient
.
Receive
(
ref
broadcastEndPoint
);
}
private
void
Flag
()
{
ushort
n
=
0
;
while
(
true
)
{
if
(
_flag
.
Count
<
10
)
{
_flag
.
Enqueue
(++
n
);
if
(
n
==
ushort
.
MaxValue
)
n
=
0
;
}
Thread
.
Sleep
(
5
);
}
}
private
bool
ReConnect
()
{
try
{
//初始化地址
InitAddr
();
//检查IP地址
bool
rtn
=
CheckIP
(
IP
);
if
(!
rtn
)
return
false
;
_send
=
new
System
.
Collections
.
Concurrent
.
ConcurrentQueue
<
byte
[
]>
();
_receive
=
new
System
.
Collections
.
Concurrent
.
ConcurrentQueue
<
byte
[
]>
();
_flag
=
new
System
.
Collections
.
Concurrent
.
ConcurrentQueue
<
ushort
>();
//建立连接
_client
=
new
Socket
(
AddressFamily
.
InterNetwork
,
SocketType
.
Stream
,
ProtocolType
.
Tcp
);
_client
.
SetSocketOption
(
SocketOptionLevel
.
Socket
,
SocketOptionName
.
SendTimeout
,
500
);
_client
.
SetSocketOption
(
SocketOptionLevel
.
Socket
,
SocketOptionName
.
ReceiveTimeout
,
500
);
_client
.
SetSocketOption
(
SocketOptionLevel
.
Socket
,
SocketOptionName
.
NoDelay
,
1
);
_client
.
Connect
(
IPAddress
.
Parse
(
IP
),
PORT
);
Thread
.
Sleep
(
100
);
//需要等待一会才能获取连接状态
tFlag
=
new
Thread
(
new
ThreadStart
(
Flag
));
tFlag
.
Start
();
Thread
.
Sleep
(
10
);
if
(
_logPath
==
null
)
_log
=
null
;
else
_log
=
new
LogFile
(
_logPath
,
IP
);
tSend
=
new
Thread
(
new
ThreadStart
(
Send
));
tReceive
=
new
Thread
(
new
ThreadStart
(
Receive
));
tListen
=
new
Thread
(
new
ThreadStart
(
Listen
));
tTrigger
=
new
Thread
(
new
ThreadStart
(
TriggerDIO
));
tReadInput
=
new
Thread
(
new
ThreadStart
(
AutoReadInput
));
tReadOutput
=
new
Thread
(
new
ThreadStart
(
AutoReadOutput
));
IsConn
=
true
;
_loop
=
true
;
tListen
.
Start
();
tTrigger
.
Start
();
tSend
.
Start
();
tReceive
.
Start
();
tReadInput
.
Start
();
tReadOutput
.
Start
();
ErrInfo
=
""
;
if
(
_log
!=
null
)
_log
.
OutData
(
"Connect OK"
);
return
true
;
}
catch
(
Exception
ex
)
{
IsConn
=
false
;
ErrInfo
=
ex
.
Message
;
if
(
_log
!=
null
)
_log
.
OutError
(
ex
.
Message
);
return
false
;
}
}
}
/// <summary>
/// IO模块类型
/// </summary>
public
enum
Box_Type
:
int
{
/// <summary>
/// 数字信号输入
/// </summary>
DI
,
/// <summary>
/// 数字信号输出
/// </summary>
DO
,
/// <summary>
/// 模拟量输入
/// </summary>
AI
,
/// <summary>
/// 模拟量输出
/// </summary>
AO
}
/// <summary>
/// IO模块寄存器状态
/// </summary>
public
enum
Box_Sta
:
int
{
/// <summary>
/// 断开,关闭,低电平
/// </summary>
Off
=
0
,
/// <summary>
/// 闭合,打开,高电平
/// </summary>
On
=
255
}
/// <summary>
/// 日志类型
/// </summary>
public
enum
LogType
:
int
{
/// <summary>
/// 仅错误信息
/// </summary>
OnlyError
,
/// <summary>
/// 所有
/// </summary>
All
}
}
\ No newline at end of file
编写
预览
支持
Markdown
格式
附加文件
你添加了
0
人
到此讨论。请谨慎行事。
Finish editing this message first!
Cancel
请
注册
或
登录
后发表评论