255 lines
8.8 KiB
C#
255 lines
8.8 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.ComponentModel;
|
|
using System.Threading;
|
|
using COMM;
|
|
using ENIG;
|
|
using System.Security.Cryptography;
|
|
using AR;
|
|
using System.IO.Ports;
|
|
using System.Security.Cryptography.X509Certificates;
|
|
using System.Windows.Forms;
|
|
|
|
namespace Project.Device
|
|
{
|
|
public class Xbee : SerialPort
|
|
{
|
|
public string buffer = string.Empty;
|
|
public System.Text.StringBuilder newbuffer = new StringBuilder();
|
|
public string errorMessage = string.Empty;
|
|
public DateTime LastStatusSendTime { get; set; } = DateTime.Now;
|
|
private EEProtocol proto;
|
|
|
|
public class MessageArgs : EventArgs
|
|
{
|
|
public bool IsError { get; set; }
|
|
public string Message { get; set; }
|
|
public MessageArgs(bool iserr, string m)
|
|
{
|
|
this.IsError = iserr;
|
|
this.Message = m;
|
|
}
|
|
}
|
|
|
|
public event EventHandler<MessageArgs> MessageReceived;
|
|
public event EventHandler<EEProtocol.DataEventArgs> ProtocReceived;
|
|
|
|
public Xbee()
|
|
{
|
|
this.DataReceived += Xbee_DataReceived;
|
|
proto = new EEProtocol();
|
|
proto.OnDataReceived += Proto_OnDataReceived;
|
|
proto.OnMessage += Proto_OnMessage;
|
|
}
|
|
~Xbee()
|
|
{
|
|
this.DataReceived -= Xbee_DataReceived;
|
|
proto.OnDataReceived -= Proto_OnDataReceived;
|
|
proto.OnMessage -= Proto_OnMessage;
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// 지그비장치에 데이터를 전송합니다
|
|
/// </summary>
|
|
/// <param name="data"></param>
|
|
/// <returns></returns>
|
|
public bool Send(byte[] data)
|
|
{
|
|
try
|
|
{
|
|
this.Write(data, 0, data.Length);
|
|
return true;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
errorMessage = ex.Message;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public new bool Open()
|
|
{
|
|
try
|
|
{
|
|
base.Open();
|
|
return IsOpen;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
errorMessage = ex.Message;
|
|
PUB.logxbee.AddE(errorMessage);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
private void Proto_OnDataReceived(object sender, EEProtocol.DataEventArgs e)
|
|
{
|
|
var hexstrRaw = e.ReceivedPacket.RawData.HexString();
|
|
var hexstr = e.ReceivedPacket.Data.HexString();
|
|
var cmd = e.ReceivedPacket.Command.ToString("X2");
|
|
var id = e.ReceivedPacket.ID.ToString("X2");
|
|
PUB.logxbee.Add("RX", $"{hexstrRaw}\nID:{id},CMD:{cmd},DATA:{hexstr}");
|
|
|
|
ProtocReceived?.Invoke(this, e);
|
|
|
|
|
|
|
|
|
|
}
|
|
private void Proto_OnMessage(object sender, EEProtocol.MessageEventArgs e)
|
|
{
|
|
MessageReceived?.Invoke(this, new MessageArgs(e.IsError, e.Message));
|
|
}
|
|
|
|
|
|
private void Xbee_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
|
|
{
|
|
var dev = sender as System.IO.Ports.SerialPort;
|
|
var buffer = new byte[dev.BytesToRead];
|
|
dev.Read(buffer, 0, buffer.Length);
|
|
proto.ProcessReceivedData(buffer);
|
|
}
|
|
/// <summary>
|
|
/// 이동완료 신호 전송
|
|
/// </summary>
|
|
/// <param name="tag">목적지태그값</param>
|
|
public void SendMoveComplete(string tag)
|
|
{
|
|
var id = PUB.setting.XBE_ID;
|
|
byte cmd = (byte)ENIGProtocol.AGVCommandEH.Arrived;
|
|
var data = System.Text.Encoding.Default.GetBytes(tag);
|
|
var packet = proto.CreatePacket(id, cmd, data);
|
|
Send(packet);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 신규 RFID태그값이 읽혔다면 이명령을 통해서 전송한다
|
|
/// </summary>
|
|
public void SendRFIDTag(string tag)
|
|
{
|
|
var id = PUB.setting.XBE_ID;
|
|
byte cmd = (byte)ENIGProtocol.AGVCommandEH.ReadRFID;
|
|
var data = System.Text.Encoding.Default.GetBytes(tag);
|
|
var packet = proto.CreatePacket(id, cmd, data);
|
|
Send(packet);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 오류코드를 호스트에 전송합니다
|
|
/// </summary>
|
|
/// <param name="errcode"></param>
|
|
public void SendError(ENIGProtocol.AGVErrorCode errcode, string errormessage)
|
|
{
|
|
var id = PUB.setting.XBE_ID;
|
|
byte cmd = (byte)ENIGProtocol.AGVCommandEH.Error;
|
|
if (errormessage.Length > 30) errormessage = errormessage.Substring(0, 29);
|
|
|
|
var data = new byte[] { (byte)errcode };
|
|
var datamsg = System.Text.Encoding.Default.GetBytes(errormessage);
|
|
|
|
var packet = proto.CreatePacket(id, cmd, data);
|
|
Send(packet);
|
|
}
|
|
|
|
public bool BufferInReady { get; set; }
|
|
public bool BufferInComplete { get; set; }
|
|
public bool BufferOutComplete { get; set; }
|
|
public bool BufferReadyError { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
/// AGV상태를 Xbee 로 전송한다
|
|
/// </summary>
|
|
public void SendStatus()
|
|
{
|
|
/*
|
|
Mode[1] : 0=manual, 1=auto
|
|
RunSt[1] : 0=stop, 1=run, 2=error
|
|
Diection[1] : 0=straight, 1=left, 2=right, 3=markstop
|
|
Inposition[1] : 0=off, 1=on : 목적위치에 도달완료 시 설정 이동 이동시 OFF됨
|
|
ChargeSt[1] : 0=off, 1=on
|
|
CartSt[1] : 0=off, 1=on, 2=unknown
|
|
LiftSt[1] : 0=down , 1=up, 2=unknown
|
|
LastTag[6] : "000000"
|
|
*/
|
|
try
|
|
{
|
|
byte[] data = new byte[12]; // 총 12바이트 데이터
|
|
|
|
// Mode
|
|
data[0] = (byte)(VAR.BOOL[eVarBool.FLAG_AUTORUN] ? 1 : 0);
|
|
|
|
// RunSt
|
|
if (PUB.AGV.error.Emergency)
|
|
data[1] = 2; // error
|
|
else if (PUB.AGV.system1.agv_run)
|
|
data[1] = 1; // run
|
|
else
|
|
data[1] = 0; // stop
|
|
|
|
// Motor Direction
|
|
if (PUB.AGV.data.Direction == 'F')
|
|
data[2] = 0;
|
|
else if (PUB.AGV.data.Direction == 'B')
|
|
data[2] = 1;
|
|
else
|
|
data[2] = 0xff; //unknown
|
|
|
|
// Magnet Direction
|
|
if (PUB.AGV.data.Sts == 'L')
|
|
data[3] = 1; // left
|
|
else if (PUB.AGV.data.Sts == 'R')
|
|
data[3] = 2; // right
|
|
else if (PUB.AGV.data.Sts == 'S')
|
|
data[3] = 0; // straight
|
|
else
|
|
data[3] = 0xFF; //unknown
|
|
|
|
// Inposition
|
|
data[4] = (byte)(PUB.AGV.system1.agv_stop ? 1 : 0);
|
|
|
|
// ChargeSt
|
|
data[5] = (byte)((VAR.BOOL[eVarBool.FLAG_CHARGEONA] || VAR.BOOL[eVarBool.FLAG_CHARGEONM]) ? 1 : 0);
|
|
|
|
// CartSt
|
|
if (PUB.AGV.signal.cart_detect1 && PUB.AGV.signal.cart_detect2)
|
|
data[6] = 1; // 센서두개가 모두 감지되는 경우
|
|
else if (PUB.AGV.signal.cart_detect1 == false && PUB.AGV.signal.cart_detect2 == false)
|
|
data[6] = 0; // 센서두개가 모두 감지되지 않는 경우
|
|
else
|
|
data[6] = 2; // 센서하나만 감지되는 경우
|
|
|
|
// LiftSt
|
|
if (PUB.AGV.signal.lift_up)
|
|
data[7] = 1; // 위로 올라가는 경우
|
|
else if (PUB.AGV.signal.lift_down)
|
|
data[7] = 0; // 아래로 내려가는 경우
|
|
else
|
|
data[7] = 2; // unknown (기본값)
|
|
|
|
// LastTag
|
|
string lastTag = PUB.AGV.data.TagNo.ToString("0000") ?? "0000";
|
|
byte[] tagBytes = Encoding.ASCII.GetBytes(lastTag.PadRight(4, '0'));
|
|
Array.Copy(tagBytes, 0, data, 8, lastTag.Length);
|
|
|
|
// 데이터 전송
|
|
var cmd = (byte)ENIGProtocol.AGVCommandEH.Status;
|
|
var packet = proto.CreatePacket(PUB.setting.XBE_ID, cmd, data);
|
|
if (Send(packet))
|
|
PUB.logxbee.AddI($"Send status {packet.Length} {packet.HexString()}");
|
|
LastStatusSendTime = DateTime.Now;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
errorMessage = ex.Message;
|
|
PUB.logxbee.AddE(errorMessage);
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
}
|