arMaskterK 프로젝트를 vms2016_cs 레포에서 현 레포로 이동

This commit is contained in:
Arin(asus)
2025-06-21 11:43:19 +09:00
parent 229ec8be66
commit e46b1c709b
22 changed files with 2843 additions and 0 deletions

6
Sub/arMasterK/.gitignore vendored Normal file
View File

@@ -0,0 +1,6 @@
################################################################################
# 이 .gitignore 파일은 Microsoft(R) Visual Studio에서 자동으로 만들어졌습니다.
################################################################################
/Project/bin/Debug
/Project/.vs

View File

@@ -0,0 +1,61 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" 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>{D92246F1-981A-452C-9E0A-09CD9F68B102}</ProjectGuid>
<OutputType>Exe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Demo</RootNamespace>
<AssemblyName>Demo</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<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="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Project\arMasterK.csproj">
<Project>{e0133085-e5f9-4275-9db8-f8f20ef8561f}</Project>
<Name>arMasterK</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@@ -0,0 +1,86 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Demo
{
class Program
{
static arDev.MasterK dev;
static void Main(string[] args)
{
dev = new arDev.MasterK();
dev.Message += dev_Message;
if (!dev.Init("COM8", 9600))
{
Console.WriteLine("init error");
Console.ReadKey();
return;
}
System.Text.StringBuilder sb = new StringBuilder();
sb.AppendLine("=====================");
sb.AppendLine("Master K Protocol Test");
sb.AppendLine("Version : 0.1");
sb.AppendLine("Author : tindevil@nate.com");
sb.AppendLine("=====================");
sb.AppendLine("1. Port 40 - ON");
sb.AppendLine("2. Port 40 - OFF");
sb.AppendLine("3. Port 41 - ON");
sb.AppendLine("4. Port 41 - OFF");
sb.AppendLine("5. Read Port");
sb.AppendLine("9. Exit");
sb.AppendLine("=====================");
sb.Append("Select Menu = ");
while (true)
{
Console.Write(sb.ToString());
var key = Console.ReadKey(true);
//program end
if (key.Key == ConsoleKey.D9) break;
switch (key.Key)
{
case ConsoleKey.D1:
dev.SetOutput(0, true);
break;
case ConsoleKey.D2:
dev.SetOutput(0, false);
break;
case ConsoleKey.D3:
dev.SetOutput(1, true);
break;
case ConsoleKey.D4:
dev.SetOutput(1, false);
break;
case ConsoleKey.D5:
dev.Read_RelayPort();
Console.WriteLine();
Console.WriteLine("========================");
Console.WriteLine("DI:" + dev.GetInputState());
Console.WriteLine("DO:" + dev.GetOutputState());
Console.WriteLine("========================");
Console.WriteLine("Press any key");
Console.ReadKey();
break;
default:
Console.WriteLine("unknown menu number");
break;
}
Console.Clear();
}
Console.WriteLine("Press any key : Exit");
Console.ReadKey(true);
}
static void dev_Message(object sender, arDev.MasterK.MessageEventArgs e)
{
Console.WriteLine((e.IsError ? "[ERR]" : "") + e.Message);
}
}
}

View File

@@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// 어셈블리의 일반 정보는 다음 특성 집합을 통해 제어됩니다.
// 어셈블리와 관련된 정보를 수정하려면
// 이 특성 값을 변경하십시오.
[assembly: AssemblyTitle("Demo")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Demo")]
[assembly: AssemblyCopyright("Copyright © 2018")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// ComVisible을 false로 설정하면 이 어셈블리의 형식이 COM 구성 요소에
// 표시되지 않습니다. COM에서 이 어셈블리의 형식에 액세스하려면
// 해당 형식에 대해 ComVisible 특성을 true로 설정하십시오.
[assembly: ComVisible(false)]
// 이 프로젝트가 COM에 노출되는 경우 다음 GUID는 typelib의 ID를 나타냅니다.
[assembly: Guid("d649cb64-a01f-4f2b-99b2-a2797844f375")]
// 어셈블리의 버전 정보는 다음 네 가지 값으로 구성됩니다.
//
// 주 버전
// 부 버전
// 빌드 번호
// 수정 버전
//
// 모든 값을 지정하거나 아래와 같이 '*'를 사용하여 빌드 번호 및 수정 버전이 자동으로
// 지정되도록 할 수 있습니다.
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

28
Sub/arMasterK/MasterK.sln Normal file
View File

@@ -0,0 +1,28 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0.40629.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "arMasterK", ".\Project\arMasterK.csproj", "{E0133085-E5F9-4275-9DB8-F8F20EF8561F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Demo", ".\Demo\Demo.csproj", "{D92246F1-981A-452C-9E0A-09CD9F68B102}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{E0133085-E5F9-4275-9DB8-F8F20EF8561F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E0133085-E5F9-4275-9DB8-F8F20EF8561F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E0133085-E5F9-4275-9DB8-F8F20EF8561F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E0133085-E5F9-4275-9DB8-F8F20EF8561F}.Release|Any CPU.Build.0 = Release|Any CPU
{D92246F1-981A-452C-9E0A-09CD9F68B102}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D92246F1-981A-452C-9E0A-09CD9F68B102}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D92246F1-981A-452C-9E0A-09CD9F68B102}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D92246F1-981A-452C-9E0A-09CD9F68B102}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

2
Sub/arMasterK/Project/.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
/MasterK.v12.suo
/MasterK.sln

View File

@@ -0,0 +1,236 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace arDev
{
public partial class MasterK
{
[Description("")]
public enum eMsgType
{
[Description("")]
Rx = 0,
[Description("")]
Tx,
RxRaw,
}
[Description("Operation Code , 이 코드값으로 컨트롤 보드에 명령합니다.")]
public enum eOpCode : byte
{
GET_IO_DATA = 0,
RELAY_OUTPUT,
}
/// <summary>
/// digital input/output direction
/// </summary>
public enum eIOPINDIR : byte
{
[Description("Digital Input")]
INPUT = 0,
[Description("Digital Output")]
OUTPUT = 1,
}
/// <summary>
/// error code list
/// </summary>
public enum eErrorCode : byte
{
[Description("포트가사용중입니다.")]
PortBusy = 0,
[Description("열려있지않습니다.")]
NotOpen,
[Description("쓰기오류")]
WriteError,
[Description("읽기오류")]
ReadError,
[Description("프레임오류")]
FrameError,
[Description("체크섬오류")]
ChecksumError
}
/// <summary>
/// message frame
/// </summary>
public struct sRecvMessage
{
/// <summary>
/// 국번
/// </summary>
public string Device;
/// <summary>
/// 명령어
/// </summary>
public char Command;
/// <summary>
/// 명령어타입
/// </summary>
public string CmdType;
/// <summary>
/// 블록수
/// </summary>
public int BlockCount;
/// <summary>
/// 데이터갯수
/// </summary>
public int DataLen;
/// <summary>
/// 데이터
/// </summary>
public string Data;
public string FullString;
/// <summary>
/// full message frame
/// </summary>
[Description("전체 메세지 영역")]
public byte[] Buffer;
/// <summary>
/// check byte (crc16)
/// </summary>
[Description("체크섬 2byte(CRC 16)")]
public byte[] checksum;
/// <summary>
/// checksum error
/// </summary>
[Description("체크섬에 오류가 있는지 확인합니다.(true일경우 오류)")]
public Boolean isCSError;
[Description("기타메세지")]
public string Message;
[Description("정보를 삭제합니다.")]
public void Clear()
{
Message = "NOTSET";
Data = null;
Buffer = null;
checksum = null;
isCSError = false;
BlockCount = 0;
DataLen = 0;
FullString = string.Empty;
}
[Description("응답코드가 NAK인지확인합니다. NAK응답은 컨트롤러로부터 오류가 수신되었음을 의미합니다.")]
public Boolean isNAK
{
get
{
if (Buffer[0] == 0x15) return true;
else return false;
}
}
[Description("오류가 있는지 체크합니다. 버퍼가 없거나 체크섬 오류 , DLC오류등을 체크 합니다.")]
public Boolean isError
{
get
{
if (Buffer == null || isCSError || BlockCount == 0 || isNAK) return true;
else return false;
}
}
}
public struct sSendMessage
{
/// <summary>
/// 국번
/// </summary>
public string Device;
/// <summary>
/// 명령어
/// </summary>
public char Command;
/// <summary>
/// 명령어타입
/// </summary>
public string CmdType;
/// <summary>
/// 변수길이
/// </summary>
public int DeviceLength;
public int NumberofBlock;
/// <summary>
/// 변수명
/// </summary>
public string VarName;
/// <summary>
/// 데이터갯수
/// </summary>
public int DataLen;
public string Data;
/// <summary>
/// full message frame
/// </summary>
[Description("전체 메세지 영역")]
public byte[] Buffer;
public string Strbuffer;
/// <summary>
/// check byte (crc16)
/// </summary>
[Description("체크섬 2byte(CRC 16)")]
public byte[] checksum;
/// <summary>
/// checksum error
/// </summary>
[Description("체크섬에 오류가 있는지 확인합니다.(true일경우 오류)")]
public Boolean isCSError;
[Description("기타메세지")]
public string Message;
[Description("정보를 삭제합니다.")]
public void Clear()
{
Data = string.Empty;
Message = "NOTSET";
Buffer = null;
checksum = null;
isCSError = false;
DeviceLength = 0;
NumberofBlock = 0;
DataLen = 0;
Strbuffer = string.Empty;
}
[Description("오류가 있는지 체크합니다. 버퍼가 없거나 체크섬 오류 , DLC오류등을 체크 합니다.")]
public Boolean isError
{
get
{
if (Buffer == null || isCSError || DeviceLength == 0) return true;
else return false;
}
}
}
}
}

