Add QRValidation project to repository

- Added QRValidation vision control system
- Includes CapCleaningControl UI components
- WebSocket-based barcode validation system
- Support for Crevis PLC integration
- Test projects for PLC emulator, motion, IO panel, and Modbus

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
atvstdla
2025-10-02 11:38:38 +09:00
parent 3eac3927f8
commit dc66158497
192 changed files with 27168 additions and 0 deletions

View File

@@ -0,0 +1,44 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Windows.Forms;
namespace Project
{
public partial class fMain
{
delegate void ShowLotTextHandler(string value);
delegate void UpdateDMTextHandler(string value1);
//void UpdateResultText(string value1)
//{
// if (this.lbResult.InvokeRequired)
// {
// lbResult.BeginInvoke(new UpdateDMTextHandler(UpdateResultText), new object[] { value1 });
// }
// else
// {
// lbResult.Text = value1;
// }
//}
delegate void UpdateLabelTextHandler(Control ctl, string value);
void UpdateLabelText(Control ctl, string value)
{
if (ctl.InvokeRequired)
{
ctl.BeginInvoke(new UpdateLabelTextHandler(UpdateLabelText), new object[] { ctl, value });
}
else
{
ctl.Text = value;
}
}
}
}

View File

@@ -0,0 +1,71 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Project
{
public partial class StateMachine
{
public enum eMsgOpt : byte
{
NORMAL,
STEPCHANGE,
ERROR,
}
/// <summary>
/// 000~020 : System Define
/// 020~255 : User Define
/// </summary>
public enum eSMStep : byte
{
NOTSET = 0,
INIT,
IDLE,
REQSERVM,
REQSERV,
RUN,
/// <summary>
/// 작업완룡
/// </summary>
FINISH,
/// <summary>
/// 왼쪽(출구)에서 자재를 투입합니다
/// </summary>
LTAKE,
/// <summary>
/// 오른쪽(입구)에서 자채를 투입합니다
/// </summary>
//RTAKE,
POSITION_RESET,
PAUSE,
/// <summary>
/// 시작명령을 기다리는중(PAUSE 상태에서 RESET시 설정 됨)
/// </summary>
WAITSTART,
ERROR,
UNLOADER_CHK,
OVERLOAD,
RESET,
SAFTY,
EMERGENCY,
CLEAR,
HOME,
HOMECHK,
QHOME,
CLOSING,
CLOSEWAIT,
CLOSED,
}
}
}

View File

@@ -0,0 +1,55 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Project
{
public partial class StateMachine
{
public class StateMachineMessageEventArgs : EventArgs
{
public string Header { get; set; }
public string Message { get; set; }
public StateMachineMessageEventArgs(string header_, string message_)
{
this.Message = message_;
this.Header = header_;
}
}
public event EventHandler<StateMachineMessageEventArgs> Message;
void RaiseMessage(string header, string msg)
{
if (Message != null) Message(this, new StateMachineMessageEventArgs(header, msg));
}
public class StepChangeEventArgs : EventArgs
{
public eSMStep Old { get; set; }
public eSMStep New { get; set; }
public StepChangeEventArgs(eSMStep old_,eSMStep new_)
{
this.Old = old_;
this.New = new_;
}
}
public class RunningEventArgs : EventArgs {
// public object sender { get; set; }
public Boolean isFirst { get; set; }
public eSMStep Step { get; set; }
public TimeSpan StepTime { get; set; }
public RunningEventArgs(eSMStep step_, Boolean isfirst_,TimeSpan steptime_)
{
this.isFirst = isfirst_;
this.Step = step_;
StepTime = steptime_;
// this.sender = sender_;
}
}
//public event EventHandler<StepChangeEventArgs> StepChanged;
//public event EventHandler SPS;
//public event EventHandler<RunningEventArgs> Running;
}
}

View File

