|
@@ -1,15 +1,19 @@
|
|
|
-using CCDCount.MODEL.CameraClass;
|
|
|
+using CCDCount.DLL.Tools;
|
|
|
+using CCDCount.MODEL.CameraClass;
|
|
|
using CCDCount.MODEL.ConfigModel;
|
|
|
using CCDCount.MODEL.ShuLiClass;
|
|
|
using LogClass;
|
|
|
using MvCameraControl;
|
|
|
using System;
|
|
|
+using System.Collections.Concurrent;
|
|
|
using System.Collections.Generic;
|
|
|
using System.Diagnostics;
|
|
|
using System.Drawing;
|
|
|
using System.IO;
|
|
|
using System.Linq;
|
|
|
+using System.Runtime.InteropServices;
|
|
|
using System.Runtime.Remoting.Messaging;
|
|
|
+using System.Text;
|
|
|
using System.Threading;
|
|
|
|
|
|
namespace CCDCount.DLL
|
|
@@ -21,16 +25,15 @@ namespace CCDCount.DLL
|
|
|
private bool IsSwitch = false;
|
|
|
public ShuLiClass shuLiClass = null;
|
|
|
CameraClass cameraClass = new CameraClass();
|
|
|
- public string ThisCameraDevice = string.Empty;
|
|
|
- public string ThisCameraSN = string.Empty;
|
|
|
- public string ThisCamerName = string.Empty;
|
|
|
+ public ShuLiConfigClass shuLiConfig = null;
|
|
|
+ public CameraConfig cameraConfig = null;
|
|
|
+ public bool CameraConfigIsChange = false;
|
|
|
public int ThisCamerNo = -1;
|
|
|
- //留给主界面的回调函数
|
|
|
- public event EventHandler<ActiveObjectEventArgsClass> WorkerToFrom;
|
|
|
|
|
|
public bool CameraStatic { get { return _CameraStatic; } }
|
|
|
private bool _CameraStatic = false;
|
|
|
|
|
|
+ // 返回交换线程状态
|
|
|
public bool CameraRunStatic { get { return IsSwitch; } }
|
|
|
|
|
|
public bool IsOpenLoadThread { get { return _IsOpenLoadThread; }}
|
|
@@ -40,9 +43,15 @@ namespace CCDCount.DLL
|
|
|
public int OkHistoryNum { get { return shuLiClass.GetOkHistoryNum(); } }
|
|
|
public int NgHistoryNum { get { return shuLiClass.GetNgHistoryNum(); } }
|
|
|
|
|
|
- ZmcauxClass zmcauxClass = new ZmcauxClass();
|
|
|
- //private BottingClass Botting = new BottingClass();
|
|
|
- //private MechanicalControlClass MechanicalControl = new MechanicalControlClass();
|
|
|
+ // 数粒信息发送线程
|
|
|
+ Thread SendBottLogicMessageThread = null;
|
|
|
+ bool IsSend = false;
|
|
|
+
|
|
|
+ // Modbus客户端实例
|
|
|
+ ModbusTcpClient modbusTcpClient = null;
|
|
|
+
|
|
|
+ // 颗粒结果待发送队列
|
|
|
+ ConcurrentQueue<ushort> SendQueue = new ConcurrentQueue<ushort>();
|
|
|
|
|
|
/// <summary>
|
|
|
/// 数粒状态计时器
|
|
@@ -53,16 +62,44 @@ namespace CCDCount.DLL
|
|
|
/// </summary>
|
|
|
private bool _ShuLiState = true;
|
|
|
public bool ShuLiState { get { return _ShuLiState; } }
|
|
|
+
|
|
|
+ private bool IsDebug = false;
|
|
|
+ private bool IsConnectModbus = false;
|
|
|
#endregion
|
|
|
|
|
|
#region 公共方法
|
|
|
+ /// <summary>
|
|
|
+ /// 设置ModbusTcpClient
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="modbusTcpClient"></param>
|
|
|
+ public void SetModbusClient(ModbusTcpClient modbusTcpClient)
|
|
|
+ {
|
|
|
+ this.modbusTcpClient = modbusTcpClient;
|
|
|
+ if (!this.modbusTcpClient.IsTcpClientConnected())
|
|
|
+ {
|
|
|
+ FaultLog.RecordErrorMessage("ModbusTcpClient Connect Failed!");
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ FaultLog.RecordLogMessage("ModbusTcpClient Connect Success!", 6);
|
|
|
+ IsConnectModbus = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 初始化构造方法
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="configClass"></param>
|
|
|
+ /// <param name="CameraConfig"></param>
|
|
|
public MainThreadClass(ShuLiConfigClass configClass,CameraConfig CameraConfig)
|
|
|
{
|
|
|
+ shuLiConfig = configClass;
|
|
|
+ cameraConfig = CameraConfig;
|
|
|
// 数粒配置文件地址
|
|
|
if (configClass!=null)
|
|
|
{
|
|
|
// 创建数粒对象(配置文件)
|
|
|
- shuLiClass = new ShuLiClass(configClass);
|
|
|
+ shuLiClass = new ShuLiClass(shuLiConfig);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
@@ -70,117 +107,134 @@ namespace CCDCount.DLL
|
|
|
shuLiClass = new ShuLiClass();
|
|
|
}
|
|
|
|
|
|
- _IsOpenLoadThread = CameraConfig.IsOpenLoad;
|
|
|
- ThisCameraSN = CameraConfig.CameraSNNum;
|
|
|
- ThisCamerName = CameraConfig.CameraName;
|
|
|
- ThisCameraDevice = CameraConfig.DeviceName;
|
|
|
- ThisCamerNo = CameraConfig.CamerNo;
|
|
|
+ _IsOpenLoadThread = cameraConfig.IsOpenLoad;
|
|
|
+ ThisCamerNo = cameraConfig.CamerNo;
|
|
|
}
|
|
|
- /// <summary>
|
|
|
- /// 开始主线程
|
|
|
- /// </summary>
|
|
|
- public bool StartMianThread(CameraConfig DeviceConfig)
|
|
|
+
|
|
|
+ public bool LoadCamera()
|
|
|
{
|
|
|
bool result = false;
|
|
|
// 相机列表
|
|
|
- List<CameraInfoClass> list = new List<CameraInfoClass>();
|
|
|
- // 获取相机列表
|
|
|
- cameraClass.GetCameraList(out list);
|
|
|
- if (list.Count == 0)
|
|
|
+ try
|
|
|
{
|
|
|
- LOG.error(string.Format("{0}:没有相机", "MainThreadClass-StartMianThread"));
|
|
|
- // 如果没有相机,则退出
|
|
|
- return result;
|
|
|
+ // 获取相机列表
|
|
|
+ cameraClass.GetCameraList(out List<CameraInfoClass> list);
|
|
|
+ if (list.Count == 0)
|
|
|
+ {
|
|
|
+ FaultLog.RecordErrorMessage(string.Format("{0}:没有相机", "MainThreadClass-StartMianThread"));
|
|
|
+ // 如果没有相机,则退出
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+ // 加载相机
|
|
|
+ // cameraClass.LoadCamereDevice(list.First().DeviceSN);
|
|
|
+ if (!cameraClass.LoadCamereDevice(cameraConfig))
|
|
|
+ {
|
|
|
+ FaultLog.RecordErrorMessage(string.Format("{0}:相机加载失败", "MainThreadClass-StartMianThread"));
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+ CameraConfigIsChange = false;
|
|
|
}
|
|
|
- // 加载相机
|
|
|
- // cameraClass.LoadCamereDevice(list.First().DeviceSN);
|
|
|
- if(!cameraClass.LoadCamereDevice(DeviceConfig))
|
|
|
+ catch
|
|
|
{
|
|
|
- LOG.error(string.Format("{0}:相机加载失败", "MainThreadClass-StartMianThread"));
|
|
|
- return result;
|
|
|
+
|
|
|
}
|
|
|
- // 取图线程开启
|
|
|
- cameraClass.StartCamera();
|
|
|
- _CameraStatic = true;
|
|
|
- // 数据交换线程开启
|
|
|
- StartSwitchThread();
|
|
|
- // 为数粒算法的识别成功一粒回调函数添加方法
|
|
|
- shuLiClass.WorkCompleted += Worker_OneGrainCompleted;
|
|
|
- // 开启识别线程
|
|
|
- shuLiClass.StartIdentifyFuntion(cameraClass.GetCamereImageSize().Width);
|
|
|
- zmcauxClass.OpenZmcauxCard();
|
|
|
- result = true;
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
+ public void ReLoadCameraConfig()
|
|
|
+ {
|
|
|
+ if(CameraConfigIsChange)
|
|
|
+ {
|
|
|
+ CameraConfig OldcameraConfig = cameraClass.GetConfigValue();
|
|
|
+ if(OldcameraConfig.CameraSNNum != cameraConfig.CameraSNNum)
|
|
|
+ {
|
|
|
+ cameraClass.LoadCamereDevice(cameraConfig);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ cameraClass.ReLoadCameraConfig(cameraConfig);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
/// <summary>
|
|
|
/// 开始主线程
|
|
|
/// </summary>
|
|
|
public bool StartMianThread()
|
|
|
{
|
|
|
bool result = false;
|
|
|
- // 相机列表
|
|
|
- List<CameraInfoClass> list = new List<CameraInfoClass>();
|
|
|
- // 获取相机列表
|
|
|
- cameraClass.GetCameraList(out list);
|
|
|
- if (list.Count == 0)
|
|
|
+ try
|
|
|
{
|
|
|
- // 如果没有相机,则退出
|
|
|
- return result;
|
|
|
+ // 取图线程开启
|
|
|
+ cameraClass.StartCamera();
|
|
|
+ _CameraStatic = true;
|
|
|
+ StartSendBottLogicMessageThread();
|
|
|
+ // 数据交换线程开启
|
|
|
+ StartSwitchThread();
|
|
|
+ // 为数粒算法的识别成功一粒回调函数添加方法
|
|
|
+ shuLiClass.WorkCompleted += Worker_OneGrainCompleted;
|
|
|
+ // 开启识别线程
|
|
|
+ shuLiClass.StartIdentifyFuntion(cameraClass.GetCamereImageSize().Width);
|
|
|
+ result = true;
|
|
|
+ }
|
|
|
+ catch
|
|
|
+ {
|
|
|
+
|
|
|
}
|
|
|
- // 为数粒算法的识别成功一粒回调函数添加方法
|
|
|
- shuLiClass.WorkCompleted += Worker_OneGrainCompleted;
|
|
|
- // 加载相机
|
|
|
- if (!cameraClass.LoadCamereDevice(new CameraConfig() { CameraSNNum = list.First().DeviceSN}))
|
|
|
- return result;
|
|
|
- _CameraStatic = true;
|
|
|
- // 取图线程开启
|
|
|
- cameraClass.StartCamera();
|
|
|
- // 数据交换线程开启
|
|
|
- StartSwitchThread();
|
|
|
- // 开启识别线程
|
|
|
- shuLiClass.StartIdentifyFuntion(cameraClass.GetCamereImageSize().Width);
|
|
|
- zmcauxClass.OpenZmcauxCard();
|
|
|
- result = true;
|
|
|
return result;
|
|
|
}
|
|
|
+
|
|
|
/// <summary>
|
|
|
/// 停止主线程
|
|
|
/// </summary>
|
|
|
- public void StopMianThread()
|
|
|
+ public bool StopMianThread()
|
|
|
+ {
|
|
|
+ bool result = false;
|
|
|
+ try
|
|
|
+ {
|
|
|
+ _CameraStatic = false;
|
|
|
+ shuLiClass.WorkCompleted -= Worker_OneGrainCompleted;
|
|
|
+ // 相机取图关闭
|
|
|
+ cameraClass.StopCamera();
|
|
|
+ // 数据交换线程关闭
|
|
|
+ StopSwitchThread();
|
|
|
+ // 数粒识别线程关闭
|
|
|
+ shuLiClass.StopIdentifyFuntion();
|
|
|
+ StopSendBottLogicMessageThread();
|
|
|
+ result = true;
|
|
|
+ }
|
|
|
+ catch
|
|
|
+ {
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 释放相机资源
|
|
|
+ /// </summary>
|
|
|
+ public void DisposeCamera()
|
|
|
{
|
|
|
- shuLiClass.WorkCompleted -= Worker_OneGrainCompleted;
|
|
|
- // 相机取图线程关闭
|
|
|
cameraClass.StopCamera();
|
|
|
- // 数据交换线程关闭
|
|
|
- StopSwitchThread();
|
|
|
- // 数粒识别线程关闭
|
|
|
- shuLiClass.StopIdentifyFuntion();
|
|
|
- zmcauxClass.CloseZmcauxCard();
|
|
|
+ cameraClass.DisPoseCamera();
|
|
|
}
|
|
|
|
|
|
+ /// <summary>
|
|
|
+ /// 重加载相机
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="CameraSN"></param>
|
|
|
+ /// <returns></returns>
|
|
|
public bool ReLoadCamera(string CameraSN)
|
|
|
{
|
|
|
bool result = false;
|
|
|
result = cameraClass.ReLoadCameraDevice(CameraSN);
|
|
|
if (result)
|
|
|
{
|
|
|
- CameraConfig ReloadCaonfig = cameraClass.GetConfigValue();
|
|
|
- ThisCameraSN = ReloadCaonfig.CameraSNNum;
|
|
|
- ThisCamerName = ReloadCaonfig.CameraName;
|
|
|
- ThisCameraDevice = ReloadCaonfig.DeviceName;
|
|
|
+ cameraConfig = cameraClass.GetConfigValue();
|
|
|
}
|
|
|
return result;
|
|
|
|
|
|
}
|
|
|
|
|
|
- public void DisposeCamera()
|
|
|
- {
|
|
|
- cameraClass.StopCamera();
|
|
|
- ThisCameraSN = string.Empty;
|
|
|
- ThisCamerName = string.Empty;
|
|
|
- ThisCameraDevice = string.Empty;
|
|
|
- }
|
|
|
/// <summary>
|
|
|
/// 获取显示用的图片数据
|
|
|
/// </summary>
|
|
@@ -199,49 +253,94 @@ namespace CCDCount.DLL
|
|
|
List<ActiveObjectClass> Data = shuLiClass.GetHistoryActive().Where(o => o.LastSeenLine > NewActive.LastSeenLine - ImageHeight).ToList();
|
|
|
Data.ForEach(o => o.RowsData.ForEach(p => RowsShowList.Add(p)));
|
|
|
Bitmap BitmapImage = new Bitmap(NewActive.ImageWidth, ImageHeight);
|
|
|
- Graphics g = Graphics.FromImage(BitmapImage);
|
|
|
- Pen redPen = new Pen(Color.Red, 1);
|
|
|
- List<RowStartEndCol> ShowList = RowsShowList.Where(o => o.RowsCol > NewActive.LastSeenLine - BitmapImage.Height).ToList();
|
|
|
- RowsShowList.Where(o => o.RowsCol < NewActive.LastSeenLine - BitmapImage.Height).ToList().ForEach(o => RowsShowList.Remove(o));
|
|
|
- RowsShowList.Clear();
|
|
|
- ShowList.ForEach(o => g.DrawLine(redPen, new Point(o.StartCol, (int)(NewActive.LastSeenLine - o.RowsCol)), new Point(o.EndCol, (int)(NewActive.LastSeenLine - o.RowsCol))));
|
|
|
- ShowList.Clear();
|
|
|
+ using (Graphics g = Graphics.FromImage(BitmapImage))
|
|
|
+ {
|
|
|
+ g.Clear(Color.White);
|
|
|
+ using (Pen RedPan = new Pen(Color.Red, 5))
|
|
|
+ {
|
|
|
+ for (int i = 0; i < shuLiClass.ChannelsRoi.Count - 1; i++)
|
|
|
+ {
|
|
|
+ g.DrawLine(RedPan, new Point(shuLiClass.ChannelsRoi[i], 0), new Point(shuLiClass.ChannelsRoi[i], BitmapImage.Height));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ using (Pen BlackPen = new Pen(Color.Black, 1))
|
|
|
+ {
|
|
|
+ List<RowStartEndCol> ShowList = RowsShowList.Where(o => o.RowsCol > NewActive.LastSeenLine - BitmapImage.Height).ToList();
|
|
|
+ RowsShowList.Where(o => o.RowsCol < NewActive.LastSeenLine - BitmapImage.Height).ToList().ForEach(o => RowsShowList.Remove(o));
|
|
|
+ RowsShowList.Clear();
|
|
|
+ ShowList.ForEach(o => g.DrawLine(BlackPen, new Point(o.StartCol, (int)(NewActive.LastSeenLine - o.RowsCol)), new Point(o.EndCol, (int)(NewActive.LastSeenLine - o.RowsCol))));
|
|
|
+ ShowList.Clear();
|
|
|
+ }
|
|
|
+ }
|
|
|
ImageData = BitmapImage.Clone() as Bitmap;
|
|
|
BitmapImage.Dispose();
|
|
|
//GC.Collect();
|
|
|
}
|
|
|
|
|
|
+ /// <summary>
|
|
|
+ /// 获取无数据的图片
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="ImageWidth"></param>
|
|
|
+ /// <param name="ImageHeight"></param>
|
|
|
+ /// <param name="ImageData"></param>
|
|
|
+ public void GetNullShowImage(int ImageWidth, int ImageHeight, out Bitmap ImageData)
|
|
|
+ {
|
|
|
+ Bitmap BitmapImage = new Bitmap(ImageWidth, ImageHeight);
|
|
|
+ using (Graphics g = Graphics.FromImage(BitmapImage))
|
|
|
+ {
|
|
|
+ g.Clear(Color.White);
|
|
|
+ using (Pen RedPan = new Pen(Color.Red, 8))
|
|
|
+ {
|
|
|
+ for (int i = 0; i < shuLiClass.ChannelsRoi.Count - 1; i++)
|
|
|
+ {
|
|
|
+ g.DrawLine(RedPan, new Point(shuLiClass.ChannelsRoi[i], 0), new Point(shuLiClass.ChannelsRoi[i], BitmapImage.Height));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ ImageData = BitmapImage.Clone() as Bitmap;
|
|
|
+ BitmapImage.Dispose();
|
|
|
+ }
|
|
|
+
|
|
|
/// <summary>
|
|
|
/// 获取此刻的Config数据
|
|
|
/// </summary>
|
|
|
/// <param name="config"></param>
|
|
|
- public void GetConfigValue(out CameraConfig Camconfig,out ShuLiConfigClass shuLiConfig)
|
|
|
+ public void GetAllConfigValue(out CameraConfig Camconfig,out ShuLiConfigClass shuLiConfig)
|
|
|
{
|
|
|
//判断是否加载了相机
|
|
|
if(cameraClass.IsLoadCamera())
|
|
|
+ {
|
|
|
//获取已经加载的相机的配置
|
|
|
- Camconfig = cameraClass.GetConfigValue();
|
|
|
+ cameraConfig = cameraClass.GetConfigValue();
|
|
|
+ Camconfig = cameraConfig;
|
|
|
+ }
|
|
|
else
|
|
|
- //新建一个相机配置
|
|
|
- Camconfig = new CameraConfig();
|
|
|
+ {
|
|
|
+ cameraConfig = new CameraConfig();
|
|
|
+ Camconfig = cameraConfig;
|
|
|
+ }
|
|
|
//读取视觉配置
|
|
|
shuLiConfig = shuLiClass.GetConfigValue();
|
|
|
+ this.shuLiConfig = shuLiConfig;
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 获取相机此刻的Config数据
|
|
|
/// </summary>
|
|
|
/// <param name="CameraConfig"></param>
|
|
|
- public void GetCameraConfig(out CameraConfig CameraConfig)
|
|
|
+ public CameraConfig GetCameraConfig()
|
|
|
{
|
|
|
+ CameraConfig result = null;
|
|
|
//判断是否加载了相机
|
|
|
if (cameraClass.IsLoadCamera())
|
|
|
+ {
|
|
|
//获取已经加载的相机的配置
|
|
|
- CameraConfig = cameraClass.GetConfigValue();
|
|
|
- else
|
|
|
- //新建一个相机配置
|
|
|
- CameraConfig = new CameraConfig();
|
|
|
+ result = cameraClass.GetConfigValue();
|
|
|
+ cameraConfig = result;
|
|
|
+ }
|
|
|
+ return result;
|
|
|
}
|
|
|
+
|
|
|
/// <summary>
|
|
|
/// 保存所有Config
|
|
|
/// </summary>
|
|
@@ -262,9 +361,28 @@ namespace CCDCount.DLL
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
- public void Dispose()
|
|
|
+ /// <summary>
|
|
|
+ /// 清除历史数据
|
|
|
+ /// </summary>
|
|
|
+ /// <returns></returns>
|
|
|
+ public bool ClearHistoryActive()
|
|
|
{
|
|
|
- //MechanicalControl.Dispose();
|
|
|
+ bool result = false;
|
|
|
+ if(shuLiClass != null)
|
|
|
+ result = shuLiClass.ClearHistoryActive();
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 获取过去一秒内颗粒数量
|
|
|
+ /// </summary>
|
|
|
+ /// <returns></returns>
|
|
|
+ public int GetOneSecondActiveNum()
|
|
|
+ {
|
|
|
+ int result = 0;
|
|
|
+ if(shuLiClass != null)
|
|
|
+ result = shuLiClass.GetHistoryActive().Where(o=>o.EndCheckTime>DateTime.Now-TimeSpan.FromSeconds(1)).Count();
|
|
|
+ return result;
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
@@ -280,7 +398,9 @@ namespace CCDCount.DLL
|
|
|
/// <param name="e"></param>
|
|
|
private void Worker_OneGrainCompleted(object sender, ActiveObjectEventArgsClass e)
|
|
|
{
|
|
|
- LOG.log("有活跃物体转换为了历史物体,回调事件被触发!",6);
|
|
|
+ LOG.log("有活跃物体转换为了历史物体,回调事件被触发!", 6);
|
|
|
+ LOG.log(string.Format("图像处理实例中的待识别图像缓存队列长度{0}", shuLiClass.ImageNum), 6);
|
|
|
+
|
|
|
if (e.Actives.Where(o => o.StateCode == 7).Count() > 0)
|
|
|
{
|
|
|
stopwatch.Restart();
|
|
@@ -291,92 +411,34 @@ namespace CCDCount.DLL
|
|
|
stopwatch.Stop();
|
|
|
_ShuLiState = true;
|
|
|
}
|
|
|
+ //往数组中计数
|
|
|
+ ushort result = new ushort();
|
|
|
+ // 事件处理逻辑
|
|
|
foreach (ActiveObjectClass oneActive in e.Actives)
|
|
|
{
|
|
|
- LOG.log(string.Format("输出当前颗粒信息,开始行:{0},结束行:{1},开始时间:{2}结束时间:{3},颗粒状态:{4}",
|
|
|
- oneActive.StartLine, oneActive.LastSeenLine, oneActive.StartCheckTime.ToString("O"), oneActive.EndCheckTime.ToString("O"), oneActive.StateCode), 6);
|
|
|
+ Console.WriteLine(string.Format("输出当前颗粒信息,开始行:{0},结束行:{1},开始时间:{2}结束时间:{3},颗粒状态:{4},通道数:{5}",
|
|
|
+ oneActive.StartLine, oneActive.LastSeenLine, oneActive.StartCheckTime.ToString("O"), oneActive.EndCheckTime.ToString("O"), oneActive.StateCode, oneActive.ChannelNO));
|
|
|
+ LOG.log(string.Format("输出当前颗粒信息,开始行:{0},结束行:{1},开始时间:{2}结束时间:{3},颗粒状态:{4},通道数:{5}",
|
|
|
+ oneActive.StartLine, oneActive.LastSeenLine, oneActive.StartCheckTime.ToString("O"), oneActive.EndCheckTime.ToString("O"), oneActive.StateCode, oneActive.ChannelNO), 6);
|
|
|
|
|
|
- }
|
|
|
- // 事件处理逻辑
|
|
|
- float step = -1;
|
|
|
- float[] floats = new float[9];
|
|
|
- zmcauxClass.GetMessageFromVar("countStep", ref step);
|
|
|
- LOG.log(string.Format("{0}:countStep = {1}", "MainThreadClass-Worker_OneGrainCompleted", step),6);
|
|
|
- if (step < 1 || step>3)
|
|
|
- {
|
|
|
- zmcauxClass.GetMessageFromArray("CCD_DATA4", ref floats, 0, 9);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- switch (step)
|
|
|
+ if (oneActive.StateCode == 0 && oneActive.ChannelNO != -1)
|
|
|
{
|
|
|
- case 1:
|
|
|
- zmcauxClass.GetMessageFromArray("CCD_DATA1", ref floats, 0, 9);
|
|
|
- break;
|
|
|
- case 2:
|
|
|
- zmcauxClass.GetMessageFromArray("CCD_DATA2", ref floats, 0, 9);
|
|
|
- break;
|
|
|
- case 3:
|
|
|
- zmcauxClass.GetMessageFromArray("CCD_DATA3", ref floats, 0, 9);
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- LOG.log("读取轴卡结果数据:" + floats[0] + " " + floats[1] + " " + floats[2] + " " + floats[3] + " " + floats[4] + " " + floats[5] + " " + floats[6] + " " + floats[7] + " " + floats[8],6);
|
|
|
- foreach (ActiveObjectClass oneActive in e.Actives)
|
|
|
- {
|
|
|
- if (oneActive.StateCode != 0)
|
|
|
- {
|
|
|
- floats[8] += 1;
|
|
|
+ //单通道合格计数
|
|
|
+ result |= (ushort)(1 << (oneActive.ChannelNO));
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- if (oneActive.ChannelNO != -1)
|
|
|
- floats[oneActive.ChannelNO] += 1;
|
|
|
- else
|
|
|
- floats[8] += 1;
|
|
|
+ //单通道不合格计数
|
|
|
+ result |= (ushort)(1 << 8);
|
|
|
}
|
|
|
-
|
|
|
}
|
|
|
- LOG.log("写入轴卡结果数据:" + floats[0] + " " + floats[1] + " " + floats[2] + " " + floats[3] + " " + floats[4] + " " + floats[5] + " " + floats[6] + " " + floats[7] + " " + floats[8],6);
|
|
|
- if (step < 1 || step>3)
|
|
|
+ LOG.log("当前待发送队列数量:" + SendQueue.Count, 6);
|
|
|
+ if(IsSend)
|
|
|
{
|
|
|
- zmcauxClass.SetMessageToArray("CCD_DATA4", floats, 0, 9);
|
|
|
+ SendQueue.Enqueue(result);
|
|
|
}
|
|
|
- else
|
|
|
- {
|
|
|
- switch (step)
|
|
|
- {
|
|
|
- case 1:
|
|
|
- zmcauxClass.SetMessageToArray("CCD_DATA1", floats, 0, 9);
|
|
|
- break;
|
|
|
- case 2:
|
|
|
- zmcauxClass.SetMessageToArray("CCD_DATA2", floats, 0, 9);
|
|
|
- break;
|
|
|
- case 3:
|
|
|
- zmcauxClass.SetMessageToArray("CCD_DATA3", floats, 0, 9);
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- //OnOneGrain(e.Actives);
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// 装瓶逻辑
|
|
|
- /// </summary>
|
|
|
- private void BottLogicFunction()
|
|
|
- {
|
|
|
-
|
|
|
}
|
|
|
|
|
|
- /// <summary>
|
|
|
- /// 对外通知事件
|
|
|
- /// </summary>
|
|
|
- private void OnOneGrain(List<ActiveObjectClass> activeObject)
|
|
|
- {
|
|
|
- ActiveObjectEventArgsClass activeObjectEventArgs = new ActiveObjectEventArgsClass(activeObject);
|
|
|
- // 触发事件
|
|
|
- WorkerToFrom?.Invoke(this, activeObjectEventArgs);
|
|
|
- }
|
|
|
#endregion
|
|
|
|
|
|
#region 线程方法
|
|
@@ -406,7 +468,7 @@ namespace CCDCount.DLL
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
- LOG.error("Start thread failed!, " + ex.Message);
|
|
|
+ FaultLog.RecordErrorMessage("Start thread failed!, " + ex.Message);
|
|
|
throw;
|
|
|
}
|
|
|
}
|
|
@@ -423,7 +485,7 @@ namespace CCDCount.DLL
|
|
|
{
|
|
|
if (stopwatch.ElapsedMilliseconds > 1000)
|
|
|
{
|
|
|
- Console.WriteLine("交换线程-图像处理实例中的待识别图像缓存队列长度{0}", shuLiClass.ImageNum);
|
|
|
+ //Console.WriteLine("交换线程-图像处理实例中的待识别图像缓存队列长度{0}", shuLiClass.ImageNum);
|
|
|
GC.Collect();
|
|
|
stopwatch.Restart();
|
|
|
}
|
|
@@ -431,6 +493,11 @@ namespace CCDCount.DLL
|
|
|
bool result = cameraClass.GetOnceImage(out IFramedata);
|
|
|
if (result)
|
|
|
{
|
|
|
+ //Debug模式,不进行图像处理
|
|
|
+ if (IsDebug)
|
|
|
+ {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
if (IFramedata == null)
|
|
|
continue;
|
|
|
shuLiClass.SetOnceIdentifyImageData(IFramedata.Image);
|
|
@@ -441,6 +508,101 @@ namespace CCDCount.DLL
|
|
|
}
|
|
|
stopwatch.Stop();
|
|
|
}
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 启动发送消息线程
|
|
|
+ /// </summary>
|
|
|
+ private void StartSendBottLogicMessageThread()
|
|
|
+ {
|
|
|
+ try
|
|
|
+ {
|
|
|
+ if(!IsConnectModbus) return;
|
|
|
+ //zmcauxClass.OpenZmcauxCard();
|
|
|
+
|
|
|
+ timeBeginPeriod(1); // 设置为1ms精度
|
|
|
+ IsSend = true;
|
|
|
+ SendBottLogicMessageThread = new Thread(SendBottLogicMessageProcess);
|
|
|
+ SendBottLogicMessageThread.Start();
|
|
|
+ }
|
|
|
+ catch (Exception ex)
|
|
|
+ {
|
|
|
+ FaultLog.RecordErrorMessage("Start thread failed!, " + ex.Message);
|
|
|
+ throw;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ /// <summary>
|
|
|
+ /// 停止发送消息线程
|
|
|
+ /// </summary>
|
|
|
+ private void StopSendBottLogicMessageThread()
|
|
|
+ {
|
|
|
+ try
|
|
|
+ {
|
|
|
+ // 标志位设为false
|
|
|
+ IsSend = false;
|
|
|
+ if (SendBottLogicMessageThread != null && SendBottLogicMessageThread.IsAlive)
|
|
|
+ SendBottLogicMessageThread.Join();
|
|
|
+ if (modbusTcpClient != null) modbusTcpClient.Disconnect();
|
|
|
+ }
|
|
|
+ catch (Exception ex)
|
|
|
+ {
|
|
|
+ FaultLog.RecordErrorMessage("Start thread failed!, " + ex.Message);
|
|
|
+ throw;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 信息发送线程
|
|
|
+ /// </summary>
|
|
|
+ private void SendBottLogicMessageProcess()
|
|
|
+ {
|
|
|
+ //获取数据
|
|
|
+ ushort sendMessage = 0;
|
|
|
+ bool AllowTransfer = false;
|
|
|
+ bool TransferDone = false;
|
|
|
+ Stopwatch sw = Stopwatch.StartNew();
|
|
|
+ while (IsSend)
|
|
|
+ {
|
|
|
+ //LOG.log("进入线程", 6);
|
|
|
+ sw.Restart();
|
|
|
+ sendMessage = new ushort();
|
|
|
+ //读取装瓶状态
|
|
|
+ AllowTransfer = false;
|
|
|
+ TransferDone = false;
|
|
|
+ bool[] ReadResult = modbusTcpClient.ReadCoilsRegister(slaveId: 1, startAddress: 11, numRegisters: 2);
|
|
|
+ if (ReadResult == null)
|
|
|
+ {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ AllowTransfer = ReadResult[1];
|
|
|
+ TransferDone = ReadResult[0];
|
|
|
+ //LOG.log(string.Format("读取值:AllowTransfer[0]:{0},TransferDone[1]:{1}", AllowTransfer, TransferDone), 6);
|
|
|
+ //当允许写入且处于未写入的状态时
|
|
|
+ if (AllowTransfer && !TransferDone)
|
|
|
+ {
|
|
|
+ if (SendQueue.Count() > 0)
|
|
|
+ {
|
|
|
+ if (!SendQueue.TryDequeue(out sendMessage))
|
|
|
+ {
|
|
|
+ FaultLog.RecordErrorMessage("MainThreadClass-SendBottLogicMessageProcess-SendQueue.TryDequeue failed!");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (sendMessage != 0)
|
|
|
+ {
|
|
|
+ //写入数据
|
|
|
+ modbusTcpClient.WriteSingleRegister(slaveId: 1, registerAddress: 100, value: sendMessage);
|
|
|
+ modbusTcpClient.WriteCoilsRegister(slaveId: 1, CoilsAddress: 11, values: true);
|
|
|
+ }
|
|
|
+ sw.Stop();
|
|
|
+ FaultLog.RecordLogMessage(string.Format("sendMessage[1]:{0},此次写值耗时:{1}", sendMessage, sw.Elapsed),1);
|
|
|
+ }
|
|
|
+ Thread.Sleep(1);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ #endregion
|
|
|
+
|
|
|
+ #region 外部函数
|
|
|
+ [DllImport("winmm.dll")]
|
|
|
+ static extern uint timeBeginPeriod(uint period);
|
|
|
#endregion
|
|
|
}
|
|
|
}
|