add emulator
This commit is contained in:
298
Emulator/AGVEmulator/DevPLC.cs
Normal file
298
Emulator/AGVEmulator/DevPLC.cs
Normal file
@@ -0,0 +1,298 @@
|
||||
using System;
|
||||
using static AGVEmulator.DevBMS;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Diagnostics.Contracts;
|
||||
using arCtl;
|
||||
using System.Xml.Schema;
|
||||
using System.Drawing;
|
||||
|
||||
namespace AGVEmulator
|
||||
{
|
||||
class DevPLC : AR.Dev.RS232
|
||||
{
|
||||
byte runtime = 0;
|
||||
|
||||
|
||||
public enum eCommand : byte
|
||||
{
|
||||
LOAD = 0, //EEPROM 불러오기
|
||||
SAVE, //EEPROM 저장
|
||||
RESET, //초기화
|
||||
PINGCHK,
|
||||
SET_PINMODE, //PINMODE 설정
|
||||
SET_DOUTPUT, //디지털출력설정(포트번호,값[1,0])
|
||||
SET_AOUTPUT, //아날로그출력설정(포트GET_SETTING = 50, //셋팅값 요청
|
||||
SET_FLAG,
|
||||
SET_EEPROM,
|
||||
SET_MANUALSPEED,
|
||||
GET_SETTING = 50,
|
||||
GUIDE_MOT = 90, //가이드커버(양쪽) 0=멈춤,1=UP,2=DN 아스키코드표 90=Z
|
||||
SET_EEP_DIREV,
|
||||
};
|
||||
|
||||
public enum DOName
|
||||
{
|
||||
PINO_GUIDEMOTOR_LDIR,
|
||||
PINO_GUIDEMOTOR_LRUN,
|
||||
PINO_GUIDEMOTOR_RDIR,
|
||||
PINO_GUIDEMOTOR_RRUN,
|
||||
PINO_EMPTY_26,
|
||||
PINO_EMPTY_27,
|
||||
PINO_EMPTY_28,
|
||||
PINO_EMPTY_29,
|
||||
}
|
||||
|
||||
public enum DIName
|
||||
{
|
||||
PINI_EMG,
|
||||
PINI_BTN_1,
|
||||
PINI_BTN_2,
|
||||
PINI_BTN_3,
|
||||
PINI_BTN_4,
|
||||
PINI_OVERLOADL,
|
||||
PINI_OVERLOADR,
|
||||
PINI_EMPTY_36,
|
||||
PINI_EMPTY_37,
|
||||
PINI_EMPTY_38,
|
||||
PINI_BTN_ZUP,
|
||||
PINI_BTN_ZDN,
|
||||
PINI_LIMIT_LU,
|
||||
PINI_LIMIT_LD,
|
||||
PINI_LIMIT_RU,
|
||||
PINI_LIMIT_RD,
|
||||
PINI_STOP,
|
||||
}
|
||||
|
||||
public class ValueChangedArgs : EventArgs
|
||||
{
|
||||
public int Idx { get; set; }
|
||||
public bool Value { get; set; }
|
||||
public bool IsOut { get; set; }
|
||||
public ValueChangedArgs(int idx, bool val, bool isOut)
|
||||
{
|
||||
this.Idx = idx;
|
||||
this.Value = val;
|
||||
this.IsOut = isOut;
|
||||
}
|
||||
}
|
||||
|
||||
public class RequestBatteryDataArgs : EventArgs
|
||||
{
|
||||
public UInt32 IOValue { get; set; }
|
||||
public UInt32 FGValue { get; set; }
|
||||
public RequestBatteryDataArgs()
|
||||
{
|
||||
this.IOValue = 0x00;
|
||||
this.FGValue = 0xFF;
|
||||
}
|
||||
}
|
||||
public event EventHandler<RequestBatteryDataArgs> RequestData;
|
||||
public event EventHandler<ValueChangedArgs> ValueChanged;
|
||||
|
||||
public override bool ProcessRecvData(byte[] data)
|
||||
{
|
||||
//dd로 시작하고 34개의 데이터
|
||||
// var sample = "DD 03 00 1B 0A 65 00 00 21 63 29 04 00 00 2C 92 00 00 00 00 00 00 28 51 03 08 02 0B 69 0B 66 FC 9C 77";
|
||||
// var barr = sample.Split(' ').ToList().Select(t => Convert.ToByte(t, 16)).ToArray();
|
||||
var datalne = data[2];
|
||||
byte[] buffer = new byte[datalen];
|
||||
Array.Copy(data, 3, buffer, 0, buffer.Length);
|
||||
|
||||
var cmd = (eCommand)buffer[0];
|
||||
if (cmd == eCommand.GUIDE_MOT)
|
||||
{
|
||||
var p1 = (char)buffer[1];
|
||||
var p2 = (char)buffer[2];
|
||||
|
||||
switch (p1)
|
||||
{
|
||||
case 'A': //all
|
||||
if (p2 == 'P')
|
||||
{
|
||||
ValueChanged?.Invoke(this, new ValueChangedArgs((int)DOName.PINO_GUIDEMOTOR_LRUN, true, true));
|
||||
ValueChanged?.Invoke(this, new ValueChangedArgs((int)DOName.PINO_GUIDEMOTOR_RRUN, true, true));
|
||||
ValueChanged?.Invoke(this, new ValueChangedArgs((int)DOName.PINO_GUIDEMOTOR_LDIR, true, true));
|
||||
ValueChanged?.Invoke(this, new ValueChangedArgs((int)DOName.PINO_GUIDEMOTOR_RDIR, true, true));
|
||||
}
|
||||
else if (p2 == 'N')
|
||||
{
|
||||
ValueChanged?.Invoke(this, new ValueChangedArgs((int)DOName.PINO_GUIDEMOTOR_LRUN, true, true));
|
||||
ValueChanged?.Invoke(this, new ValueChangedArgs((int)DOName.PINO_GUIDEMOTOR_RRUN, true, true));
|
||||
ValueChanged?.Invoke(this, new ValueChangedArgs((int)DOName.PINO_GUIDEMOTOR_LDIR, false, true));
|
||||
ValueChanged?.Invoke(this, new ValueChangedArgs((int)DOName.PINO_GUIDEMOTOR_RDIR, false, true));
|
||||
}
|
||||
else if(p2 == 'S')
|
||||
{
|
||||
ValueChanged?.Invoke(this, new ValueChangedArgs((int)DOName.PINO_GUIDEMOTOR_LRUN, false, true));
|
||||
ValueChanged?.Invoke(this, new ValueChangedArgs((int)DOName.PINO_GUIDEMOTOR_RRUN, false, true));
|
||||
}
|
||||
break;
|
||||
case 'L':
|
||||
if (p2 == 'P')
|
||||
{
|
||||
ValueChanged?.Invoke(this, new ValueChangedArgs((int)DOName.PINO_GUIDEMOTOR_LRUN, true, true));
|
||||
ValueChanged?.Invoke(this, new ValueChangedArgs((int)DOName.PINO_GUIDEMOTOR_LDIR, true, true));
|
||||
}
|
||||
else if (p2 == 'N')
|
||||
{
|
||||
ValueChanged?.Invoke(this, new ValueChangedArgs((int)DOName.PINO_GUIDEMOTOR_LRUN, true, true));
|
||||
ValueChanged?.Invoke(this, new ValueChangedArgs((int)DOName.PINO_GUIDEMOTOR_LDIR, false, true));
|
||||
}
|
||||
else if (p2 == 'S')
|
||||
{
|
||||
ValueChanged?.Invoke(this, new ValueChangedArgs((int)DOName.PINO_GUIDEMOTOR_LRUN, false, true));
|
||||
}
|
||||
break;
|
||||
case 'R':
|
||||
if (p2 == 'P')
|
||||
{
|
||||
ValueChanged?.Invoke(this, new ValueChangedArgs((int)DOName.PINO_GUIDEMOTOR_RRUN, true, true));
|
||||
ValueChanged?.Invoke(this, new ValueChangedArgs((int)DOName.PINO_GUIDEMOTOR_RDIR, true, true));
|
||||
}
|
||||
else if (p2 == 'N')
|
||||
{
|
||||
ValueChanged?.Invoke(this, new ValueChangedArgs((int)DOName.PINO_GUIDEMOTOR_RRUN, true, true));
|
||||
ValueChanged?.Invoke(this, new ValueChangedArgs((int)DOName.PINO_GUIDEMOTOR_RDIR, false, true));
|
||||
}
|
||||
else if (p2 == 'S')
|
||||
{
|
||||
ValueChanged?.Invoke(this, new ValueChangedArgs((int)DOName.PINO_GUIDEMOTOR_RRUN, false, true));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void AutoSendData()
|
||||
{
|
||||
//if (_device.DtrEnable == false) return;
|
||||
|
||||
List<byte> barr = new List<byte>();
|
||||
barr.Add((byte)'@');
|
||||
barr.Add((byte)'@');
|
||||
barr.Add(10);
|
||||
barr.Add((byte)'I');
|
||||
|
||||
//입/출력포트 각 16접 데이터 입력
|
||||
UInt32 iovalue = 0;
|
||||
//플래그 각 16접 데이터 입력
|
||||
UInt32 fgvalue = 0;
|
||||
|
||||
|
||||
if (RequestData != null)
|
||||
{
|
||||
var p = new RequestBatteryDataArgs();
|
||||
RequestData.Invoke(this, p);
|
||||
iovalue = p.IOValue;
|
||||
fgvalue = p.FGValue;
|
||||
}
|
||||
|
||||
|
||||
var arr_volt = BitConverter.GetBytes(iovalue).ToArray();
|
||||
foreach (var b in arr_volt)
|
||||
barr.Add(b);
|
||||
|
||||
|
||||
arr_volt = BitConverter.GetBytes(fgvalue).ToArray();
|
||||
foreach (var b in arr_volt)
|
||||
barr.Add(b);
|
||||
|
||||
|
||||
if (runtime < 255) runtime += 1;
|
||||
else runtime = 0;
|
||||
barr.Add(runtime);
|
||||
|
||||
//체크섬무시
|
||||
barr.Add((byte)'*');
|
||||
//barr.Add((byte)'*');
|
||||
|
||||
barr.Add(0x0D);
|
||||
barr.Add(0x0A);
|
||||
|
||||
RaiseMessage(MessageType.Normal, "Tx:" + barr.ToArray().HexString());
|
||||
WriteData(barr.ToArray());
|
||||
}
|
||||
|
||||
bool findstx2 = false;
|
||||
byte datalen = 0;
|
||||
protected override bool CustomParser(byte[] buf, out byte[] remainBuffer)
|
||||
{
|
||||
//DD A5 03 00 FF FD 77 0D
|
||||
//remainBuffer = new byte[] { };
|
||||
List<byte> remain = new List<byte>();
|
||||
bool retval = false;
|
||||
foreach (var b in buf)
|
||||
{
|
||||
if (retval)
|
||||
{
|
||||
remain.Add(b);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if (findSTX == false)
|
||||
{
|
||||
if (b == '@')
|
||||
{
|
||||
tempBuffer.Clear();
|
||||
tempBuffer.Add(b);
|
||||
findSTX = true;
|
||||
findstx2 = false;
|
||||
datalen = 0;
|
||||
}
|
||||
}
|
||||
else if (findstx2 == false)
|
||||
{
|
||||
if (b == '@')
|
||||
{
|
||||
tempBuffer.Add(b);
|
||||
findstx2 = true;
|
||||
datalen = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
tempBuffer.Clear();
|
||||
findSTX = false;
|
||||
findstx2 = false;
|
||||
}
|
||||
}
|
||||
else if (datalen == 0)
|
||||
{
|
||||
tempBuffer.Add(b);
|
||||
datalen = b;
|
||||
}
|
||||
else
|
||||
{
|
||||
//데이터길이가 만족한 상태
|
||||
tempBuffer.Add(b);
|
||||
var maxlen = datalen + 3 + 3;
|
||||
|
||||
if (tempBuffer.Count == maxlen)
|
||||
{
|
||||
if (tempBuffer[tempBuffer.Count - 1] == 0x0A && tempBuffer[tempBuffer.Count - 2] == 0x0D)
|
||||
{
|
||||
//무조건 맞는걸로 하자 체크섬은 체크하지 말자
|
||||
retval = true;
|
||||
}
|
||||
}
|
||||
else if (tempBuffer.Count > maxlen)
|
||||
{
|
||||
RaiseMessage(MessageType.Error, $"buffer over({maxlen})");
|
||||
findstx2 = false;
|
||||
findSTX = false;
|
||||
datalen = 0;
|
||||
tempBuffer.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
remainBuffer = remain.ToArray();
|
||||
return retval;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user