@@ -0,0 +1,327 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using WatsonWebsocket;
namespace Project
{
public partial class fMain
{
Byte sendseq = 0;
DateTime[] cameraconntimechk = new DateTime[] { DateTime.Now, DateTime.Now };
private void bwConn_DoWork(object sender, DoWorkEventArgs e)
{
PUB.log_[0].Add("Device connection thread start");
PUB.log_[1].Add("Device connection thread start");
var logIdx = 0;
System.Diagnostics.Stopwatch wat = new System.Diagnostics.Stopwatch();
int idx = 0;
while (bRunConnection && this.IsDisposed == false && this.Disposing == false)
{
//Check listener status
if (idx == 0)
{
//left socket listening
if (PUB.setting.CameraIndexL >= 0)
{
logIdx = 0;
if (PUB.wsock_[logIdx].IsListening == false)
{
var tsli = DateTime.Now - PUB.Time_WS_Listen_Try[PUB.setting.CameraIndexL];
if (tsli.TotalSeconds > 5)
{
//Server retry
PUB.log_[logIdx].AddAT($"Server listen retry port:{PUB.setting.listenPortL}");
try
{
PUB.wsock_[logIdx] = new Class.WebSocket("localhost", PUB.setting.listenPortL);
PUB.wsock_[logIdx].Start();
PUB.wsock_[logIdx].MessageReceived += Ws_DataArrival;
PUB.wsock_[logIdx].ClientConnected += Ws_Connected;
PUB.wsock_[logIdx].ClientDisconnected += Ws_Disconnected;
}
catch (Exception ex)
{
PUB.wsock_[logIdx].MessageReceived -= Ws_DataArrival;
PUB.wsock_[logIdx].ClientConnected -= Ws_Connected;
PUB.wsock_[logIdx].ClientDisconnected -= Ws_Disconnected;
PUB.log_[logIdx].AddE("Server retry listen failed:" + ex.Message);
}
PUB.Time_WS_Listen_Try[PUB.setting.CameraIndexL] = DateTime.Now;
}
}
}
idx += 1;
}
else if (idx == 1)
{
//right socket listening
if (PUB.setting.CameraIndexR >= 0)
{
logIdx = 1;
if (PUB.wsock_[logIdx].IsListening == false)
{
var tsli = DateTime.Now - PUB.Time_WS_Listen_Try[PUB.setting.CameraIndexR];
if (tsli.TotalSeconds > 5)
{
//Server retry
PUB.log_[logIdx].AddAT($"Server listen retry port:{PUB.setting.listenPortR}");
try
{
PUB.wsock_[logIdx] = new Class.WebSocket("localhost", PUB.setting.listenPortR);
PUB.wsock_[logIdx].Start();
PUB.wsock_[logIdx].MessageReceived += Ws_DataArrival;
PUB.wsock_[logIdx].ClientConnected += Ws_Connected;
PUB.wsock_[logIdx].ClientDisconnected += Ws_Disconnected;
}
catch (Exception ex)
{
PUB.wsock_[logIdx].MessageReceived -= Ws_DataArrival;
PUB.wsock_[logIdx].ClientConnected -= Ws_Connected;
PUB.wsock_[logIdx].ClientDisconnected -= Ws_Disconnected;
PUB.log_[logIdx].AddE("Server retry listen failed:" + ex.Message);
}
PUB.Time_WS_Listen_Try[PUB.setting.CameraIndexR] = DateTime.Now;
}
}
}
idx += 1;
}
else if (idx == 2)
{
//Initialization process
try
{
var status = PUB._virtualFG40.InitSystem();
if (status != Crevis.VirtualFG40Library.VirtualFG40Library.MCAM_ERR_SUCCESS)
{
PUB.log_[0].AddE($"Crevis:System Initialize failed : {status}");
PUB.log_[1].AddE($"Crevis:System Initialize failed : {status}");
}
else Console.WriteLine("Camera init ok");
}
catch (Exception ex)
{
Console.WriteLine($"Camera init error {ex.Message}");
}
idx += 1;
}
else if (idx == 3)
{
//open camera
if (camNum > 0 && PUB.setting.CameraIndexL >= 0 && PUB.setting.CameraIndexL < camNum)
{
bool initok = false;
PUB._virtualFG40.IsInitSystem(ref initok);
if (initok)
{
var camIdx = PUB.setting.CameraIndexL;
if (camIdx >= camNum)
{
//Card corresponding to specified index does not exist
}
else if (PUB._hDevice[camIdx] < 0)
{
//Camera index is 0,1 but vision index uses 0,2 as before. 1 is for central Keyence
PUB.log_[logIdx].Add($"Camera {camIdx} connection in progress");
var Piv = camIdx == PUB.setting.CameraIndexL ? this.pivLeft : this.pIvRight;
if (CrevisOpen(camIdx)) PUB.CrevisGrab(camIdx, true, Piv); //Try to capture one image
cameraconntimechk[camIdx] = DateTime.Now;
}
else
{
//Has been connected before.
var ts = DateTime.Now - cameraconntimechk[camIdx];
if (ts.TotalSeconds > 5)
{
bool iscon = false;
var rlt = PUB._virtualFG40.IsOpenDevice(PUB._hDevice[camIdx], ref iscon);
if (rlt == Crevis.VirtualFG40Library.VirtualFG40Library.MCAM_ERR_SUCCESS)
{
var status = PUB._virtualFG40.GetAvailableCameraNum(ref camNum);
if (iscon == false)
{
var Piv = camIdx == PUB.setting.CameraIndexL ? this.pivLeft : this.pIvRight;
if (CrevisOpen(camIdx)) PUB.CrevisGrab(camIdx, true, Piv); //Try to capture one image
}
else
{
//Already connected.
}
}
else if (rlt == Crevis.VirtualFG40Library.VirtualFG40Library.MCAM_ERR_NO_DEVICE)
{
//Device not found, refreshing list.
PUB._virtualFG40.UpdateDevice();
var status = PUB._virtualFG40.GetAvailableCameraNum(ref camNum);
if (camNum <= camIdx)
{
PUB._virtualFG40.FreeSystem();
PUB.log_[logIdx].AddE("The camera can not be connected.");
}
//else
//{
PUB._hDevice[camIdx] = -1; //Induce reconnection work
//}
}
cameraconntimechk[camIdx] = DateTime.Now;
}
}
}
}
//Pub.flag.set(eFlag.CHECKCAMERA, false, "LOAD");
idx += 1;
}
else if (idx == 4)
{
//open camera
bool initok = false;
try
{
PUB._virtualFG40.IsInitSystem(ref initok);
}
catch (Exception ex)
{
Console.WriteLine($"Error _virtualFG40.IsInitSystem : {ex.Message}");
initok = false;
}
if (initok)
{
var camIdx = PUB.setting.CameraIndexR;
if (camIdx >= camNum)
{
//지정한 인덱스에 해당하는 카드가 존재하지 않음
}
else if (camIdx != PUB.setting.CameraIndexL)
{
if (PUB._hDevice[camIdx] < 0)
{
//Camera index is 0,1 but vision index uses 0,2 as before. 1 is for central Keyence
PUB.log_[logIdx].Add($"Camera {camIdx} connection in progress");
var Piv = camIdx == PUB.setting.CameraIndexL ? this.pivLeft : this.pIvRight;
if (CrevisOpen(camIdx)) PUB.CrevisGrab(camIdx, true, Piv); //Try to capture one image
cameraconntimechk[camIdx] = DateTime.Now;
}
else
{
//최소 셋팅된 번호와 현재 카메라 번호가 다르면 초기화를 해준다.
if (FirstCrevisIndex[camIdx] != -1 && FirstCrevisIndex[camIdx] != PUB._hDevice[camIdx])
{
PUB.log_[logIdx].AddE($"Camera Index({camIdx}) error");
PUB._hDevice[camIdx] = -1;
}
else if(PUB._hDevice[0] == PUB._hDevice[1]) //error condition
{
PUB.log_[logIdx].AddE($"Camera Index({camIdx}) error init");
PUB._hDevice[0] = -1;
PUB._hDevice[1] = -1;
FirstCrevisIndex[0] = -1;
FirstCrevisIndex[1] = -1;
}
else
{
//Has been connected before.
var ts = DateTime.Now - cameraconntimechk[camIdx];
if (ts.TotalSeconds > 5)
{
bool iscon = false;
var rlt = PUB._virtualFG40.IsOpenDevice(PUB._hDevice[camIdx], ref iscon);
if (rlt == Crevis.VirtualFG40Library.VirtualFG40Library.MCAM_ERR_SUCCESS)
{
var status = PUB._virtualFG40.GetAvailableCameraNum(ref camNum);
if (iscon == false)
{
var Piv = camIdx == PUB.setting.CameraIndexL ? this.pivLeft : this.pIvRight;
if (CrevisOpen(camIdx)) PUB.CrevisGrab(camIdx, true, Piv); //Try to capture one image
}
else
{
//Already connected.
}
}
else if (rlt == Crevis.VirtualFG40Library.VirtualFG40Library.MCAM_ERR_NO_DEVICE)
{
//Device not found, refreshing list.
PUB._virtualFG40.UpdateDevice();
var status = PUB._virtualFG40.GetAvailableCameraNum(ref camNum);
if (camNum <= camIdx)
{
PUB._virtualFG40.FreeSystem();
PUB.log_[logIdx].AddE("The camera can not be connected.");
}
//else
//{
PUB._hDevice[camIdx] = -1; //Induce reconnection work
//}
}
cameraconntimechk[camIdx] = DateTime.Now;
}
}
}
}
}
// panMiniDisplay.Invalidate();
//Pub.flag.set(eFlag.CHECKCAMERA, false, "LOAD");
idx += 1;
}
else
{
idx = 0;
}
if (sendseq == 0)
{
if (PUB.setting.CameraIndexL >= 0)
SendStatus(eTarget.Left);
sendseq += 1;
}
else if (sendseq == 1)
{
if (PUB.setting.CameraIndexR >= 0 && PUB.setting.CameraIndexR != PUB.setting.CameraIndexL)
SendStatus(eTarget.Right);
sendseq += 1;
}
else sendseq = 0;
if (idx > 4) idx = 0;
//heartbeat
if (this.IsDisposed == false)
{
this.Invoke(new Action(() =>
{
try
{
if (this.sbConnState.ForeColor == Color.LimeGreen)
this.sbConnState.ForeColor = Color.Green;
else
this.sbConnState.ForeColor = Color.LimeGreen;
}
catch { }
}));
}
System.Threading.Thread.Sleep(250);
}
}
}
}

View File

@@ -0,0 +1,112 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using WatsonWebsocket;
namespace Project
{
public partial class fMain
{
private void bwLeft_DoWork(object sender, DoWorkEventArgs e)
{
var camIdx = PUB.setting.CameraIndexL;
var logIdx = 0;
PUB.log_[logIdx].Add("Camera thread(L) start");
System.Diagnostics.Stopwatch wat = new System.Diagnostics.Stopwatch();
var framedelay = (int)(1000f / 12f);//Time required to get 1 frame 12f / 1000;
while (bRunConnection && this.IsDisposed == false && this.Disposing == false)
{
wat.Restart();
var _fpsms = framedelay;// IsTrigger ? Pub.setting.GrabDelayFast : Pub.setting.GrabDelaySlow;
if (PUB.imgque == null || PUB.imgque.Any() == false) continue;
if (PUB.imgque.Peek().Equals(this.Name) == false) continue;
if (camIdx < 0)
{
this.BeginInvoke(new Action(() =>
{
sbConnCamL.ForeColor = Color.Red;
}));
System.Threading.Thread.Sleep(1000);
continue;
}
//If camera is not connected, do not process.
if (PUB._isCrevisOpen[camIdx] == false || PUB.IsLive[camIdx] == false || PUB.flag.get(eFlag.CAMERAINIT) == false) _fpsms = 1000;
else
{
//Data processing after image acquisition
var Piv = camIdx == PUB.setting.CameraIndexL ? this.pivLeft : this.pIvRight;
if (PUB.CrevisGrab(camIdx, true, Piv))
{
if (PUB.IsProcess[camIdx] || PUB.IsTrigger[camIdx])
PUB.CreavisProcess(camIdx, PUB.IsTrigger[camIdx], Piv);
}
//this.BeginInvoke(new Action(() => {
// //Update current time
// if (iv[camIdx] != null)
// {
// if (iv[camIdx].Shapes.Count < 1)
// iv[camIdx].Shapes.AddText(100, 100, DateTime.Now.ToShortTimeString(), Color.Lime, 100);
// else
// iv[camIdx].Shapes[0].Title = DateTime.Now.ToShortTimeString();
// iv[camIdx].Invalidate();
// }
//}));
if (PUB.IsTrigger[camIdx] && PUB.setting.TriggerTimeout > 0 && PUB.setting.TriggerTimeout < 999)
{
var ts = DateTime.Now - PUB.triggerTime[camIdx];
if (ts.TotalSeconds > PUB.setting.TriggerTimeout)
{
PUB.log_[logIdx].Add($"Trigger maximum time({PUB.setting.TriggerTimeout}) exceeded, releasing");
PUB.IsTrigger[camIdx] = false;
PUB.IsLive[camIdx] = false;
PUB.IsProcess[camIdx] = false;
}
}
}
wat.Stop();
if (wat.ElapsedMilliseconds < _fpsms)
{
try
{
if (PUB.setting.AutoDeleteSeconds > 0 && PUB.setting.AutoDeleteSeconds < 99)
{
var di = new System.IO.DirectoryInfo(PUB.setting.ImageSavePath);
var ttime = DateTime.Now.AddSeconds(-PUB.setting.AutoDeleteSeconds);
var dellist = di.GetFiles().Where(t => t.CreationTime <= ttime).FirstOrDefault();
if (dellist != null) dellist.Delete();
}
}
catch { }
System.Threading.Thread.Sleep(_fpsms - (int)wat.ElapsedMilliseconds);
}
//heart beat
this.BeginInvoke(new Action(() =>
{
if (sbConnCamL.ForeColor == Color.Green)
sbConnCamL.ForeColor = Color.LimeGreen;
else
sbConnCamL.ForeColor = Color.Green;
}));
}
}
}
}

