1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Text.RegularExpressions;
using System.Collections.ObjectModel;
using FLY.ModbusModule;
using FObjBase;
namespace FLY.FeedbackRenZiJia.Server
{
public class HMI : IPLCLink
{
FLY.ModbusModule.ServerTCP modbusserver;
PLCRegister mPLCRegs;
#region 地址
const int ADDR_M_HasElectricCurrent = 0;//bit 三相电 电流
const int ADDR_M_HasFan = 1;//bit 风机启动
const int ADDR_D_ChannelCnt = 0;//加热通道数
const int ADDR_D_HeatUpdate = 1;//加热更新
const int ADDR_D_CurrUpdate = 2;//当前值更新
const int ADDR_D_Heats = 100;//加热量
const int ADDR_D_Currs = 300;//当前值
#endregion
public HMI()
{
mPLCRegs = new PLCRegister(3, 600);
mPLCRegs.RegChanged += new PLCRegister.RegChangedEventHandler(mPLCRegs_RegChanged);
RegToPropertyNameInit();
modbusserver = new ServerTCP(mPLCRegs);
PollModule.Current.Poll_Config(PollModule.POLL_CONFIG.ADD, new PollModule.PollHandler(OnPoll));
}
void mPLCRegs_RegChanged(object sender, PLCRegister.RegChangedEventArgs e)
{
var propertyNames = from _r in rpn where _r.type == e.RegType && e.IsCover(_r.addr,_r.len) select _r.propertyName;
if (propertyNames.Count() > 0)
{
foreach (var n in propertyNames)
NotifyPropertyChanged(n);
}
}
class RegToPropertyName
{
public PLCRegister.RegChangedEventArgs.REG_TYPE type;
public int addr;
public int len;
public string propertyName;
public RegToPropertyName(PLCRegister.RegChangedEventArgs.REG_TYPE type, int addr, int len, string propertyName)
{
this.type = type;
this.addr = addr;
this.len = len;
this.propertyName = propertyName;
}
}
List<RegToPropertyName> rpn = new List<RegToPropertyName>();
/// <summary>
/// 用于 外部写入后,地址转为PropertyName 触发 PropertyChanged
/// </summary>
void RegToPropertyNameInit()
{
rpn.Add(new RegToPropertyName(PLCRegister.RegChangedEventArgs.REG_TYPE.COIL, ADDR_M_HasElectricCurrent, 1, "HasElectricity"));
rpn.Add(new RegToPropertyName(PLCRegister.RegChangedEventArgs.REG_TYPE.COIL, ADDR_M_HasFan, 1, "HasFan"));
rpn.Add(new RegToPropertyName(PLCRegister.RegChangedEventArgs.REG_TYPE.REG, ADDR_D_ChannelCnt, 1, "ChannelCnt"));
rpn.Add(new RegToPropertyName(PLCRegister.RegChangedEventArgs.REG_TYPE.REG, ADDR_D_HeatUpdate, 1, "HeatUpdate_R"));
rpn.Add(new RegToPropertyName(PLCRegister.RegChangedEventArgs.REG_TYPE.REG, ADDR_D_CurrUpdate, 1, "CurrUpdate"));
}
public void OnPoll()
{
//需要访问modbusserver 判断最近有没通讯
if (DateTime.Now.Subtract(modbusserver.LastCommDT).TotalSeconds > 3)
{
//有3秒没通讯
Errno = -1;
}
else
{
Errno = 0;
}
}
#region PLCLink 成员
#region 状态
/// <summary>
/// -1 HMI 没有连接到 本服务器; -2 串口打开异常
/// </summary>
public int Errno { get; set; } = -1;
public int RetCode { get; set; }
#endregion
/// <summary>
/// 当前电流 有没?
/// </summary>
public bool HasElectricity
{
get {
return mPLCRegs.GetBool(ADDR_M_HasElectricCurrent);
}
}
/// <summary>
/// 风机是否启动?
/// </summary>
public bool HasFan
{
get
{
return mPLCRegs.GetBool(ADDR_M_HasFan);
}
}
public ushort ChannelCnt
{
get
{
return mPLCRegs.GetUInt16(ADDR_D_ChannelCnt);
}
set
{
mPLCRegs.SetUInt16(ADDR_D_ChannelCnt, value);
}
}
public ushort HeatUpdate
{
get
{
return mPLCRegs.GetUInt16(ADDR_D_HeatUpdate);
}
set
{
mPLCRegs.SetUInt16(ADDR_D_HeatUpdate, value);
}
}
public ushort HeatUpdate_R
{
get
{
return mPLCRegs.GetUInt16(ADDR_D_HeatUpdate);
}
}
public ushort CurrUpdate
{
get
{
return mPLCRegs.GetUInt16(ADDR_D_CurrUpdate);
}
set
{
mPLCRegs.SetUInt16(ADDR_D_CurrUpdate, value);
}
}
public void SetHeat(IEnumerable<UInt16> value)
{
for (int i = 0; i < value.Count(); i++)
{
mPLCRegs.SetUInt16(ADDR_D_Heats + i, value.ElementAt(i));
}
}
public IEnumerable<UInt16> GetCurr()
{
List<UInt16> list = new List<UInt16>();
for (int i = 0; i < ChannelCnt; i++)
{
list.Add(mPLCRegs.GetUInt16(ADDR_D_Currs + i));
}
return list;
}
#endregion
#region INotifyPropertyChanged 成员
public event PropertyChangedEventHandler PropertyChanged;
protected void NotifyPropertyChanged(string propertyname)
{
if (PropertyChanged != null)
{
PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyname));
}
}
#endregion
}
}