View File

@@ -0,0 +1,131 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace arDev
{
public partial class MasterK
{
public class DataEventArgs : EventArgs
{
private byte[] _buffer = null;
/// <summary>
/// 바이트배열의 버퍼값
/// </summary>
public byte[] Value { get { return _buffer; } }
public eMsgType Direction { get; set; }
/// <summary>
/// 버퍼(바이트배열)의 데이터를 문자로 반환합니다.
/// </summary>
public string StrValue
{
get
{
if (_buffer == null || _buffer.Length < 1) return string.Empty;
return System.Text.Encoding.Default.GetString(_buffer);
}
}
public DataEventArgs(eMsgType dir_, byte[] buffer)
{
_buffer = buffer;
Direction = dir_;
}
}
public class MessageEventArgs : EventArgs
{
protected Boolean _isError = false;
public Boolean IsError { get { return _isError; } }
protected string _message = string.Empty;
public string Message { get { return _message; } }
public MessageEventArgs(Boolean isError, string Message)
{
_isError = isError;
_message = Message;
}
}
public class FrameEventArgs : EventArgs
{
public eOpCode OpCode { get; set; }
public FrameEventArgs(eOpCode opCode_)
{
OpCode = opCode_;
}
}
public class IOValueEventArgs : EventArgs
{
protected eIOPINDIR _direction;
protected int _arridx;
protected Boolean _oldvalue;
protected Boolean _newvalue;
public eIOPINDIR Direction { get { return _direction; } }
public int ArrIDX { get { return _arridx; } }
public Boolean OldValue { get { return _oldvalue; } }
public Boolean NewValue { get { return _newvalue; } }
public IOValueEventArgs(eIOPINDIR dir, int arridx, Boolean oldvalue, Boolean newvalue)
{
_direction = dir;
_arridx = arridx;
_oldvalue = oldvalue;
_newvalue = newvalue;
}
}
public class AIValueEventArgs : EventArgs
{
public float[] Value { get; protected set; }
public AIValueEventArgs(float[] value_)
{
Value = value_;
}
}
#region "Events"
/// <summary>
/// 일반적인 메세지 혹은 오류메세지 이벤트
/// </summary>
public event EventHandler<MessageEventArgs> Message;
/// <summary>
/// 데이터메시이벤트 (Rx,Tx) 별로 구분됩니다.
/// </summary>
public event EventHandler<DataEventArgs> DataMessage;
/// <summary>
/// 가공되어진 최종 메세지 형태값을 가지고 있습니다.
/// </summary>
public event EventHandler<FrameEventArgs> ReceiveFrame;
/// <summary>
/// ReadProcess에의해서 감시되며 포트의 상태값이 바뀐다면 발생함
/// </summary>
public event EventHandler<IOValueEventArgs> IOValueChanged;
/// <summary>
/// AI의 값을 이벤트로 발생합니다.발생주기는 AIInterval을 참고합니다.
/// </summary>
public event EventHandler<AIValueEventArgs> AIValueChanged;
/// <summary>
/// 오류발생시 메세지가 발생함
/// </summary>
public event EventHandler<MessageEventArgs> IOErrorMessage;
/// <summary>
/// anlog 관련한 오류 메세지
/// </summary>
/// <remarks>Analog Data Error Message</remarks>
public event EventHandler<MessageEventArgs> AIErrorMessage;
#endregion
}
}

View File

@@ -0,0 +1,13 @@
181005 chi init 시 baudrate 를 기본값 19200 설정
180802 chi init 시에 baudrate 도 입력하도록 함
180625 chi TestVersion 0.1;
RunMonitor 가 중복실행되지 않도록 수정
makepacket 수정
00RSB06%PW00001
00WSS0107%PX004001
[18-03-29 06:45:38] RAW: 06 30 30 52 53 42 30 31 30 32 30 30 30 30 03
00RSB01020000
180329 Create

View File

@@ -0,0 +1,686 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.ComponentModel;
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Design;
using System.Reflection;
using System.Runtime;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
namespace arDev
{
public partial class MasterK : IDisposable
{
#region "Variable"
public bool bRunMonitor; //쓰레드작동시그널
public Boolean bAIMonitor=false; //배경쓰레드에서 아날로그값을 모니터링 합니다.\
public Boolean bDIOMonitor=true; //배경쓰레드에서 dIO를 모니터링 할것인가?
public string errorMessage = string.Empty;
System.Diagnostics.Stopwatch aiMonWatch = new System.Diagnostics.Stopwatch();
public long LoopDelay;
protected byte wSTX = 0x05;
protected byte wETX = 0x04;
protected byte rSTX = 0x06;
protected byte rETX = 0x03;
protected int interchar_delay;
protected Boolean bSyncRecvOK = false;// 메세지를 수신할 경우 설정됩니다.
protected Boolean _isInit = false;// 보드가 초기화가 되었는지 확인합니다.
public Boolean disposed = false;// Dipose 되었는가?
protected byte _CommandCode = 0x00;// recv command code
protected Boolean _bDlc = false;
protected int _dlc = 0;
protected Boolean _bStx = false; //stx를 찾앗는지?
protected Boolean _bEtx = false; //etx를 찾앗는지?
protected Boolean[] _valueI; //입력접점
protected Boolean[] _valueO; //출력접점
protected Boolean[] OldvalueI;
protected Boolean[] OldvalueO;
protected Thread thMonitor; //배경쓰레드(상태체크 및 이벤트 발생)
protected ManualResetEvent _mre;
protected string _mreowner = string.Empty;
protected System.Diagnostics.Stopwatch wat = new System.Diagnostics.Stopwatch();
protected System.IO.Ports.SerialPort _device;
public int DOCount { get; protected set; }
public int DICount { get; protected set; }
public double ThreadSpeed = 0;
public sRecvMessage LastRecvMessage;
public sSendMessage lastSendMessage;
public DateTime lastSendTime;
public byte[] lastSendBuffer;
/// <summary>
/// device index
/// </summary>
public byte IDX = 0;
#endregion
public MasterK()
{
//serial port
_device = new System.IO.Ports.SerialPort();
_device.BaudRate = 9600;
_device.DtrEnable = false;
_device.WriteTimeout = 2000;
_device.ReadTimeout = 2000;
_device.DiscardNull = true;
//autoreset events
_mre = new System.Threading.ManualResetEvent(true);
bRunMonitor = false;
LoopDelay = 150;
//모든ls산전은 논리적으로 64개가 지정되어있다.
this.DICount = 64;
this.DOCount = 64;
//변수초기화
this._valueI = new bool[DICount];
this._valueO = new bool[DOCount];
this.OldvalueI = new bool[_valueI.Length];
this.OldvalueO = new bool[_valueO.Length];
//초기값설정(인풋)
for (int i = 0; i < _valueI.Length; i++)
{
this._valueI[i] = false;
this.OldvalueI[i] = false;
}
//초기값설정(아웃풋)
for (int i = 0; i < _valueO.Length; i++)
{
this._valueO[i] = false;
this.OldvalueO[i] = false;
}
}
~MasterK()
{
Dispose(false);
}
public void Close()
{
if (_device.IsOpen)
{
if (_mre.WaitOne(3000))
{
_mre.Reset();
_mreowner = "Close";
_device.Close();
_mre.Set();
}
else
{
RaiseMessage(true, "close error timeout");
}
}
}
/// <summary>
/// 개체를 해제합니다.
/// </summary>
[Description("")]
public virtual void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
// Protected implementation of Dispose pattern.
protected virtual void Dispose(bool disposing)
{
if (disposed)
return;
if (disposing)
{
// Dispose managed resources.
}
StopMonitor();
// Call the appropriate methods to clean up
// unmanaged resources here.
// If disposing is false,
// only the following code is executed.
// Note disposing has been done.
disposed = true;
}
public string PortName
{
get
{
return _device.PortName;
}
set
{
_device.PortName = value;
}
}
public Boolean Init(string port,int baud = 19200)
{
Close();
errorMessage = string.Empty;
_device.PortName = port;
_device.BaudRate = baud;
try
{
_device.Open();
_device.DiscardInBuffer();
_device.DiscardOutBuffer();
_isInit = true;
sw_ch = new System.Diagnostics.Stopwatch();
interchar_delay = GetIntercharDelay();
interframe_delay = GetInterframeDelay();
}
catch (Exception ex)
{
_isInit = false;
errorMessage = ex.Message;
RaiseMessage(true, ex.Message);
}
return _isInit;
}
#region "Properties"
/// <summary>
/// 입력핀 상태값을 확인합니다.
/// </summary>
/// <param name="arridx">0부터 시작하는 인덱스값</param>
/// <returns></returns>
[Description("")]
public Boolean INPUT(int arridx)
{
if (arridx < 0 || arridx > DICount - 1)
{
if (IOErrorMessage != null)
IOErrorMessage(this, new MessageEventArgs(true, "INPUT Command : ArrayIndex Error Value=" + arridx.ToString()));
return false;
}
return this._valueI[arridx];
}
/// <summary>
/// 입력핀 상태를 모두 반환합니다.
/// </summary>
[Description("")]
public Boolean[] getInputArray
{
get
{
return (Boolean[])this._valueI.Clone();
}
}
public byte getInputValueToByte(int startindex)
{
System.Collections.BitArray ba = new System.Collections.BitArray(this._valueI);
byte[] value = new byte[8];
ba.CopyTo(value, startindex);
return value[0];
}
public Int64 getInputValue
{
get
{
System.Collections.BitArray ba = new System.Collections.BitArray(this._valueI);
byte[] value = new byte[8];
ba.CopyTo(value, 0);
return BitConverter.ToInt64(value, 0);
}
}
/// <summary>
/// 출력핀 상태를 모두 반환합니다.
/// </summary>
[Description("")]
public Boolean[] getOutputArray
{
get
{
return (Boolean[])this._valueO.Clone();
}
}
/// <summary>
/// 출력핀 상태 값을 확인합니다.
/// </summary>
/// <param name="arridx">0부터 시작하는 인덱스값</param>
/// <returns></returns>
[Description("")]
public Boolean OUTPUT(int arridx)
{
// get { return (Boolean[])this._valueO.Clone(); }
if (arridx < 0 || arridx > DOCount - 1)
{
if (IOErrorMessage != null)
IOErrorMessage(this, new MessageEventArgs(true, "OUTPUT Command : ArrayIndex Error Value=" + arridx.ToString()));
return false;
}
return this._valueO[arridx];
}
/// <summary>
/// read digital input port state
/// </summary>
/// <returns></returns>
[Description("")]
public string GetInputState()
{
System.Text.StringBuilder sb = new StringBuilder();
for (int i = 0; i < OldvalueI.Length; i++)
sb.Append(OldvalueI[i] ? "1" : "0");
return sb.ToString();
}
/// <summary>
/// read digital output port state
/// </summary>
/// <returns></returns>
[Description("")]
public string GetOutputState()
{
System.Text.StringBuilder sb = new StringBuilder();
for (int i = 0; i < OldvalueO.Length; i++)
sb.Append(OldvalueO[i] ? "1" : "0");
return sb.ToString();
}
#endregion
#region "Method"
/// <summary>
/// 오류메세지 반환
/// </summary>
/// <returns></returns>
[Description("")]
public string GetErrorMessage()
{
return this.errorMessage;
}
#region "raise Message"
/// <summary>
/// 일반메세지륿 라생시킵니다.
/// </summary>
/// <param name="isError"></param>
/// <param name="message"></param>
[Description("")]
public void RaiseMessage(Boolean isError, string message)
{
if (isError) errorMessage = message; //170920
if (Message != null) Message(this, new MessageEventArgs(isError, message));
}
/// <summary>
/// 지정한 데이터로 바코드가 수신된것처럼 발생시킵니다.(Parser를 사용함)
/// </summary>
/// <param name="b"></param>
[Description("")]
public void RaiseDataMessage(eMsgType dir, byte[] Data)
{
try
{
if (dir == eMsgType.Rx) Parse_RecvBuffer(Data);
if (DataMessage != null) DataMessage(this, new DataEventArgs(dir,Data));
}
catch (Exception ex)
{
errorMessage = ex.Message;
RaiseMessage(true, "RaiseDataMessage:" + ex.Message);
}
}
#endregion
/// <summary>
/// Input / Output 핀 상태를 지속적으로 읽는 쓰레드작업을 시작합니다.
/// </summary>
[Description("")]
public void RunMonitor(int loopDelay_ = 150)
{
this.LoopDelay = loopDelay_;
if(!this.bRunMonitor)
{
this.bRunMonitor = true;
this.thMonitor = new Thread(new ThreadStart(this.bwMonitor));
this.thMonitor.IsBackground = true;
this.thMonitor.Start();
}
}
/// <summary>
/// INPUT/OUPUT 핀 상태를 모니터링하는 쓰레드를 종료시킵니다.
/// </summary>
/// <returns></returns>
[Description("")]
public bool StopMonitor()
{
try
{
this.bRunMonitor = false;
RaiseMessage(false, "Stop Monitor");
return true;
}
catch (Exception ex)
{
RaiseMessage(true, ex.Message);
return false;
}
}
/// <summary>
/// 지정한 출력포트의 값을 반전 시킵니다.
/// </summary>
/// <param name="arrIndex"></param>
/// <returns></returns>
[Description("")]
public Boolean SetToggle(int arrIndex)
{
if (!IsInit) return false;
if (arrIndex < 0 || (arrIndex + 1) > DOCount)
throw new Exception(string.Format("IDX Range Errror({0}~{1})", 0, DOCount-1));
Boolean currentValue = OUTPUT(arrIndex);
return SetOutput(arrIndex, !currentValue);
}
/// <summary>
/// 출력을 설정합니다.
/// </summary>
/// <param name="arrIndex"></param>
/// <param name="Value"></param>
/// <param name="Duration"></param>
/// <returns></returns>
[Description("")]
public Boolean SetOutput(int arrIndex, Boolean Value, int Duration = 0)
{
errorMessage = string.Empty;
if (!IsInit)
{
//RaiseMessage(true, "SetOutput:No Init");
return false;
}
//RaiseMessage(false, "Set Output Index=" + arrIndex.ToString() + ",Value=" + Value.ToString());
if (arrIndex < 0 || (arrIndex + 1) > DOCount)
{
RaiseMessage(true, "SetOutput:ArrIndex Error = " + arrIndex.ToString());
return false;
}
if (!_mre.WaitOne(1000))
{
RaiseMessage(true, "SetOutput Wait on timeout");
return false;
}
_mre.Reset();
if (Duration < 0) Duration = 0;
int Port = 0x40 + arrIndex; //출력포트는 64번부터 시작한다.
string cmd = "00WSS0107%PX00" + Port.ToString("X2") + (Value ? "01":"00");
//해당라인에 그값을 쓴다.
Boolean bRet = true;
try
{
var buffer = WriteSync(cmd);
string strBuffer = System.Text.Encoding.Default.GetString(buffer);
if (buffer == null)
{
RaiseMessage(true, "SetOutput:No Response");
bRet= false;
}
else
{
if(buffer[0] == 0x06)
{
if (Duration != 0)
{
var task = new Task(() =>
{
Thread.Sleep(Duration);
string cmd2 = "00WSS0107%PX00" + Port.ToString("X2") + (Value ? "00" : "01");
var buffer2 = WriteSync(cmd2);
if (buffer2 == null)
{
RaiseMessage(true, "SetOutput:Duration toggle Error:No Reponse");
}
});
task.Start(); //비동기로 실행한다.
}
}
else
{
RaiseMessage(true, "SetOutput:Nak response");
bRet = false;
}
}
}
catch (Exception ex)
{
RaiseMessage(true, "SetOutput:"+ex.Message);
bRet = false;
}
_mre.Set();
return bRet;
}
/// <summary>
/// 이벤트를 강제 생성합니다.
/// </summary>
/// <param name="Direction"></param>
/// <param name="ArrIDX"></param>
/// <param name="newvalue"></param>
[Description("")]
public void RaiseEvent(eIOPINDIR Direction, int ArrIDX, Boolean newvalue)
{
if (IOValueChanged != null)
{
//mre.WaitOne();
//mre.Reset();
//171226
if (Direction == eIOPINDIR.INPUT)
{
_valueI[ArrIDX] = newvalue;
OldvalueI[ArrIDX] = newvalue;
}
else
{
_valueO[ArrIDX] = newvalue;
OldvalueO[ArrIDX] = newvalue;
}
try
{
if (IOValueChanged != null)
IOValueChanged(this, new IOValueEventArgs(Direction, ArrIDX, !newvalue, newvalue));
}
catch (Exception ex)
{
if (IOErrorMessage != null)
this.IOErrorMessage(this, new MessageEventArgs(true , string.Format( "{0},{1}:{2}:{3}",ex.Message,Direction,ArrIDX,newvalue)));
}
//mre.Set();
}
}
public virtual void UserMonitorCode() { }
private byte loopIndex = 0;
/// <summary>
/// I/O상태를 모니터링 하여 내부 변수에 값을 저장합니다.
/// </summary>
[Description("")]
protected void bwMonitor()
{
DateTime lastaitime = DateTime.Now;
DateTime lastmottime = DateTime.Now;
System.Diagnostics.Stopwatch wat = new System.Diagnostics.Stopwatch();
while (this.bRunMonitor)
{
wat.Restart();
//170905
if (!IsInit)
{
aiMonWatch.Stop();
System.Threading.Thread.Sleep(1000);
continue;
}
else
{
if (!aiMonWatch.IsRunning) aiMonWatch.Reset();
}
//read dio status
if (loopIndex == 0)
{
//RaiseMessage(false,"Run IOMonitor");
if (bDIOMonitor)
Read_RelayPort();
loopIndex += 1;
}
else
{
//RaiseMessage(false, "Run AIMonitor");
UserMonitorCode();
loopIndex = 0;
}
wat.Stop();
ThreadSpeed = wat.ElapsedMilliseconds;
if(wat.ElapsedMilliseconds < LoopDelay)
{
Thread.Sleep((int)(LoopDelay- wat.ElapsedMilliseconds));
}
}
wat.Stop();
}
#endregion
#region "Send Method"
//public Boolean Read_AIPort()
//{
// if (!_mre.WaitOne(1000))
// {
// RaiseMessage(true, "Read_AIPort Wait on timeout");
// return false;
// }
// //RaiseMessage(false, "Read_AIPort");
// _mre.Reset();
// System.Threading.Thread.Sleep(25);
// _mre.Set();
// return true;
//}
public Boolean isValid
{
get
{
var ts = DateTime.Now - lastrecvTime;
if (ts.TotalSeconds > 5) return false;
else return true;
}
}
private DateTime lastrecvTime = DateTime.Now;
public Boolean Read_RelayPort()
{
if(!_mre.WaitOne(1000))
{
RaiseMessage(true, "Read_RelayPort Wait on timeout");
return false;
}
// RaiseMessage(false, "Read_RelayPort");
_mre.Reset();
var packet = MakePacket(0, 'R', "SB","%PW000", 8); //"00RSB06%PW00008"
var buffer = WriteSync(packet);
if(buffer != null)
{
var frame = Parse_RecvBuffer(buffer);
if(!frame.isError)
{
this.Run_RelayPortData(ref frame);
lastrecvTime = DateTime.Now;
}
LastRecvMessage = frame;
}
_mre.Set();
return buffer != null;
}
/// <summary>
///
/// </summary>
/// <param name="Station">0~9</param>
/// <param name="Command">R,W</param>
/// <param name="CmdType">SB,SW ??</param>
/// <param name="Device">%PW000</param>
/// <param name="NumberofData">1</param>
/// <param name="data">HexString</param>
/// <returns></returns>
public string MakePacket(byte Station,char Command,string CmdType,string Device,byte NumberofData,string data = "")
{
string buffer = Station.ToString("X2").PadLeft(2, '0') +
Command +
CmdType +
Device.Length.ToString("X2").PadLeft(2, '0') +
Device +
NumberofData.ToString("X2").PadLeft(2, '0');
if (data != "") buffer += data;
return buffer;
}
#endregion
}
}

View File

@@ -0,0 +1,230 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace arDev
{
public partial class MasterK
{
public sRecvMessage Parse_RecvBuffer(byte[] buffer)
{
sRecvMessage frame = new sRecvMessage();
frame.Clear();
frame.Message = string.Empty;
if(buffer==null)
{
frame.Message = "null buffer";
return frame;
}
frame.FullString = System.Text.Encoding.Default.GetString(buffer);
if (buffer == null || buffer.Length < 5)
{
frame.Message = "No Buffer";
errorMessage = frame.Message;
return frame;
}
//buffer copy
frame.Buffer = new byte[buffer.Length];
buffer.CopyTo(frame.Buffer, 0);
if ((buffer[0] != 0x06 && buffer[0] != 0x15) || buffer[buffer.Length - 1] != 0x03)
{
frame.Message = "No STX,ETX";
errorMessage = frame.Message;
return frame;
}
try
{
frame.checksum = new byte[2];
frame.isCSError = false;// !CheckCrc(buffer);
frame.Device = System.Text.Encoding.Default.GetString(buffer, 1, 2);
frame.Command = (char)buffer[3];
frame.CmdType = System.Text.Encoding.Default.GetString(buffer, 4, 2);
//쓰기명령은 데이터가 없다.
if (frame.Command == 'W')
{
frame.BlockCount = 0;
frame.DataLen = 0;
frame.Data = null;
}
else
{
if (!frame.isNAK)
{
frame.BlockCount = Convert.ToInt32(System.Text.Encoding.Default.GetString(buffer, 6, 2), 16);
frame.DataLen = Convert.ToInt32(System.Text.Encoding.Default.GetString(buffer, 8, 2), 16);
int stringDataLen = frame.BlockCount * frame.DataLen * 2;
if (frame.FullString.Length < stringDataLen + 10)
{
frame.BlockCount = 0;
frame.Data = string.Empty;
errorMessage = "Frame length Error:" + frame.FullString;
}
else
{
frame.Data = frame.FullString.Substring(10, stringDataLen); //, 10, DataBufferLen);
}
}
}
} catch(Exception ex) //180706
{
frame.BlockCount = 0;
errorMessage = ex.Message;
}
if (frame.isError && errorMessage == "") errorMessage = "Recvbuffer Has Error";
return frame;
}
public sSendMessage Parse_SendBuffer(byte[] buffer)
{
sSendMessage msg = new sSendMessage();
msg.Clear();
msg.Message = string.Empty;
if (buffer == null || buffer.Length < 5)
{
msg.Message = "No Buffer";
errorMessage = msg.Message;
return msg;
}
//buffer copy
msg.Buffer = new byte[buffer.Length];
msg.Strbuffer = System.Text.Encoding.Default.GetString(buffer);
buffer.CopyTo(msg.Buffer, 0);
if ((buffer[0] != wSTX) || buffer[buffer.Length - 1] != wETX)
{
msg.Message = "No STX,ETX";
errorMessage = msg.Message;
return msg;
}
msg.checksum = new byte[2];
msg.isCSError = false;// !CheckCrc(buffer);
msg.Device = System.Text.Encoding.Default.GetString(buffer, 1, 2);
msg.Command = (char)buffer[3];
if (msg.Command == 'R')
{
msg.CmdType = msg.Strbuffer.Substring(4, 2);
msg.DeviceLength = int.Parse(msg.Strbuffer.Substring( 6, 2));
msg.VarName = msg.Strbuffer.Substring( 8, msg.DeviceLength);
msg.DataLen = int.Parse(msg.Strbuffer.Substring( 8 + msg.DeviceLength, 2));
} else if (msg.Command == 'W')
{
msg.CmdType = System.Text.Encoding.Default.GetString(buffer, 4, 2);
if(msg.CmdType == "SB")
{
//블록수가 없다.
msg.NumberofBlock = 0;
msg.DeviceLength = int.Parse(msg.Strbuffer.Substring(6, 2));
msg.VarName = msg.Strbuffer.Substring(8, msg.DeviceLength);
msg.DataLen = Convert.ToByte(msg.Strbuffer.Substring(8 + msg.DeviceLength, 2),16);
int remain = msg.Strbuffer.Length - 2 - 10 - msg.DeviceLength+1;
msg.Data = msg.Strbuffer.Substring(10 + msg.DeviceLength, remain);
}
else
{
msg.NumberofBlock = int.Parse(msg.Strbuffer.Substring(6, 2));
msg.DeviceLength = int.Parse(msg.Strbuffer.Substring(8, 2));
msg.VarName = msg.Strbuffer.Substring(10, msg.DeviceLength);
msg.Data = msg.Strbuffer.Substring(10 + msg.DeviceLength, 2);
msg.DataLen = (int)(msg.Data.Length / 2.0);
}
}
return msg;
}
/// <summary>
/// 수신된 데이터를 분석하고 관련 메세지를 생성합니다.
/// </summary>
/// <param name="opCode"></param>
/// <param name="dataBuffer"></param>
[Description("")]
protected void Run_RelayPortData(ref sRecvMessage message)
{
if (message.isNAK) return; //req nak process
if (message.Command == 'R')
{
if (message.CmdType == "SB")
{
var Port = lastSendMessage.VarName.Substring(1, 1);
var DataType = lastSendMessage.VarName.Substring(2, 1);
//int DataLen = 0;
//if (DataType == "W") DataLen = 16;
switch (Port)
{
case "P": //relay
//들어온값이 16진수 문자형태이므로 숫자로 변경
var InBufferStrH = message.Data.Substring(0, 8);
var InBufferStrL = message.Data.Substring(8, 8);
var OtBufferStrH = message.Data.Substring(16, 8);
var OtBufferStrL = message.Data.Substring(24, 8);
Int32 numvalueHI = Convert.ToInt32(InBufferStrL, 16);
Int32 numvalueLI = Convert.ToInt32(InBufferStrH, 16);
Int32 numvalueHO = Convert.ToInt32(OtBufferStrL, 16);
Int32 numvalueLO = Convert.ToInt32(OtBufferStrH, 16);
var bufHI = BitConverter.GetBytes(numvalueHI).ToArray();
var bufLI = BitConverter.GetBytes(numvalueLI).ToArray();
var bufHO = BitConverter.GetBytes(numvalueHO).ToArray();
var bufLO = BitConverter.GetBytes(numvalueLO).ToArray();
System.Collections.BitArray b = new System.Collections.BitArray(new byte[] { bufLI[2], bufLI[3], bufLI[0], bufLI[1] });
for (int i = 0; i < b.Length; i++)
{
this._valueI[i] = b.Get(i);
if (OldvalueI[i] != this._valueI[i])
{
try
{
if (IOValueChanged != null)
IOValueChanged(this, new IOValueEventArgs(eIOPINDIR.INPUT, i, OldvalueI[i], _valueI[i]));
}
catch (Exception ex)
{
if (IOErrorMessage != null)
IOErrorMessage(this, new MessageEventArgs(true, ex.Message));
}
this.OldvalueI[i] = this._valueI[i];
}
}
System.Collections.BitArray bO = new System.Collections.BitArray(new byte[] { bufLO[2], bufLO[3], bufLO[0], bufLO[1] });
for (int i = 0; i < bO.Length; i++)
{
this._valueO[i] = bO.Get(i);
if (OldvalueO[i] != this._valueO[i])
{
try
{
if (IOValueChanged != null)
IOValueChanged(this, new IOValueEventArgs(eIOPINDIR.OUTPUT, i, OldvalueO[i], _valueO[i]));
}
catch (Exception ex)
{
if (IOErrorMessage != null)
IOErrorMessage(this, new MessageEventArgs(true, ex.Message));
}
this.OldvalueO[i] = this._valueO[i];
}
}
break;
}
}
}
}
}
}

View File

@@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// 어셈블리의 일반 정보는 다음 특성 집합을 통해 제어됩니다.
// 어셈블리와 관련된 정보를 수정하려면
// 이 특성 값을 변경하십시오.
[assembly: AssemblyTitle("MasterK PLC I/O DLL")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("SIMP")]
[assembly: AssemblyProduct("MasterKDLL")]
[assembly: AssemblyCopyright("Copyright © SIMP 2018")]
[assembly: AssemblyTrademark("SimpleSoft")]
[assembly: AssemblyCulture("")]
// ComVisible을 false로 설정하면 이 어셈블리의 형식이 COM 구성 요소에
// 표시되지 않습니다. COM에서 이 어셈블리의 형식에 액세스하려면
// 해당 형식에 대해 ComVisible 특성을 true로 설정하십시오.
[assembly: ComVisible(false)]
// 이 프로젝트가 COM에 노출되는 경우 다음 GUID는 typelib의 ID를 나타냅니다.
[assembly: Guid("59413cb9-8a6a-4a66-92c1-94d7baea812d")]
// 어셈블리의 버전 정보는 다음 네 가지 값으로 구성됩니다.
//
// 주 버전
// 부 버전
// 빌드 번호
// 수정 버전
//
// 모든 값을 지정하거나 아래와 같이 '*'를 사용하여 빌드 번호 및 수정 버전이 자동으로
// 지정되도록 할 수 있습니다.
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("18.08.02.1730")]
[assembly: AssemblyFileVersion("18.08.02.1730")]

View File

@@ -0,0 +1,63 @@
//------------------------------------------------------------------------------
// <auto-generated>
// 이 코드는 도구를 사용하여 생성되었습니다.
// 런타임 버전:4.0.30319.42000
//
// 파일 내용을 변경하면 잘못된 동작이 발생할 수 있으며, 코드를 다시 생성하면
// 이러한 변경 내용이 손실됩니다.
// </auto-generated>
//------------------------------------------------------------------------------
namespace arDev.Properties {
using System;
/// <summary>
/// 지역화된 문자열 등을 찾기 위한 강력한 형식의 리소스 클래스입니다.
/// </summary>
// 이 클래스는 ResGen 또는 Visual Studio와 같은 도구를 통해 StronglyTypedResourceBuilder
// 클래스에서 자동으로 생성되었습니다.
// 멤버를 추가하거나 제거하려면 .ResX 파일을 편집한 다음 /str 옵션을 사용하여 ResGen을
// 다시 실행하거나 VS 프로젝트를 다시 빌드하십시오.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources() {
}
/// <summary>
/// 이 클래스에서 사용하는 캐시된 ResourceManager 인스턴스를 반환합니다.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("arDev.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// 이 강력한 형식의 리소스 클래스를 사용하여 모든 리소스 조회에 대해 현재 스레드의 CurrentUICulture 속성을
/// 재정의합니다.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
}
}

View File

@@ -0,0 +1,117 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@@ -0,0 +1,26 @@
//------------------------------------------------------------------------------
// <auto-generated>
// 이 코드는 도구를 사용하여 생성되었습니다.
// 런타임 버전:4.0.30319.42000
//
// 파일 내용을 변경하면 잘못된 동작이 발생할 수 있으며, 코드를 다시 생성하면
// 이러한 변경 내용이 손실됩니다.
// </auto-generated>
//------------------------------------------------------------------------------
namespace arDev.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.11.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
public static Settings Default {
get {
return defaultInstance;
}
}
}
}

View File

@@ -0,0 +1,7 @@
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
<Profiles>
<Profile Name="(Default)" />
</Profiles>
<Settings />
</SettingsFile>

View File