View File

@@ -0,0 +1,98 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using WatsonWebsocket;
namespace Project
{
public partial class fMain
{
private void bwRight_DoWork(object sender, DoWorkEventArgs e)
{
var camIdx = PUB.setting.CameraIndexR;
var logIdx = 1;
PUB.log_[logIdx].Add("Camera thread(R) start");
System.Diagnostics.Stopwatch wat = new System.Diagnostics.Stopwatch();
var framedelay = (int)(1000f / 12f);//Time required to get 1 frame 12f / 1000;
while (bRunConnection && this.IsDisposed == false && this.Disposing == false)
{
wat.Restart();
var _fpsms = framedelay;// IsTrigger ? Pub.setting.GrabDelayFast : Pub.setting.GrabDelaySlow;
if (PUB.imgque == null || PUB.imgque.Any() == false) continue;
if (PUB.imgque.Peek().Equals(this.Name) == false) continue;
if (camIdx < 0 || PUB.setting.CameraIndexL == PUB.setting.CameraIndexR)
{
this.BeginInvoke(new Action(() =>
{
sbConnCamR.ForeColor = Color.Red;
}));
System.Threading.Thread.Sleep(1000);
continue;
}
//If camera is not connected, do not process.
if (PUB._isCrevisOpen[camIdx] == false || PUB.IsLive[camIdx] == false || PUB.flag.get(eFlag.CAMERAINIT) == false) _fpsms = 1000;
else
{
//Data processing after image acquisition
var Piv = this.pIvRight;
if (PUB.CrevisGrab(camIdx, true, Piv))
{
if (PUB.IsProcess[camIdx])
PUB.CreavisProcess(camIdx, PUB.IsTrigger[camIdx], Piv);
}
if (PUB.setting.TriggerTimeout > 0 && PUB.setting.TriggerTimeout < 999)
{
var ts = DateTime.Now - PUB.triggerTime[camIdx];
if (PUB.IsTrigger[camIdx] && ts.TotalSeconds > PUB.setting.TriggerTimeout)
{
PUB.log_[logIdx].Add($"Trigger maximum time({PUB.setting.TriggerTimeout}) exceeded, releasing");
PUB.IsTrigger[camIdx] = false;
}
}
}
wat.Stop();
if (wat.ElapsedMilliseconds < _fpsms)
{
try
{
if (PUB.setting.AutoDeleteSeconds > 0 && PUB.setting.AutoDeleteSeconds < 99)
{
var di = new System.IO.DirectoryInfo(PUB.setting.ImageSavePath);
var ttime = DateTime.Now.AddSeconds(-PUB.setting.AutoDeleteSeconds);
var dellist = di.GetFiles().Where(t => t.CreationTime <= ttime).FirstOrDefault();
if (dellist != null) dellist.Delete();
}
}
catch { }
System.Threading.Thread.Sleep(_fpsms - (int)wat.ElapsedMilliseconds);
}
//heart beat
this.BeginInvoke(new Action(() =>
{
if (sbConnCamR.ForeColor == Color.Green)
sbConnCamR.ForeColor = Color.LimeGreen;
else
sbConnCamR.ForeColor = Color.Green;
}));
}
}
}
}

View File

