파일정리
This commit is contained in:
414
HMI/SubProject/AGV/Command.cs
Normal file
414
HMI/SubProject/AGV/Command.cs
Normal file
@@ -0,0 +1,414 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.ComponentModel;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Collections;
|
||||
using COMM;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using AR;
|
||||
|
||||
namespace arDev
|
||||
{
|
||||
public enum eNarumiTurn
|
||||
{
|
||||
None = 0,
|
||||
LeftIng,
|
||||
Left,
|
||||
RightIng,
|
||||
Right,
|
||||
}
|
||||
public class NarumiTurnInfo
|
||||
{
|
||||
public DateTime Start { get; set; }
|
||||
public DateTime End { get; set; }
|
||||
public TimeSpan Runtime
|
||||
{
|
||||
get
|
||||
{
|
||||
if (End.Year < 2000) return DateTime.Now - Start;
|
||||
if (End < Start) return DateTime.Now - Start;
|
||||
else return End - Start;
|
||||
}
|
||||
}
|
||||
public eNarumiTurn State { get; set; }
|
||||
public NarumiTurnInfo()
|
||||
{
|
||||
Start = new DateTime(1982, 11, 23);
|
||||
End = new DateTime(1982, 11, 23);
|
||||
State = eNarumiTurn.None;
|
||||
}
|
||||
}
|
||||
public class NarumiCommandTime
|
||||
{
|
||||
public DateTime Time { get; set; }
|
||||
public ushort count { get; set; }
|
||||
public NarumiCommandTime(ushort cnt)
|
||||
{
|
||||
Time = DateTime.Now;
|
||||
this.count = cnt;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// error 이상은모두 처리불가한 오류 조건을 의미한다
|
||||
/// </summary>
|
||||
public enum eNarumiCommandResult : byte
|
||||
{
|
||||
Fail = 0,
|
||||
Success = 1,
|
||||
Wait = 2,
|
||||
Error = 100,
|
||||
Timeout,
|
||||
|
||||
}
|
||||
public partial class Narumi
|
||||
{
|
||||
public NarumiTurnInfo TurnInformation { get; set; } = null;
|
||||
Dictionary<string, NarumiCommandTime> SendCommandFailList { get; set; } = new Dictionary<string, NarumiCommandTime>();
|
||||
|
||||
public eNarumiCommandResult AGVMoveSet(BunkiData opt)
|
||||
{
|
||||
var param = opt.ToString();
|
||||
return AddCommand(eAgvCmd.MoveSet, param);
|
||||
}
|
||||
|
||||
public eNarumiCommandResult AGVMoveManual(ManulOpt opt, Speed spd, Sensor ss)
|
||||
{
|
||||
var param = opt.ToString() + spd.ToString()[0] + ((int)ss).ToString();
|
||||
return AddCommand(eAgvCmd.ManualMove, param);
|
||||
}
|
||||
public eNarumiCommandResult AGVMoveRun(eRunOpt opt = eRunOpt.NotSet)
|
||||
{
|
||||
System.Text.StringBuilder sb = new StringBuilder();
|
||||
if (opt == eRunOpt.Backward) sb.Append("B");
|
||||
else if (opt == eRunOpt.Forward) sb.Append("F");
|
||||
else sb.Append("0");
|
||||
sb.Append("000");
|
||||
return AddCommand(eAgvCmd.MoveStart, sb.ToString());
|
||||
}
|
||||
|
||||
public eNarumiCommandResult AGVSetSpeed(eSetSpeed item, int speed)
|
||||
{
|
||||
string cmd = "SS";
|
||||
if (item == eSetSpeed.Rotation) cmd = "SRS";
|
||||
else cmd += item.ToString()[0];
|
||||
cmd += speed.ToString("0000");
|
||||
return AddCommand(cmd);
|
||||
}
|
||||
public eNarumiCommandResult AGVMoveStop(string Reason, eStopOpt opt = eStopOpt.Stop)
|
||||
{
|
||||
System.Text.StringBuilder sb = new StringBuilder();
|
||||
if (opt == eStopOpt.MarkStop) sb.Append("MS");
|
||||
else if (opt == eStopOpt.MarkRotateLeft) sb.Append("TL");
|
||||
else if (opt == eStopOpt.MarkRotateRight) sb.Append("TR");
|
||||
else if (opt == eStopOpt.MarkChangeDirection) sb.Append("BS");
|
||||
else sb.Append("0S");
|
||||
sb.Append("00");
|
||||
sb.Append("0000"); //재기동시간
|
||||
|
||||
//동작중이면 이 멈춤 명령을 기록으로 남긴다 230116
|
||||
if (this.system1.agv_run)
|
||||
RaiseMessage(MessageType.Normal, $"stop command from {Reason}");
|
||||
var retval = AddCommand(eAgvCmd.MoveStop, sb.ToString());
|
||||
//if (retval == eNarumiCommandResult.Success && opt == eStopOpt.MarkStop)
|
||||
// VAR.BOOL[eVarBool.NEXTSTOP_MARK] = true;
|
||||
|
||||
return retval;
|
||||
}
|
||||
public eNarumiCommandResult AGVCommand(string cmd, string data)
|
||||
{
|
||||
return AddCommand(cmd + data);
|
||||
}
|
||||
|
||||
public eNarumiCommandResult LiftControl(LiftCommand cmd)
|
||||
{
|
||||
return AddCommand(eAgvCmd.LiftControl, cmd.ToString());
|
||||
}
|
||||
public eNarumiCommandResult AGVCharge(int chargetID, bool on, int waittime = 3)
|
||||
{
|
||||
if (on)
|
||||
return AddCommand(eAgvCmd.ChargeOn, chargetID.ToString("0000"));
|
||||
else
|
||||
return AddCommand(eAgvCmd.ChargeOf, chargetID.ToString("0000"));
|
||||
}
|
||||
public eNarumiCommandResult SetBackturnTime(int time)
|
||||
{
|
||||
return AddCommand(eAgvCmd.BackTrunResumeTime, time.ToString("0000"));
|
||||
}
|
||||
public eNarumiCommandResult SetGateOutOffTime(int time)
|
||||
{
|
||||
return AddCommand(eAgvCmd.GateoutTime, time.ToString("0000"));
|
||||
}
|
||||
|
||||
public eNarumiCommandResult TurnGDSCenterScope(UInt16 time)
|
||||
{
|
||||
if (time > 2000) time = 2000;
|
||||
return AddCommand(eAgvCmd.TurnGDSCenterScope, time.ToString("0000"));
|
||||
}
|
||||
public eNarumiCommandResult AGVMoveLeft180Turn()
|
||||
{
|
||||
return AddCommand(eAgvCmd.TurnLeft);
|
||||
}
|
||||
public eNarumiCommandResult AGVMoveRight180Turn()
|
||||
{
|
||||
return AddCommand(eAgvCmd.TurnRight);
|
||||
}
|
||||
public eNarumiCommandResult AGVMoveBack180Turn(bool leftTurn)
|
||||
{
|
||||
var dir = leftTurn ? "L" : "R";
|
||||
return AddCommand(eAgvCmd.BackAndTurn, dir);
|
||||
}
|
||||
|
||||
public eNarumiCommandResult AGVErrorReset()
|
||||
{
|
||||
return AddCommand(eAgvCmd.ErrorReset, "FFFF");
|
||||
}
|
||||
public eNarumiCommandResult AGVTowerLamp(bool on)
|
||||
{
|
||||
return AddCommand(eAgvCmd.TowerLamp, (on ? "I" : "O"));
|
||||
}
|
||||
public eNarumiCommandResult AGVSetAddress(int value)
|
||||
{
|
||||
return AddCommand($"SAD{value:0000}");
|
||||
}
|
||||
public eNarumiCommandResult AGVSetPanID(string value)
|
||||
{
|
||||
value = value.PadLeft(4, '0');
|
||||
return AddCommand($"SPN{value}");
|
||||
}
|
||||
public eNarumiCommandResult AGVSetChannel(string value)
|
||||
{
|
||||
value = value.PadLeft(4, '0');
|
||||
return AddCommand($"SCH{value}");
|
||||
}
|
||||
|
||||
public eNarumiCommandResult AGVSetTagReinputTime(int value)
|
||||
{
|
||||
return AddCommand($"STT{value:0000}");
|
||||
}
|
||||
|
||||
///// <summary>
|
||||
///// 전송에 성공한 명령시간
|
||||
///// </summary>
|
||||
////public Dictionary<String, DateTime> LastCommandOKTime { get; set; }
|
||||
protected bool SendCommand(string cmdline)
|
||||
{
|
||||
bool ret = true;
|
||||
ACKData = string.Empty;
|
||||
var fullcmd = MakeCheckSum(cmdline);
|
||||
if (WriteData(fullcmd) == false) ret = false;
|
||||
System.Threading.Thread.Sleep(1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ManualResetEvent mrecmd = new ManualResetEvent(true);
|
||||
public eNarumiCommandResult AddCommand(string cmd, int waitms = 1)
|
||||
{
|
||||
if (mrecmd.WaitOne(waitms) == false)
|
||||
{
|
||||
//다른명령을 처리하는 중이므로 대기상태로 반환한다
|
||||
return eNarumiCommandResult.Wait;
|
||||
}
|
||||
|
||||
//다른신호를 처리하지 못하게한다.
|
||||
mrecmd.Reset();
|
||||
|
||||
try
|
||||
{
|
||||
if (SendCommandFailList.ContainsKey(cmd) == false)
|
||||
{
|
||||
//실패기록이 없다
|
||||
var ret = SendCommand(cmd);
|
||||
if (ret == false)
|
||||
{
|
||||
SendCommandFailList.Add(cmd, new NarumiCommandTime(1));
|
||||
return eNarumiCommandResult.Fail;
|
||||
}
|
||||
else return eNarumiCommandResult.Success;
|
||||
}
|
||||
else
|
||||
{
|
||||
//실패기록이 존재한다.
|
||||
//1.동일 명령이 아니면 바로 전송한다
|
||||
var precmd = SendCommandFailList[cmd];
|
||||
|
||||
//동일명령의 실패기록이 존재한다.
|
||||
//2초간의 간격을 둔다
|
||||
var ts = DateTime.Now - precmd.Time;
|
||||
if (ts.TotalSeconds < 2)
|
||||
{
|
||||
precmd.Time = DateTime.Now;
|
||||
SendCommandFailList[cmd] = precmd;
|
||||
return eNarumiCommandResult.Wait; //대기한다
|
||||
}
|
||||
else
|
||||
{
|
||||
//오류가 누적되었다.
|
||||
var ret = SendCommand(cmd);
|
||||
if (ret == false)
|
||||
{
|
||||
precmd.Time = DateTime.Now;
|
||||
precmd.count += 1;
|
||||
SendCommandFailList[cmd] = precmd;
|
||||
|
||||
//5회연속 실패했다면 타임아웃처리한다
|
||||
if (precmd.count > 5)
|
||||
{
|
||||
//타임아웃
|
||||
return eNarumiCommandResult.Timeout;
|
||||
}
|
||||
else
|
||||
{
|
||||
//실패
|
||||
return eNarumiCommandResult.Fail;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//전송이성공했으니 키를 제거한다.
|
||||
SendCommandFailList.Remove(cmd);
|
||||
return eNarumiCommandResult.Success;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"narumi addCommand error : {ex.Message}");
|
||||
return eNarumiCommandResult.Error;
|
||||
}
|
||||
finally
|
||||
{
|
||||
mrecmd.Set();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected eNarumiCommandResult AddCommand(eAgvCmd command, BunkiData param)
|
||||
{
|
||||
return AddCommand(command, param.ToString());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// CBR커맨드를 사용하여 옵션값을 전송 합니다
|
||||
/// 11.분기명령 = CBR
|
||||
/// </summary>
|
||||
/// <param name="param"></param>
|
||||
/// <param name="Repeat"></param>
|
||||
protected eNarumiCommandResult AddCommand(BunkiData param)
|
||||
{
|
||||
return AddCommand(eAgvCmd.MoveSet, param.ToString());
|
||||
}
|
||||
|
||||
protected eNarumiCommandResult AddCommand(eAgvCmd command, string param = "")
|
||||
{
|
||||
string cmdString;
|
||||
eNarumiCommandResult retval = eNarumiCommandResult.Error;
|
||||
switch (command)
|
||||
{
|
||||
case eAgvCmd.ErrorReset:
|
||||
cmdString = $"SFR{param}";
|
||||
retval = AddCommand(cmdString);
|
||||
break;
|
||||
case eAgvCmd.TowerLamp:
|
||||
cmdString = $"CBZ" + $"0299{param}0000";
|
||||
retval = AddCommand(cmdString);
|
||||
break;
|
||||
case eAgvCmd.MoveStop:
|
||||
cmdString = $"CST{param}";
|
||||
system1.agv_run_manual = false;
|
||||
retval = AddCommand(cmdString);
|
||||
break;
|
||||
case eAgvCmd.MoveStart:
|
||||
cmdString = $"CRN{param}";
|
||||
retval = AddCommand(cmdString);
|
||||
break;
|
||||
|
||||
case eAgvCmd.ChargeOf:
|
||||
cmdString = $"CBT{param}O0003"; ///0003=충전대기시간
|
||||
retval = AddCommand(cmdString);
|
||||
RaiseMessage(NarumiSerialComm.MessageType.Normal, "충전취소전송");
|
||||
break;
|
||||
case eAgvCmd.ChargeOn:
|
||||
cmdString = $"CBT{param}I0003"; ///0003=충전대기시간
|
||||
retval = AddCommand(cmdString);
|
||||
RaiseMessage(NarumiSerialComm.MessageType.Normal, "충전명령전송");
|
||||
break;
|
||||
|
||||
case eAgvCmd.TurnLeft:
|
||||
cmdString = $"CTL0000";
|
||||
retval = AddCommand(cmdString);
|
||||
if (retval == eNarumiCommandResult.Success)
|
||||
{
|
||||
if (TurnInformation == null) TurnInformation = new NarumiTurnInfo();
|
||||
TurnInformation.Start = DateTime.Now;
|
||||
TurnInformation.End = new DateTime(1982, 11, 23);
|
||||
TurnInformation.State = eNarumiTurn.LeftIng;
|
||||
}
|
||||
break;
|
||||
case eAgvCmd.TurnRight:
|
||||
cmdString = $"CTR0000";
|
||||
retval = AddCommand(cmdString);
|
||||
if (retval == eNarumiCommandResult.Success)
|
||||
{
|
||||
if (TurnInformation == null) TurnInformation = new NarumiTurnInfo();
|
||||
TurnInformation.Start = DateTime.Now;
|
||||
TurnInformation.End = new DateTime(1982, 11, 23);
|
||||
TurnInformation.State = eNarumiTurn.RightIng;
|
||||
}
|
||||
break;
|
||||
case eAgvCmd.BackAndTurn:
|
||||
if (param.isEmpty()) param = "L";
|
||||
cmdString = $"CTB000{param}";
|
||||
retval = AddCommand(cmdString);
|
||||
break;
|
||||
case eAgvCmd.CallCancle:
|
||||
cmdString = $"CCL0{param}010000";
|
||||
retval = AddCommand(cmdString);
|
||||
break;
|
||||
|
||||
|
||||
case eAgvCmd.MoveSet:
|
||||
cmdString = $"CBR{param}";
|
||||
retval = AddCommand(cmdString);
|
||||
break;
|
||||
case eAgvCmd.ManualMove:
|
||||
system1.agv_run_manual = true;
|
||||
cmdString = $"CRT{param}";
|
||||
retval = AddCommand(cmdString);
|
||||
break;
|
||||
|
||||
case eAgvCmd.LiftControl:
|
||||
cmdString = "CLF" + param.PadRight(6, '0');
|
||||
retval = AddCommand(cmdString);
|
||||
break;
|
||||
|
||||
case eAgvCmd.CPUReset:
|
||||
cmdString = "CRS0000";
|
||||
retval = AddCommand(cmdString);
|
||||
break;
|
||||
case eAgvCmd.TurnGDSCenterScope:
|
||||
if (param.isEmpty()) param = "1000";
|
||||
cmdString = $"SGS{param}";
|
||||
retval = AddCommand(cmdString);
|
||||
break;
|
||||
case eAgvCmd.BackTrunResumeTime:
|
||||
cmdString = $"SST{param}";
|
||||
retval = AddCommand(cmdString);
|
||||
break;
|
||||
case eAgvCmd.GateoutTime:
|
||||
cmdString = $"SGT{param}";
|
||||
retval = AddCommand(cmdString);
|
||||
break;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
19
HMI/SubProject/AGV/DataEventArgs.cs
Normal file
19
HMI/SubProject/AGV/DataEventArgs.cs
Normal file
@@ -0,0 +1,19 @@
|
||||
using System;
|
||||
|
||||
namespace arDev
|
||||
{
|
||||
public partial class Narumi
|
||||
{
|
||||
public class DataEventArgs : EventArgs
|
||||
{
|
||||
public DataType DataType { get; set; }
|
||||
|
||||
public DataEventArgs(DataType type)
|
||||
{
|
||||
DataType = type;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
69
HMI/SubProject/AGV/Dataframe.cs
Normal file
69
HMI/SubProject/AGV/Dataframe.cs
Normal file
@@ -0,0 +1,69 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using AR;
|
||||
|
||||
namespace arDev
|
||||
{
|
||||
public partial class Narumi
|
||||
{
|
||||
public class Dataframe
|
||||
{
|
||||
public byte STX { get; private set; }
|
||||
public byte ETX { get; private set; }
|
||||
public byte[] Data { get; private set; }
|
||||
public string DataString { get; private set; }
|
||||
public byte[] checksum { get; private set; } = new byte[2];
|
||||
public bool Valid { get; private set; } = false;
|
||||
public string Message { get; private set; } = string.Empty;
|
||||
public byte[] Buffer { get; private set; }
|
||||
public string Cmd { get; private set; } = string.Empty;
|
||||
|
||||
public bool Parse(byte[] data, int MinRecvLength = 0)
|
||||
{
|
||||
if (data == null || data.Any() == false)
|
||||
{
|
||||
this.Message = string.Format("수신 데이터가 없습니다");
|
||||
return false;
|
||||
}
|
||||
else if (data.Length < 5)
|
||||
{
|
||||
this.Message = $"데이터의 길이가 5보다 작습니다 길이={data.Length}";
|
||||
return false;
|
||||
}
|
||||
else if (MinRecvLength > 0 && data.Length < MinRecvLength)
|
||||
{
|
||||
this.Message = $"데이터의 길이가 {MinRecvLength}보다 작습니다 길이={data.Length}";
|
||||
return false;
|
||||
}
|
||||
else if (data[0] != 0x02 || data[data.Length - 1] != 0x03)
|
||||
{
|
||||
this.Message = $"STX/ETX Error";
|
||||
return false;
|
||||
}
|
||||
Buffer = new byte[data.Length];
|
||||
Array.Copy(data, Buffer, data.Length);
|
||||
STX = data[0];
|
||||
ETX = data[data.Length - 1];
|
||||
Array.Copy(data, data.Length - 3, checksum, 0, 2);
|
||||
|
||||
Data = new byte[data.Length - 4];
|
||||
Array.Copy(data, 1, Data, 0, data.Length - 4);
|
||||
|
||||
if (data.Length > 2) Cmd = System.Text.Encoding.Default.GetString(Data, 0, 3);
|
||||
|
||||
this.DataString = System.Text.Encoding.Default.GetString(Data);
|
||||
|
||||
|
||||
Valid = true;
|
||||
return true;
|
||||
}
|
||||
public Dataframe(byte[] buffer = null, int minlen = 0)
|
||||
{
|
||||
if (buffer != null) Parse(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
221
HMI/SubProject/AGV/EnumData.cs
Normal file
221
HMI/SubProject/AGV/EnumData.cs
Normal file
@@ -0,0 +1,221 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace arDev
|
||||
{
|
||||
public partial class Narumi
|
||||
{
|
||||
public enum eMoveDir
|
||||
{
|
||||
Forward,
|
||||
Backward,
|
||||
}
|
||||
public enum eMoveSpd
|
||||
{
|
||||
High,
|
||||
Mid,
|
||||
Low,
|
||||
}
|
||||
public enum eSetPIDSpeed
|
||||
{
|
||||
High,
|
||||
Middle,
|
||||
Low,
|
||||
Stop,
|
||||
}
|
||||
public enum eSetSpeed
|
||||
{
|
||||
High,
|
||||
Middle,
|
||||
Low,
|
||||
Stop,
|
||||
Rotation,
|
||||
}
|
||||
public enum eBunki
|
||||
{
|
||||
Right,
|
||||
Strate,
|
||||
Left,
|
||||
}
|
||||
|
||||
public enum Messagetype
|
||||
{
|
||||
Normal,
|
||||
Error,
|
||||
Send,
|
||||
Recv,
|
||||
}
|
||||
public enum DataType
|
||||
{
|
||||
UNKNOWN,
|
||||
TAG,
|
||||
CALL,
|
||||
STS,
|
||||
ACK,
|
||||
NAK,
|
||||
CCA,
|
||||
}
|
||||
public class BunkiData
|
||||
{
|
||||
public BunkiData()
|
||||
{
|
||||
|
||||
}
|
||||
public BunkiData(char dir, char bunki, char speed)
|
||||
{
|
||||
if (dir == 'F') Direction = eMoveDir.Forward;
|
||||
else if (dir == 'B') Direction = eMoveDir.Backward;
|
||||
|
||||
if (bunki == 'S') Bunki = eBunki.Strate;
|
||||
else if (bunki == 'L') Bunki = eBunki.Left;
|
||||
else if (bunki == 'R') Bunki = eBunki.Right;
|
||||
|
||||
if (speed == 'H') this.Speed = eMoveSpd.High;
|
||||
else if (speed == 'M') this.Speed = eMoveSpd.Mid;
|
||||
else if (speed == 'L') this.Speed = eMoveSpd.Low;
|
||||
}
|
||||
public eMoveDir Direction { get; set; } = eMoveDir.Forward;
|
||||
public eBunki Bunki { get; set; } = eBunki.Strate;
|
||||
public eMoveSpd Speed { get; set; } = eMoveSpd.Mid;
|
||||
public int PBSSensor { get; set; } = 1;
|
||||
public override string ToString()
|
||||
{
|
||||
System.Text.StringBuilder sb = new StringBuilder();
|
||||
sb.Append(Direction.ToString()[0]);
|
||||
sb.Append(Bunki.ToString()[0]);
|
||||
sb.Append(Speed.ToString()[0]);
|
||||
sb.Append(PBSSensor.ToString()[0]);
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
public enum eAgvCmd
|
||||
{
|
||||
/// <summary>
|
||||
/// 충전시작
|
||||
/// CMD : CBT02{nBatteryNo}I0103
|
||||
/// </summary>
|
||||
ChargeOn,
|
||||
|
||||
/// <summary>
|
||||
/// 충전취소
|
||||
/// CMD : CBT02{nBatteryNo}O0103
|
||||
/// </summary>
|
||||
ChargeOf,
|
||||
|
||||
/// <summary>
|
||||
/// 이동명령(파라미터필요)
|
||||
/// 이동대상,속도(H,M,L),센서사용여부(1,0)
|
||||
/// ex) BSLTH0
|
||||
/// CMD : CRT{param}
|
||||
/// </summary>
|
||||
ManualMove,
|
||||
|
||||
/// <summary>
|
||||
/// 기동명령
|
||||
/// CMD : CRN0000
|
||||
/// </summary>
|
||||
MoveStart,
|
||||
|
||||
/// <summary>
|
||||
/// 분기명령
|
||||
/// CMD : CBR{param}
|
||||
/// </summary>
|
||||
MoveSet,
|
||||
|
||||
/// <summary>
|
||||
/// 정지 명령
|
||||
/// CMD : CST0S000000
|
||||
/// </summary>
|
||||
MoveStop,
|
||||
|
||||
/// <summary>
|
||||
/// 콜 취소,
|
||||
/// Param : 번호 char(1)
|
||||
/// CMD : CCL0{param}010000
|
||||
/// </summary>
|
||||
CallCancle,
|
||||
|
||||
/// <summary>
|
||||
/// CMD : CTL0000
|
||||
/// </summary>
|
||||
TurnLeft,
|
||||
|
||||
/// <summary>
|
||||
/// CMD : CTR0000
|
||||
/// </summary>
|
||||
TurnRight,
|
||||
|
||||
/// <summary>
|
||||
/// CMD : CTB0000
|
||||
/// </summary>
|
||||
BackAndTurn,
|
||||
|
||||
/// <summary>
|
||||
/// CMD : CBZ
|
||||
/// </summary>
|
||||
TowerLamp,
|
||||
|
||||
/// <summary>
|
||||
/// CMD : SFR
|
||||
/// </summary>
|
||||
ErrorReset,
|
||||
|
||||
/// <summary>
|
||||
/// CMD : CLF
|
||||
/// </summary>
|
||||
LiftControl,
|
||||
|
||||
/// <summary>
|
||||
/// SS(H/M/L/S)
|
||||
/// SRS
|
||||
/// </summary>
|
||||
SetSpeed,
|
||||
|
||||
CPUReset,
|
||||
|
||||
TurnGDSCenterScope,
|
||||
|
||||
BackTrunResumeTime,
|
||||
GateoutTime,
|
||||
|
||||
}
|
||||
public enum eForm
|
||||
{
|
||||
DriveControl,
|
||||
ManualControl,
|
||||
RouteSelect,
|
||||
Setting,
|
||||
ModeChange,
|
||||
}
|
||||
public enum eNotify
|
||||
{
|
||||
ReadTag,
|
||||
IpAddresschanged,
|
||||
NameChanged,
|
||||
ReadViewStep,
|
||||
ReadViewCall,
|
||||
WatchError,
|
||||
|
||||
/// <summary>
|
||||
/// 통신에서받은 AGV의 상태값이며, 속도 진행 방향을 가지고 있음
|
||||
/// Dashboardform 하단에 상태 표시 함
|
||||
/// </summary>
|
||||
StatusDisplay,
|
||||
StatusComm,
|
||||
StatusRiv,
|
||||
StatusETC,
|
||||
|
||||
ChangeMode,
|
||||
/// <summary>
|
||||
/// 편집대상경로는 아래 변수에 저장되어잇음
|
||||
/// datamanager.sEditrRoute
|
||||
/// </summary>
|
||||
EditRoute,
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
69
HMI/SubProject/AGV/NARUMI.csproj
Normal file
69
HMI/SubProject/AGV/NARUMI.csproj
Normal file
@@ -0,0 +1,69 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{8BAE0EAC-3D25-402F-9A65-2BA1ECFE28B7}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>arDevice</RootNamespace>
|
||||
<AssemblyName>Narumi</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<Deterministic>true</Deterministic>
|
||||
<TargetFrameworkProfile />
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="arCommUtil">
|
||||
<HintPath>..\..\..\DLL\arCommUtil.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="DataEventArgs.cs" />
|
||||
<Compile Include="Dataframe.cs" />
|
||||
<Compile Include="EnumData.cs" />
|
||||
<Compile Include="Command.cs" />
|
||||
<Compile Include="NarumiSerialComm.cs" />
|
||||
<Compile Include="Structure\ErrorFlag.cs" />
|
||||
<Compile Include="Narumi.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Structure\SystemFlag0.cs" />
|
||||
<Compile Include="Structure\AgvData.cs" />
|
||||
<Compile Include="Structure\Signals.cs" />
|
||||
<Compile Include="Structure\SystemFlag1.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\CommData\CommData.csproj">
|
||||
<Project>{14e8c9a5-013e-49ba-b435-efefc77dd623}</Project>
|
||||
<Name>CommData</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
||||
519
HMI/SubProject/AGV/Narumi.cs
Normal file
519
HMI/SubProject/AGV/Narumi.cs
Normal file
@@ -0,0 +1,519 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.ComponentModel;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Collections;
|
||||
using COMM;
|
||||
using AR;
|
||||
using System.Xml;
|
||||
|
||||
namespace arDev
|
||||
{
|
||||
public partial class Narumi : arDev.NarumiSerialComm
|
||||
{
|
||||
Hashtable SystemCheck, ErrorCheck;
|
||||
private Queue Errlog; // 에러발생시 코드 임시 저장용(쓰레드 동기화용)
|
||||
|
||||
public int nBatteryNo { get; set; } = 0;
|
||||
|
||||
public Narumi()
|
||||
{
|
||||
SystemCheck = new Hashtable();
|
||||
SystemCheck.Add(15, "100");
|
||||
SystemCheck.Add(14, "9");
|
||||
SystemCheck.Add(13, "8");
|
||||
SystemCheck.Add(12, "53");
|
||||
SystemCheck.Add(11, "3");
|
||||
//SystemCheck.Add(10, "66");
|
||||
//SystemCheck.Add(9, "56");
|
||||
SystemCheck.Add(8, "6");
|
||||
SystemCheck.Add(7, "5");
|
||||
SystemCheck.Add(6, "60");
|
||||
SystemCheck.Add(5, "1");
|
||||
SystemCheck.Add(4, "2");
|
||||
//SystemCheck.Add(3, "65");
|
||||
//SystemCheck.Add(2, "55");
|
||||
//SystemCheck.Add(1, "11");
|
||||
//SystemCheck.Add(0, "22");
|
||||
|
||||
ErrorCheck = new Hashtable();
|
||||
ErrorCheck.Add(15, "17");
|
||||
ErrorCheck.Add(14, "15");
|
||||
ErrorCheck.Add(13, "18");
|
||||
ErrorCheck.Add(12, "19");
|
||||
//ErrorCheck.Add(11, "300");
|
||||
ErrorCheck.Add(10, "299");
|
||||
ErrorCheck.Add(9, "298");
|
||||
ErrorCheck.Add(8, "297");
|
||||
ErrorCheck.Add(7, "296");
|
||||
//ErrorCheck.Add(6,"");
|
||||
ErrorCheck.Add(5, "12");
|
||||
ErrorCheck.Add(4, "13");
|
||||
ErrorCheck.Add(3, "14");
|
||||
ErrorCheck.Add(2, "16");
|
||||
ErrorCheck.Add(1, "11");
|
||||
ErrorCheck.Add(0, "10");
|
||||
|
||||
Errlog = new Queue();
|
||||
MinRecvLength = 4;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
#region "External Events"
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 분석완료된 데이터 이벤트
|
||||
/// </summary>
|
||||
public event EventHandler<DataEventArgs> DataReceive;
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
protected override bool CustomParser(byte[] buf, out byte[] remainBuffer)
|
||||
{
|
||||
List<byte> remain = new List<byte>();
|
||||
|
||||
//데이터는 총 34byt 이며 , DD~77로 구성됨
|
||||
Boolean bComplete = false;
|
||||
for (int i = 0; i < buf.Length; i++)
|
||||
{
|
||||
var incomByte = buf[i];
|
||||
if (bComplete == true)
|
||||
{
|
||||
remain.Add(incomByte);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (incomByte == 0x02)
|
||||
{
|
||||
findSTX = true;
|
||||
tempBuffer.Clear();
|
||||
tempBuffer.Add(incomByte);
|
||||
}
|
||||
else if (incomByte == 0x03)
|
||||
{
|
||||
//데이터가 맞게 수신됨
|
||||
//tempBuffer.Add(incomByte);
|
||||
tempBuffer.Add(incomByte);
|
||||
findSTX = false;
|
||||
bComplete = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
tempBuffer.Add(incomByte);
|
||||
if (tempBuffer.Count == 150) //data overload
|
||||
{
|
||||
findSTX = false;
|
||||
tempBuffer.Clear();
|
||||
bComplete = false;
|
||||
RaiseMessage(MessageType.Error, "Buffer Over");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
remainBuffer = remain.ToArray();
|
||||
return bComplete;
|
||||
}
|
||||
|
||||
public override bool ProcessRecvData(byte[] data)
|
||||
{
|
||||
//LastReceiveBuffer
|
||||
var frame = new Dataframe(data, MinRecvLength);
|
||||
if (frame.Valid == false)
|
||||
{
|
||||
RaiseMessage(MessageType.Error, frame.Message);
|
||||
return false;
|
||||
}
|
||||
else if (frame.DataString.StartsWith("$") == false && CheckSum(data) == false)
|
||||
{
|
||||
RaiseMessage(MessageType.Error, "Checksum Error MSG=" + frame.DataString);
|
||||
return false;
|
||||
}
|
||||
|
||||
var retval = true;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
if (frame.Cmd.Equals("ACK") || frame.Cmd.Equals("NAK"))
|
||||
{ // 응답확인값 수신 : Header(ACX), Length(9), CheckSum 확인
|
||||
RevACK(frame);
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
else if (frame.Cmd.Equals("STS"))
|
||||
{ // AGV 상태 정보 : Header(STS), Length(30), CheckSum 확인
|
||||
RevSTS(frame);
|
||||
}
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
else if ((frame.Cmd.Equals("TAG") || frame.Cmd.Equals("CAL") || frame.Cmd.Equals("CCA")))
|
||||
{ // TAG ID 정보 : Header(STX), Length(13), CheckSum 확인
|
||||
RevTAG(frame);
|
||||
}
|
||||
else if (frame.DataString.StartsWith("$"))
|
||||
{
|
||||
// $로 시작되는 AGV 상태 표시
|
||||
//var text_Sts_Etc = Encoding.Default.GetString(bRcvData, 3, bRcvData.Length - 2).TrimStart(' '); //20210311 김정만 - SmartX FrameWork 사용 안함으로 주석처리
|
||||
//var sMessageOther = Encoding.Default.GetString(bRcvData, 3, bRcvData.Length - 2).TrimStart(' ');
|
||||
RaiseMessage(MessageType.Normal, "$메세지수신:" + frame.DataString);
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
DataReceive?.Invoke(this, new DataEventArgs(DataType.UNKNOWN));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
RaiseMessage(MessageType.Error, ex.Message);
|
||||
retval = false;
|
||||
}
|
||||
}
|
||||
return retval;
|
||||
|
||||
|
||||
}
|
||||
|
||||
#region [수신] ACK(응답확인값) 분석
|
||||
|
||||
public string ACKData { get; set; } = string.Empty;
|
||||
public DateTime ACKtime { get; set; } = DateTime.Now;
|
||||
private void RevACK(Dataframe frame)
|
||||
{
|
||||
//ACKSADA7
|
||||
var rcvdNow = frame.DataString;
|
||||
var bRcvData = frame.Buffer;
|
||||
|
||||
ACKData = rcvdNow.Substring(3);
|
||||
ACKtime = DateTime.Now;
|
||||
|
||||
if (rcvdNow.StartsWith("ACK"))
|
||||
{
|
||||
//RaiseMessage("get ack");
|
||||
DataReceive?.Invoke(this, new DataEventArgs(DataType.ACK));
|
||||
//if (datamanager.commandQueue.Count != 0)
|
||||
//{
|
||||
// byte[] bCmdData = encoding.GetBytes((String)datamanager.commandQueue.Peek());
|
||||
// if (bCmdData[1] == bRcvData[4] && bCmdData[2] == bRcvData[5] && bCmdData[3] == bRcvData[6]) //보낸값이 맞는지 확인후 Dequeue
|
||||
// {
|
||||
// nSendCount = 0;
|
||||
// datamanager.commandQueue.Dequeue();
|
||||
// sSendCommandString = "";
|
||||
// }
|
||||
//}
|
||||
}
|
||||
else if (rcvdNow.StartsWith("NAK"))
|
||||
{
|
||||
//RaiseMessage("get nak");
|
||||
DataReceive?.Invoke(this, new DataEventArgs(DataType.NAK));
|
||||
//nSendCount = 0; //NAK - 재전송이 날아왔을때 nSendCommandCounter 초기화
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public SystemFlag0 system0 = new SystemFlag0();
|
||||
public SystemFlag1 system1 = new SystemFlag1();
|
||||
public ErrorFlag error = new ErrorFlag();
|
||||
public AgvData data = new AgvData();
|
||||
public Signal1 signal1 = new Signal1();
|
||||
public Signal2 signal2 = new Signal2();
|
||||
|
||||
#region [수신] STS(AGV상태정보) 분석
|
||||
public string LastSTS { get; set; } = string.Empty;
|
||||
private void RevSTS(Dataframe frame)
|
||||
{
|
||||
LastSTS = frame.DataString;
|
||||
string rcvdNow = frame.DataString.Replace("\0", "");
|
||||
byte[] bRcvData = frame.Buffer;
|
||||
var encoding = System.Text.Encoding.Default;
|
||||
try
|
||||
{
|
||||
|
||||
// AGV 베터리 잔량 표시 flag (4~6) /////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
var idx = 3;
|
||||
var battery = int.Parse(rcvdNow.Substring(idx, 3)) / 10f;// Convert.ToDouble(encoding.GetString(rcvdNow, 3, 3)) / 10;
|
||||
idx += 3;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// AGV 장치연결상태 flag (7~10) - System Flag 0
|
||||
var nDataTemp = Convert.ToInt16(rcvdNow.Substring(idx, 4), 16);
|
||||
system0.SetValue(nDataTemp);
|
||||
idx += 4;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// AGV Sts(현재 상태) flag (11~14) - System Flag 1
|
||||
nDataTemp = Convert.ToInt16(rcvdNow.Substring(idx, 4), 16);
|
||||
system1.SetValue(nDataTemp);
|
||||
idx += 4;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// AGV Error flag (15~18) - Error Flag
|
||||
nDataTemp = Convert.ToInt16(rcvdNow.Substring(idx, 4), 16);
|
||||
error.SetValue(nDataTemp);
|
||||
idx += 4;
|
||||
|
||||
data.Speed = rcvdNow.Substring(idx, 1)[0]; idx += 1; //L,M.H
|
||||
data.Sts = rcvdNow.Substring(idx, 1)[0]; idx += 1; //S(직진),L(좌분기),R(우분기)
|
||||
data.Direction = rcvdNow.Substring(idx, 1)[0]; idx += 1; //F,B,L,R
|
||||
data.guidesensor = int.Parse(rcvdNow.Substring(idx, 1)); idx += 1; //가이드 좌측부터 1~9
|
||||
|
||||
nDataTemp = Convert.ToByte(rcvdNow.Substring(idx, 2), 16);
|
||||
signal1.SetValue(nDataTemp); idx += 2;
|
||||
|
||||
//agv가 멈춰있고 마크센서가 들어온경우, 턴 작업이었다면 턴 셋팅을 한다
|
||||
if (system1.agv_run == false && system1.agv_stop == true &&
|
||||
TurnInformation != null && signal1.mark_sensor)
|
||||
{
|
||||
if (TurnInformation.Start.Year > 2000)
|
||||
{
|
||||
if (TurnInformation.State == eNarumiTurn.LeftIng || TurnInformation.State == eNarumiTurn.RightIng)
|
||||
{
|
||||
TurnInformation.End = DateTime.Now;
|
||||
if (TurnInformation.State == eNarumiTurn.LeftIng) TurnInformation.State = eNarumiTurn.Left;
|
||||
if (TurnInformation.State == eNarumiTurn.RightIng) TurnInformation.State = eNarumiTurn.Right;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//시작시간이 설정되지 않았다면 처리하지 않는다.
|
||||
}
|
||||
}
|
||||
|
||||
if (idx <= rcvdNow.Length - 2)
|
||||
{
|
||||
nDataTemp = Convert.ToByte(rcvdNow.Substring(idx, 2), 16);
|
||||
signal2.SetValue(nDataTemp);
|
||||
}
|
||||
|
||||
|
||||
DataReceive?.Invoke(this, new DataEventArgs(DataType.STS));
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
RaiseMessage(MessageType.Error, $"Parse Error(STS) = {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#region [수신] TAG(태그정보) 분석
|
||||
|
||||
System.Text.Encoding encoding = System.Text.Encoding.Default;
|
||||
string old_TagString = string.Empty;
|
||||
string old_CALString = string.Empty;
|
||||
string old_CCAString = string.Empty;
|
||||
private void RevTAG(Dataframe frame)
|
||||
{
|
||||
string rcvdNow = frame.DataString;
|
||||
byte[] bRcvData = frame.Buffer;
|
||||
if (rcvdNow.StartsWith("TAG"))
|
||||
{
|
||||
//221123 chi 숫자로변경
|
||||
var tagnostr = rcvdNow.Substring(3);
|
||||
if (ushort.TryParse(tagnostr, out ushort tagnoint))
|
||||
{
|
||||
var Changed = !old_TagString.Equals(tagnostr);
|
||||
data.TagString = tagnostr;
|
||||
data.TagNo = tagnoint;
|
||||
old_TagString = tagnostr;
|
||||
DataReceive?.Invoke(this, new DataEventArgs(DataType.TAG));
|
||||
}
|
||||
|
||||
WriteData(MakeCheckSum("ACKTAG"));
|
||||
|
||||
}
|
||||
else if (rcvdNow.StartsWith("CAL"))
|
||||
{
|
||||
|
||||
var tagnostr = encoding.GetString(bRcvData, 4, 4);
|
||||
if (int.TryParse(tagnostr, out int tagnoint))
|
||||
{
|
||||
var Changed = !old_CALString.Equals(tagnostr);
|
||||
data.CallString = tagnostr;
|
||||
data.CallNo = tagnoint;
|
||||
old_CALString = tagnostr;
|
||||
if (Changed) DataReceive?.Invoke(this, new DataEventArgs(DataType.CALL));
|
||||
}
|
||||
WriteData(MakeCheckSum("ACKCAL"));
|
||||
}
|
||||
else if (rcvdNow.StartsWith("CCA")) //능동형 Call에 의하여 들어 오는 구문
|
||||
{
|
||||
|
||||
var tagnostr = encoding.GetString(bRcvData, 4, 4);
|
||||
if (int.TryParse(tagnostr, out int tagnoint))
|
||||
{
|
||||
var Changed = !old_CCAString.Equals(tagnostr);
|
||||
data.CCAString = tagnostr;
|
||||
data.CCANo = tagnoint;
|
||||
old_CCAString = tagnostr;
|
||||
if (Changed) DataReceive?.Invoke(this, new DataEventArgs(DataType.CCA));
|
||||
}
|
||||
WriteData(MakeCheckSum("ACKCCA"));
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
private string MakeCheckSum(string sCommand)
|
||||
{
|
||||
//sCommand = sCommand.ToUpper();
|
||||
|
||||
List<byte> buffer = new List<byte>();
|
||||
buffer.Add(0x02);
|
||||
|
||||
//byte[] bCommand = System.Text.ASCIIEncoding.ASCII.GetBytes(sCommand);
|
||||
buffer.AddRange(System.Text.ASCIIEncoding.ASCII.GetBytes(sCommand));
|
||||
|
||||
//make sum
|
||||
int nSum = 0;
|
||||
for (int nCnt = 1; nCnt < buffer.Count; nCnt++)
|
||||
nSum += buffer[nCnt];
|
||||
|
||||
string sSum = nSum.ToString("X2").ToUpper();// Convert.ToString(nSum, 16).ToUpper();
|
||||
if (sSum.Length < 2) sSum = "0" + sSum;
|
||||
sSum = sSum.Substring(sSum.Length - 2);
|
||||
|
||||
//if (sSum.Length == 3)
|
||||
// sSum = sSum.Remove(0, 1);
|
||||
//else if (sSum.Length == 4)
|
||||
// sSum = sSum.Remove(0, 2);
|
||||
|
||||
buffer.AddRange(System.Text.ASCIIEncoding.Default.GetBytes(sSum));
|
||||
buffer.Add(0x03);
|
||||
|
||||
// byte[] bStxEtx = { 0x02, 0x03 };
|
||||
|
||||
|
||||
|
||||
//var orgstr = (System.Text.ASCIIEncoding.ASCII.GetString(bStxEtx, 0, 1) + sCommand + sSum + System.Text.ASCIIEncoding.ASCII.GetString(bStxEtx, 1, 1));
|
||||
var newstr = System.Text.Encoding.Default.GetString(buffer.ToArray());
|
||||
return newstr;
|
||||
|
||||
}
|
||||
|
||||
///// <summary>
|
||||
///// commandQueue에 명령을 추가합니다(체크섬은 자동 추가됨)
|
||||
///// </summary>
|
||||
///// <param name="cmd">체크섬을 제외한 평문</param>
|
||||
///// <param name="addlog">sendlog 에 추가할 경우 true를 입력하세요</param>
|
||||
//public void AddCommand(string cmd, bool addlog = true, int Repeat = 1)
|
||||
//{
|
||||
// var fullcmd = MakeCheckSum(cmd);
|
||||
// for (int i = 0; i < Repeat; i++)
|
||||
// commandQueue.Enqueue(fullcmd);
|
||||
// if (addlog)
|
||||
// {
|
||||
// Message?.Invoke(this, new MessageEventArgs()
|
||||
// }
|
||||
//}
|
||||
|
||||
public enum eStopOpt
|
||||
{
|
||||
Stop = 0,
|
||||
MarkStop,
|
||||
MarkRotateLeft,
|
||||
MarkRotateRight,
|
||||
MarkChangeDirection,
|
||||
}
|
||||
public enum eRunOpt
|
||||
{
|
||||
NotSet,
|
||||
Forward,
|
||||
Backward,
|
||||
}
|
||||
|
||||
public enum ManulOpt
|
||||
{
|
||||
FS,
|
||||
BS,
|
||||
RT,
|
||||
LT,
|
||||
FL,
|
||||
FR,
|
||||
BL,
|
||||
BR,
|
||||
}
|
||||
public enum Sensor
|
||||
{
|
||||
PBSOff = 0,
|
||||
PBSOn,
|
||||
AllOn,
|
||||
}
|
||||
public enum Speed
|
||||
{
|
||||
High,
|
||||
Mid,
|
||||
Low,
|
||||
}
|
||||
public enum LiftCommand
|
||||
{
|
||||
/// <summary>
|
||||
/// lift up
|
||||
/// </summary>
|
||||
UP,
|
||||
/// <summary>
|
||||
/// lift down
|
||||
/// </summary>
|
||||
DN,
|
||||
/// <summary>
|
||||
/// lift 동작 정지
|
||||
/// </summary>
|
||||
STP,
|
||||
/// <summary>
|
||||
/// magnet holder on
|
||||
/// </summary>
|
||||
ON,
|
||||
/// <summary>
|
||||
/// magnet holder off
|
||||
/// </summary>
|
||||
OFF
|
||||
}
|
||||
|
||||
|
||||
private bool CheckSum(byte[] bData)
|
||||
{
|
||||
if (bData.Length < 2) // 데이터 길이가 2이하일 경우 비정상 처리
|
||||
return false;
|
||||
|
||||
int nSum = 0;
|
||||
// byte[] bData = encoding.GetBytes(sData);
|
||||
|
||||
for (int nCnt = 1; nCnt < bData.Length - 3; nCnt++)
|
||||
{
|
||||
nSum += bData[nCnt];
|
||||
}
|
||||
|
||||
|
||||
string sSum = Convert.ToString(nSum, 16).ToUpper();
|
||||
|
||||
string sCSTemp = string.Empty;
|
||||
|
||||
if (sSum.Length == 3)
|
||||
sCSTemp = sSum.Remove(0, 1);
|
||||
else if (sSum.Length == 4)
|
||||
sCSTemp = sSum.Remove(0, 2);
|
||||
|
||||
if (bData[bData.Length - 2] == '*' && bData[bData.Length - 3] == '*')
|
||||
return true;
|
||||
|
||||
if (sCSTemp[0] == (char)(bData[bData.Length - 3]) && sCSTemp[1] == (char)(bData[bData.Length - 2]))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
609
HMI/SubProject/AGV/NarumiSerialComm.cs
Normal file
609
HMI/SubProject/AGV/NarumiSerialComm.cs
Normal file
@@ -0,0 +1,609 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
|
||||
namespace arDev
|
||||
{
|
||||
public abstract class NarumiSerialComm : ISerialComm, IDisposable
|
||||
{
|
||||
protected System.IO.Ports.SerialPort _device;
|
||||
protected ManualResetEvent _mre;
|
||||
protected byte[] LastReceiveBuffer = new byte[] { };
|
||||
/// <summary>
|
||||
/// 최종 전송 메세지
|
||||
/// </summary>
|
||||
public byte[] lastSendBuffer = new byte[] { };
|
||||
//public int ValidCheckTimeMSec { get; set; } = 5000;
|
||||
protected List<byte> tempBuffer = new List<byte>();
|
||||
protected Boolean findSTX = false;
|
||||
public string ErrorMessage { get; set; }
|
||||
public DateTime LastConnTime { get; set; }
|
||||
public DateTime LastConnTryTime { get; set; }
|
||||
public DateTime lastSendTime;
|
||||
/// <summary>
|
||||
/// 메세지 수신시 사용하는 내부버퍼
|
||||
/// </summary>
|
||||
protected List<byte> _buffer = new List<byte>();
|
||||
/// <summary>
|
||||
/// 데이터조회간격(초)
|
||||
/// </summary>
|
||||
public float ScanInterval { get; set; }
|
||||
|
||||
// public byte[] LastRecvData;
|
||||
public string LastRecvString
|
||||
{
|
||||
get
|
||||
{
|
||||
if (LastReceiveBuffer == null) return String.Empty;
|
||||
else return System.Text.Encoding.Default.GetString(LastReceiveBuffer);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 마지막으로 데이터를 받은 시간
|
||||
/// </summary>
|
||||
public DateTime lastRecvTime;
|
||||
|
||||
|
||||
public int WriteError = 0;
|
||||
public string WriteErrorMessage = string.Empty;
|
||||
public int WaitTimeout { get; set; } = 1000;
|
||||
public int MinRecvLength { get; set; } = 1;
|
||||
|
||||
// Polling Thread related
|
||||
protected Thread _recvThread;
|
||||
protected volatile bool _isReading = false;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 포트이름
|
||||
/// </summary>
|
||||
[Description("시리얼 포트 이름")]
|
||||
[Category("설정"), DisplayName("Port Name")]
|
||||
public string PortName
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_device == null) return string.Empty;
|
||||
else return _device.PortName;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (this.IsOpen)
|
||||
{
|
||||
Message?.Invoke(this, new MessageEventArgs("포트가 열려있어 포트이름을 변경할 수 없습니다", true));
|
||||
}
|
||||
else if (String.IsNullOrEmpty(value) == false)
|
||||
_device.PortName = value;
|
||||
else
|
||||
{
|
||||
Message?.Invoke(this, new MessageEventArgs("No PortName", true));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int BaudRate
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_device == null) return 0;
|
||||
else return _device.BaudRate;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (this.IsOpen)
|
||||
{
|
||||
Message?.Invoke(this, new MessageEventArgs("포트가 열려있어 BaudRate(를) 변경할 수 없습니다", true));
|
||||
}
|
||||
else if (value != 0)
|
||||
_device.BaudRate = value;
|
||||
else Message?.Invoke(this, new MessageEventArgs("No baud rate", true));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public NarumiSerialComm()
|
||||
{
|
||||
_device = new System.IO.Ports.SerialPort();
|
||||
this.BaudRate = 57600;
|
||||
ScanInterval = 10;
|
||||
// _device.DataReceived += barcode_DataReceived; // Removed event handler
|
||||
_device.ErrorReceived += this.barcode_ErrorReceived;
|
||||
_device.WriteTimeout = 3000;
|
||||
_device.ReadTimeout = 3000;
|
||||
_device.ReadBufferSize = 8192;
|
||||
_device.WriteBufferSize = 8192;
|
||||
//_device.DiscardInBuffer();
|
||||
//_device.DiscardOutBuffer();
|
||||
ErrorMessage = string.Empty;
|
||||
lastRecvTime = DateTime.Parse("1982-11-23");
|
||||
LastConnTime = DateTime.Parse("1982-11-23");
|
||||
LastConnTryTime = DateTime.Parse("1982-11-23");
|
||||
lastRecvTime = DateTime.Parse("1982-11-23");
|
||||
this._mre = new ManualResetEvent(true);
|
||||
}
|
||||
|
||||
~NarumiSerialComm()
|
||||
{
|
||||
Dispose(false);
|
||||
}
|
||||
|
||||
|
||||
// Flag: Has Dispose already been called?
|
||||
bool disposed = false;
|
||||
|
||||
// Public implementation of Dispose pattern callable by consumers.
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
// Protected implementation of Dispose pattern.
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (disposed)
|
||||
return;
|
||||
|
||||
if (disposing)
|
||||
{
|
||||
// Free any other managed objects here.
|
||||
//
|
||||
}
|
||||
|
||||
// Stop reading thread
|
||||
_isReading = false;
|
||||
|
||||
// _device.DataReceived -= barcode_DataReceived; // Removed event handler
|
||||
_device.ErrorReceived -= this.barcode_ErrorReceived;
|
||||
|
||||
if (_recvThread != null && _recvThread.IsAlive)
|
||||
{
|
||||
_recvThread.Join(500);
|
||||
}
|
||||
|
||||
if (_device != null)
|
||||
{
|
||||
if (_device.IsOpen) _device.Close();
|
||||
_device.Dispose();
|
||||
}
|
||||
|
||||
// Free any unmanaged objects here.
|
||||
//
|
||||
disposed = true;
|
||||
}
|
||||
|
||||
public Boolean Open()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_device.IsOpen == false)
|
||||
{
|
||||
_device.Open();
|
||||
}
|
||||
|
||||
if (_device.IsOpen)
|
||||
{
|
||||
// Start polling thread
|
||||
if (_isReading == false)
|
||||
{
|
||||
_isReading = true;
|
||||
_recvThread = new Thread(ReadPort);
|
||||
_recvThread.IsBackground = true;
|
||||
_recvThread.Start();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ErrorMessage = ex.Message;
|
||||
Message.Invoke(this, new MessageEventArgs(ex.Message, true));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
public string GetHexString(Byte[] input)
|
||||
{
|
||||
System.Text.StringBuilder sb = new System.Text.StringBuilder();
|
||||
foreach (byte b in input)
|
||||
sb.Append(" " + b.ToString("X2"));
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 포트가 열려있는지 확인
|
||||
/// </summary>
|
||||
[Description("현재 시리얼포트가 열려있는지 확인합니다")]
|
||||
[Category("정보"), DisplayName("Port Open")]
|
||||
public Boolean IsOpen
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_device == null) return false;
|
||||
return _device.IsOpen;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual bool Close()
|
||||
{
|
||||
try
|
||||
{
|
||||
_isReading = false; // Stop thread loop
|
||||
|
||||
if (_recvThread != null && _recvThread.IsAlive)
|
||||
{
|
||||
if (!_recvThread.Join(500)) // Wait for thread to finish
|
||||
{
|
||||
// _recvThread.Abort(); // Avoid Abort if possible
|
||||
}
|
||||
}
|
||||
|
||||
if (_device != null && _device.IsOpen)
|
||||
{
|
||||
_device.DiscardInBuffer();
|
||||
_device.DiscardOutBuffer();
|
||||
_device.Close(); //dispose에서는 포트를 직접 클리어하지 않게 해뒀다.
|
||||
return true;
|
||||
}
|
||||
else return false;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
protected Boolean RaiseRecvData()
|
||||
{
|
||||
return RaiseRecvData(LastReceiveBuffer.ToArray(), false);
|
||||
}
|
||||
/// <summary>
|
||||
/// 수신받은 메세지를 발생 시킵니다
|
||||
/// </summary>
|
||||
/// <param name="data"></param>
|
||||
/// <returns></returns>
|
||||
public virtual Boolean RaiseRecvData(byte[] Data, bool udpatelastbuffer)
|
||||
{
|
||||
//181206 - 최종수신 메세지 기록
|
||||
lastRecvTime = DateTime.Now;
|
||||
if (udpatelastbuffer && Data != null)
|
||||
{
|
||||
if (LastReceiveBuffer == null || LastReceiveBuffer.Length != Data.Length)
|
||||
{
|
||||
LastReceiveBuffer = new byte[Data.Length];
|
||||
Array.Copy(Data, LastReceiveBuffer, Data.Length);
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// UI update might need Invoke if this event handler updates UI directly,
|
||||
// but usually the subscriber handles Invoke.
|
||||
// Since we are running on a background thread now, subscribers must be aware.
|
||||
Message?.Invoke(this, new MessageEventArgs(Data, true)); //recvmessage
|
||||
if (ProcessRecvData(Data) == false)
|
||||
{
|
||||
//Message?.Invoke(this, new MessageEventArgs(Data, true)); //recvmessage
|
||||
Message?.Invoke(this, new MessageEventArgs(this.ErrorMessage, true)); //errormessage
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.ErrorMessage = ex.Message;
|
||||
this.Message?.Invoke(this, new MessageEventArgs(ex.Message, true));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 수신받은 자료를 처리한다
|
||||
/// </summary>
|
||||
/// <param name="data"></param>
|
||||
/// <returns></returns>
|
||||
public abstract bool ProcessRecvData(byte[] data);
|
||||
|
||||
#region "Internal Events"
|
||||
|
||||
void barcode_ErrorReceived(object sender, System.IO.Ports.SerialErrorReceivedEventArgs e)
|
||||
{
|
||||
Message?.Invoke(this, new MessageEventArgs(e.ToString(), true));
|
||||
}
|
||||
|
||||
byte[] buffer = new byte[] { };
|
||||
|
||||
// Replaced with ReadPort Loop
|
||||
/*
|
||||
void barcode_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
int ReadCount = _device.BytesToRead;
|
||||
|
||||
buffer = new byte[ReadCount];
|
||||
_device.Read(buffer, 0, buffer.Length);
|
||||
|
||||
System.Text.StringBuilder LogMsg = new StringBuilder();
|
||||
|
||||
byte[] remainBuffer;
|
||||
Repeat:
|
||||
if (CustomParser(buffer, out remainBuffer))
|
||||
{
|
||||
//분석완료이므로 받은 데이터를 버퍼에 기록한다
|
||||
if (LastReceiveBuffer == null || (LastReceiveBuffer.Length != tempBuffer.Count))
|
||||
Array.Resize(ref LastReceiveBuffer, tempBuffer.Count);
|
||||
Array.Copy(tempBuffer.ToArray(), LastReceiveBuffer, tempBuffer.Count);
|
||||
tempBuffer.Clear();
|
||||
|
||||
//수신메세지발생
|
||||
RaiseRecvData();
|
||||
if (remainBuffer != null && remainBuffer.Length > 0)
|
||||
{
|
||||
//버퍼를 변경해서 다시 전송을 해준다.
|
||||
Array.Resize(ref buffer, remainBuffer.Length);
|
||||
Array.Copy(remainBuffer, buffer, remainBuffer.Length);
|
||||
goto Repeat; //남은 버퍼가 있다면 진행을 해준다.
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
//if (IsOpen)
|
||||
//{
|
||||
// //_device.DiscardInBuffer();
|
||||
// //_device.DiscardOutBuffer();
|
||||
//}
|
||||
ErrorMessage = ex.Message;
|
||||
this.Message?.Invoke(this, new MessageEventArgs(ex.Message, true));
|
||||
}
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
void ReadPort()
|
||||
{
|
||||
while (_isReading)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_device == null || !_device.IsOpen)
|
||||
{
|
||||
Thread.Sleep(100);
|
||||
continue;
|
||||
}
|
||||
|
||||
int readCount = _device.BytesToRead;
|
||||
if (readCount > 0)
|
||||
{
|
||||
byte[] buffer = new byte[readCount];
|
||||
_device.Read(buffer, 0, buffer.Length);
|
||||
|
||||
byte[] remainBuffer;
|
||||
Repeat:
|
||||
if (CustomParser(buffer, out remainBuffer))
|
||||
{
|
||||
//분석완료이므로 받은 데이터를 버퍼에 기록한다
|
||||
if (LastReceiveBuffer == null || (LastReceiveBuffer.Length != tempBuffer.Count))
|
||||
Array.Resize(ref LastReceiveBuffer, tempBuffer.Count);
|
||||
Array.Copy(tempBuffer.ToArray(), LastReceiveBuffer, tempBuffer.Count);
|
||||
tempBuffer.Clear();
|
||||
|
||||
//수신메세지발생
|
||||
RaiseRecvData();
|
||||
if (remainBuffer != null && remainBuffer.Length > 0)
|
||||
{
|
||||
//버퍼를 변경해서 다시 전송을 해준다.
|
||||
buffer = new byte[remainBuffer.Length]; // Reallocate buffer for remaining data
|
||||
Array.Copy(remainBuffer, buffer, remainBuffer.Length);
|
||||
goto Repeat; //남은 버퍼가 있다면 진행을 해준다.
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Thread.Sleep(20); // Data 없음, 대기
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// Thread 상에서 Exception 발생 시 로그 남기고 계속 진행 여부 결정
|
||||
// 여기서는 에러 메시지 발생시키고 Sleep
|
||||
ErrorMessage = ex.Message;
|
||||
this.Message?.Invoke(this, new MessageEventArgs(ex.Message, true));
|
||||
Thread.Sleep(1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region "External Events"
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 오류 및 기타 일반 메세지
|
||||
/// </summary>
|
||||
public event EventHandler<MessageEventArgs> Message;
|
||||
|
||||
#endregion
|
||||
|
||||
#region "Event Args"
|
||||
|
||||
/// <summary>
|
||||
/// 데이터를 수신할떄 사용함(RAW 포함)
|
||||
/// </summary>
|
||||
public class ReceiveDataEventArgs : EventArgs
|
||||
{
|
||||
private byte[] _buffer = null;
|
||||
|
||||
/// <summary>
|
||||
/// 바이트배열의 버퍼값
|
||||
/// </summary>
|
||||
public byte[] Value { get { return _buffer; } }
|
||||
|
||||
/// <summary>
|
||||
/// 버퍼(바이트배열)의 데이터를 문자로 반환합니다.
|
||||
/// </summary>
|
||||
public string StrValue
|
||||
{
|
||||
get
|
||||
{
|
||||
//return string.Empty;
|
||||
|
||||
if (_buffer == null || _buffer.Length < 1) return string.Empty;
|
||||
else return System.Text.Encoding.Default.GetString(_buffer);
|
||||
}
|
||||
}
|
||||
public ReceiveDataEventArgs(byte[] buffer)
|
||||
{
|
||||
_buffer = buffer;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 메세지를 강제 발생
|
||||
/// </summary>
|
||||
/// <param name="mt"></param>
|
||||
/// <param name="message"></param>
|
||||
protected virtual void RaiseMessage(MessageType mt, string message)
|
||||
{
|
||||
this.Message?.Invoke(this, new MessageEventArgs(mt, message));
|
||||
}
|
||||
public enum MessageType
|
||||
{
|
||||
Normal,
|
||||
Error,
|
||||
Send,
|
||||
Recv,
|
||||
}
|
||||
|
||||
public class MessageEventArgs : EventArgs
|
||||
{
|
||||
public MessageType MsgType { get; set; }
|
||||
private string _message = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Recv,Send,Normal,Error 모두 지원
|
||||
/// </summary>
|
||||
public string Message { get { return _message; } }
|
||||
|
||||
private byte[] _data = null;
|
||||
|
||||
/// <summary>
|
||||
/// Recv,Send에서만 값이 존재 합니다
|
||||
/// </summary>
|
||||
public byte[] Data { get { return _data; } }
|
||||
public MessageEventArgs(string Message, bool isError = false)
|
||||
{
|
||||
if (isError) MsgType = MessageType.Error;
|
||||
else MsgType = MessageType.Normal;
|
||||
_message = Message;
|
||||
}
|
||||
public MessageEventArgs(MessageType msgtype, string Message)
|
||||
{
|
||||
MsgType = msgtype;
|
||||
_message = Message;
|
||||
_data = System.Text.Encoding.Default.GetBytes(Message);
|
||||
}
|
||||
|
||||
public MessageEventArgs(byte[] buffer, bool isRecv = true)
|
||||
{
|
||||
if (isRecv) MsgType = MessageType.Recv;
|
||||
else MsgType = MessageType.Send;
|
||||
_data = new byte[buffer.Length];
|
||||
Array.Copy(buffer, _data, Data.Length);
|
||||
_message = System.Text.Encoding.Default.GetString(_data);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
protected abstract bool CustomParser(byte[] buf, out byte[] remainBuffer);
|
||||
|
||||
/// <summary>
|
||||
/// 포트가 열려있거나 데이터 수신시간이 없는경우 false를 반환합니다
|
||||
/// </summary>
|
||||
public Boolean IsValid
|
||||
{
|
||||
get
|
||||
{
|
||||
if (IsOpen == false) return false;
|
||||
if (lastRecvTime.Year == 1982) return false;
|
||||
var ts = DateTime.Now - lastRecvTime;
|
||||
if (ts.TotalSeconds > (this.ScanInterval * 2.5)) return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
protected bool WriteData(string cmd)
|
||||
{
|
||||
return WriteData(System.Text.Encoding.Default.GetBytes(cmd));
|
||||
}
|
||||
/// <summary>
|
||||
/// 포트에 쓰기(barcode_DataReceived 이벤트로 메세지수신)
|
||||
/// </summary>
|
||||
protected Boolean WriteData(byte[] data)
|
||||
{
|
||||
Boolean bRet = false;
|
||||
|
||||
//171205 : 타임아웃시간추가
|
||||
if (!_mre.WaitOne(WaitTimeout))
|
||||
{
|
||||
ErrorMessage = $"WriteData:MRE:WaitOne:TimeOut {WaitTimeout}ms";
|
||||
this.Message?.Invoke(this, new MessageEventArgs(ErrorMessage, true));
|
||||
return false;
|
||||
}
|
||||
|
||||
_mre.Reset();
|
||||
|
||||
//Array.Resize(ref data, data.Length + 2);
|
||||
|
||||
try
|
||||
{
|
||||
lastSendTime = DateTime.Now;
|
||||
if (lastSendBuffer == null) lastSendBuffer = new byte[data.Length]; //171113
|
||||
else Array.Resize(ref lastSendBuffer, data.Length);
|
||||
Array.Copy(data, lastSendBuffer, data.Length);
|
||||
|
||||
for (int i = 0; i < data.Length; i++)
|
||||
_device.Write(data, i, 1);
|
||||
|
||||
//_device.Write(data, 0, data.Length);
|
||||
|
||||
//171113
|
||||
this.Message?.Invoke(this, new MessageEventArgs(data, false));
|
||||
|
||||
bRet = true;
|
||||
WriteError = 0;
|
||||
WriteErrorMessage = string.Empty;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// this.isinit = false;
|
||||
this.Message?.Invoke(this, new MessageEventArgs(ex.Message, true));
|
||||
bRet = false;
|
||||
WriteError += 1; //연속쓰기오류횟수
|
||||
WriteErrorMessage = ex.Message;
|
||||
}
|
||||
finally
|
||||
{
|
||||
_mre.Set();
|
||||
}
|
||||
return bRet;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
36
HMI/SubProject/AGV/Properties/AssemblyInfo.cs
Normal file
36
HMI/SubProject/AGV/Properties/AssemblyInfo.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// 어셈블리에 대한 일반 정보는 다음 특성 집합을 통해
|
||||
// 제어됩니다. 어셈블리와 관련된 정보를 수정하려면
|
||||
// 이러한 특성 값을 변경하세요.
|
||||
[assembly: AssemblyTitle("BMS Commnunication Module")]
|
||||
[assembly: AssemblyDescription("BMS Commnunication Module")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("ATK4")]
|
||||
[assembly: AssemblyProduct("BMS Commnunication Module")]
|
||||
[assembly: AssemblyCopyright("Copyright ©ATK4 2020")]
|
||||
[assembly: AssemblyTrademark("ATK4")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// ComVisible을 false로 설정하면 이 어셈블리의 형식이 COM 구성 요소에
|
||||
// 표시되지 않습니다. COM에서 이 어셈블리의 형식에 액세스하려면
|
||||
// 해당 형식에 대해 ComVisible 특성을 true로 설정하세요.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// 이 프로젝트가 COM에 노출되는 경우 다음 GUID는 typelib의 ID를 나타냅니다.
|
||||
[assembly: Guid("7a94c30c-6772-4f71-bf9c-111071a1bc70")]
|
||||
|
||||
// 어셈블리의 버전 정보는 다음 네 가지 값으로 구성됩니다.
|
||||
//
|
||||
// 주 버전
|
||||
// 부 버전
|
||||
// 빌드 번호
|
||||
// 수정 버전
|
||||
//
|
||||
// 모든 값을 지정하거나 아래와 같이 '*'를 사용하여 빌드 번호 및 수정 번호를
|
||||
// 기본값으로 할 수 있습니다.
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("20.03.09.0000")]
|
||||
[assembly: AssemblyFileVersion("20.03.09.0000")]
|
||||
86
HMI/SubProject/AGV/Structure/AgvData.cs
Normal file
86
HMI/SubProject/AGV/Structure/AgvData.cs
Normal file
@@ -0,0 +1,86 @@
|
||||
using System;
|
||||
|
||||
namespace arDev
|
||||
{
|
||||
public partial class Narumi
|
||||
{
|
||||
|
||||
public class AgvData
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// S: Straight
|
||||
/// L: Left
|
||||
/// R: Right
|
||||
/// </summary>
|
||||
public char Sts { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// H : High
|
||||
/// M : Middle
|
||||
/// L : Low
|
||||
/// S : Mark Stop
|
||||
/// </summary>
|
||||
public char Speed { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// F : Front
|
||||
/// B : Back
|
||||
/// </summary>
|
||||
public char Direction { get; set; }
|
||||
|
||||
public int guidesensor { get; set; }
|
||||
|
||||
|
||||
public string TagString { get; set; } = string.Empty;
|
||||
public ushort TagNo { get; set; } = 0;
|
||||
public string CallString { get; set; } = string.Empty;
|
||||
public int CallNo { get; set; } = -1;
|
||||
public string CCAString { get; set; } = string.Empty;
|
||||
public int CCANo { get; set; } = -1;
|
||||
|
||||
|
||||
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
//모든사태값을 탭으로 구분하여 문자를 생성한다
|
||||
var sb = new System.Text.StringBuilder();
|
||||
|
||||
sb.AppendLine($"[Sts] : {Sts}");
|
||||
sb.AppendLine($"[Speed] : {Speed}");
|
||||
sb.AppendLine($"[Direction] : {Direction}");
|
||||
sb.AppendLine($"[guidesensor] : {guidesensor}");
|
||||
|
||||
sb.AppendLine($"[TagNo] : {TagNo}");
|
||||
sb.AppendLine($"[CallNo] : {CallNo}");
|
||||
sb.AppendLine($"[CCANo] : {CCANo}");
|
||||
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public string ToRtfString()
|
||||
{
|
||||
var sb = new System.Text.StringBuilder();
|
||||
sb.AppendLine(@"{\rtf1\ansi\deff0");
|
||||
sb.AppendLine(@"{\colortbl ;\red0\green0\blue255;}"); // Color 1 = Blue
|
||||
|
||||
sb.AppendLine($"[Sts] : {Sts}" + @"\line");
|
||||
sb.AppendLine($"[Speed] : {Speed}" + @"\line");
|
||||
sb.AppendLine($"[Direction] : {Direction}" + @"\line");
|
||||
sb.AppendLine($"[guidesensor] : {guidesensor}" + @"\line");
|
||||
sb.AppendLine($"[TagNo] : {TagNo}" + @"\line");
|
||||
sb.AppendLine($"[CallNo] : {CallNo}" + @"\line");
|
||||
sb.AppendLine($"[CCANo] : {CCANo}" + @"\line");
|
||||
|
||||
sb.AppendLine("}");
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
142
HMI/SubProject/AGV/Structure/ErrorFlag.cs
Normal file
142
HMI/SubProject/AGV/Structure/ErrorFlag.cs
Normal file
@@ -0,0 +1,142 @@
|
||||
using System;
|
||||
|
||||
namespace arDev
|
||||
{
|
||||
public partial class Narumi
|
||||
{
|
||||
|
||||
public class ErrorFlag
|
||||
{
|
||||
private COMM.Flag _value { get; set; } = new COMM.Flag(16);
|
||||
public void SetValue(Int16 value) { this._value.writeValue(value); }
|
||||
public UInt16 Value
|
||||
{
|
||||
get
|
||||
{
|
||||
return (UInt16)_value.Value;
|
||||
}
|
||||
}
|
||||
public enum eflag
|
||||
{
|
||||
Emergency = 0,
|
||||
Overcurrent,
|
||||
Charger_run_error,
|
||||
Charger_pos_error,
|
||||
line_out_error = 4,
|
||||
|
||||
/// <summary>
|
||||
/// 기동시 자석 감지 에러
|
||||
/// </summary>
|
||||
runerror_by_no_magent_line=5,
|
||||
/// <summary>
|
||||
/// 호출제어기 통신 오류
|
||||
/// </summary>
|
||||
controller_comm_error =6,
|
||||
|
||||
/// <summary>
|
||||
/// 배터리 저전압
|
||||
/// </summary>
|
||||
battery_low_voltage=7,
|
||||
|
||||
spare08=8,
|
||||
|
||||
lift_timeout=9,
|
||||
lift_driver_overcurrent=10,
|
||||
lift_driver_emergency = 11,
|
||||
|
||||
/// <summary>
|
||||
/// 도착경보기 통신 오류
|
||||
/// </summary>
|
||||
arrive_ctl_comm_error,
|
||||
|
||||
/// <summary>
|
||||
/// 자동문제어기 통신 오류
|
||||
/// </summary>
|
||||
door_ctl_comm_error,
|
||||
|
||||
/// <summary>
|
||||
/// 자동충전기 통신 오류
|
||||
/// </summary>
|
||||
charger_comm_error,
|
||||
|
||||
/// <summary>
|
||||
/// 교차로 제어기 통신 오류
|
||||
/// </summary>
|
||||
cross_ctrl_comm_error,
|
||||
}
|
||||
|
||||
public bool GetValue(eflag idx)
|
||||
{
|
||||
return _value.Get((int)idx);
|
||||
}
|
||||
public bool GetChanged(eflag idx)
|
||||
{
|
||||
return _value.GetChanged((int)idx);
|
||||
}
|
||||
|
||||
public bool Emergency { get { return GetValue(eflag.Emergency); } }
|
||||
public bool Overcurrent { get { return GetValue(eflag.Overcurrent); } }
|
||||
public bool Charger_run_error { get { return GetValue(eflag.Charger_run_error); } }
|
||||
public bool Charger_pos_error { get { return GetValue(eflag.Charger_pos_error); } }
|
||||
public bool line_out_error { get { return GetValue(eflag.line_out_error); } }
|
||||
public bool runerror_by_no_magent_line { get { return GetValue(eflag.runerror_by_no_magent_line); } }
|
||||
public bool controller_comm_error { get { return GetValue(eflag.controller_comm_error); } }
|
||||
public bool arrive_ctl_comm_error { get { return GetValue(eflag.arrive_ctl_comm_error); } }
|
||||
public bool door_ctl_comm_error { get { return GetValue(eflag.door_ctl_comm_error); } }
|
||||
public bool charger_comm_error { get { return GetValue(eflag.charger_comm_error); } }
|
||||
public bool cross_ctrl_comm_error { get { return GetValue(eflag.cross_ctrl_comm_error); } }
|
||||
public override string ToString()
|
||||
{
|
||||
//모든사태값을 탭으로 구분하여 문자를 생성한다
|
||||
var sb = new System.Text.StringBuilder();
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
var def = Enum.IsDefined(typeof(eflag), i);
|
||||
if (def)
|
||||
{
|
||||
var flag = (eflag)i;
|
||||
var value = _value.Get(i);
|
||||
sb.AppendLine($"[{i:00}][{flag}] : {value}");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public string ToRtfString()
|
||||
{
|
||||
var sb = new System.Text.StringBuilder();
|
||||
sb.AppendLine(@"{\rtf1\ansi\deff0");
|
||||
sb.AppendLine(@"{\colortbl ;\red0\green0\blue255;}"); // Color 1 = Blue
|
||||
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
var def = Enum.IsDefined(typeof(eflag), i);
|
||||
if (def)
|
||||
{
|
||||
var flag = (eflag)i;
|
||||
var value = _value.Get(i);
|
||||
string line = $"[{i:00}][{flag}] : {value}";
|
||||
|
||||
// : true가 포함된 줄은 파란색
|
||||
if (value == true)
|
||||
{
|
||||
sb.AppendLine(@"\cf1 " + line + @"\cf0\line");
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.AppendLine(line + @"\line");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sb.AppendLine("}");
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
187
HMI/SubProject/AGV/Structure/Signals.cs
Normal file
187
HMI/SubProject/AGV/Structure/Signals.cs
Normal file
@@ -0,0 +1,187 @@
|
||||
using System;
|
||||
|
||||
namespace arDev
|
||||
{
|
||||
public partial class Narumi
|
||||
{
|
||||
public enum eSignal1
|
||||
{
|
||||
front_gate_out = 0,
|
||||
rear_gte_out,
|
||||
mark_sensor_1,
|
||||
mark_sensor_2,
|
||||
lift_down_sensor,
|
||||
lift_up_sensor,
|
||||
magnet_relay,
|
||||
charger_align_sensor,
|
||||
}
|
||||
public enum eSignal2
|
||||
{
|
||||
cart_detect1 = 0,
|
||||
cart_detect2,
|
||||
}
|
||||
|
||||
public class Signal1
|
||||
{
|
||||
private COMM.Flag _value { get; set; } = new COMM.Flag(8);
|
||||
public void SetValue(Int16 value) { this._value.writeValue(value); }
|
||||
public UInt16 Value
|
||||
{
|
||||
get
|
||||
{
|
||||
return (UInt16)_value.Value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public bool GetValue(eSignal1 idx)
|
||||
{
|
||||
return _value.Get((int)idx);
|
||||
}
|
||||
public bool GetChanged(eSignal1 idx)
|
||||
{
|
||||
return _value.GetChanged((int)idx);
|
||||
}
|
||||
|
||||
public Boolean front_gate_out { get { return GetValue(eSignal1.front_gate_out); } }
|
||||
public Boolean rear_sensor_out { get { return GetValue(eSignal1.rear_gte_out); } }
|
||||
public Boolean mark_sensor_1 { get { return GetValue(eSignal1.mark_sensor_1); } }
|
||||
public Boolean mark_sensor_2 { get { return GetValue(eSignal1.mark_sensor_2); } }
|
||||
public Boolean mark_sensor { get { return mark_sensor_1 || mark_sensor_2; } }
|
||||
public Boolean charger_align_sensor { get { return GetValue(eSignal1.charger_align_sensor); } }
|
||||
public Boolean lift_up { get { return GetValue(eSignal1.lift_up_sensor); } }
|
||||
public Boolean lift_down { get { return GetValue(eSignal1.lift_down_sensor); } }
|
||||
public Boolean magnet_on { get { return GetValue(eSignal1.magnet_relay); } }
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
//모든사태값을 탭으로 구분하여 문자를 생성한다
|
||||
var sb = new System.Text.StringBuilder();
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
var def = Enum.IsDefined(typeof(eSignal1), i);
|
||||
if (def)
|
||||
{
|
||||
var flag = (eSignal1)i;
|
||||
var value = _value.Get(i);
|
||||
sb.AppendLine($"[{i:00}][{flag}] : {value}");
|
||||
}
|
||||
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public string ToRtfString()
|
||||
{
|
||||
var sb = new System.Text.StringBuilder();
|
||||
sb.AppendLine(@"{\rtf1\ansi\deff0");
|
||||
sb.AppendLine(@"{\colortbl ;\red0\green0\blue255;}"); // Color 1 = Blue
|
||||
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
var def = Enum.IsDefined(typeof(eSignal1), i);
|
||||
if (def)
|
||||
{
|
||||
var flag = (eSignal1)i;
|
||||
var value = _value.Get(i);
|
||||
string line = $"[{i:00}][{flag}] : {value}";
|
||||
|
||||
// : true가 포함된 줄은 파란색
|
||||
if (value == true)
|
||||
{
|
||||
sb.AppendLine(@"\cf1 " + line + @"\cf0\line");
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.AppendLine(line + @"\line");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sb.AppendLine("}");
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public class Signal2
|
||||
{
|
||||
private COMM.Flag _value { get; set; } = new COMM.Flag(8);
|
||||
public void SetValue(Int16 value) { this._value.writeValue(value); }
|
||||
public UInt16 Value
|
||||
{
|
||||
get
|
||||
{
|
||||
return (UInt16)_value.Value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public bool GetValue(eSignal2 idx)
|
||||
{
|
||||
return _value.Get((int)idx);
|
||||
}
|
||||
public bool GetChanged(eSignal2 idx)
|
||||
{
|
||||
return _value.GetChanged((int)idx);
|
||||
}
|
||||
|
||||
|
||||
public Boolean cart_detect1 { get { return GetValue(eSignal2.cart_detect1); } }
|
||||
public Boolean cart_detect2 { get { return GetValue(eSignal2.cart_detect2); } }
|
||||
public override string ToString()
|
||||
{
|
||||
//모든사태값을 탭으로 구분하여 문자를 생성한다
|
||||
var sb = new System.Text.StringBuilder();
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
var def = Enum.IsDefined(typeof(eSignal2), i);
|
||||
if(def)
|
||||
{
|
||||
var flag = (eSignal2)i;
|
||||
var value = _value.Get(i);
|
||||
sb.AppendLine($"[{i:00}][{flag}] : {value}");
|
||||
}
|
||||
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public string ToRtfString()
|
||||
{
|
||||
var sb = new System.Text.StringBuilder();
|
||||
sb.AppendLine(@"{\rtf1\ansi\deff0");
|
||||
sb.AppendLine(@"{\colortbl ;\red0\green0\blue255;}"); // Color 1 = Blue
|
||||
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
var def = Enum.IsDefined(typeof(eSignal2), i);
|
||||
if (def)
|
||||
{
|
||||
var flag = (eSignal2)i;
|
||||
var value = _value.Get(i);
|
||||
string line = $"[{i:00}][{flag}] : {value}";
|
||||
|
||||
// : true가 포함된 줄은 파란색
|
||||
if (value == true)
|
||||
{
|
||||
sb.AppendLine(@"\cf1 " + line + @"\cf0\line");
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.AppendLine(line + @"\line");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sb.AppendLine("}");
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
108
HMI/SubProject/AGV/Structure/SystemFlag0.cs
Normal file
108
HMI/SubProject/AGV/Structure/SystemFlag0.cs
Normal file
@@ -0,0 +1,108 @@
|
||||
using System;
|
||||
|
||||
namespace arDev
|
||||
{
|
||||
public partial class Narumi
|
||||
{
|
||||
|
||||
public class SystemFlag0
|
||||
{
|
||||
private COMM.Flag _value { get; set; } = new COMM.Flag(16);
|
||||
public void SetValue(Int16 value) { this._value.writeValue(value); }
|
||||
public UInt16 Value
|
||||
{
|
||||
get
|
||||
{
|
||||
return (UInt16)_value.Value;
|
||||
}
|
||||
}
|
||||
|
||||
public enum eflag
|
||||
{
|
||||
Memory_RW_State = 5,
|
||||
EXT_IO_Conn_State,
|
||||
RFID_Conn_State,
|
||||
M5E_Module_Run_State = 8,
|
||||
Front_Ultrasonic_Conn_State,
|
||||
Front_Untrasonic_Sensor_State,
|
||||
Side_Ultrasonic_Conn_State,
|
||||
Side_Ultrasonic_Sensor_State = 12,
|
||||
Front_Guide_Sensor_State,
|
||||
Rear_Guide_Sensor_State,
|
||||
Battery_Level_Check
|
||||
}
|
||||
|
||||
public bool GetValue(eflag idx)
|
||||
{
|
||||
return _value.Get((int)idx);
|
||||
}
|
||||
public bool GetChanged(eflag idx)
|
||||
{
|
||||
return _value.GetChanged((int)idx);
|
||||
}
|
||||
public bool Memory_RW_State { get { return GetValue(eflag.Memory_RW_State); } }
|
||||
public bool EXT_IO_Conn_State { get { return GetValue(eflag.EXT_IO_Conn_State); } }
|
||||
public bool RFID_Conn_State { get { return GetValue(eflag.RFID_Conn_State); } }
|
||||
public bool M5E_Module_Run_State { get { return GetValue(eflag.M5E_Module_Run_State); } }
|
||||
public bool Front_Ultrasonic_Conn_State { get { return GetValue(eflag.Front_Ultrasonic_Conn_State); } }
|
||||
public bool Front_Untrasonic_Sensor_State { get { return GetValue(eflag.Front_Untrasonic_Sensor_State); } }
|
||||
public bool Side_Ultrasonic_Conn_State { get { return GetValue(eflag.Side_Ultrasonic_Conn_State); } }
|
||||
public bool Side_Ultrasonic_Sensor_State { get { return GetValue(eflag.Side_Ultrasonic_Sensor_State); } }
|
||||
public bool Front_Guide_Sensor_State { get { return GetValue(eflag.Front_Guide_Sensor_State); } }
|
||||
public bool Rear_Guide_Sensor_State { get { return GetValue(eflag.Rear_Guide_Sensor_State); } }
|
||||
public bool Battery_Level_Check { get { return GetValue(eflag.Battery_Level_Check); } }
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
//모든사태값을 탭으로 구분하여 문자를 생성한다
|
||||
var sb = new System.Text.StringBuilder();
|
||||
for(int i = 0; i < 16; i++)
|
||||
{
|
||||
var def = Enum.IsDefined(typeof(eflag), i);
|
||||
if (def)
|
||||
{
|
||||
var flag = (eflag)i;
|
||||
var value = _value.Get(i);
|
||||
sb.AppendLine($"[{i:00}][{flag}] : {value}");
|
||||
}
|
||||
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public string ToRtfString()
|
||||
{
|
||||
var sb = new System.Text.StringBuilder();
|
||||
sb.AppendLine(@"{\rtf1\ansi\deff0");
|
||||
sb.AppendLine(@"{\colortbl ;\red0\green0\blue255;}"); // Color 1 = Blue
|
||||
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
var def = Enum.IsDefined(typeof(eflag), i);
|
||||
if (def)
|
||||
{
|
||||
var flag = (eflag)i;
|
||||
var value = _value.Get(i);
|
||||
string line = $"[{i:00}][{flag}] : {value}";
|
||||
|
||||
// : true가 포함된 줄은 파란색
|
||||
if (value == true)
|
||||
{
|
||||
sb.AppendLine(@"\cf1 " + line + @"\cf0\line");
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.AppendLine(line + @"\line");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sb.AppendLine("}");
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
128
HMI/SubProject/AGV/Structure/SystemFlag1.cs
Normal file
128
HMI/SubProject/AGV/Structure/SystemFlag1.cs
Normal file
@@ -0,0 +1,128 @@
|
||||
using System;
|
||||
|
||||
namespace arDev
|
||||
{
|
||||
public partial class Narumi
|
||||
{
|
||||
|
||||
public class SystemFlag1
|
||||
{
|
||||
private COMM.Flag _value { get; set; } = new COMM.Flag(16);
|
||||
public void SetValue(Int16 value) { this._value.writeValue(value); }
|
||||
|
||||
public UInt16 Value
|
||||
{
|
||||
get
|
||||
{
|
||||
return (UInt16)_value.Value;
|
||||
}
|
||||
}
|
||||
public enum eflag
|
||||
{
|
||||
Side_Detect_Ignore = 3,
|
||||
Melody_check,
|
||||
Mark2_check,
|
||||
Mark1_check,
|
||||
gateout_check,
|
||||
Battery_charging = 8,
|
||||
re_Start,
|
||||
|
||||
/// <summary>
|
||||
/// 전방 감지 무시
|
||||
/// </summary>
|
||||
front_detect_ignore,
|
||||
|
||||
/// <summary>
|
||||
/// 전방장애물감지상태
|
||||
/// </summary>
|
||||
front_detect_check,
|
||||
|
||||
/// <summary>
|
||||
/// 전방감지 후 정지 상태
|
||||
/// </summary>
|
||||
stop_by_front_detect = 12,
|
||||
/// <summary>
|
||||
/// 교차로 진입 후 정지 상태
|
||||
/// </summary>
|
||||
stop_by_cross_in,
|
||||
agv_stop,
|
||||
agv_run
|
||||
}
|
||||
|
||||
public bool GetValue(eflag idx)
|
||||
{
|
||||
return _value.Get((int)idx);
|
||||
}
|
||||
public bool GetChanged(eflag idx)
|
||||
{
|
||||
return _value.GetChanged((int)idx);
|
||||
}
|
||||
public bool Side_Detect_Ignore { get { return GetValue(eflag.Side_Detect_Ignore); } }
|
||||
public bool Melody_check { get { return GetValue(eflag.Melody_check); } }
|
||||
public bool Mark2_check { get { return GetValue(eflag.Mark2_check); } }
|
||||
public bool Mark1_check { get { return GetValue(eflag.Mark1_check); } }
|
||||
public bool gateout_check { get { return GetValue(eflag.gateout_check); } }
|
||||
public bool Battery_charging { get { return GetValue(eflag.Battery_charging); } }
|
||||
public bool re_Start { get { return GetValue(eflag.re_Start); } }
|
||||
public bool front_detect_ignore { get { return GetValue(eflag.front_detect_ignore); } }
|
||||
public bool front_detect_check { get { return GetValue(eflag.front_detect_check); } }
|
||||
public bool stop_by_front_detect { get { return GetValue(eflag.stop_by_front_detect); } }
|
||||
public bool stop_by_cross_in { get { return GetValue(eflag.stop_by_cross_in); } }
|
||||
public bool agv_stop { get { return GetValue(eflag.agv_stop); } }
|
||||
public bool agv_run { get { return GetValue(eflag.agv_run); } }
|
||||
public bool agv_run_manual { get; set; }
|
||||
public override string ToString()
|
||||
{
|
||||
//모든사태값을 탭으로 구분하여 문자를 생성한다
|
||||
var sb = new System.Text.StringBuilder();
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
var def = Enum.IsDefined(typeof(eflag), i);
|
||||
if (def)
|
||||
{
|
||||
var flag = (eflag)i;
|
||||
var value = _value.Get(i);
|
||||
sb.AppendLine($"[{i:00}][{flag}] : {value}");
|
||||
}
|
||||
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public string ToRtfString()
|
||||
{
|
||||
var sb = new System.Text.StringBuilder();
|
||||
sb.AppendLine(@"{\rtf1\ansi\deff0");
|
||||
sb.AppendLine(@"{\colortbl ;\red0\green0\blue255;}"); // Color 1 = Blue
|
||||
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
var def = Enum.IsDefined(typeof(eflag), i);
|
||||
if (def)
|
||||
{
|
||||
var flag = (eflag)i;
|
||||
var value = _value.Get(i);
|
||||
string line = $"[{i:00}][{flag}] : {value}";
|
||||
|
||||
// : true가 포함된 줄은 파란색
|
||||
if (value == true)
|
||||
{
|
||||
sb.AppendLine(@"\cf1 " + line + @"\cf0\line");
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.AppendLine(line + @"\line");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sb.AppendLine("}");
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user