@@ -0,0 +1,425 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
namespace arDev
{
public partial class MasterK
{
protected int ReceiveByte()
{
bool done = false;
int ret_val;
// Await 1 char...
if (!sw_ch.IsRunning)
sw_ch.Start();
do
{
if (_device.BytesToRead > 0)
{
ret_val = _device.ReadByte();
done = true;
}
else
ret_val = -1;
} while ((!done) && ((sw_ch.ElapsedMilliseconds - char_tmo) < 10));
if (done)
char_tmo = sw_ch.ElapsedMilliseconds; // Char received with no errors...reset timeout counter for next char!
return ret_val;
}
protected int GetInterframeDelay()
{
int ret_val;
if (_device.BaudRate > 19200)
ret_val = 2; // Fixed value = 1.75ms up rounded
else
{
int nbits = 1 + _device.DataBits;
nbits += _device.Parity == System.IO.Ports.Parity.None ? 0 : 1;
switch (_device.StopBits)
{
case System.IO.Ports.StopBits.One:
nbits += 1;
break;
case System.IO.Ports.StopBits.OnePointFive: // Ceiling
case System.IO.Ports.StopBits.Two:
nbits += 2;
break;
}
ret_val = Convert.ToInt32(Math.Ceiling(1 / (((double)_device.BaudRate / ((double)nbits * 3.5d)) / 1000)));
}
return ret_val;
}
protected int GetIntercharDelay()
{
int ret_val;
if (_device.BaudRate > 19200)
ret_val = 1; // Fixed value = 0.75 ms up rounded
else
{
int nbits = 1 + _device.DataBits;
nbits += _device.Parity == System.IO.Ports.Parity.None ? 0 : 1;
switch (_device.StopBits)
{
case System.IO.Ports.StopBits.One:
nbits += 1;
break;
case System.IO.Ports.StopBits.OnePointFive: // Ceiling
case System.IO.Ports.StopBits.Two:
nbits += 2;
break;
}
ret_val = Convert.ToInt32(Math.Ceiling(1 / (((double)_device.BaudRate / ((double)nbits * 1.5d)) / 1000)));
}
return ret_val;
}
/// <summary>
/// IO모니터가 실행중인지 확인합니다.
/// </summary>
[Description("I/O보드 핀 상태를 쓰레드를 이용하여 읽고 있는지 여부"), Browsable(false)]
public Boolean isRunMonitor
{
get
{
if (thMonitor == null) return false;
return this.thMonitor.IsAlive;
}
}
/// <summary>
/// 16진수 문자열 형태로 반환합니다.
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[Description("")]
protected string GetHexString(Byte[] input)
{
if (input == null || input.Length < 1) return string.Empty;
System.Text.StringBuilder sb = new System.Text.StringBuilder();
foreach (byte b in input)
sb.Append(" " + b.ToString("X2"));
return sb.ToString();
}
/// <summary>
/// 현재 시스템이 x64 인지 확인합니다.
/// </summary>
[Description("")]
protected Boolean isX64
{
get
{
if (IntPtr.Size == 8) return true;
else return false;
}
}
/// <summary>
/// 초기화가 되어잇는지 체크합니다.
/// </summary>
[Description("")]
public bool IsInit
{
get
{
if (!IsOpen() || !this._isInit) return false;
else return true;
}
}
/// <summary>
/// 해당 버퍼가 NAK 응답인지 체크합니다.
/// </summary>
/// <param name="buffer"></param>
/// <returns></returns>
[Description("")]
protected Boolean isNak(byte[] buffer)
{
if (buffer[0] == 0x15)
{
string hexString = GetHexString(buffer);
RaiseMessage(true, "NAK Response : " + hexString);
return true;
}
return false;
}
public bool IsOpen()
{
if (_device == null) return false;
return _device.IsOpen;
}
protected void ClearBuffer(Boolean ClearDeviceBuffer=false)
{
_dlc = 0;
_bDlc = false;
_bStx = false;
_CommandCode = 0x00;
if (ClearDeviceBuffer)
{
this._device.DiscardInBuffer();
this._device.DiscardOutBuffer();
}
}
/// <summary>
/// io모니터창을 표시합니다.
/// </summary>
[Description("")]
public void ShowIOMonitor()
{
fIOMonitor f = new fIOMonitor(this);
f.Show();
}
#region "html generate"
private string getHtmlHeader()
{
return "<html>" +
"<head>" +
"<script src=\"https://rawgit.com/google/code-prettify/master/loader/run_prettify.js?autoload=true&amp;skin=sunburst&amp;lang=css\" defer></script>" +
"<link rel=\"stylesheet\" href=\"styles.css\">" +
"</head>" +
"<body>";
}
private string getHtmlTail()
{
return "</body></html>";
}
private string getTableHeadStr()
{
return "<table> <thead> <tr> <td>Type</td> <td>Name</td> <td>Return</td> <td>Description</td> </tr> </thead> <tbody>";
}
private string getTableHead()
{
return "<table> <thead> <tr> <td>Type</td> <td>Name</td><td>Description</td> </tr> </thead> <tbody>";
}
private string getTableHeadEnum()
{
return "<table> <thead> <tr> <td>Return</td> <td>Name</td> <td>Description</td> </tr> </thead> <tbody>";
}
private string getTableTail()
{
return "</tbody></table>";
}
private string findReturnType(string fieldname)
{
if (fieldname.IndexOf('+') >= 0)
{
return fieldname.Split('+')[1];
}
else return fieldname;
}
private string getMethodReturnType(Type source, MemberInfo member)
{
switch (member.MemberType)
{
case MemberTypes.Method:
var met = source.GetMethod(member.Name);
return source.GetMethod(member.Name).ReturnType.ToString().Substring(7);
case MemberTypes.Property:
var pt = source.GetProperty(member.Name);
if (pt != null)
return pt.PropertyType.FullName.Substring(7);
break;
case MemberTypes.Field:
var fd = source.GetField(member.Name);
string fieldname = fd.FieldType.FullName.Substring(7);
return findReturnType(fieldname);
}
return "";
}
/// <summary>
/// HTML 메뉴얼작성용 코드를 생성합니다.(0==command,1==enum,2==structure)
/// </summary>
public string MakeHTML(byte type = 0)
{
System.Text.StringBuilder sb = new StringBuilder();
sb.AppendLine(getHtmlHeader());
if (type == 2)
{
var typeSmsg = typeof(sRecvMessage);
sb.AppendLine("<h4 class=\"structure\">[ " + typeSmsg.Name + " ]</h4>");
sb.AppendLine(getTableHeadStr());
foreach (var member in typeSmsg.GetMembers())
{
if (member.Name.StartsWith("get_") || member.Name.StartsWith("set_") ||
member.Name.StartsWith("Equals") || member.Name.StartsWith("GetHashCode") ||
member.Name.StartsWith("GetType")) continue;
sb.AppendLine("<tr>");
sb.AppendLine(" <td>" + member.MemberType.ToString() + "</td>");
sb.AppendLine(" <td class=\"tleft\">" + member.Name + "</td>");
sb.AppendLine(" <td>" + getMethodReturnType(typeSmsg, member) + "</td>");
sb.AppendLine(" <td class=\"tleft\">" + member.Name + "</td>");
sb.AppendLine("</tr>");
}
sb.AppendLine(getTableTail());
}
else if (type == 1)
{
//enum list
var typeeIO = typeof(eIOPINDIR);
sb.AppendLine("<h4 class=\"enum\">[ " + typeeIO.Name + " ]</h4>");
sb.AppendLine(getTableHeadEnum());
foreach (var member in typeeIO.GetFields())
{
if (member.Name.StartsWith("get_") || member.Name.StartsWith("set_") ||
member.Name.StartsWith("Equals") || member.Name.StartsWith("GetHashCode") ||
member.Name.StartsWith("GetType") || member.Name.EndsWith("__")) continue;
sb.AppendLine("<tr>");
sb.AppendLine(" <td>Byte</td>");
sb.AppendLine(" <td class=\"tleft\">" + member.Name + "</td>");
sb.AppendLine(" <td class=\"tleft\">" + member.Name + "</td>");
sb.AppendLine("</tr>");
}
sb.AppendLine(getTableTail());
typeeIO = typeof(eErrorCode);
sb.AppendLine("<h4 class=\"enum\">[ " + typeeIO.Name + " ]</h4>");
sb.AppendLine(getTableHeadEnum());
foreach (var member in typeeIO.GetFields())
{
if (member.Name.StartsWith("get_") || member.Name.StartsWith("set_") ||
member.Name.StartsWith("Equals") || member.Name.StartsWith("GetHashCode") ||
member.Name.StartsWith("GetType") || member.Name.EndsWith("__")) continue;
sb.AppendLine("<tr>");
sb.AppendLine(" <td>Byte</td>");
sb.AppendLine(" <td class=\"tleft\">" + member.Name + "</td>");
sb.AppendLine(" <td class=\"tleft\">" + member.Name + "</td>");
sb.AppendLine("</tr>");
}
sb.AppendLine(getTableTail());
typeeIO = typeof(eOpCode);
sb.AppendLine("<h4 class=\"enum\">[ " + typeeIO.Name + " ]</h4>");
sb.AppendLine(getTableHeadEnum());
foreach (var member in typeeIO.GetFields())
{
if (member.Name.StartsWith("get_") || member.Name.StartsWith("set_") ||
member.Name.StartsWith("Equals") || member.Name.StartsWith("GetHashCode") ||
member.Name.StartsWith("GetType") || member.Name.EndsWith("__")) continue;
sb.AppendLine("<tr>");
sb.AppendLine(" <td>Byte</td>");
sb.AppendLine(" <td class=\"tleft\">" + member.Name + "</td>");
sb.AppendLine(" <td class=\"tleft\">" + member.Name + "</td>");
sb.AppendLine("</tr>");
}
sb.AppendLine(getTableTail());
}
else
{
//main
sb.AppendLine("<h4 class=\"method\">[ Methods ]</h4>");
sb.AppendLine(getTableHead());
foreach (var member in GetType().GetMethods())
{
if (member.Name.StartsWith("get_") || member.Name.StartsWith("set_") ||
member.Name.StartsWith("Equals") || member.Name.StartsWith("GetHashCode") ||
member.Name.StartsWith("GetType") || member.Name.StartsWith("add_") ||
member.Name.StartsWith("remove_")) continue;
sb.AppendLine("<tr>");
sb.AppendLine(" <td>" + findReturnType(member.ReturnType.ToString().Substring(7)) + "</td>");
sb.AppendLine(" <td class=\"tleft\">" + member.Name + "</td>");
sb.AppendLine(" <td class=\"tleft\">" + member.Name + "</td>");
sb.AppendLine("</tr>");
}
sb.AppendLine(getTableTail());
sb.AppendLine("<h4 class=\"method\">[ Properties ]</h4>");
sb.AppendLine(getTableHead());
foreach (var member in GetType().GetProperties())
{
if (member.Name.StartsWith("get_") || member.Name.StartsWith("set_") ||
member.Name.StartsWith("Equals") || member.Name.StartsWith("GetHashCode") ||
member.Name.StartsWith("GetType") || member.Name.StartsWith("add_") ||
member.Name.StartsWith("remove_")) continue;
sb.AppendLine("<tr>");
sb.AppendLine(" <td>" + findReturnType(member.PropertyType.FullName.Substring(7)) + "</td>");
sb.AppendLine(" <td class=\"tleft\">" + member.Name + "</td>");
sb.AppendLine(" <td class=\"tleft\">" + member.Name + "</td>");
sb.AppendLine("</tr>");
}
sb.AppendLine(getTableTail());
sb.AppendLine("<h4 class=\"method\">[ Events ]</h4>");
sb.AppendLine(getTableHead());
foreach (var member in GetType().GetEvents())
{
if (member.Name.StartsWith("get_") || member.Name.StartsWith("set_") ||
member.Name.StartsWith("Equals") || member.Name.StartsWith("GetHashCode") ||
member.Name.StartsWith("GetType") || member.Name.StartsWith("add_") ||
member.Name.StartsWith("remove_")) continue;
sb.AppendLine("<tr>");
sb.AppendLine(" <td>" + "" + "</td>");
sb.AppendLine(" <td class=\"tleft\">" + member.Name + "</td>");
sb.AppendLine(" <td class=\"tleft\">" + member.Name + "</td>");
sb.AppendLine("</tr>");
}
sb.AppendLine(getTableTail());
sb.AppendLine("<h4 class=\"method\">[ Fields ]</h4>");
sb.AppendLine(getTableHead());
foreach (var member in GetType().GetFields())
{
if (member.Name.StartsWith("get_") || member.Name.StartsWith("set_") ||
member.Name.StartsWith("Equals") || member.Name.StartsWith("GetHashCode") ||
member.Name.StartsWith("GetType") || member.Name.StartsWith("add_") ||
member.Name.StartsWith("remove_")) continue;
sb.AppendLine("<tr>");
sb.AppendLine(" <td>" + findReturnType(member.FieldType.FullName.Substring(7)) + "</td>");
sb.AppendLine(" <td class=\"tleft\">" + member.Name + "</td>");
sb.AppendLine(" <td class=\"tleft\">" + member.Name + "</td>");
sb.AppendLine("</tr>");
}
sb.AppendLine(getTableTail());
}
sb.AppendLine(getHtmlTail());
return sb.ToString();
}
#endregion
}
}

View File

@@ -0,0 +1,213 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.ComponentModel;
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Design;
using System.Reflection;
using System.Runtime;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
//for tcp,udp
using System.Net.Sockets;
using System.Net;
namespace arDev
{
public partial class MasterK
{
protected Boolean Send(byte[] packet)
{
try
{
_device.DiscardInBuffer();
System.Threading.Thread.Sleep(1);
_device.DiscardOutBuffer();
System.Threading.Thread.Sleep(1);
_device.Write(packet, 0, packet.Length);
char_tmo = 0;
return true;
}
catch (Exception ex)
{
RaiseMessage(true, "Device Send Error : " + ex.Message);
return false;
}
}
protected Boolean Write(byte[] packet)
{
bSyncRecvOK = false;
errorMessage = string.Empty;
lastSendTime = DateTime.Now;
lastSendMessage = Parse_SendBuffer(packet);
Boolean retval = Send(packet);
if (!retval) RaiseMessage(true, "Tx Error : " + System.Text.Encoding.Default.GetString(packet));
else RaiseDataMessage(eMsgType.Tx, packet);
return retval;
}
public byte[] UserWrite(string command)
{
_mre.Reset();
var buffer = WriteSync(command);
_mre.Set();
return buffer;
}
protected byte[] WriteSync(string command)
{
var bytes = System.Text.Encoding.Default.GetBytes(command);
if (command[0] == (char)wSTX)
{
return WriteSync(bytes);
}
else
{
List<byte> packet = new List<byte>();
packet.Add(wSTX);
packet.AddRange(bytes);
packet.Add(wETX);
return WriteSync(packet.ToArray());
}
}
protected int interframe_delay;
System.Diagnostics.Stopwatch sw_ch;
long char_tmo;
string savefil = string.Empty;
// Int64 writeCnt = 0;
protected byte[] WriteSync(byte[] command)
{
//writeCnt += 1;
//RaiseMessage(false, ">> WriteSync Enter " + writeCnt.ToString());
if (savefil == "")
{
savefil = Environment.CurrentDirectory + "\rxBuffer.txt";
}
// if (!mre.WaitOne(500))
// {
// errorMessage = "WaitOne error 500ms";
// return null;
// }
//// RaiseMessage(false, "write data sync");
// mre.Reset();
//Boolean isComplete = false;
Boolean isTimeOut = false;
errorMessage = "Wait Data #2";
LastRecvMessage.Clear();
List<byte> _buffer = new List<byte>();
wat.Restart();
System.Threading.Thread.Sleep(interframe_delay);
//send data
if (!Write(command))
{
errorMessage = "sync Buffer is null(1)";
//mre.Set();
//RaiseMessage(false, "<< WriteSync Out " + writeCnt.ToString());
return null;
}
bool done = false;
System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
sw.Start();
int rcv ;
long tmo = 0;
do
{
int buffercnt = 0;
try
{
buffercnt = _device.BytesToRead;
}
catch (Exception ex)
{
RaiseMessage(true, ex.Message);
}
if (buffercnt > 0)
{
try
{
rcv = _device.ReadByte();
// System.IO.File.WriteAllBytes(savefil, new byte[] { (byte)rcv });
RaiseDataMessage(eMsgType.RxRaw, new byte[(byte)rcv]);
if (rcv == 0x06 || rcv == 0x015)
{
_buffer.Clear();
_buffer.Add((byte)rcv);
//isComplete = false;
}
else if (rcv == 0x03) //endtext
{
//모두 수신한경우이다.
_buffer.Add((byte)rcv);
//isComplete = true;
done = true;
break;
}
else
{
_buffer.Add((byte)rcv);
}
}
catch {
}
}
tmo = sw.ElapsedMilliseconds;
} while ((!done) && (_device.ReadTimeout > tmo));
sw_ch.Stop();
sw.Stop();
if (tmo >= _device.ReadTimeout)
{
errorMessage = string.Format("Writesync TimeOut({0})", _device.ReadTimeout);
isTimeOut = true;
}
byte[] Dummy = new byte[_buffer.Count];
_buffer.CopyTo(Dummy);
// mre.Set();
if (isTimeOut)
{
RaiseMessage(true, errorMessage);
//RaiseMessage(false, "<< WriteSync Out " + writeCnt.ToString());
return null;
}
else
{
RaiseDataMessage(eMsgType.Rx, Dummy);
var frame = Parse_RecvBuffer(Dummy);
if (frame.Buffer == null)
{
errorMessage = "sync buffer is null(2)";
RaiseMessage(true, errorMessage);
// RaiseMessage(false, "<< WriteSync Out " + writeCnt.ToString());
return null;
}
else
{
// RaiseMessage(false, "<< WriteSync Out " + writeCnt.ToString());
return frame.Buffer;
}
}
}
}
}

