Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
H
hemei
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
潘栩锋
hemei
Commits
cdae5181
Commit
cdae5181
authored
Jan 12, 2019
by
潘栩锋
🚴
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
正在改线程办ModbusMapper
parent
a13b615a
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
287 additions
and
1 deletion
+287
-1
FLY.ModbusMapper.csproj
...FLY.ModbusMapper/FLY.ModbusMapper/FLY.ModbusMapper.csproj
+1
-0
ClientTCP.cs
...FLY.ModbusMapper/FLY.ModbusMapper/WithThread/ClientTCP.cs
+6
-1
ModbusMapper_Client.cs
...Mapper/FLY.ModbusMapper/WithThread/ModbusMapper_Client.cs
+280
-0
No files found.
Project.FLY.ModbusMapper/FLY.ModbusMapper/FLY.ModbusMapper.csproj
View file @
cdae5181
...
...
@@ -57,6 +57,7 @@
<Compile
Include=
"Properties\AssemblyInfo.cs"
/>
<Compile
Include=
"WithThread\ClientTCP.cs"
/>
<Compile
Include=
"WithThread\IModbusClient.cs"
/>
<Compile
Include=
"WithThread\ModbusMapper_Client.cs"
/>
</ItemGroup>
<ItemGroup>
<ProjectReference
Include=
"..\..\Project.FLY.FObjSys\FObjSys\FObjBase.csproj"
>
...
...
Project.FLY.ModbusMapper/FLY.ModbusMapper/WithThread/ClientTCP.cs
View file @
cdae5181
...
...
@@ -97,10 +97,15 @@ namespace FLY.Modbus.WithThread
bool
TranExecute
(
Pack_Proto
request
,
out
Pack_Proto
reponse
)
{
reponse
=
new
Pack_Proto
();
if
(!
IsConnected
)
return
false
;
lock
(
this
)
{
if
(!
IsConnected
)
goto
_end
;
return
false
;
try
{
sock
.
Send
(
request
.
ToBytes
());
...
...
Project.FLY.ModbusMapper/FLY.ModbusMapper/WithThread/ModbusMapper_Client.cs
0 → 100644
View file @
cdae5181
using
System
;
using
System.Collections.Generic
;
using
System.Diagnostics
;
using
System.Linq
;
using
System.Text
;
namespace
FLY.Modbus.WithThread
{
/// <summary>
/// 使用线程版本
/// 支持自定义逻辑
/// </summary>
public
class
ModbusMapper_Client
:
ModbusMapper
{
/// <summary>
/// 更新周期,单位ms,
/// </summary>
public
int
UpdateInterval
=
200
;
/// <summary>
/// 实际更新间隔
/// </summary>
public
TimeSpan
ActUpdateInterval
{
get
;
protected
set
;
}
private
Stopwatch
mStopwatch
=
new
Stopwatch
();
class
RegWrite
{
public
PLCAddressArea
dataArea
;
public
int
addr
;
public
object
val
;
public
RegWrite
(
PLCAddressArea
dataArea
,
int
addr
,
object
val
)
{
this
.
dataArea
=
dataArea
;
this
.
addr
=
addr
;
this
.
val
=
val
;
}
}
List
<
RegWrite
>
rws
=
new
List
<
RegWrite
>();
/// <summary>
/// tcp client
/// </summary>
public
ClientTCP
mclient
;
/// <summary>
///
/// </summary>
/// <param name="clienttcp"></param>
public
ModbusMapper_Client
(
ClientTCP
clienttcp
)
{
mclient
=
clienttcp
;
FObjBase
.
PollModule
.
Current
.
Poll_Config
(
OnPoll_update
);
mclient
.
PropertyChanged
+=
Mclient_PropertyChanged
;
}
public
override
string
ToString
()
{
return
mclient
.
ToString
();
}
private
void
Mclient_PropertyChanged
(
object
sender
,
System
.
ComponentModel
.
PropertyChangedEventArgs
e
)
{
if
(
e
.
PropertyName
==
"IsConnected"
)
{
if
(!
mclient
.
IsConnected
)
{
coils
.
ClearPlanState
();
registers
.
ClearPlanState
();
//复位全部状态
isInCommunication
=
false
;
p_doing
=
null
;
isUpdating
=
false
;
curr_area_idx
=
0
;
// DRMap 的数据 与 下端 属性的数据一致
foreach
(
RegWrite
rw
in
rws
)
{
//更新 本地的 PLC 数据
SetModbusData
(
rw
.
dataArea
,
rw
.
addr
,
rw
.
val
);
}
rws
.
Clear
();
mStopwatch
.
Stop
();
}
}
}
void
OnPoll_update
()
{
if
(!
mclient
.
IsConnected
)
return
;
if
(!
mStopwatch
.
IsRunning
)
mStopwatch
.
Restart
();
if
(
mStopwatch
.
ElapsedMilliseconds
>=
UpdateInterval
)
{
//检查上次更新周期是否完成
if
(!
isUpdating
)
{
isUpdating
=
true
;
ActUpdateInterval
=
mStopwatch
.
Elapsed
;
mStopwatch
.
Restart
();
}
}
NextPlan
();
}
int
curr_area_idx
=
0
;
void
NextPlan
()
{
if
(
isInCommunication
)
//已经在通讯中
return
;
if
(
rws
.
Count
()
>
0
)
UpdateWriteData
();
if
(
isUpdating
)
{
p_doing
=
mAreaManager
[
curr_area_idx
].
GetNextPlan
();
if
(
p_doing
!=
null
)
{
p_doing
.
isDoing
=
false
;
UpdateReadData
();
}
else
{
//读完
curr_area_idx
++;
if
(
curr_area_idx
>=
mAreaManager
.
Count
())
{
isUpdating
=
false
;
//读完一轮了
curr_area_idx
=
0
;
}
else
{
NextPlan
();
}
}
}
}
/// <summary>
/// 读 多个线圈回调
/// </summary>
/// <param name="val"></param>
/// <param name="obj"></param>
void
Do_01_callback
(
bool
[]
val
,
object
obj
)
{
ModbusMapper
.
Plan
p
=
obj
as
ModbusMapper
.
Plan
;
p
.
isDoing
=
false
;
SetModbusData
(
PLCAddressArea
.
Coil
,
p
.
addr
,
val
);
isInCommunication
=
false
;
NextPlan
();
}
/// <summary>
/// 读多个寄存器回调
/// </summary>
/// <param name="val"></param>
/// <param name="obj"></param>
void
Do_03_callback
(
UInt16
[]
val
,
object
obj
)
{
ModbusMapper
.
Plan
p
=
obj
as
ModbusMapper
.
Plan
;
p
.
isDoing
=
false
;
SetModbusData
(
PLCAddressArea
.
Register
,
p
.
addr
,
val
);
isInCommunication
=
false
;
NextPlan
();
}
void
Do_0F_callback
(
object
obj
)
{
isInCommunication
=
false
;
NextPlan
();
}
void
Do_10_callback
(
object
obj
)
{
isInCommunication
=
false
;
NextPlan
();
}
/// <summary>
/// 正在通讯中
/// </summary>
bool
isInCommunication
=
false
;
/// <summary>
/// 读更新流程中
/// </summary>
bool
isUpdating
=
false
;
/// <summary>
/// 读更新 的计划
/// </summary>
ModbusMapper
.
Plan
p_doing
=
null
;
///// <summary>
/////
///// </summary>
///// <param name="propertyname"></param>
//protected void NotifyPropertyChanged(string propertyname)
//{
// PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyname));
//}
///// <summary>
/////
///// </summary>
//public event PropertyChangedEventHandler PropertyChanged;
/// <summary>
/// PC -> PLC
/// 为命名数据赋值,会改变Modbus的寄存器值,并产生通知
/// </summary>
/// <param name="dr">数据映射</param>
/// <param name="val">数据值,不能为空</param>
/// <returns></returns>
public
override
bool
SetNameData
(
DataToRegs
dr
,
object
val
)
{
RegWrite
rw
;
switch
(
dr
.
dataArea
)
{
case
PLCAddressArea
.
Coil
:
rw
=
rws
.
Find
((
c
)
=>
{
return
(
c
.
addr
==
dr
.
addr
)
&&
(
c
.
dataArea
==
PLCAddressArea
.
Coil
);
});
if
(
rw
!=
null
)
rws
.
Remove
(
rw
);
rws
.
Add
(
new
RegWrite
(
dr
.
dataArea
,
dr
.
addr
,
dr
.
ToBools
(
val
)));
return
true
;
case
PLCAddressArea
.
Register
:
rw
=
rws
.
Find
((
c
)
=>
{
return
(
c
.
addr
==
dr
.
addr
)
&&
(
c
.
dataArea
==
PLCAddressArea
.
Register
);
});
if
(
rw
!=
null
)
rws
.
Remove
(
rw
);
rws
.
Add
(
new
RegWrite
(
dr
.
dataArea
,
dr
.
addr
,
dr
.
ToRegs
(
val
)));
return
true
;
}
return
false
;
}
/// <summary>
/// 更新写命令缓冲区
/// </summary>
void
UpdateWriteData
()
{
RegWrite
rw
=
rws
.
First
();
switch
(
rw
.
dataArea
)
{
case
PLCAddressArea
.
Coil
:
if
(
mclient
.
Do_0F
((
UInt16
)
rw
.
addr
,
(
bool
[])(
rw
.
val
),
Do_0F_callback
,
null
)
!=
ModbusClient_Errno
.
OK
)
return
;
SetModbusData
(
rw
.
dataArea
,
rw
.
addr
,
rw
.
val
);
break
;
case
PLCAddressArea
.
Register
:
if
(
mclient
.
Do_10
((
UInt16
)
rw
.
addr
,
(
UInt16
[])
rw
.
val
,
Do_10_callback
,
null
)
!=
ModbusClient_Errno
.
OK
)
return
;
SetModbusData
(
rw
.
dataArea
,
rw
.
addr
,
rw
.
val
);
break
;
}
//更新 本地的 PLC 数据
SetModbusData
(
rw
.
dataArea
,
rw
.
addr
,
rw
.
val
);
rws
.
Remove
(
rw
);
isInCommunication
=
true
;
}
void
UpdateReadData
()
{
switch
(
p_doing
.
area
)
{
case
PLCAddressArea
.
Coil
:
mclient
.
Do_01
((
UInt16
)
p_doing
.
addr
,
(
UInt16
)
p_doing
.
num
,
Do_01_callback
,
p_doing
);
break
;
case
PLCAddressArea
.
Register
:
mclient
.
Do_03
((
UInt16
)
p_doing
.
addr
,
(
UInt16
)
p_doing
.
num
,
Do_03_callback
,
p_doing
);
break
;
}
p_doing
.
isDoing
=
true
;
isInCommunication
=
true
;
}
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment