Commit 26d99f02 authored by 潘栩锋's avatar 潘栩锋 🚴

优化 AD盒模拟器,吹膜的PLC模拟器 使用 V3接口

parent 87d5e93d
...@@ -162,7 +162,8 @@ namespace FLY.Simulation.Blowing ...@@ -162,7 +162,8 @@ namespace FLY.Simulation.Blowing
/// </summary> /// </summary>
public double CurrFilmVelocity { get; private set; } public double CurrFilmVelocity { get; private set; }
#endregion #endregion
public HMI mHMI; public IPlcLink plcLink;
public int Avg { get; set; } public int Avg { get; set; }
public double[] mFilmLength3D; public double[] mFilmLength3D;
...@@ -267,16 +268,21 @@ namespace FLY.Simulation.Blowing ...@@ -267,16 +268,21 @@ namespace FLY.Simulation.Blowing
mAirRing2.AfterDatasUpdateEvent += new Action<ObservableCollection<int>>(mAirRing2_AfterDatasUpdateEvent); mAirRing2.AfterDatasUpdateEvent += new Action<ObservableCollection<int>>(mAirRing2_AfterDatasUpdateEvent);
Avg = (int)(BeforeDatas.Average());//原始平均值 Avg = (int)(BeforeDatas.Average());//原始平均值
mAirRing2.Bads[2] = true;
mAirRing2.Bads[30] = true;
mAirRing2.Bads[31] = true;
TestPos = 500; TestPos = 500;
UpdateTestHeat(); UpdateTestHeat();
//AfterDatas.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(AfterDatas_CollectionChanged); //AfterDatas.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(AfterDatas_CollectionChanged);
PropertyChanged += new PropertyChangedEventHandler(Blowing_PropertyChanged); PropertyChanged += new PropertyChangedEventHandler(Blowing_PropertyChanged);
mHMI = new HMI(); //plcLink = new HMI();
mHMI.mAirRing = mAirRing2; //plcLink.Init(mAirRing2);
var plc = new PlcLink();
plc.Init(mAirRing2);
plcLink = plc;
Is360 = false; Is360 = false;
...@@ -317,6 +323,12 @@ namespace FLY.Simulation.Blowing ...@@ -317,6 +323,12 @@ namespace FLY.Simulation.Blowing
/// 加热量, 数据量为 ChannelCnt /// 加热量, 数据量为 ChannelCnt
/// </summary> /// </summary>
public int[] Heats; public int[] Heats;
/// <summary>
/// 坏的加热棒
/// </summary>
public bool[] Bads;
public bool HasElectricCurrent;
/// <summary> /// <summary>
/// 第1个加热棒,对应的 数据序号, 数据量为 1000, BeforeData.Count /// 第1个加热棒,对应的 数据序号, 数据量为 1000, BeforeData.Count
/// </summary> /// </summary>
...@@ -375,11 +387,24 @@ namespace FLY.Simulation.Blowing ...@@ -375,11 +387,24 @@ namespace FLY.Simulation.Blowing
{ {
ChannelCnt = channelcnt; ChannelCnt = channelcnt;
Heats = new int[ChannelCnt]; Heats = new int[ChannelCnt];
Bads = new bool[ChannelCnt];
Array.Clear(Heats, 0, ChannelCnt); Array.Clear(Heats, 0, ChannelCnt);
} }
public event Action<ObservableCollection<int>> AfterDatasUpdateEvent; public event Action<ObservableCollection<int>> AfterDatasUpdateEvent;
public void HeatApply() public void HeatApply()
{ {
bool current = false;
for (int i = 0; i < ChannelCnt; i++)
{
if ((Bads[i] == false) && (Heats[i] > 0))
{
current = true;
break;
}
}
HasElectricCurrent = current;
int boltcnt = BeforeDatas.Count(); int boltcnt = BeforeDatas.Count();
double b_c = (double)(boltcnt)/ChannelCnt; double b_c = (double)(boltcnt)/ChannelCnt;
int b = Channel1stIndex; int b = Channel1stIndex;
......
...@@ -47,7 +47,9 @@ ...@@ -47,7 +47,9 @@
<Compile Include="FilmLength3D.cs" /> <Compile Include="FilmLength3D.cs" />
<Compile Include="GageAD.cs" /> <Compile Include="GageAD.cs" />
<Compile Include="HMI.cs" /> <Compile Include="HMI.cs" />
<Compile Include="IPlcLink.cs" />
<Compile Include="OrgData.cs" /> <Compile Include="OrgData.cs" />
<Compile Include="PlcLink.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
...@@ -59,6 +61,10 @@ ...@@ -59,6 +61,10 @@
<Project>{5EE61AC6-5269-4F0F-B8FA-4334FE4A678F}</Project> <Project>{5EE61AC6-5269-4F0F-B8FA-4334FE4A678F}</Project>
<Name>Misc</Name> <Name>Misc</Name>
</ProjectReference> </ProjectReference>
<ProjectReference Include="..\..\Project.FLY.ModbusMapper\FLY.ModbusMapper\FLY.ModbusMapper.csproj">
<Project>{6d4b9bda-2a66-4583-b244-758bc4213d9f}</Project>
<Name>FLY.ModbusMapper</Name>
</ProjectReference>
<ProjectReference Include="..\..\Project.FLY.ModbusModule\FLY.ModbusModule\FLY.ModbusModule.csproj"> <ProjectReference Include="..\..\Project.FLY.ModbusModule\FLY.ModbusModule\FLY.ModbusModule.csproj">
<Project>{8e19c40f-ce7f-4982-bd90-4eb4e9e04e34}</Project> <Project>{8e19c40f-ce7f-4982-bd90-4eb4e9e04e34}</Project>
<Name>FLY.ModbusModule</Name> <Name>FLY.ModbusModule</Name>
......
...@@ -4,10 +4,11 @@ using System.Linq; ...@@ -4,10 +4,11 @@ using System.Linq;
using System.Text; using System.Text;
using System.ComponentModel; using System.ComponentModel;
using System.Net; using System.Net;
using System.IO;
namespace FLY.Simulation.Blowing namespace FLY.Simulation.Blowing
{ {
public class HMI:INotifyPropertyChanged public class HMI: IPlcLink
{ {
const int ADDR_M_HasElectricCurrent = 0;//bit 三相电 电流 const int ADDR_M_HasElectricCurrent = 0;//bit 三相电 电流
const int ADDR_M_HasFan = 1;//bit 风机启动 const int ADDR_M_HasFan = 1;//bit 风机启动
...@@ -33,12 +34,12 @@ namespace FLY.Simulation.Blowing ...@@ -33,12 +34,12 @@ namespace FLY.Simulation.Blowing
/// 风机是否启动? /// 风机是否启动?
/// </summary> /// </summary>
public bool HasFan { get; set; } = true; public bool HasFan { get; set; } = true;
public string PlcAddr { get; set; } = "127.0.0.1";
UInt16 heatupdate = 1; UInt16 heatupdate = 1;
UInt16 currupdate = 1; UInt16 currupdate = 1;
UInt16 heatupdate_last = 1; UInt16 heatupdate_last = 1;
UInt16[] heats; UInt16[] heats;
bool[] Bads;
public Blowing.AirRing mAirRing; public Blowing.AirRing mAirRing;
FLY.ModbusModule.ClientTCP mbclient; FLY.ModbusModule.ClientTCP mbclient;
...@@ -46,26 +47,34 @@ namespace FLY.Simulation.Blowing ...@@ -46,26 +47,34 @@ namespace FLY.Simulation.Blowing
public HMI() public HMI()
{ {
mbclient = new FLY.ModbusModule.ClientTCP(IPAddress.Parse("127.0.0.1"));
if (!Load())
Save();
heats = new UInt16[100]; heats = new UInt16[100];
Bads = new bool[100];
Array.Clear(heats, 0, 100); Array.Clear(heats, 0, 100);
Array.Clear(Bads, 0, 100);
Bads[2] = true;
Bads[30] = true;
heatupdate = 1; heatupdate = 1;
heatupdate_last = 1; heatupdate_last = 1;
currupdate = 1; currupdate = 1;
mbclient.PropertyChanged += new PropertyChangedEventHandler(mbclient_PropertyChanged);
}
public void Init(Blowing.AirRing mAirRing)
{
this.mAirRing = mAirRing;
mbclient = new FLY.ModbusModule.ClientTCP(IPAddress.Parse(PlcAddr));
mbclient.PropertyChanged += new PropertyChangedEventHandler(mbclient_PropertyChanged);
//每1秒读取一次 //每1秒读取一次
FObjBase.PollModule.Current.Poll_Config(FObjBase.PollModule.POLL_CONFIG.ADD, FObjBase.PollModule.Current.Poll_Config(FObjBase.PollModule.POLL_CONFIG.ADD,
new FObjBase.PollModule.PollHandler(OnPoll),TimeSpan.FromMilliseconds(200) ); new FObjBase.PollModule.PollHandler(OnPoll), TimeSpan.FromMilliseconds(200));
} }
void mbclient_PropertyChanged(object sender, PropertyChangedEventArgs e) void mbclient_PropertyChanged(object sender, PropertyChangedEventArgs e)
{ {
if (e.PropertyName == "IsConnected") if (e.PropertyName == "IsConnected")
...@@ -134,23 +143,61 @@ namespace FLY.Simulation.Blowing ...@@ -134,23 +143,61 @@ namespace FLY.Simulation.Blowing
mAirRing.HeatApply(); mAirRing.HeatApply();
SendHeats(); SendHeats();
bool current = false; HasElectricCurrent = mAirRing.HasElectricCurrent;
for (int i = 0; i < mAirRing.ChannelCnt; i++)
{
if ( (Bads[i]==false) && (mAirRing.Heats[i]>0))
{
current = true;
break;
}
}
HasElectricCurrent = current;
CurrUpdate++; CurrUpdate++;
SendUpdate(); SendUpdate();
} }
SendStatue(); SendStatue();
} }
string filePath = "airRingPlc.json";
bool Load()
{
return HmiJsonDb.Load(filePath, this);
}
public bool Save()
{
return HmiJsonDb.Save(filePath, this);
}
public event PropertyChangedEventHandler PropertyChanged; public event PropertyChangedEventHandler PropertyChanged;
} }
public class HmiJsonDb
{
public string PlcAddr = "127.0.0.1";
public static bool Save(string filePath, HMI plcLink)
{
try
{
HmiJsonDb jsondb = new HmiJsonDb()
{
PlcAddr = plcLink.PlcAddr
};
string json = Newtonsoft.Json.JsonConvert.SerializeObject(jsondb, Newtonsoft.Json.Formatting.Indented);
File.WriteAllText(filePath, json);
return true;
}
catch
{
return false;
}
}
public static bool Load(string filePath, HMI plcLink)
{
try
{
if (!File.Exists(filePath))
return false;
string json = File.ReadAllText(filePath);
var jsonDb = Newtonsoft.Json.JsonConvert.DeserializeObject<HmiJsonDb>(json);
plcLink.PlcAddr = jsonDb.PlcAddr;
return true;
}
catch
{
return false;
}
}
}
} }
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FLY.Simulation.Blowing
{
public interface IPlcLink: INotifyPropertyChanged
{
string PlcAddr { get; set; }
/// <summary>
/// 当前电流 有没?
/// </summary>
bool HasElectricCurrent { get; set; }
/// <summary>
/// 风机是否启动?
/// </summary>
bool HasFan { get; set; }
UInt16 HeatUpdate { get; set; }
bool Save();
}
}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FLY.Simulation.Blowing
{
public class PlcLink : IPlcLink
{
public event PropertyChangedEventHandler PropertyChanged;
public string PlcAddr { get; set; } = "127.168.50.60:502";
//D200 4x201 通道数量
//D201 4x202 设置值 更新
//D202 4x203 当前值 更新 //不用
//D400 4x401 设置值 160个
//D600 4x601 当前值 160个 //不用
//M3 0x4 风环开关
//M4 0x5 检测电流
public FLY.Modbus.WithThread.ServerTCP mserver;
public Blowing.AirRing mAirRing;
public UInt16 HeatUpdate { get; set; }
/// <summary>
/// 当前电流 有没?
/// </summary>
public bool HasElectricCurrent { get; set; }
/// <summary>
/// 风机是否启动?
/// </summary>
public bool HasFan { get; set; } = true;
public PlcLink()
{
if (!Load())
Save();
}
public void Init(Blowing.AirRing mAirRing)
{
this.mAirRing = mAirRing;
mserver = new Modbus.WithThread.ServerTCP(Misc.StringConverter.ToIPEndPoint(PlcAddr), GetValue, SetValue);
mserver.Start();
}
void GetValue(int addr, object values)
{
if (values is UInt16[])
{
var uint16s = values as UInt16[];
for (int i = 0; i < uint16s.Count(); i++) {
uint16s[i] = GetValue_reg(i+addr);
}
}
else if (values is bool[])
{
var bools = values as bool[];
for (int i = 0; i < bools.Count(); i++)
{
bools[i] = GetValue_coil(i + addr);
}
}
}
UInt16 GetValue_reg(int addr)
{
if (addr == 200)
{
return (UInt16)mAirRing.ChannelCnt;
}
else if (addr == 201)
{
return HeatUpdate;
}
else if (addr >= 400 && addr < 400 + 160)
{
int idx = addr - 400;
if (idx >= 0 && idx < mAirRing.Heats.Count())
return (UInt16)mAirRing.Heats[idx];
else
return 0;
}
else {
return 0;
}
}
bool GetValue_coil(int addr)
{
if (addr == 3)
{
return HasFan;
}
else if (addr == 4)
{
return HasElectricCurrent;
}
else
{
return false;
}
}
void SetValue(int addr, object values)
{
if (values is UInt16[])
{
var uint16s = values as UInt16[];
for (int i = 0; i < uint16s.Count(); i++)
{
SetValue_reg(i + addr, uint16s[i]);
}
}
else if (values is bool[])
{
var bools = values as bool[];
for (int i = 0; i < bools.Count(); i++)
{
SetValue_coil(i + addr, bools[i]);
}
}
}
void SetValue_reg(int addr, UInt16 reg)
{
if (addr == 200)
{
mAirRing.SetChannelCnt(reg);
}
else if (addr == 201)
{
if (HeatUpdate != reg)
{
HeatUpdate = reg;
mAirRing.HeatApply();
HasElectricCurrent = mAirRing.HasElectricCurrent;
}
}
else if (addr >= 400 && addr < 400 + 160)
{
int idx = addr - 400;
if (idx >= 0 && idx < mAirRing.Heats.Count())
{
mAirRing.Heats[idx] = reg;
}
}
else
{
}
}
void SetValue_coil(int addr, bool coil)
{
}
string filePath = "airRingPlc.json";
bool Load()
{
return PlcLinkJsonDb.Load(filePath, this);
}
public bool Save()
{
return PlcLinkJsonDb.Save(filePath, this);
}
}
public class PlcLinkJsonDb
{
public string PlcAddr = "127.168.50.60:502";
public static bool Save(string filePath, PlcLink plcLink)
{
try
{
PlcLinkJsonDb jsondb = new PlcLinkJsonDb()
{
PlcAddr = plcLink.PlcAddr
};
string json = Newtonsoft.Json.JsonConvert.SerializeObject(jsondb, Newtonsoft.Json.Formatting.Indented);
File.WriteAllText(filePath, json);
return true;
}
catch {
return false;
}
}
public static bool Load(string filePath, PlcLink plcLink)
{
try
{
if (!File.Exists(filePath))
return false;
string json = File.ReadAllText(filePath);
var jsonDb = Newtonsoft.Json.JsonConvert.DeserializeObject<PlcLinkJsonDb>(json);
plcLink.PlcAddr = jsonDb.PlcAddr;
return true;
}
catch
{
return false;
}
}
}
}
...@@ -150,9 +150,14 @@ namespace FLYAD7_Simulation_Wpf ...@@ -150,9 +150,14 @@ namespace FLYAD7_Simulation_Wpf
} }
private void button2_Click(object sender, RoutedEventArgs e) private void button2_Click(object sender, RoutedEventArgs e)
{
if (MessageBox.Show("需要重启,才能生效", "提示", MessageBoxButton.OKCancel) == MessageBoxResult.OK)
{ {
flyad7.Save(); flyad7.Save();
MessageBox.Show("保存成功,请重启"); FLY.AppHelper.AppJustOne.Restart();
}
} }
private void button3_Click(object sender, RoutedEventArgs e) private void button3_Click(object sender, RoutedEventArgs e)
......
...@@ -86,10 +86,16 @@ ...@@ -86,10 +86,16 @@
<GroupBox Header="电柜" Margin="2" > <GroupBox Header="电柜" Margin="2" >
<StackPanel > <StackPanel >
<StackPanel x:Name="spPlc"> <StackPanel x:Name="spPlc">
<StackPanel>
<TextBlock Text="PLC地址"/>
<TextBox Text="{Binding PlcAddr}"/>
</StackPanel>
<CheckBox Content="电流计" Height="16" Margin="5" IsChecked="{Binding HasElectricCurrent}" IsEnabled="False"/> <CheckBox Content="电流计" Height="16" Margin="5" IsChecked="{Binding HasElectricCurrent}" IsEnabled="False"/>
<CheckBox Content="风机开" Height="16" Margin="5" IsChecked="{Binding HasFan}" /> <CheckBox Content="风机开" Height="16" Margin="5" IsChecked="{Binding HasFan}" />
<Button Content="保存PLC设置" Padding="5,2" Click="btnPlcSaveClick"/>
</StackPanel> </StackPanel>
<CheckBox Content="屏蔽I9" Height="16" Margin="5" IsChecked="{Binding IsShieldI9}" /> <CheckBox Content="屏蔽I9" Height="16" Margin="5" IsChecked="{Binding IsShieldI9}" />
</StackPanel> </StackPanel>
</GroupBox> </GroupBox>
</StackPanel> </StackPanel>
......
...@@ -147,7 +147,7 @@ namespace FLYAD7_Simulation_Wpf ...@@ -147,7 +147,7 @@ namespace FLYAD7_Simulation_Wpf
private void Window_Loaded(object sender, RoutedEventArgs e) private void Window_Loaded(object sender, RoutedEventArgs e)
{ {
this.DataContext = mBlowing; this.DataContext = mBlowing;
this.spPlc.DataContext = mBlowing.mHMI; this.spPlc.DataContext = mBlowing.plcLink;
mBlowing.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(mBlowing_PropertyChanged); mBlowing.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(mBlowing_PropertyChanged);
DataBindAll(); DataBindAll();
chart1.ChartAreas["Default"].CursorX.Position = mBlowing.TestPos; chart1.ChartAreas["Default"].CursorX.Position = mBlowing.TestPos;
...@@ -221,9 +221,21 @@ namespace FLYAD7_Simulation_Wpf ...@@ -221,9 +221,21 @@ namespace FLYAD7_Simulation_Wpf
} }
private void btnSaveClick(object sender, RoutedEventArgs e) private void btnSaveClick(object sender, RoutedEventArgs e)
{
if (MessageBox.Show("需要重启,才能生效", "提示", MessageBoxButton.OKCancel) == MessageBoxResult.OK)
{ {
mBlowing.Save(); mBlowing.Save();
MessageBox.Show("已经保存数据,请重启"); FLY.AppHelper.AppJustOne.Restart();
}
}
private void btnPlcSaveClick(object sender, RoutedEventArgs e)
{
if (MessageBox.Show("需要重启,才能生效", "提示", MessageBoxButton.OKCancel) == MessageBoxResult.OK)
{
mBlowing.plcLink.Save();
FLY.AppHelper.AppJustOne.Restart();
}
} }
} }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment