添加新的测温功能
This commit is contained in:
parent
7580afe92f
commit
dc3d0f85f6
@ -8,6 +8,10 @@
|
||||
<AKunTemp id="AKunTemp" module="" display="AKunTemp" scBasePath="TempSensors" MaxChannels="4" MinimalTemp="600"/>
|
||||
</AKunTemps>
|
||||
|
||||
<AKunTemps classType="MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Temps.AKunTriggerTemp" assembly="MECF.Framework.RT.EquipmentLibrary">
|
||||
<AKunTemp id="AKunTriggerTemp" module="PM1" display="AKunTriggerTemp" scBasePath="TempSensors" MaxChannels="1" WaferNum="1" TrayNum="1" MinimalTemp="500"/>
|
||||
</AKunTemps>
|
||||
|
||||
<SensorTemps classType="MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Temps.SensorTemp" assembly="MECF.Framework.RT.EquipmentLibrary">
|
||||
<SensorTemp id="SensorTemp1" module="" display="SensorTemp1" scBasePath="TempSensors.Sensor" MaxChannels="1" MinimalTemp="600"/>
|
||||
<SensorTemp id="SensorTemp2" module="" display="SensorTemp2" scBasePath="TempSensors.Sensor" MaxChannels="1" MinimalTemp="600"/>
|
||||
|
||||
@ -23,8 +23,8 @@
|
||||
<DI_ITEM Index="20" Name="DI_CDAPressureSWReady" BufferOffset="20" Addr="20" Description="" />
|
||||
<DI_ITEM Index="21" Name="DI_WaterFlowSWReady" BufferOffset="21" Addr="21" Description="" />
|
||||
<DI_ITEM Index="22" Name="DI_LoadLockGateClosed" BufferOffset="22" Addr="22" Description="" />
|
||||
<DI_ITEM Index="24" Name="DI_LoadLSideDoorClosed" BufferOffset="24" Addr="24" Description="" Visible="false"/>
|
||||
<DI_ITEM Index="25" Name="DI_LoadLSideDoorOpened" BufferOffset="25" Addr="25" Description="" Visible="false"/>
|
||||
<DI_ITEM Index="24" Name="DI_LoadLSideDoorClosed" BufferOffset="24" Addr="24" Description="" />
|
||||
<DI_ITEM Index="25" Name="DI_LoadLSideDoorOpened" BufferOffset="25" Addr="25" Description="" />
|
||||
<DI_ITEM Index="26" Name="DI_LoadRSideDoorClosed" BufferOffset="26" Addr="26" Description="" Visible="false"/>
|
||||
<DI_ITEM Index="27" Name="DI_LoadRSideDoorOpened" BufferOffset="27" Addr="27" Description="" Visible="false"/>
|
||||
<DI_ITEM Index="31" Name="DI_RobotOnBackPos" BufferOffset="31" Addr="31" Description="" />
|
||||
@ -34,7 +34,7 @@
|
||||
<DI_ITEM Index="35" Name="DI_LoadWaferPlaced" BufferOffset="35" Addr="35" Description="" />
|
||||
<DI_ITEM Index="36" Name="DI_LoaderTraySensor" BufferOffset="36" Addr="36" Description="" />
|
||||
<DI_ITEM Index="37" Name="DI_BufferStationOptSensorHigh" BufferOffset="37" Addr="37" Description="" />
|
||||
<DI_ITEM Index="38" Name="DI_BufferStationOptSensorMid" BufferOffset="38" Addr="38" Description="" Visible="false"/>
|
||||
<DI_ITEM Index="38" Name="DI_BufferStationOptSensorMid" BufferOffset="38" Addr="38" Description="" />
|
||||
<DI_ITEM Index="39" Name="DI_BufferStationOptSensorLow" BufferOffset="39" Addr="39" Description="" Visible="false"/>
|
||||
<DI_ITEM Index="40" Name="DI_UnloadStationWaferPresence" BufferOffset="40" Addr="40" Description="" Visible="false"/>
|
||||
<DI_ITEM Index="41" Name="DI_UnloadStationGateINTK" BufferOffset="41" Addr="41" Description="" Visible="false"/>
|
||||
|
||||
@ -1216,9 +1216,9 @@
|
||||
<config default="AKunTemp.t2" name="OuterTemp" description="设置Outer温度数据通道,重启生效" max="" min="" paramter="AETemp.t1;AETemp.t2;AETemp.t3;AETemp.t4;AKunTemp.t1;AKunTemp.t2;AKunTemp.t3;AKunTemp.t4;SensorTemp1.t1;SensorTemp2.t1;SensorTemp3.t1;SensorTemp4.t1;StrongTemp1.t1;StrongTemp2.t1;StrongTemp3.t1;StrongTemp4.t1;Disabled" tag="ReadOnlySelection" unit="" type="String" visible="false"/>
|
||||
<config default="Disabled" name="InnerTemp" description="设置Inner温度数据通道,重启生效" max="" min="" paramter="AETemp.t1;AETemp.t2;AETemp.t3;AETemp.t4;AKunTemp.t1;AKunTemp.t2;AKunTemp.t3;AKunTemp.t4;SensorTemp1.t1;SensorTemp2.t1;SensorTemp3.t1;SensorTemp4.t1;StrongTemp1.t1;StrongTemp2.t1;StrongTemp3.t1;StrongTemp4.t1;Disabled" tag="ReadOnlySelection" unit="" type="String" visible="false"/>
|
||||
|
||||
<config default="AKunTemp.CH1" name="Middle" description="设置Middle温度数据通道,重启生效" max="" min="" paramter="AETemp.CH1;AETemp.CH2;AETemp.CH3;AETemp.CH4;AKunTemp.CH1;AKunTemp.CH2;AKunTemp.CH3;AKunTemp.CH4;SensorTemp1.CH1;SensorTemp2.CH1;SensorTemp3.CH1;SensorTemp4.CH1;StrongTemp1.CH1;StrongTemp2.CH1;StrongTemp3.CH1;StrongTemp4.CH1;Disabled" tag="ReadOnlySelection" unit="" type="String" />
|
||||
<config default="AKunTemp.CH2" name="Outer" description="设置Outer温度数据通道,重启生效" max="" min="" paramter="AETemp.CH1;AETemp.CH2;AETemp.CH3;AETemp.CH4;AKunTemp.CH1;AKunTemp.CH2;AKunTemp.CH3;AKunTemp.CH4;SensorTemp1.CH1;SensorTemp2.CH1;SensorTemp3.CH1;SensorTemp4.CH1;StrongTemp1.CH1;StrongTemp2.CH1;StrongTemp3.CH1;StrongTemp4.CH1;Disabled" tag="ReadOnlySelection" unit="" type="String" />
|
||||
<config default="Disabled" name="Inner" description="设置Inner温度数据通道,重启生效" max="" min="" paramter="AETemp.CH1;AETemp.CH2;AETemp.CH3;AETemp.CH4;AKunTemp.CH1;AKunTemp.CH2;AKunTemp.CH3;AKunTemp.CH4;SensorTemp1.CH1;SensorTemp2.CH1;SensorTemp3.CH1;SensorTemp4.CH1;StrongTemp1.CH1;StrongTemp2.CH1;StrongTemp3.CH1;StrongTemp4.CH1;Disabled" tag="ReadOnlySelection" unit="" type="String" />
|
||||
<config default="Disabled" name="Middle" description="设置Middle温度数据通道,重启生效" max="" min="" paramter="AKunTriggerTemp.CH1;AKunTriggerTemp.CH2;AKunTriggerTemp.CH3;AKunTriggerTemp.CH4;SensorTemp1.CH1;SensorTemp2.CH1;SensorTemp3.CH1;SensorTemp4.CH1;Disabled" tag="ReadOnlySelection" unit="" type="String" />
|
||||
<config default="Disabled" name="Outer" description="设置Outer温度数据通道,重启生效" max="" min="" paramter="AKunTriggerTemp.CH1;AKunTriggerTemp.CH2;AKunTriggerTemp.CH3;AKunTriggerTemp.CH4;SensorTemp1.CH1;SensorTemp2.CH1;SensorTemp3.CH1;SensorTemp4.CH1;Disabled" tag="ReadOnlySelection" unit="" type="String" />
|
||||
<config default="Disabled" name="Inner" description="设置Inner温度数据通道,重启生效" max="" min="" paramter="AKunTriggerTemp.CH1;AKunTriggerTemp.CH2;AKunTriggerTemp.CH3;AKunTriggerTemp.CH4;SensorTemp1.CH1;SensorTemp2.CH1;SensorTemp3.CH1;SensorTemp4.CH1;Disabled" tag="ReadOnlySelection" unit="" type="String" />
|
||||
<config default="None" name="FilterType" description="温度滤波器类型" max="0" min="0" paramter="None;MAF" tag="ReadOnlySelection" unit="" type="String" />
|
||||
<configs name="Filters">
|
||||
<configs name="MAF">
|
||||
@ -1855,9 +1855,9 @@
|
||||
<config default="AKunTemp.t4" name="OuterTemp" description="设置Outer温度数据通道,重启生效" max="" min="" paramter="AETemp.t1;AETemp.t2;AETemp.t3;AETemp.t4;AKunTemp.t1;AKunTemp.t2;AKunTemp.t3;AKunTemp.t4;SensorTemp1.t1;SensorTemp2.t1;SensorTemp3.t1;SensorTemp4.t1;StrongTemp1.t1;StrongTemp2.t1;StrongTemp3.t1;StrongTemp4.t1;Disabled" tag="ReadOnlySelection" unit="" type="String" visible="false"/>
|
||||
<config default="Disabled" name="InnerTemp" description="设置Inner温度数据通道,重启生效" max="" min="" paramter="AETemp.t1;AETemp.t2;AETemp.t3;AETemp.t4;AKunTemp.t1;AKunTemp.t2;AKunTemp.t3;AKunTemp.t4;SensorTemp1.t1;SensorTemp2.t1;SensorTemp3.t1;SensorTemp4.t1;StrongTemp1.t1;StrongTemp2.t1;StrongTemp3.t1;StrongTemp4.t1;Disabled" tag="ReadOnlySelection" unit="" type="String" visible="false"/>
|
||||
|
||||
<config default="Disabled" name="Middle" description="设置Middle温度数据通道,重启生效" max="" min="" paramter="AETemp.CH1;AETemp.CH2;AETemp.CH3;AETemp.CH4;AKunTemp.CH1;AKunTemp.CH2;AKunTemp.CH3;AKunTemp.CH4;SensorTemp1.CH1;SensorTemp2.CH1;SensorTemp3.CH1;SensorTemp4.CH1;StrongTemp1.CH1;StrongTemp2.CH1;StrongTemp3.CH1;StrongTemp4.CH1;Disabled" tag="ReadOnlySelection" unit="" type="String" />
|
||||
<config default="Disabled" name="Outer" description="设置Outer温度数据通道,重启生效" max="" min="" paramter="AETemp.CH1;AETemp.CH2;AETemp.CH3;AETemp.CH4;AKunTemp.CH1;AKunTemp.CH2;AKunTemp.CH3;AKunTemp.CH4;SensorTemp1.CH1;SensorTemp2.CH1;SensorTemp3.CH1;SensorTemp4.CH1;StrongTemp1.CH1;StrongTemp2.CH1;StrongTemp3.CH1;StrongTemp4.CH1;Disabled" tag="ReadOnlySelection" unit="" type="String" />
|
||||
<config default="Disabled" name="Inner" description="设置Inner温度数据通道,重启生效" max="" min="" paramter="AETemp.CH1;AETemp.CH2;AETemp.CH3;AETemp.CH4;AKunTemp.CH1;AKunTemp.CH2;AKunTemp.CH3;AKunTemp.CH4;SensorTemp1.CH1;SensorTemp2.CH1;SensorTemp3.CH1;SensorTemp4.CH1;StrongTemp1.CH1;StrongTemp2.CH1;StrongTemp3.CH1;StrongTemp4.CH1;Disabled" tag="ReadOnlySelection" unit="" type="String" />
|
||||
<config default="Disabled" name="Middle" description="设置Middle温度数据通道,重启生效" max="" min="" paramter="AKunTriggerTemp.CH1;AKunTriggerTemp.CH2;AKunTriggerTemp.CH3;AKunTriggerTemp.CH4;SensorTemp1.CH1;SensorTemp2.CH1;SensorTemp3.CH1;SensorTemp4.CH1;Disabled" tag="ReadOnlySelection" unit="" type="String" />
|
||||
<config default="Disabled" name="Outer" description="设置Outer温度数据通道,重启生效" max="" min="" paramter="AKunTriggerTemp.CH1;AKunTriggerTemp.CH2;AKunTriggerTemp.CH3;AKunTriggerTemp.CH4;SensorTemp1.CH1;SensorTemp2.CH1;SensorTemp3.CH1;SensorTemp4.CH1;Disabled" tag="ReadOnlySelection" unit="" type="String" />
|
||||
<config default="Disabled" name="Inner" description="设置Inner温度数据通道,重启生效" max="" min="" paramter="AKunTriggerTemp.CH1;AKunTriggerTemp.CH2;AKunTriggerTemp.CH3;AKunTriggerTemp.CH4;SensorTemp1.CH1;SensorTemp2.CH1;SensorTemp3.CH1;SensorTemp4.CH1;Disabled" tag="ReadOnlySelection" unit="" type="String" />
|
||||
<config default="None" name="FilterType" description="温度滤波器类型" max="0" min="0" paramter="None;MAF" tag="ReadOnlySelection" unit="" type="String" />
|
||||
<configs name="Filters">
|
||||
<configs name="MAF">
|
||||
@ -2239,6 +2239,12 @@
|
||||
<config default="10" name="ControllerAverageTime" description="AKun温度平滑时间,AKun间隔/ms采样温度,设置后立即生效" max="10000" min="1" paramter="" tag="" unit="ms" type="Integer" />
|
||||
</configs>
|
||||
|
||||
|
||||
<configs name="AKunTriggerTemp">
|
||||
<config default="false" name="EnableDevice" description="AKun带Trigger设备启用,设置后重启生效" max="" min="" paramter="" tag="" unit="" type="Bool" />
|
||||
<config default="127.0.0.1:55888" name="Address" description="AKunTrigger IP address,Default IP: 127.0.0.1:55888" max="" min="" paramter="" tag="" unit="" type="String" />
|
||||
</configs>
|
||||
|
||||
<configs name="Sensor">
|
||||
<configs name="SensorTemp1">
|
||||
<config default="false" name="EnableDevice" description="Sensor1启用,设置后重启生效" max="" min="" paramter="" tag="" unit="" type="Bool" />
|
||||
|
||||
@ -0,0 +1,288 @@
|
||||
using Aitex.Core.RT.DataCenter;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Temps
|
||||
{
|
||||
public enum DataType
|
||||
{
|
||||
Wafer,
|
||||
Tray,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测温点位置
|
||||
/// </summary>
|
||||
public enum EnumZoneNum
|
||||
{
|
||||
Center,
|
||||
CenterEdge,
|
||||
Edge
|
||||
}
|
||||
|
||||
public class AKunTriggerChannelWaferTempData
|
||||
{
|
||||
/// <summary>
|
||||
/// 创建通道对应的单个晶圆温度对象
|
||||
/// </summary>
|
||||
/// <param name="waferNum">晶圆编号</param>
|
||||
/// <param name="ch">测温设备通道编号</param>
|
||||
/// <param name="name">当前晶圆对象的名称,Wafer or Tray,测温对象也能反馈Tray温度</param>
|
||||
public AKunTriggerChannelWaferTempData(int waferNum, int ch = 1, string name = "Wafer")
|
||||
{
|
||||
Detector = ch;
|
||||
WaferNum = waferNum;
|
||||
WaferName = $"CH{Detector}.{name}{waferNum}"; //eg: CH1.Wafer1 CH1.Wafer2 CH2.Wafer1 CH2.Wafer2
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 通道编号,默认为1
|
||||
/// </summary>
|
||||
public int Detector { get; set; }
|
||||
|
||||
public string WaferName { get; set; }
|
||||
|
||||
public int WaferNum { get; set; }
|
||||
|
||||
public DataType Type { get; set; }
|
||||
|
||||
public double Temp { get; set; }
|
||||
|
||||
public int ZoneNum { get; set; }
|
||||
|
||||
public EnumZoneNum ZoneNumSelect { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 0表示无效晶圆代表Dummy晶圆或者空位,此位置的温度不能参与STC控温
|
||||
/// </summary>
|
||||
public int PocketNum { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The reflection of 404nm
|
||||
/// </summary>
|
||||
public double Reflect1 { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The reflection of 633nm.
|
||||
/// </summary>
|
||||
public double Reflect2 { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The reflection of 950nm.
|
||||
/// </summary>
|
||||
public double Reflect3 { get; set; }
|
||||
|
||||
public double Curvature { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// false不参与控温,晶圆温度是否参与区域计算,不放片或者放Dummy时,不参与区域计算
|
||||
/// </summary>
|
||||
public bool CalZone { get; set; }
|
||||
|
||||
public void UpData(AKunTriggerChannelWaferTempData newData)
|
||||
{
|
||||
// 确保传入的 newData 对象不为空
|
||||
if (newData == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(newData));
|
||||
}
|
||||
|
||||
Detector = newData.Detector;
|
||||
WaferNum = newData.WaferNum;
|
||||
Temp = newData.Temp;
|
||||
ZoneNum = newData.ZoneNum;
|
||||
ZoneNumSelect = newData.ZoneNumSelect;
|
||||
Reflect1 = newData.Reflect1;
|
||||
Curvature = newData.Curvature;
|
||||
}
|
||||
}
|
||||
|
||||
public class AKunTriggerTempDataManager(int waferNum, double minTemp)
|
||||
{
|
||||
private readonly int _waferNum = waferNum;
|
||||
private double _minTemp = minTemp;
|
||||
|
||||
private List<AKunTriggerChannelWaferTempData> _waferTempDataList = new();
|
||||
private static readonly object _lock = new object();
|
||||
|
||||
#region 重新整理温度解析
|
||||
|
||||
public bool ProcessReceivedData(string tcpReceive)
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
List<AKunTriggerChannelWaferTempData> tempDataList = new List<AKunTriggerChannelWaferTempData>();
|
||||
AKunTriggerChannelWaferTempData aKunChWaferTempData;
|
||||
string[] keyValuePairs = tcpReceive.Split('\0');
|
||||
|
||||
for (int i = 0; i < keyValuePairs.Length - 1; i++)
|
||||
{
|
||||
aKunChWaferTempData = new AKunTriggerChannelWaferTempData(-999);
|
||||
string[] keyValues = keyValuePairs[i].Split(',');
|
||||
foreach (string pair in keyValues)
|
||||
{
|
||||
string[] keyValue = pair.Split('=');
|
||||
switch (keyValue[0])
|
||||
{
|
||||
case "Detector":
|
||||
aKunChWaferTempData.Detector = int.Parse(keyValue[1]);
|
||||
break;
|
||||
|
||||
case "PocketNum":
|
||||
aKunChWaferTempData.PocketNum = int.Parse(keyValue[1]);
|
||||
break;
|
||||
|
||||
case "WaferNum":
|
||||
aKunChWaferTempData.WaferNum = int.Parse(keyValue[1]);
|
||||
break;
|
||||
|
||||
case "CalZone":
|
||||
aKunChWaferTempData.CalZone = int.Parse(keyValue[1]) == 1;
|
||||
break;
|
||||
|
||||
case "TTemp":
|
||||
aKunChWaferTempData.Temp = double.Parse(keyValue[1]);
|
||||
break;
|
||||
|
||||
case "ZoneNum":
|
||||
aKunChWaferTempData.ZoneNum = int.Parse(keyValue[1]);
|
||||
aKunChWaferTempData.ZoneNumSelect =
|
||||
(EnumZoneNum)Enum.Parse(typeof(EnumZoneNum), keyValue[1]);
|
||||
break;
|
||||
|
||||
case "Reflec1":
|
||||
aKunChWaferTempData.Reflect1 = double.Parse(keyValue[1]);
|
||||
break;
|
||||
|
||||
case "Reflec2":
|
||||
aKunChWaferTempData.Reflect2 = double.Parse(keyValue[1]);
|
||||
break;
|
||||
|
||||
case "Reflec3":
|
||||
aKunChWaferTempData.Reflect3 = double.Parse(keyValue[1]);
|
||||
break;
|
||||
|
||||
case "Curvature":
|
||||
aKunChWaferTempData.Curvature = double.Parse(keyValue[1]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (aKunChWaferTempData.WaferNum == -999)
|
||||
return true;
|
||||
|
||||
tempDataList.Add(aKunChWaferTempData);
|
||||
}
|
||||
|
||||
_waferTempDataList = tempDataList;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public bool[] GetCalZone()
|
||||
{
|
||||
bool[] calZone = new bool[_waferNum];
|
||||
if (_waferTempDataList.Count < _waferNum)
|
||||
return calZone;
|
||||
|
||||
for (int i = 0; i < _waferNum; i++) //只有前面几个数据,是需要统计是否参与计算
|
||||
{
|
||||
calZone[i] = _waferTempDataList[i].CalZone;
|
||||
}
|
||||
|
||||
return calZone;
|
||||
}
|
||||
|
||||
//public double[] GetWaferTemp()
|
||||
//{
|
||||
// double[] waferTemps = Enumerable.Repeat(_minTemp, _waferNum).ToArray();
|
||||
// if (_waferTempDataList.Count < _waferNum)
|
||||
// return waferTemps;
|
||||
|
||||
// int count = (_waferTempDataList.Count - 1) / _waferNum ;//分区数计算,最后一个数据是托盘的,所以减一,
|
||||
// if ((_waferTempDataList.Count - 1) % _waferNum != 0)//分区数量不是整数,温度不解析防呆,
|
||||
// return waferTemps;
|
||||
|
||||
// for (int i = 0; i < _waferNum; i++) //Wafer温度只取每个晶圆的第一个设置的中心温度
|
||||
// {
|
||||
// var index = i * count;
|
||||
// waferTemps[i] = _waferTempDataList[index].Temp;//直接使用第一个中心温度作为中心温度
|
||||
|
||||
// //要求不判断中心点,只用第一个分区温度
|
||||
// //for (int j = index; j < index + count ; j++)
|
||||
// //{
|
||||
// // if(_waferTempDataList[j].ZoneNum==0)
|
||||
// // {
|
||||
// // waferTemps[i] = _waferTempDataList[j].Temp;//有中心温度设置,获取第一个中心温度作为晶圆温度
|
||||
// // break;
|
||||
// // }
|
||||
// //}
|
||||
// }
|
||||
|
||||
// return waferTemps;
|
||||
//}
|
||||
|
||||
public double[] GetWaferTemp()
|
||||
{
|
||||
double[] waferTemps = Enumerable.Repeat(_minTemp, _waferNum).ToArray();
|
||||
if (_waferTempDataList.Count < _waferNum)
|
||||
return waferTemps;
|
||||
|
||||
//这届
|
||||
for (int i = 0; i < _waferNum; i++) //只有前面几个温度数据,才是需要统计的
|
||||
{
|
||||
waferTemps[i] = _waferTempDataList[i].Temp;
|
||||
}
|
||||
|
||||
//_waferTempDataList[i].CalZone
|
||||
//for (int i = 0; i < _waferNum; i++)
|
||||
//{
|
||||
// //根据编号,获取同一分区所有温度数据
|
||||
// var tempCaches = _waferTempDataList.Where(item => item.PocketNum == i + 1);
|
||||
// if (tempCaches != null && tempCaches.Count() > 0)
|
||||
// {
|
||||
// //同一分区所有温度数据,查找第一个CalZone为true的温度数据
|
||||
// var matchedItem = tempCaches.Where(item => item.CalZone).FirstOrDefault();
|
||||
|
||||
// if (matchedItem != null)
|
||||
// waferTemps[i] = matchedItem.Temp;
|
||||
// else
|
||||
// waferTemps[i] = tempCaches.First().Temp;//未设置CalZone为true,使用当前分区第一个数据作为默认温度值
|
||||
// }
|
||||
// else
|
||||
// waferTemps[i] = -1;//没有分区温度是乱的无法解析,使用-1作为提示
|
||||
//}
|
||||
|
||||
return waferTemps;
|
||||
}
|
||||
|
||||
public double GetTrayTemp()
|
||||
{
|
||||
if (_waferTempDataList.Count == 0)
|
||||
return _minTemp;
|
||||
|
||||
return _waferTempDataList[_waferTempDataList.Count - 1].Temp; //最后一个数据才是Tray温度
|
||||
}
|
||||
|
||||
#endregion 重新整理温度解析
|
||||
|
||||
public List<double[]> GetReflectValue()
|
||||
{
|
||||
List<double[]> reflectList = Enumerable.Range(0, _waferNum)
|
||||
.Select(_ => new double[3]) // 每个数组默认元素为 0
|
||||
.ToList();
|
||||
if (_waferTempDataList.Count < _waferNum)
|
||||
return reflectList;
|
||||
|
||||
for (int i = 0; i < _waferNum; i++) //只有前面几个反射率数据,才是需要统计的
|
||||
{
|
||||
var data = _waferTempDataList[i];
|
||||
reflectList.Add([data.Reflect1, data.Reflect2, data.Reflect3]);
|
||||
}
|
||||
|
||||
return reflectList;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,308 @@
|
||||
using Aitex.Core.RT.DataCenter;
|
||||
using Aitex.Core.RT.Event;
|
||||
using Aitex.Core.RT.IOCore;
|
||||
using Aitex.Core.RT.Log;
|
||||
using Aitex.Core.RT.OperationCenter;
|
||||
using Aitex.Core.RT.SCCore;
|
||||
using Aitex.Core.Util;
|
||||
using Kxware.Connectivity.Remoting.Messages;
|
||||
using MECF.Framework.Common.Communications.Tcp.Socket.Framing;
|
||||
using MECF.Framework.Common.Communications.Tcp.Socket.Server.APM;
|
||||
using MECF.Framework.Common.Communications.Tcp.Socket.Server.APM.EventArgs;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
|
||||
namespace MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Temps
|
||||
{
|
||||
/// <summary>
|
||||
/// 昂坤测温使用Trigger触发,
|
||||
/// 返回温度数组,依次包含CH平均,Wafer平均,Tray平均
|
||||
/// 目前仅支持一个托盘计算
|
||||
/// </summary>
|
||||
public class AKunTriggerTemp : TempSensorBase
|
||||
{
|
||||
private TcpSocketServer _socketServer;
|
||||
private TcpSocketSession _session;
|
||||
private int _port;
|
||||
private string _ip;
|
||||
|
||||
/// <summary>
|
||||
/// 温度不变Trig
|
||||
/// </summary>
|
||||
private readonly R_TRIG _rTrigTempNoChange = new();
|
||||
|
||||
/// <summary>
|
||||
/// 通讯超时时间秒
|
||||
/// </summary>
|
||||
private const int TCP_TIME_OUT = 6;
|
||||
|
||||
/// <summary>
|
||||
/// 晶圆的数量
|
||||
/// </summary>
|
||||
private readonly int _waferNum=1;
|
||||
|
||||
/// <summary>
|
||||
/// 晶圆的数量
|
||||
/// </summary>
|
||||
private readonly int _trayNum=1;
|
||||
|
||||
///// <summary>
|
||||
///// 一个测温通道对应一个集合索引
|
||||
///// </summary>
|
||||
//private readonly List<AKunTriggerChannelWaferTempData[]> _chWaferTempDataList=new ();
|
||||
|
||||
private double _trayTemp;
|
||||
//private bool[] _calZone;
|
||||
|
||||
/// <summary>
|
||||
/// 反射率数组
|
||||
/// </summary>
|
||||
private List<double[]> _reflects;
|
||||
|
||||
//private AKunTriggerChannelWaferTempData[] _tempDataArray;
|
||||
|
||||
private AKunTriggerTempDataManager _aKunTempManager;
|
||||
|
||||
/// <summary>
|
||||
/// 定义时钟监视数据发送,有可能通讯还在数据不发送
|
||||
/// </summary>
|
||||
private DeviceTimer _timer = new DeviceTimer();
|
||||
|
||||
public AKunTriggerTemp(string module, XmlElement node, string ioModule = "") : base(module, node, ioModule)
|
||||
{
|
||||
var maxWaferNum = node.GetAttribute("WaferNum");
|
||||
|
||||
//if (string.IsNullOrWhiteSpace(maxWaferNum))
|
||||
// _waferNum = SC.GetStringValue($"System.InchType") == "Inch6" ? 8 : 5;
|
||||
//else
|
||||
// int.TryParse(maxWaferNum, out _waferNum);
|
||||
|
||||
//var trayNum = node.GetAttribute("TrayNum");
|
||||
//if (!string.IsNullOrWhiteSpace(trayNum) && int.TryParse(trayNum, out var maxT))
|
||||
// _trayNum = maxT;
|
||||
|
||||
RTrigs.Add(_rTrigTempNoChange);
|
||||
}
|
||||
|
||||
protected override void InitTempDataFilter()
|
||||
{
|
||||
TempBasFunction = new TempBasFunction(Name, MinimalTemp, _waferNum);
|
||||
_aKunTempManager = new(_waferNum, MinimalTemp);
|
||||
|
||||
_trayTemp = MinimalTemp;
|
||||
|
||||
TempBasFunction.SetTempCh(_waferNum);
|
||||
|
||||
Temp = Enumerable.Repeat(MinimalTemp, _waferNum).ToArray();
|
||||
//_calZone = new bool[_waferNum];
|
||||
//PM可以选的Wafer注册,初始索引需要加上通道数
|
||||
for (var i = 0; i < _waferNum; i++)
|
||||
{
|
||||
var index = i;
|
||||
DATA.Subscribe($"TempSensor.{Name}.Wafer{i + 1}.Temp", () => Temp[index]);
|
||||
}
|
||||
|
||||
//PM可以选的Tray注册,初始索引需要加上通道数和Wafer数量
|
||||
DATA.Subscribe($"TempSensor.{Name}.Tray.Temp", () => _trayTemp);
|
||||
|
||||
//DATA.Subscribe($"TempSensor.{Name}.CalZone", () => _calZone);
|
||||
|
||||
#region 注册反射率数据
|
||||
_reflects = Enumerable
|
||||
.Range(0, _waferNum)
|
||||
.Select(i => new double[3])
|
||||
.ToList();
|
||||
|
||||
for (int i = 0; i < _waferNum; i++)
|
||||
{
|
||||
var index = i;
|
||||
DATA.Subscribe($"TempSensor.{Name}.Wafer{index + 1}.Reflect1", () => _reflects[index][0]);
|
||||
DATA.Subscribe($"TempSensor.{Name}.Wafer{index + 1}.Reflect2", () => _reflects[index][1]);
|
||||
DATA.Subscribe($"TempSensor.{Name}.Wafer{index + 1}.Reflect3", () => _reflects[index][2]);
|
||||
}
|
||||
|
||||
#endregion 注册反射率数据
|
||||
|
||||
OP.Subscribe($"{Module}.AKunTriggerTemp.MarkerActive", (function, args) =>
|
||||
{
|
||||
ProcessWriteMessage($"MarkerActive={args[0]}");
|
||||
return true;
|
||||
});
|
||||
|
||||
OP.Subscribe($"{Module}.AKunTriggerTemp.RunID", (function, args) =>
|
||||
{
|
||||
ProcessWriteMessage($"RunID={args[0]}");
|
||||
return true;
|
||||
});
|
||||
|
||||
OP.Subscribe($"{Module}.AKunTriggerTemp.StepCode", (function, args) =>
|
||||
{
|
||||
ProcessWriteMessage($"StepCode={args[0]}");
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
protected override bool HandleInitialize()
|
||||
{
|
||||
InitController();
|
||||
return true;
|
||||
}
|
||||
|
||||
private void InitController()
|
||||
{
|
||||
var data = SC.GetStringValue($"{ScBasePath}.{Name}.Address").Split(':');
|
||||
_ip = data[0]; ;
|
||||
_port = Convert.ToInt32(data[1]);
|
||||
TcpSocketServerConfiguration config = new TcpSocketServerConfiguration()
|
||||
{
|
||||
FrameBuilder = new LineBasedFrameBuilder(new LineDelimiter("\r\n")),
|
||||
};
|
||||
_socketServer = new TcpSocketServer(IPAddress.Parse(_ip), _port, config);
|
||||
_socketServer.ClientConnected += ClientConnected;
|
||||
_socketServer.ClientDisconnected += ClientDisconnected;
|
||||
_socketServer.ClientDataReceived += ClientDataReceived;
|
||||
}
|
||||
|
||||
protected override void HandleMonitor()
|
||||
{
|
||||
if (_socketServer == null)
|
||||
return;
|
||||
|
||||
if (!_socketServer.IsListening)
|
||||
{
|
||||
_socketServer.Listen();
|
||||
}
|
||||
|
||||
if (_timer.IsTimeout())
|
||||
{
|
||||
_timer.Stop();
|
||||
if (IsProcess())
|
||||
{
|
||||
TempBasFunction.PMPostLog(Module, $"TCP server received temp data timeout {TCP_TIME_OUT}s, {_ip}:{_port}, {Module}.{Name}", EV.PostWarningLog);
|
||||
TempBasFunction.SetPmIoForInterlock(Module, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ClientDataReceived(object sender, TcpClientDataReceivedEventArgs e)
|
||||
{
|
||||
OnReadMessage(Encoding.UTF8.GetString(e.Data, e.DataOffset, e.DataLength));
|
||||
}
|
||||
|
||||
private void OnReadMessage(string message)
|
||||
{
|
||||
_timer.Stop();
|
||||
if (IsEnableLog)
|
||||
LOG.Write(message);
|
||||
|
||||
if (_aKunTempManager.ProcessReceivedData(message))
|
||||
TempReadThread();
|
||||
else
|
||||
TempBasFunction.PMPostLog(Module, $"TCP server received error temp data from AKun {_ip}:{_port}, {Module}.{Name}\r\ninf:'{message}'", EV.PostWarningLog);
|
||||
|
||||
_timer.Start(TCP_TIME_OUT * 1000);
|
||||
}
|
||||
|
||||
private void ClientDisconnected(object sender, TcpClientDisconnectedEventArgs e)
|
||||
{
|
||||
_socketServer.CloseSession(_session.SessionKey);
|
||||
_session = null;
|
||||
TempBasFunction.PMPostLog(Module, $"Can not connect with {_ip}:{_port}, {Module}.{Name}", EV.PostWarningLog);
|
||||
TempBasFunction.SetPmIoForInterlock(Module, true);
|
||||
}
|
||||
|
||||
private void ClientConnected(object sender, TcpClientConnectedEventArgs e)
|
||||
{
|
||||
_session = e.Session;
|
||||
TempBasFunction.PMPostLog(Module, $"Connected with {_ip}:{_port}, {Module}.{Name}", EV.PostInfoLog);
|
||||
TempBasFunction.SetPmIoForInterlock(Module, false);
|
||||
_timer.Start(TCP_TIME_OUT * 1000);
|
||||
}
|
||||
|
||||
private void ProcessWriteMessage(string msg)
|
||||
{
|
||||
TempBasFunction.PMPostLog(Module, $"{Name}: Tcp Socket Write Message {msg}", EV.PostInfoLog);
|
||||
if (_session != null)
|
||||
_session.Send(Encoding.ASCII.GetBytes(msg));
|
||||
else
|
||||
TempBasFunction.PMPostLog(Module, $"Tcp Socket Server is null {_ip}:{_port}, {Module}.{Name}", EV.PostWarningLog);
|
||||
}
|
||||
|
||||
protected override bool DoTempReadThread()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool TempReadThread()
|
||||
{
|
||||
// get temp. points according to the "IsSimulatorMode" system config.
|
||||
|
||||
var temps = IsSimMode ? RandomTemps(_waferNum) : HandleReadTemp();
|
||||
_rTrigReadTempFailed.CLK = temps == null || temps.Length != (_waferNum);
|
||||
if (_rTrigReadTempFailed.Q)
|
||||
{
|
||||
LOG.Error(temps != null
|
||||
? $"{this} {_waferNum} temperature data wanted but {temps.Length} points read."
|
||||
: $"{this} None temperature data read from controller.");
|
||||
}
|
||||
|
||||
// Too less temp. points read from the sensor.
|
||||
if (_rTrigReadTempFailed.M)
|
||||
return true;
|
||||
|
||||
if (IsProcess() && AllTempNoChange(temps))//检测所有通道温度是否变化
|
||||
return true;
|
||||
|
||||
// Get the right temp value from the filter
|
||||
for (var i = 0; i < Temp.Length; i++)
|
||||
{
|
||||
Temp[i] = temps[i];
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool AllTempNoChange(double[] tempArray)
|
||||
{
|
||||
int noChangeCount = TempBasFunction.AllTempNoChangeCount(tempArray, out string resuonInf);
|
||||
if (noChangeCount >= 18)
|
||||
{
|
||||
_rTrigTempNoChange.CLK = true;
|
||||
if (_rTrigTempNoChange.Q)
|
||||
{
|
||||
TempBasFunction.PMPostLog(Module, $"{this} all temp no change: \r\n" +
|
||||
$"{resuonInf}", EV.PostWarningLog);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected override double[] HandleReadTemp()
|
||||
{
|
||||
//昂坤的温度数据上位机在这里被动接受
|
||||
//_calZone = _aKunTempManager.GetCalZone();
|
||||
_trayTemp = _aKunTempManager.GetTrayTemp();
|
||||
_reflects = _aKunTempManager.GetReflectValue();
|
||||
|
||||
return _aKunTempManager.GetWaferTemp();
|
||||
}
|
||||
|
||||
public override void Terminate()
|
||||
{
|
||||
_socketServer.Shutdown();
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
_timer.Start(TCP_TIME_OUT * 1000);
|
||||
base.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,7 +1,10 @@
|
||||
using Aitex.Core.RT.IOCore;
|
||||
using Aitex.Core.RT.SCCore;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Temps
|
||||
{
|
||||
@ -19,20 +22,31 @@ namespace MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Temps
|
||||
|
||||
private string DeviceName { get; set; }
|
||||
|
||||
private float[] tempChangeCache;
|
||||
private double[] _chTempChangeCache;
|
||||
|
||||
private double[] _allChTempChangeCache;
|
||||
|
||||
//硬件通道数
|
||||
private int NumberOfChannels;
|
||||
private int _numberOfChannels;
|
||||
|
||||
private const double Epsilon = 0.001;
|
||||
|
||||
/// <summary>
|
||||
/// 统计温度相同次数
|
||||
/// 统计单路温度相同次数
|
||||
/// </summary>
|
||||
private int noChangeNum;
|
||||
private int _chNoChangeNum;
|
||||
|
||||
/// <summary>
|
||||
/// 统计单路温度相同次数
|
||||
/// </summary>
|
||||
private int _allChNoChangeNum;
|
||||
|
||||
/// <summary>
|
||||
/// 记录温度不变时数据,最多记录10次
|
||||
/// </summary>
|
||||
private StringBuilder strNoChangeMeg = new();
|
||||
private readonly StringBuilder _strChNoChangeMeg = new();
|
||||
|
||||
private readonly StringBuilder _strAllChNoChangeMeg = new();
|
||||
|
||||
/// <summary>
|
||||
/// 测温硬件最低测试温度,传入温度为此数值,不进行温度数据变化对比
|
||||
@ -48,12 +62,20 @@ namespace MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Temps
|
||||
{
|
||||
DeviceName = deviceName;
|
||||
TempMin = tempMin;
|
||||
NumberOfChannels = numberOfChannels;
|
||||
tempChangeCache = new float[NumberOfChannels];
|
||||
_numberOfChannels = numberOfChannels;
|
||||
_chTempChangeCache = new double[numberOfChannels];
|
||||
_allChTempChangeCache = new double[numberOfChannels];
|
||||
IsPM1Installed = SC.GetValue<bool>($"System.SetUp.IsPM1Installed");
|
||||
IsPM2Installed = SC.GetValue<bool>($"System.SetUp.IsPM2Installed");
|
||||
}
|
||||
|
||||
public void SetTempCh(int numberOfChannels)
|
||||
{
|
||||
_numberOfChannels = numberOfChannels;
|
||||
_chTempChangeCache = new double[numberOfChannels];
|
||||
_allChTempChangeCache = new double[numberOfChannels];
|
||||
}
|
||||
|
||||
public void PM1PM2PostLog(string str, Action<string, string, int> action)
|
||||
{
|
||||
if (IsPM1Installed)
|
||||
@ -84,7 +106,7 @@ namespace MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Temps
|
||||
{
|
||||
string PM = pm.ToUpper();
|
||||
if (IsMP(PM))
|
||||
IO.DO[$"PM1.DO_PyroCommunicationError"].SetValue(isReset, out _);
|
||||
IO.DO[$"{PM}.DO_PyroCommunicationError"].SetValue(isReset, out _);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -106,34 +128,71 @@ namespace MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Temps
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 温度是否发生改变,返回数据不发生改变次数
|
||||
/// 温度是否发生改变(单路温度不变记录),返回数据不发生改变次数
|
||||
/// </summary>
|
||||
/// <param name="outputTemp"></param>
|
||||
/// <returns></returns>
|
||||
public int TempInvariantCount(float[] outputTemp, out string errorInf)
|
||||
public int TempNoChangeCount(float[] outputTemp, out string errorInf)
|
||||
{
|
||||
errorInf = "";
|
||||
if (noChangeNum > 999999)//防止数据溢出
|
||||
noChangeNum = 0;
|
||||
if (_chNoChangeNum > 999999)//防止数据溢出
|
||||
_chNoChangeNum = 0;
|
||||
for (int i = 0; i < outputTemp.Length; i++)
|
||||
{
|
||||
if (outputTemp[i] <= TempMin)//低于温度下限,数据不做对比
|
||||
continue;
|
||||
|
||||
if (outputTemp[i] == tempChangeCache[i])
|
||||
if (Math.Abs(outputTemp[i] - _chTempChangeCache[i]) < Epsilon)
|
||||
{
|
||||
if (noChangeNum < 10)//记录前10次的数据
|
||||
strNoChangeMeg.Append($"#{i + 1}:{outputTemp[i]:0.00} ");
|
||||
if (_chNoChangeNum < 10)//记录前10次的数据
|
||||
_strChNoChangeMeg.Append($"#{i + 1}:{outputTemp[i]:0.00} ");
|
||||
|
||||
errorInf = strNoChangeMeg.ToString();
|
||||
return noChangeNum++;
|
||||
errorInf = _strChNoChangeMeg.ToString();
|
||||
return _chNoChangeNum++;
|
||||
}
|
||||
tempChangeCache[i] = outputTemp[i];
|
||||
_chTempChangeCache[i] = outputTemp[i];
|
||||
}
|
||||
|
||||
//只要数据不同,就可以复位计数和缓存
|
||||
strNoChangeMeg.Clear();
|
||||
noChangeNum = 0;
|
||||
_strChNoChangeMeg.Clear();
|
||||
_chNoChangeNum = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 温度是否发生改变(所有温度不变记录),返回数据不发生改变次数
|
||||
/// </summary>
|
||||
/// <param name="outputTemp"></param>
|
||||
/// <returns></returns>
|
||||
public int AllTempNoChangeCount(double[] outputTemp, out string errorInf)
|
||||
{
|
||||
errorInf = "";
|
||||
if (_allChNoChangeNum > 999999)//防止数据溢出
|
||||
_allChNoChangeNum = 0;
|
||||
|
||||
int noChangeCount = 0;
|
||||
for (int i = 0; i < outputTemp.Length; i++)
|
||||
{
|
||||
if (outputTemp[i] <= TempMin)//低于温度下限,数据不做对比
|
||||
continue;
|
||||
if (Math.Abs(outputTemp[i] - _allChTempChangeCache[i]) < Epsilon)
|
||||
{
|
||||
if (_allChNoChangeNum < 10) //记录前10次的数据
|
||||
_strAllChNoChangeMeg.Append($"#{i + 1}: {outputTemp[i]:0.00}; ");
|
||||
|
||||
errorInf = _strAllChNoChangeMeg.ToString();
|
||||
noChangeCount += 1;
|
||||
}
|
||||
_allChTempChangeCache[i] = outputTemp[i];
|
||||
}
|
||||
|
||||
if (noChangeCount == outputTemp.Length)//不变次数等于数组长度时,断定所有数据均无变化
|
||||
{
|
||||
_strAllChNoChangeMeg.Append("\r\n");
|
||||
return _allChNoChangeNum++;
|
||||
}
|
||||
//只要数据不同,就可以复位计数和缓存
|
||||
_strAllChNoChangeMeg.Clear();
|
||||
_allChNoChangeNum = 0;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,12 +1,13 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Xml;
|
||||
using Aitex.Core.Account;
|
||||
using Aitex.Core.RT.DataCenter;
|
||||
using Aitex.Core.RT.Device;
|
||||
using Aitex.Core.RT.Log;
|
||||
using Aitex.Core.RT.SCCore;
|
||||
using Aitex.Core.Util;
|
||||
using MECF.Framework.Common.Communications;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Xml;
|
||||
|
||||
namespace MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Temps;
|
||||
|
||||
@ -19,15 +20,12 @@ public abstract class TempSensorBase : BaseDevice, IDevice, IConnection, ITempSe
|
||||
protected TempBasFunction TempBasFunction;
|
||||
|
||||
private readonly Random _rndTempGen = new();
|
||||
private readonly R_TRIG _rTrigReadTempFailed = new();
|
||||
protected readonly R_TRIG _rTrigReadTempFailed = new();
|
||||
private PeriodicJob _tReadTemp;
|
||||
//private Misc.FilterTypes _filterType;
|
||||
//private TempDataFilter[] _tempFilters;
|
||||
|
||||
private readonly Stopwatch _swSimSineWave = new();
|
||||
private const double SINE_T = 5.0;
|
||||
private const double SINE_F = 2.0 * Math.PI * (1 / SINE_T);
|
||||
|
||||
#endregion
|
||||
|
||||
#region Ctor
|
||||
@ -67,7 +65,10 @@ public abstract class TempSensorBase : BaseDevice, IDevice, IConnection, ITempSe
|
||||
|
||||
public int MaxChannels { get; }
|
||||
|
||||
public double[] Temp { get; private set; }
|
||||
/// <summary>
|
||||
/// 硬件输出的温度
|
||||
/// </summary>
|
||||
public double[] Temp { get; protected set; }
|
||||
|
||||
#endregion
|
||||
|
||||
@ -77,10 +78,10 @@ public abstract class TempSensorBase : BaseDevice, IDevice, IConnection, ITempSe
|
||||
/// 生成随机温度。
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private double[] RandomTemps(double baseTemp = 800, double peakPeak = 200, double jitter = 50.0)
|
||||
protected double[] RandomTemps(int channels, double baseTemp = 800, double peakPeak = 200, double jitter = 50.0)
|
||||
{
|
||||
var rndTemps = new double[MaxChannels];
|
||||
for (var i = 0; i < MaxChannels; i++)
|
||||
var rndTemps = new double[channels];
|
||||
for (var i = 0; i < channels; i++)
|
||||
{
|
||||
var t = _swSimSineWave.Elapsed.TotalSeconds; // current moment
|
||||
var tempSine = peakPeak * Math.Sin(SINE_F * t + (i * Math.PI / 3)); //temperature following sine wave with 60 deg(π/3 rad) phase-diff per channel
|
||||
@ -91,10 +92,12 @@ public abstract class TempSensorBase : BaseDevice, IDevice, IConnection, ITempSe
|
||||
return rndTemps;
|
||||
}
|
||||
|
||||
private bool DoTempReadThread()
|
||||
|
||||
|
||||
protected virtual bool DoTempReadThread()
|
||||
{
|
||||
// get temp. points according to the "IsSimulatorMode" system config.
|
||||
var temps = IsSimMode ? RandomTemps() : HandleReadTemp();
|
||||
var temps = IsSimMode ? RandomTemps(MaxChannels) : HandleReadTemp();
|
||||
|
||||
_rTrigReadTempFailed.CLK = temps == null || temps.Length != MaxChannels;
|
||||
if (_rTrigReadTempFailed.Q)
|
||||
@ -112,23 +115,13 @@ public abstract class TempSensorBase : BaseDevice, IDevice, IConnection, ITempSe
|
||||
for (var i = 0; i < MaxChannels; i++)
|
||||
{
|
||||
Temp[i] = temps[i];
|
||||
|
||||
//_tempFilters[i].AddRawTemp(temps![i]);
|
||||
|
||||
//Temp[i] = _filterType switch
|
||||
//{
|
||||
// Misc.FilterTypes.None => _tempFilters[i].Raw,
|
||||
// Misc.FilterTypes.MAF => _tempFilters[i].FilteredMAF,
|
||||
// _ => _tempFilters[i].Raw
|
||||
//};
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void InitTempDataFilter()
|
||||
protected virtual void InitTempDataFilter()
|
||||
{
|
||||
//_tempFilters = new TempDataFilter[MaxChannels];
|
||||
Temp = new double[MaxChannels];
|
||||
|
||||
for (var i = 0; i < MaxChannels; i++)
|
||||
@ -138,8 +131,6 @@ public abstract class TempSensorBase : BaseDevice, IDevice, IConnection, ITempSe
|
||||
|
||||
var ch = i;
|
||||
DATA.Subscribe($"TempSensor.{Name}.CH{ch + 1}", () => Temp[ch]);
|
||||
//DATA.Subscribe($"TempSensor.{Name}.CH{ch + 1}MAF", () => _tempFilters[ch].FilteredMAF);
|
||||
//DATA.Subscribe($"TempSensor.{Name}.CH{ch + 1}Raw", () => _tempFilters[ch].Raw);
|
||||
}
|
||||
}
|
||||
|
||||
@ -165,8 +156,6 @@ public abstract class TempSensorBase : BaseDevice, IDevice, IConnection, ITempSe
|
||||
|
||||
IsEnableLog = SC.SafeGetValue($"TempSensors.EnableLogMessage", false);
|
||||
|
||||
//_filterType = ConvertToFilterType(SC.SafeGetStringValue($"{ScBasePath}.FilterType", "None"));
|
||||
|
||||
var pollInvMs = SC.SafeGetValue($"{ScBasePath}.PollInterval", 100);
|
||||
|
||||
|
||||
@ -174,9 +163,6 @@ public abstract class TempSensorBase : BaseDevice, IDevice, IConnection, ITempSe
|
||||
SC.RegisterValueChangedCallback($"{ScBasePath}.PollInterval",
|
||||
(obj) => { _tReadTemp.ChangeInterval((int)obj); });
|
||||
|
||||
//SC.RegisterValueChangedCallback($"{ScBasePath}.FilterType",
|
||||
// (obj) => { _filterType = ConvertToFilterType(obj?.ToString() ?? ""); });
|
||||
|
||||
SC.RegisterValueChangedCallback($"TempSensors.EnableLogMessage",
|
||||
(obj) =>
|
||||
{
|
||||
@ -201,6 +187,11 @@ public abstract class TempSensorBase : BaseDevice, IDevice, IConnection, ITempSe
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsProcess()
|
||||
{
|
||||
return DATA.Poll($"{Module}.Status").ToString() == "Process";
|
||||
}
|
||||
|
||||
public virtual bool Connect()
|
||||
{
|
||||
return true;
|
||||
|
||||
@ -336,6 +336,8 @@
|
||||
<Compile Include="HardwareUnits\Temps\AE\AETempConnection.cs" />
|
||||
<Compile Include="HardwareUnits\Temps\AE\AETempHandler.cs" />
|
||||
<Compile Include="HardwareUnits\Temps\AKunTemp\AKunTemp.cs" />
|
||||
<Compile Include="HardwareUnits\Temps\AKunTriggerTemp\AKunTriggerChannelWaferTempData.cs" />
|
||||
<Compile Include="HardwareUnits\Temps\AKunTriggerTemp\AKunTriggerTemp.cs" />
|
||||
<Compile Include="HardwareUnits\Temps\Eurotherm\P116PIDTC.cs" />
|
||||
<Compile Include="HardwareUnits\Temps\Eurotherm\P116PIDTCHandler.cs" />
|
||||
<Compile Include="HardwareUnits\Temps\Eurotherm\P116PIDTCConnection.cs" />
|
||||
|
||||
Loading…
Reference in New Issue
Block a user