View File

@@ -0,0 +1,100 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" 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>{E0133085-E5F9-4275-9DB8-F8F20EF8561F}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>arDev</RootNamespace>
<AssemblyName>arMasterK</AssemblyName>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<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' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>..\..\DLL\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup>
<StartupObject />
</PropertyGroup>
<ItemGroup>
<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.Deployment" />
<Reference Include="System.Drawing" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Util.cs" />
<Compile Include="Parser.cs" />
<Compile Include="EventArgs.cs" />
<Compile Include="EnumAStruct.cs" />
<Compile Include="fIOMonitor.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="fIOMonitor.Designer.cs">
<DependentUpon>fIOMonitor.cs</DependentUpon>
</Compile>
<Compile Include="Write.cs" />
<Compile Include="MasterK.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<EmbeddedResource Include="fIOMonitor.resx">
<DependentUpon>fIOMonitor.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
<SubType>Designer</SubType>
</EmbeddedResource>
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
<DesignTime>True</DesignTime>
</Compile>
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
<Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
</ItemGroup>
<ItemGroup>
<Content Include="History.txt" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@@ -0,0 +1,144 @@
namespace arDev
{
partial class fIOMonitor
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
this.label1 = new System.Windows.Forms.Label();
this.label2 = new System.Windows.Forms.Label();
this.tblOutput = new System.Windows.Forms.TableLayoutPanel();
this.tblINput = new System.Windows.Forms.TableLayoutPanel();
this.tableLayoutPanel1.SuspendLayout();
this.SuspendLayout();
//
// tableLayoutPanel1
//
this.tableLayoutPanel1.ColumnCount = 2;
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.tableLayoutPanel1.Controls.Add(this.label1, 0, 0);
this.tableLayoutPanel1.Controls.Add(this.label2, 1, 0);
this.tableLayoutPanel1.Controls.Add(this.tblOutput, 1, 1);
this.tableLayoutPanel1.Controls.Add(this.tblINput, 0, 1);
this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0);
this.tableLayoutPanel1.Name = "tableLayoutPanel1";
this.tableLayoutPanel1.RowCount = 2;
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 36F));
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel1.Size = new System.Drawing.Size(582, 480);
this.tableLayoutPanel1.TabIndex = 0;
//
// label1
//
this.label1.Dock = System.Windows.Forms.DockStyle.Fill;
this.label1.Location = new System.Drawing.Point(3, 0);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(285, 36);
this.label1.TabIndex = 0;
this.label1.Text = "INPUT";
this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// label2
//
this.label2.Dock = System.Windows.Forms.DockStyle.Fill;
this.label2.Location = new System.Drawing.Point(294, 0);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(285, 36);
this.label2.TabIndex = 0;
this.label2.Text = "OUTPUT";
this.label2.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// tblOutput
//
this.tblOutput.ColumnCount = 4;
this.tblOutput.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 25F));
this.tblOutput.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 25F));
this.tblOutput.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 25F));
this.tblOutput.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 25F));
this.tblOutput.Dock = System.Windows.Forms.DockStyle.Fill;
this.tblOutput.Location = new System.Drawing.Point(294, 39);
this.tblOutput.Name = "tblOutput";
this.tblOutput.RowCount = 8;
this.tblOutput.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 12.5F));
this.tblOutput.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 12.5F));
this.tblOutput.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 12.5F));
this.tblOutput.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 12.5F));
this.tblOutput.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 12.5F));
this.tblOutput.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 12.5F));
this.tblOutput.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 12.5F));
this.tblOutput.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 12.5F));
this.tblOutput.Size = new System.Drawing.Size(285, 438);
this.tblOutput.TabIndex = 1;
//
// tblINput
//
this.tblINput.ColumnCount = 4;
this.tblINput.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 25F));
this.tblINput.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 25F));
this.tblINput.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 25F));
this.tblINput.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 25F));
this.tblINput.Dock = System.Windows.Forms.DockStyle.Fill;
this.tblINput.Location = new System.Drawing.Point(3, 39);
this.tblINput.Name = "tblINput";
this.tblINput.RowCount = 8;
this.tblINput.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 12.5F));
this.tblINput.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 12.5F));
this.tblINput.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 12.5F));
this.tblINput.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 12.5F));
this.tblINput.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 12.5F));
this.tblINput.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 12.5F));
this.tblINput.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 12.5F));
this.tblINput.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 12.5F));
this.tblINput.Size = new System.Drawing.Size(285, 438);
this.tblINput.TabIndex = 1;
//
// fIOMonitor
//
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(582, 480);
this.Controls.Add(this.tableLayoutPanel1);
this.Name = "fIOMonitor";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "fIOMonitor";
this.Load += new System.EventHandler(this.fIOMonitor_Load);
this.tableLayoutPanel1.ResumeLayout(false);
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.TableLayoutPanel tblOutput;
private System.Windows.Forms.TableLayoutPanel tblINput;
}
}

View File

@@ -0,0 +1,77 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace arDev
{
public partial class fIOMonitor : Form
{
MasterK dio;
public fIOMonitor(MasterK _device)
{
InitializeComponent();
dio = _device;
}
Button[] btInput;
Button[] btOutput;
private void fIOMonitor_Load(object sender, EventArgs e)
{
btInput = new Button[dio.DICount];
btOutput = new Button[dio.DOCount];
for(int i = 0; i< dio.DICount;i++)
{
Button lb = new Button();
lb.Text = string.Format("{0}",i+1);
lb.Tag = i;
lb.Click += lb_ClickI;
lb.Dock = DockStyle.Fill;
lb.BackColor = dio.INPUT(i) ? Color.Lime : Color.White;
btInput[i] = lb;
this.tblINput.Controls.Add(lb);
}
for (int i = 0; i < dio.DOCount; i++)
{
Button lb = new Button();
lb.Text = string.Format("{0}", i + 1);
lb.Tag = i;
lb.Click += lb_ClickO;
lb.Dock = DockStyle.Fill;
lb.BackColor = dio.OUTPUT(i) ? Color.Lime : Color.White;
btOutput[i] = lb;
this.tblOutput.Controls.Add(lb);
}
dio.IOValueChanged += dio_IOValueChanged;
}
void dio_IOValueChanged(object sender, MasterK.IOValueEventArgs e)
{
if(e.Direction == MasterK.eIOPINDIR.INPUT)
{
btInput[e.ArrIDX].BackColor = e.NewValue ? Color.Lime : Color.White;
}
else
{
btOutput[e.ArrIDX].BackColor = e.NewValue ? Color.Lime : Color.White;
}
}
void lb_ClickI(object sender, EventArgs e)
{
var bt = sender as Button;
//MessageBox.Show("input click : " + bt.Tag.ToString());
}
void lb_ClickO(object sender, EventArgs e)
{
var bt = sender as Button;
var idx = int.Parse(bt.Tag.ToString());
dio.SetToggle(idx);
}
}
}

View File

@@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>