@@ -0,0 +1,55 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
namespace Project
{
public partial class fMain
{
/// <summary>
/// Function executed once when closing the program
/// </summary>
private void _Close_Start()
{
//동작코드off
PUB.IsTrigger[0] = PUB.IsTrigger[1] = false;
PUB.IsProcess[0] = PUB.IsProcess[1] = false;
PUB.IsLive[0] = PUB.IsLive[1] = false;
tmDisplay.Stop();
PUB.log_[0].Add("Socket close");
PUB.log_[1].Add("Socket close");
try
{
PUB.wsock_[0].Stop();
PUB.wsock_[1].Stop();
}
catch { }
//연결체크용 쓰레드 종료
bRunConnection = false;
PUB.log_[0].Add("Program Close");
PUB.log_[1].Add("Program Close");
PUB.LogFlush();
//크레비스OFF - 210203
try
{
if (PUB._hDevice[PUB.setting.CameraIndexL] > 0)
PUB._virtualFG40.AcqStop(PUB._hDevice[PUB.setting.CameraIndexL]);
if (PUB._hDevice[PUB.setting.CameraIndexR] > 0)
PUB._virtualFG40.AcqStop(PUB._hDevice[PUB.setting.CameraIndexR]);
PUB._virtualFG40.FreeSystem();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
}

View File

@@ -0,0 +1,258 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Crevis.VirtualFG40Library;
using Emgu.CV;
using Emgu.CV.CvEnum;
using Emgu.CV.Structure;
#if V22
using Euresys.Open_eVision_22_12;
using Euresys.Open_eVision_22_12.Easy3D;
#else
using Euresys.Open_eVision_2_11;
#endif
namespace Project
{
public partial class fMain
{
UInt32 camNum = 0;
/// <summary>
/// Crevis must be initialized in the main thread
/// </summary>
void _SM_RUN_INIT_CAMERA()
{
//Crevis Init
PUB._virtualFG40 = new VirtualFG40Library();
Int32 status = VirtualFG40Library.MCAM_ERR_SUCCESS;
try
{
//System InitializSend_WSocke
status = PUB._virtualFG40.InitSystem();
if (status != VirtualFG40Library.MCAM_ERR_SUCCESS)
{
PUB.log_[0].AddE($"Crevis:System Initialize failed : {status}");
PUB.log_[1].AddE($"Crevis:System Initialize failed : {status}");
}
else
{
// Update Device List
//status = _virtualFG40.UpdateDevice();
//if (status != VirtualFG40Library.MCAM_ERR_SUCCESS)
//{
// _virtualFG40.FreeSystem();
// throw new Exception(String.Format("Update Device list failed : {0}", status));
//}
status = PUB._virtualFG40.GetAvailableCameraNum(ref camNum);
if (camNum <= 0)
{
PUB._virtualFG40.FreeSystem();
PUB.log_[0].AddE("The camera can not be connected.");
PUB.log_[1].AddE("The camera can not be connected.");
}
else Console.WriteLine($"Camera {camNum} Found");
//camNum = 1;
}
//if (camNum > 0)
//{
// //카메라 인덱스는 0,1 이지만 비젼인덱스는 기존대로 0,2번을 사용한다. 1번은 중앙 키엔스용이다
// Pub.log.Add($"{Pub.setting.CameraIndex}번 카메라 연결 진행");
// if (CrevisOpen(Pub.setting.CameraIndex)) CrevisGrab(true); //한장을 수집해본다
//}
}
catch (Exception ex)
{
PUB.log_[0].AddE("Crevis:" + ex.Message);
PUB.log_[1].AddE("Crevis:" + ex.Message);
}
}
int[] FirstCrevisIndex = new int[] { -1, -1 };
/// <summary>
/// Camera open
/// </summary>
/// <param name="camIdx"></param>
/// <returns></returns>
Boolean CrevisOpen(int camIdx)
{
Int32 status = VirtualFG40Library.MCAM_ERR_SUCCESS;
var logIdx = camIdx == PUB.setting.CameraIndexL ? 0 : 1;
try
{
// camera open
status = PUB._virtualFG40.OpenDevice((uint)camIdx, ref PUB._hDevice[camIdx]);
if (status != VirtualFG40Library.MCAM_ERR_SUCCESS)
{
PUB._virtualFG40.FreeSystem();
PUB.log_[logIdx].AddE($"Open device failed : {status}");
PUB._isCrevisOpen[camIdx] = false;
return false;
}
if (FirstCrevisIndex[camIdx] == -1)
FirstCrevisIndex[camIdx] = PUB._hDevice[camIdx];
PUB._isCrevisOpen[camIdx] = true;
// Call Set Feature
CrevisSetFeature((uint)camIdx);
// Get Width
status = PUB._virtualFG40.GetIntReg(PUB._hDevice[camIdx], VirtualFG40Library.MCAM_WIDTH, ref PUB._width[camIdx]);
if (status != VirtualFG40Library.MCAM_ERR_SUCCESS)
{
throw new Exception(String.Format("Read Register MCAM_WIDTH failed : {0}", status));
}
// Get Height
status = PUB._virtualFG40.GetIntReg(PUB._hDevice[camIdx], VirtualFG40Library.MCAM_HEIGHT, ref PUB._height[camIdx]);
if (status != VirtualFG40Library.MCAM_ERR_SUCCESS)
{
throw new Exception(String.Format("Read Register MCAM_HEIGHT failed : {0}", status));
}
// Get FPS
//status = _virtualFG40.GetIntReg(_hDevice, VirtualFG40Library.MCAM_ACQUISITION_FRAME_COUNT, ref _fps);
//if (status != VirtualFG40Library.MCAM_ERR_SUCCESS)
//{
// throw new Exception(String.Format("Read Register MCAM_ACQUISITION_FRAME_COUNT failed : {0}", status));
//}
PUB.log_[logIdx].AddI($"Camera({camIdx}) connection complete({PUB._width[camIdx]}x{PUB._height[camIdx]})");
uint grabtimeout = 0;
status = PUB._virtualFG40.GetGrabTimeout(PUB._hDevice[camIdx], ref grabtimeout);
if (status != VirtualFG40Library.MCAM_ERR_SUCCESS)
{
throw new Exception(String.Format("Read TimeOut failed : {0}", status));
}
else PUB._virtualFG40.SetGrabTimeout(PUB._hDevice[camIdx], 1000); //타임아웃 1초로 지정(기본값:5초) 210113
// Image buffer allocation
PUB._bufferSize[camIdx] = PUB._width[camIdx] * PUB._height[camIdx];
PUB.camPtr[camIdx] = Marshal.AllocHGlobal(PUB._bufferSize[camIdx]);
//데이터를 받을 저장소 초기화(흑백)
var bitsPerPixel = 8;
PUB._stride[camIdx] = (Int32)((PUB._width[camIdx] * bitsPerPixel + 7) / 8);
//var imgRect = new Rectangle(0, 0, _width[camIdx], _height[camIdx]);
//OrgBitmap = new Bitmap(_width, _height, _stride, PixelFormat.Format8bppIndexed, _pImage);
// SetGrayscalePalette(OrgBitmap);
//오픈이비젼은 사용가능하면 처리한다
//if (OrgEImage[camIdx] != null) OrgEImage[camIdx].Dispose();
//OrgEImage[camIdx] = new EImageBW8();
//OrgEImage[camIdx].SetImagePtr(_width[camIdx], _height[camIdx], pImage);
//openCv 이미지 처리
// OrgImage = new Image<Gray, byte>(_width, _height, _stride, _pImage);
//OrgCImage = new Image<Bgr, byte>(_width, _height, new Bgr(Color.Black));
//데이터를 표시할 저장소 초기화 (컬러)
//OrgBitmapC = new Bitmap(_width, _height, PixelFormat.Format24bppRgb);
//var lockColor = OrgBitmapC.LockBits(imgRect, ImageLockMode.ReadOnly, OrgBitmapC.PixelFormat);
//OrgImageC = new Image<Bgr, byte>(_width, _height, lockColor.Stride, lockColor.Scan0);
//OrgBitmapC.UnlockBits(lockColor);
}
catch (Exception ex)
{
PUB._isCrevisOpen[camIdx] = false;
MakeBlankImage(camIdx, "ERROR"); //빈 이미지 설정
PUB.log_[logIdx].AddE("Crevis Error:" + ex.Message);// MessageBox.Show(ex.Message);
}
PUB.flag.set(eFlag.CAMERAINIT, PUB._isCrevisOpen[camIdx], "");
//이미지를 화면에 표시한다.
//ivL.Image = OrgEImage; ivL.ZoomFit();
return PUB._isCrevisOpen[camIdx];
}
void MakeBlankImage(int camIdx, string title = "")
{
PUB._width[camIdx] = 1024;
PUB._height[camIdx] = 768;
if (PUB.mre[camIdx].WaitOne(100))
{
PUB.mre[camIdx].Reset();
PUB.OrgImage[camIdx] = new EImageBW8();
PUB.OrgImage[camIdx].SetSize(PUB._width[camIdx], PUB._height[camIdx]);
PUB.mre[camIdx].Set();
}
}
private void CrevisSetFeature(uint camIdx)
{
Int32 status = VirtualFG40Library.MCAM_ERR_SUCCESS;
var logIdx = camIdx == PUB.setting.CameraIndexL ? 0 : 1;
try
{
// Set Trigger Mode
status = PUB._virtualFG40.SetEnumReg(PUB._hDevice[camIdx], VirtualFG40Library.MCAM_TRIGGER_MODE, VirtualFG40Library.TRIGGER_MODE_OFF);
if (status != VirtualFG40Library.MCAM_ERR_SUCCESS)
{
throw new Exception(String.Format("Write Register failed : {0}", status));
}
// Set PixelFormat
status = PUB._virtualFG40.SetEnumReg(PUB._hDevice[camIdx], VirtualFG40Library.MCAM_PIXEL_FORMAT, VirtualFG40Library.PIXEL_FORMAT_MONO8);
if (status != VirtualFG40Library.MCAM_ERR_SUCCESS)
{
throw new Exception(String.Format("Write Register failed : {0}", status));
}
}
catch (Exception ex)
{
//MessageBox.Show(ex.Message);
PUB.log_[logIdx].AddE(ex.Message);
}
}
//private void SetGrayscalePalette(Bitmap bitmap)
//{
// ColorPalette GrayscalePalette = bitmap.Palette;
// for (int i = 0; i < 255; i++)
// {
// GrayscalePalette.Entries[i] = Color.FromArgb(i, i, i);
// }
// bitmap.Palette = GrayscalePalette;
//}
}
}

View File

@@ -0,0 +1,177 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json.Linq;
using WatsonWebsocket;
namespace Project
{
public partial class fMain
{
public object listlock = new object();
public List<string> ClientList = new List<string>();
private void Ws_Disconnected(object sender, ClientDisconnectedEventArgs e)
{
var ws = sender as Class.WebSocket;
var ip = e.IpPort;
var logIdx = ws.Target == eTarget.Left ? 0 : 1;
PUB.Time_WS_Disconnected[ws.TargetIdx] = DateTime.Now;
PUB.log_[logIdx].AddAT("Host connection terminated");
lock (ClientList)
{
if (ClientList.Contains(ip))
ClientList.Remove(ip);
}
}
private void Ws_Connected(object sender, ClientConnectedEventArgs e)
{
var ws = sender as Class.WebSocket;
var logIdx = ws.Target == eTarget.Left ? 0 : 1;
PUB.Time_WS_Connected[ws.TargetIdx] = DateTime.Now;
PUB.log_[logIdx].AddAT("Host connection completed");
lock (ClientList)
{
if (ClientList.Contains(e.IpPort))
ClientList.Add(e.IpPort);
}
}
void SendStatus(eTarget cam)
{
var camIdx = cam == eTarget.Left ? PUB.setting.CameraIndexL : PUB.setting.CameraIndexR;
var logIdx = cam == eTarget.Left ? 0 : 1;
var camTarget = PUB.GetTarget(camIdx);
if (camTarget == eTarget.None) return;
//데이터 생성
var msg = new
{
command = "status",
camera = PUB._isCrevisOpen[camIdx] ? "1" : "0",
live = PUB.IsLive[camIdx] ? "1" : "0",
stream = PUB.setting.DisableStreamData ? "0" : "1",
listen = PUB.wsock_[logIdx].IsListening ? "1" : "0",
trig = PUB.IsTrigger[camIdx] ? "1" : "0",
license = PUB.VisionLicense ? "1" : "0",
reel = PUB.DetectReel[camIdx] ? "1" : "0",
conv = "0",
};
var json = Newtonsoft.Json.JsonConvert.SerializeObject(msg);
try
{
//PUB.log_[logIdx].Add("상태전송:" + msg);
PUB.lastsendStatus[camIdx] = DateTime.Now;
PUB.Send_WSock(camTarget, json);
//PUB.ws[camIdx].ListClients().ToList().ForEach(t => PUB.ws[camIdx].SendAsync(t, json).Wait());
}
catch (Exception ex)
{
PUB.log_[logIdx].AddE($"(STATUS) send failed {ex.Message}");
}
}
private void Ws_DataArrival(object sender, MessageReceivedEventArgs e)
{
var ws = sender as Class.WebSocket;
var ip = e.IpPort;
var raw = Encoding.UTF8.GetString(e.Data);
var logIdx = ws.Target == eTarget.Left ? 0 : 1;
var camIdx = ws.TargetIdx;
var camTarget = PUB.GetTarget(camIdx);
PUB.log_[logIdx].Add($"Received:{raw}");
PUB.Time_WS_Recv[camIdx] = DateTime.Now;
var jvalue = JObject.Parse(raw);
//데이터 생성
var msg = new
{
guid = jvalue.Value<String>("guid"),
command = jvalue.Value<String>("command"),
data = jvalue.Value<String>("data")
};
if (msg.command == "ON" || msg.command == "BCDIN")
{
PUB.RequestNewRead = true;
PUB.triggerTime[ws.TargetIdx] = DateTime.Now;
PUB.lastguid[ws.TargetIdx] = msg.guid;
PUB.lastcmd[ws.TargetIdx] = msg.command;
PUB.lastdata[ws.TargetIdx] = msg.data;
PUB.lastip[ws.TargetIdx] = e.IpPort;
if (string.IsNullOrEmpty(PUB.lastlogbarcode)) PUB.lastlogbarcode = string.Empty;
PUB.IsTrigger[ws.TargetIdx] = true;
PUB.TriggerStart = DateTime.Now;
PUB.log_[logIdx].Add("Clearing existing data due to barcode GUID reception, value=" + PUB.lastlogbarcode);
PUB.lastlogbarcode = string.Empty; //211206
PUB.parsetime = DateTime.Now;
}
else if (msg.command == "TRIG")
{
PUB.RequestNewRead = true;
PUB.triggerTime[ws.TargetIdx] = DateTime.Now;
PUB.lastguid[ws.TargetIdx] = msg.guid;
PUB.lastcmd[ws.TargetIdx] = msg.command;
PUB.lastdata[ws.TargetIdx] = msg.data;
PUB.lastip[ws.TargetIdx] = e.IpPort;
if (string.IsNullOrEmpty(PUB.lastlogbarcode)) PUB.lastlogbarcode = string.Empty;
PUB.IsTrigger[ws.TargetIdx] = true;
PUB.TriggerStart = DateTime.Now;
PUB.log_[logIdx].Add("Clearing existing data due to barcode GUID reception, value=" + PUB.lastlogbarcode);
PUB.lastlogbarcode = string.Empty; //211206
PUB.parsetime = DateTime.Now;
PUB.IsLive[ws.TargetIdx] = true;
PUB.IsProcess[ws.TargetIdx] = true;
}
else if (msg.command == "LIVEON")
{
PUB.IsLive[ws.TargetIdx] = true;
PUB.log_[logIdx].Add("live on received");
}
else if (msg.command == "LIVEOFF")
{
PUB.IsLive[ws.TargetIdx] = false;
PUB.log_[logIdx].Add("live off received");
}
else if (msg.command == "STREAMOFF")
{
PUB.setting.DisableStreamData = true;
PUB.setting.Save();
}
else if (msg.command == "STREAMON")
{
PUB.setting.DisableStreamData = false;
PUB.setting.Save();
}
else if (msg.command == "OFF")
{
PUB.IsTrigger[ws.TargetIdx] = false;
PUB.log_[logIdx].Add("OFF 수신으로 트리거상태를 해제 합니다");
PUB.IsLive[ws.TargetIdx] = false;
PUB.IsProcess[ws.TargetIdx] = false;
}
else if (msg.command == "STATUS")
{
//나의 상태값을 전송 해야한다
SendStatus(camTarget);
}
else
{
PUB.log_[logIdx].AddAT($"Unknown command({msg.command})");
}
}
}
}

View File

@@ -0,0 +1,145 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using WatsonWebsocket;
namespace Project
{
public partial class fMain
{
DateTime tm1minute = DateTime.Now.AddDays(-1);
DateTime tm5minute = DateTime.Now;
Boolean displayOn = false;
DateTime tmPaint = DateTime.Now;
private void tmDisplay_Tick(object sender, EventArgs e)
{
if (displayOn == false) displayOn = true;
else
{
//Pub.log.AddAT("Display Timer Overlab");// Console.WriteLine("display overlab");
return;
}
//메인화면3초에 한번씩 업데이트한다
var tsPaint = DateTime.Now - tmPaint;
if (tsPaint.TotalSeconds > 3)
{
//panMiniDisplay.Invalidate();
tmPaint = DateTime.Now;
}
//트리거버튼
btTrigL.BackColor = PUB.IsTrigger[PUB.setting.CameraIndexL] ? Color.Lime : SystemColors.Control;
btTrigR.BackColor = PUB.IsTrigger[PUB.setting.CameraIndexR] ? Color.Lime : SystemColors.Control;
//라이브상태표시
if (PUB.setting.CameraIndexL >= 0)
btLiveL.BackColor = PUB.IsLive[PUB.setting.CameraIndexL] ? Color.Lime : SystemColors.Control;
else btLiveL.BackColor = SystemColors.Control;
if (PUB.setting.CameraIndexR >= 0 && PUB.setting.CameraIndexR != PUB.setting.CameraIndexL)
btLiveR.BackColor = PUB.IsLive[PUB.setting.CameraIndexR] ? Color.Lime : SystemColors.Control;
else btLiveR.BackColor = SystemColors.Control;
//프로세스버튼
btProcessL.BackColor = PUB.IsProcess[PUB.setting.CameraIndexL] ? Color.Lime : SystemColors.Control;
btProcessR.BackColor = PUB.IsProcess[PUB.setting.CameraIndexR] ? Color.Lime : SystemColors.Control;
//데이터정보
lbGuidL.Text = $"GUID : {PUB.lastguid[PUB.setting.CameraIndexL]}";
lbGuidR.Text = $"GUID : {PUB.lastguid[PUB.setting.CameraIndexR]}";
lbTimeL.Text = $"TIME : " + PUB.Time_WS_Recv[PUB.setting.CameraIndexL].ToString("yyyy-MM-dd HH:mm:ss.fff");
lbTimeR.Text = $"TIME : " + PUB.Time_WS_Recv[PUB.setting.CameraIndexR].ToString("yyyy-MM-dd HH:mm:ss.fff");
lbDataL.Text = $"DATA : " + PUB.lastdata[PUB.setting.CameraIndexL];
lbDataR.Text = $"DATA : " + PUB.lastdata[PUB.setting.CameraIndexR];
lbproctimel.Text = $"(Analysis {PUB.ProcessTime[PUB.setting.CameraIndexL]}ms)";
lbproctimer.Text = $"(Analysis {PUB.ProcessTime[PUB.setting.CameraIndexR]}ms)";
label1.Text = $"STAT: {PUB.lastsendStatus[PUB.setting.CameraIndexL].ToString("HH:mm:ss.fff")}";
label8.Text = $"STAT : {PUB.lastsendStatus[PUB.setting.CameraIndexR].ToString("HH:mm:ss.fff")}";
label2.Text = $"SEND: {PUB.lastsend[PUB.setting.CameraIndexL].ToString("HH:mm:ss.fff")}";
label9.Text = $"SEND : {PUB.lastsend[PUB.setting.CameraIndexR].ToString("HH:mm:ss.fff")}";
//sbMemMapL.ForeColor = swplc[PUB.setting.CameraIndexL].Init ? Color.Lime : Color.Red;
//sbMemMapR.ForeColor = swplc[PUB.setting.CameraIndexR].Init ? Color.Lime : Color.Red;
if (PUB.setting.CameraIndexL >= 0)
{
sbConnCamL.ForeColor = PUB._isCrevisOpen[PUB.setting.CameraIndexL] ? Color.Green : Color.Red;
sbLiveL.ForeColor = PUB.IsLive[PUB.setting.CameraIndexL] ? Color.Green : Color.Red;
sbDetectReelL.ForeColor = PUB.DetectReel[PUB.setting.CameraIndexL] ? Color.Lime : Color.Black;
sbDetectCVL.ForeColor = PUB.DetectConv[PUB.setting.CameraIndexL] ? Color.Lime : Color.Black;
sbTrigL.ForeColor = PUB.IsTrigger[PUB.setting.CameraIndexL] ? Color.Green : Color.Red;
}
else
{
var c = Color.DimGray;
sbConnCamL.ForeColor =c;
sbLiveL.ForeColor =c;
sbDetectReelL.ForeColor =c;
sbDetectCVL.ForeColor =c;
sbTrigL.ForeColor = c;
}
if (PUB.setting.CameraIndexR >= 0)
{
sbConnCamR.ForeColor = PUB._isCrevisOpen[PUB.setting.CameraIndexR] ? Color.Green : Color.Red;
sbLiveR.ForeColor = PUB.IsLive[PUB.setting.CameraIndexR] ? Color.Green : Color.Red;
sbDetectReelR.ForeColor = PUB.DetectReel[PUB.setting.CameraIndexR] ? Color.Lime : Color.Black;
sbDetectCVR.ForeColor = PUB.DetectConv[PUB.setting.CameraIndexR] ? Color.Lime : Color.Black;
sbTrigR.ForeColor = PUB.IsTrigger[PUB.setting.CameraIndexR] ? Color.Green : Color.Red;
}
else
{
var c = Color.DimGray;
sbConnCamR.ForeColor = c;
sbLiveR.ForeColor = c;
sbDetectReelR.ForeColor = c;
sbDetectCVR.ForeColor = c;
sbTrigR.ForeColor = c;
}
sbConnHostL.ForeColor = PUB.wsock_[0].ListClients().Count() > 0 ? Color.Green : Color.Red;
sbConnHostR.ForeColor = PUB.wsock_[1].ListClients().Count() > 0 ? Color.Green : Color.Red;
sbStream.ForeColor = PUB.setting.DisableStreamData ? Color.Red : Color.Green;
sbListenL.ForeColor = PUB.wsock_[0].IsListening ? Color.Green : Color.Red;
sbListenR.ForeColor = PUB.wsock_[1].IsListening ? Color.Green : Color.Red;
sbLicense.ForeColor = PUB.VisionLicense ? Color.Green : Color.Red;
#region retgion"1분 time 루틴"
var ts = DateTime.Now - tm1minute;
if (ts.TotalMinutes >= 1)
{
//리셋카운트
tm1minute = DateTime.Now;
}
#endregion
#region retgion"5분 time 루틴"
ts = DateTime.Now - tm5minute;
if (ts.TotalMinutes >= 5)
{
//남은디스크확인
tm5minute = DateTime.Now;
}
#endregion
//wat.Stop();
//Console.WriteLine("disp time : " + wat.ElapsedMilliseconds.ToString() + "ms");
displayOn = false;
}
}
}