파일정리

This commit is contained in:
ChiKyun Kim
2026-01-29 14:03:17 +09:00
parent 00cc0ef5b7
commit 58ca67150d
440 changed files with 47236 additions and 99165 deletions

68
HMI/TestProject/Test.sln Normal file
View File

@@ -0,0 +1,68 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Express 15 for Windows Desktop
VisualStudioVersion = 15.0.36324.19
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test_ACS", "Test_ACS\Test_ACS.csproj", "{A1B2C3D4-E5F6-4A5B-8C9D-0E1F2A3B4C5D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test_BMS", "Test_BMS\Test_BMS.csproj", "{CE3FFF9F-6ACA-44BD-B64A-33FF4AD5E82E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test_Narumi", "Test_Narumi\Test_Narumi.csproj", "{EB77976F-4DE4-46A5-8B25-D07226204C32}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test_Port", "Test_Port\Test_Port.csproj", "{CCFA2CE7-A539-4ADC-B803-F759284C3463}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Library", "Library", "{530A4517-6210-422B-8CB4-B7D194EE70BE}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CommData", "..\SubProject\CommData\CommData.csproj", "{14E8C9A5-013E-49BA-B435-EFEFC77DD623}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ENIGProtocol", "..\SubProject\EnigProtocol\enigprotocol\ENIGProtocol.csproj", "{9365803B-933D-4237-93C7-B502C855A71C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NARUMI", "..\SubProject\AGV\NARUMI.csproj", "{8BAE0EAC-3D25-402F-9A65-2BA1ECFE28B7}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{A1B2C3D4-E5F6-4A5B-8C9D-0E1F2A3B4C5D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A1B2C3D4-E5F6-4A5B-8C9D-0E1F2A3B4C5D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A1B2C3D4-E5F6-4A5B-8C9D-0E1F2A3B4C5D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A1B2C3D4-E5F6-4A5B-8C9D-0E1F2A3B4C5D}.Release|Any CPU.Build.0 = Release|Any CPU
{CE3FFF9F-6ACA-44BD-B64A-33FF4AD5E82E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{CE3FFF9F-6ACA-44BD-B64A-33FF4AD5E82E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CE3FFF9F-6ACA-44BD-B64A-33FF4AD5E82E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CE3FFF9F-6ACA-44BD-B64A-33FF4AD5E82E}.Release|Any CPU.Build.0 = Release|Any CPU
{EB77976F-4DE4-46A5-8B25-D07226204C32}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{EB77976F-4DE4-46A5-8B25-D07226204C32}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EB77976F-4DE4-46A5-8B25-D07226204C32}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EB77976F-4DE4-46A5-8B25-D07226204C32}.Release|Any CPU.Build.0 = Release|Any CPU
{CCFA2CE7-A539-4ADC-B803-F759284C3463}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{CCFA2CE7-A539-4ADC-B803-F759284C3463}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CCFA2CE7-A539-4ADC-B803-F759284C3463}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CCFA2CE7-A539-4ADC-B803-F759284C3463}.Release|Any CPU.Build.0 = Release|Any CPU
{14E8C9A5-013E-49BA-B435-EFEFC77DD623}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{14E8C9A5-013E-49BA-B435-EFEFC77DD623}.Debug|Any CPU.Build.0 = Debug|Any CPU
{14E8C9A5-013E-49BA-B435-EFEFC77DD623}.Release|Any CPU.ActiveCfg = Release|Any CPU
{14E8C9A5-013E-49BA-B435-EFEFC77DD623}.Release|Any CPU.Build.0 = Release|Any CPU
{9365803B-933D-4237-93C7-B502C855A71C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9365803B-933D-4237-93C7-B502C855A71C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9365803B-933D-4237-93C7-B502C855A71C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9365803B-933D-4237-93C7-B502C855A71C}.Release|Any CPU.Build.0 = Release|Any CPU
{8BAE0EAC-3D25-402F-9A65-2BA1ECFE28B7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8BAE0EAC-3D25-402F-9A65-2BA1ECFE28B7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8BAE0EAC-3D25-402F-9A65-2BA1ECFE28B7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8BAE0EAC-3D25-402F-9A65-2BA1ECFE28B7}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{14E8C9A5-013E-49BA-B435-EFEFC77DD623} = {530A4517-6210-422B-8CB4-B7D194EE70BE}
{9365803B-933D-4237-93C7-B502C855A71C} = {530A4517-6210-422B-8CB4-B7D194EE70BE}
{8BAE0EAC-3D25-402F-9A65-2BA1ECFE28B7} = {530A4517-6210-422B-8CB4-B7D194EE70BE}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {E9528217-EC4E-4991-B3C9-AE371EDFA28F}
EndGlobalSection
EndGlobal

View File

@@ -0,0 +1,67 @@
using System;
using System.IO;
using System.Windows.Forms;
using Newtonsoft.Json;
namespace Test_ACS
{
/// <summary>
/// 애플리케이션 설정을 관리하는 클래스
/// </summary>
public class AppSettings
{
public string LastPort { get; set; } = "COM1";
public string LastBaudRate { get; set; } = "9600";
public string LastRFID { get; set; } = "0001";
public string LastAlias { get; set; } = "CHARGER1";
public int LastAGV { get; set; } = 11;
private static string GetConfigFilePath()
{
// 실행 파일과 같은 폴더에 같은 이름으로 .config 파일 생성
string exePath = Application.ExecutablePath;
string exeName = Path.GetFileNameWithoutExtension(exePath);
string configPath = Path.Combine(Path.GetDirectoryName(exePath), exeName + ".config");
return configPath;
}
/// <summary>
/// 설정 파일을 로드합니다
/// </summary>
public static AppSettings Load()
{
try
{
string configPath = GetConfigFilePath();
if (File.Exists(configPath))
{
string json = File.ReadAllText(configPath);
return JsonConvert.DeserializeObject<AppSettings>(json);
}
}
catch (Exception)
{
// 로드 실패 시 기본값 반환
}
return new AppSettings();
}
/// <summary>
/// 설정을 파일에 저장합니다
/// </summary>
public void Save()
{
try
{
string configPath = GetConfigFilePath();
string json = JsonConvert.SerializeObject(this, Formatting.Indented);
File.WriteAllText(configPath, json);
}
catch (Exception)
{
// 저장 실패 시 무시
}
}
}
}

View File

@@ -0,0 +1,162 @@
# Test_ACS 변경 이력
## v1.4.0 (2025-01-12)
### 설정 파일 저장 방식 변경
- **실행 폴더에 설정 파일 저장**
- 이전: 사용자 프로파일 폴더 (`%LOCALAPPDATA%`)
- 변경: 실행 파일과 같은 폴더에 `Test_ACS.config` 저장
- 형식: JSON 형식으로 저장 (가독성 향상)
### 코드 개선
- `AppSettings` 클래스 신규 생성
- JSON 직렬화/역직렬화 지원
- 실행 파일 경로 자동 감지
- 설정 파일 자동 생성 및 로드
- Newtonsoft.Json 패키지 참조 추가
### 사용성 개선
- 설정 파일을 직접 편집 가능 (JSON 형식)
- 프로그램 이동 시에도 설정 파일 함께 이동
- 여러 버전 동시 사용 가능 (각 폴더별 독립 설정)
---
## v1.3.0 (2025-01-12)
### 신규 기능
- **AGV 상태 실시간 표시**
- AGV 상태 그룹박스 추가
- 8가지 AGV 상태 정보 표시:
- 모드 (수동/자동)
- 실행상태 (정지/실행/에러)
- 방향 (직진/좌회전/우회전/마크정지)
- 도달완료 (OFF/ON)
- 충전 상태 (OFF/ON)
- 카트 감지 (없음/있음/알 수 없음)
- 리프트 위치 (하강/상승/알 수 없음)
- 현재 RFID 태그 번호 (6자리)
- 상태별 색상 표시로 직관적 모니터링
- AGV Status 메시지(cmd=3) 자동 수신 및 업데이트
### UI 개선
- AGV 상태 그룹박스 추가 (2열 x 4행 레이아웃)
- 메인 폼 크기 확장 (539 → 588 픽셀)
- 상태별 색상 구분:
- 수동(파란색) / 자동(녹색)
- 정지(회색) / 실행(녹색) / 에러(빨간색)
- 충전중(주황색)
### 프로토콜 업데이트
- ENIGProtocol ReadMe.MD 수정
- AGV Status 프로토콜 정의 명확화 (총 13바이트)
- LastTag 필드 크기 수정 (4바이트 → 6바이트)
- CurrentPath 필드 제거 (실제 구현과 일치)
### 코드 개선
- `UpdateAGVStatus()` 메서드 구현
- Status 메시지 수신 처리 로직 추가
- 스레드 안전성 보장 (InvokeRequired 체크)
- 데이터 유효성 검사 추가
---
## v1.2.0 (2025-01-12)
### 신규 기능
- **설정 자동 저장/불러오기 기능**
- 마지막 사용 COM 포트 자동 저장
- 마지막 사용 보레이트 자동 저장
- 마지막 입력 RFID 번호 자동 저장
- 마지막 입력 별칭 자동 저장
- 마지막 선택 AGV (11/12) 자동 저장
- 프로그램 종료 시 자동 저장
- 프로그램 시작 시 자동 불러오기
### 구현 상세
- **Settings.settings 파일 확장**
- LastPort (string)
- LastBaudRate (string)
- LastRFID (string)
- LastAlias (string)
- LastAGV (int)
- **자동 저장 이벤트**
- COM 포트 선택 변경 시
- 보레이트 텍스트 변경 시
- RFID 번호 텍스트 변경 시
- 별칭 텍스트 변경 시
- AGV 선택 변경 시
- 프로그램 종료 시 (OnFormClosing)
- **자동 불러오기**
- 프로그램 시작 시 LoadSettings() 호출
- 포트 목록 로드 후 마지막 설정 적용
### 사용자 경험 개선
- 프로그램 재실행 시 이전 설정 자동 복원
- 설정 저장/불러오기 상태 로그 표시
- 에러 발생 시 로그에 에러 메시지 표시
---
## v1.1.0 (2025-01-12)
### 신규 기능
- **GotoAlias 명령어 추가**
- 별칭(Alias)을 사용한 AGV 이동 명령 지원
- RFID 번호 대신 의미 있는 이름으로 목적지 지정 가능
- 예: "CHARGER1", "BUFFER2", "STATION_A" 등
### UI 개선
- **별칭 입력 필드 추가**
- 위치: RFID 입력 필드 아래
- 기본값: "CHARGER1"
- **GotoAlias 버튼 추가**
- 위치: Goto 버튼 우측
- 버튼명: "별칭 이동 (GotoAlias)"
- **레이아웃 최적화**
- RFID 번호 입력: 라인 1
- 별칭 입력: 라인 2
- SetCurrent / GotoAlias 버튼: 라인 3
- Goto / GotoAlias 버튼: 라인 4
- Stop / Reset 버튼: 라인 5
- MarkStop 버튼 및 체크박스: 라인 6
- 수동 제어 / 리프트 제어: 하단 그룹
### 프로토콜 변경
- **AGVCommandHE Enum 확장**
- GotoAlias = 107 추가
- 데이터 형식: TargetID(2 hex) + Alias(ASCII string)
### 코드 개선
- `btnGotoAlias_Click` 이벤트 핸들러 구현
- 별칭 유효성 검사 (빈 문자열 체크)
- ASCII → HEX 변환 로직 추가
### 문서 업데이트
- README.md에 GotoAlias 사용법 추가
- 프로토콜 명령어 표에 GotoAlias 추가
- 버전 이력 업데이트
---
## v1.0.0 (2025-01-11)
### 초기 릴리즈
- ACS 시뮬레이터 기본 구현
- ENIGProtocol 프로젝트 참조
- RS232 통신 지원
- 7가지 기본 ACS 명령어:
- SetCurrent (현재 위치 설정)
- Goto (RFID 이동)
- Stop (정지)
- Reset (에러 리셋)
- Manual (수동 제어)
- MarkStop (마크센서 정지)
- LiftControl (리프트 제어)
- AGV 선택 기능 (AGV1/AGV2)
- 로그 시스템 (TX/RX/Info 탭)
- COM 포트 관리 (연결/해제/새로고침)

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,613 @@
using System;
using System.Drawing;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using ENIG;
using ENIGProtocol;
namespace Test_ACS
{
public partial class MainForm : Form
{
private SerialPort serialPort;
private EEProtocol protocol;
private byte selectedAGV = 11; // 기본값: AGV1 (11)
private AppSettings settings;
public MainForm()
{
InitializeComponent();
InitializeProtocol();
LoadPortList();
}
private void InitializeProtocol()
{
protocol = new EEProtocol();
protocol.OnDataReceived += Protocol_OnDataReceived;
protocol.OnMessage += Protocol_OnMessage;
serialPort = new SerialPort();
serialPort.ReadTimeout = 2000;
serialPort.WriteTimeout = 1000;
serialPort.DataReceived += SerialPort_DataReceived;
}
private void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
var buffer = new byte[serialPort.BytesToRead];
serialPort.Read(buffer, 0, buffer.Length);
protocol.ProcessReceivedData(buffer);
}
private void Protocol_OnDataReceived(object sender, EEProtocol.DataEventArgs e)
{
var hexstrRaw = string.Join(" ", e.ReceivedPacket.RawData.Select(b => b.ToString("X2")));
var hexstr = string.Join(" ", e.ReceivedPacket.Data.Select(b => b.ToString("X2")));
var cmd = e.ReceivedPacket.Command.ToString("X2");
var id = e.ReceivedPacket.ID.ToString("X2");
AddLog($"RX: {hexstrRaw}\nID:{id}, CMD:{cmd}, DATA:{hexstr}", LogType.RX);
// AGV 상태 수신 처리 (cmd = 3)
var device = e.ReceivedPacket.ID;
var command = (ENIGProtocol.AGVCommandEH)e.ReceivedPacket.Command;
switch (command)
{
case AGVCommandEH.Status:
UpdateAGVStatus(e.ReceivedPacket.Data);
break;
case AGVCommandEH.Error:
var errorcode = (AGVErrorCode)e.ReceivedPacket.Data[0];
var errorMessage = System.Text.Encoding.UTF8.GetString(e.ReceivedPacket.Data, 1, e.ReceivedPacket.Data.Length - 1);
AddLog($"Error Received : {errorcode} ID:{e.ReceivedPacket.ID} MSG:{errorMessage}", LogType.Info);
break;
default:
AddLog($"unknown command:{command}", LogType.Error);
break;
}
}
private void Protocol_OnMessage(object sender, EEProtocol.MessageEventArgs e)
{
AddLog(e.Message, e.IsError ? LogType.Error : LogType.Info);
}
private void LoadPortList()
{
cmbPort.Items.Clear();
foreach (var port in SerialPort.GetPortNames())
{
cmbPort.Items.Add(port);
}
// 마지막 설정 불러오기
LoadSettings();
}
private void LoadSettings()
{
try
{
// 설정 파일 로드
settings = AppSettings.Load();
// 포트 설정
if (!string.IsNullOrEmpty(settings.LastPort) && cmbPort.Items.Contains(settings.LastPort))
{
cmbPort.SelectedItem = settings.LastPort;
}
else if (cmbPort.Items.Count > 0)
{
cmbPort.SelectedIndex = 0;
}
// 보레이트 설정
txtBaudRate.Text = settings.LastBaudRate;
// RFID 번호 설정
txtRFID.Text = settings.LastRFID;
// 별칭 설정
txtAlias.Text = settings.LastAlias;
// AGV 선택 설정
if (settings.LastAGV == 11)
{
rbAGV1.Checked = true;
}
else if (settings.LastAGV == 12)
{
rbAGV2.Checked = true;
}
AddLog("설정을 불러왔습니다.", LogType.Info);
}
catch (Exception ex)
{
settings = new AppSettings();
AddLog($"설정 불러오기 실패: {ex.Message}", LogType.Error);
}
}
private void SaveSettings()
{
try
{
if (settings == null)
settings = new AppSettings();
settings.LastPort = cmbPort.Text;
settings.LastBaudRate = txtBaudRate.Text;
settings.LastRFID = txtRFID.Text;
settings.LastAlias = txtAlias.Text;
settings.LastAGV = selectedAGV;
settings.Save();
}
catch (Exception ex)
{
AddLog($"설정 저장 실패: {ex.Message}", LogType.Error);
}
}
private void btnConnect_Click(object sender, EventArgs e)
{
if (serialPort.IsOpen)
{
serialPort.Close();
btnConnect.Text = "연결";
AddLog("포트 닫힘", LogType.Info);
}
else
{
try
{
serialPort.PortName = cmbPort.Text;
serialPort.BaudRate = int.Parse(txtBaudRate.Text);
serialPort.Open();
btnConnect.Text = "해제";
AddLog($"{serialPort.PortName}:{serialPort.BaudRate} 연결됨", LogType.Info);
SaveSettings();
}
catch (Exception ex)
{
AddLog($"연결 실패: {ex.Message}", LogType.Error);
}
}
}
private void btnRefresh_Click(object sender, EventArgs e)
{
LoadPortList();
}
private void cmbPort_SelectedIndexChanged(object sender, EventArgs e)
{
//SaveSettings();
}
private void txtBaudRate_TextChanged(object sender, EventArgs e)
{
//SaveSettings();
}
private void txtRFID_TextChanged(object sender, EventArgs e)
{
//SaveSettings();
}
private void txtAlias_TextChanged(object sender, EventArgs e)
{
//SaveSettings();
}
private void rbAGV1_CheckedChanged(object sender, EventArgs e)
{
if (rbAGV1.Checked)
{
selectedAGV = 11;
//SaveSettings();
}
}
private void rbAGV2_CheckedChanged(object sender, EventArgs e)
{
if (rbAGV2.Checked)
{
selectedAGV = 12;
//SaveSettings();
}
}
private void btnSetCurrent_Click(object sender, EventArgs e)
{
// SetCurrent: data = TargetID(2 hex) + RFID(4 hex)
var targetID = selectedAGV.ToString("X2");
var rfidBytes = Encoding.ASCII.GetBytes(txtRFID.Text.PadLeft(4, '0'));
var rfidHex = string.Join("", rfidBytes.Select(b => b.ToString("X2")));
var dataStr = targetID + rfidHex;
SendCommand(AGVCommandHE.SetCurrent, dataStr);
}
private void btnGoto_Click(object sender, EventArgs e)
{
// Goto: data = TargetID(2 hex) + RFID(4 hex)
var targetID = selectedAGV.ToString("X2");
var rfidBytes = Encoding.ASCII.GetBytes(txtRFID.Text.PadLeft(4, '0'));
var rfidHex = string.Join("", rfidBytes.Select(b => b.ToString("X2")));
var dataStr = targetID + rfidHex;
SendCommand(AGVCommandHE.Goto, dataStr);
}
private void btnGotoAlias_Click(object sender, EventArgs e)
{
// GotoAlias: data = TargetID(2 hex) + Alias(ASCII string)
var alias = txtAlias.Text.Trim();
if (string.IsNullOrEmpty(alias))
{
AddLog("별칭을 입력하세요.", LogType.Error);
return;
}
var targetID = selectedAGV.ToString("X2");
var aliasBytes = Encoding.ASCII.GetBytes(alias);
var aliasHex = string.Join("", aliasBytes.Select(b => b.ToString("X2")));
var dataStr = targetID + aliasHex;
SendCommand(AGVCommandHE.GotoAlias, dataStr);
SaveSettings();
}
private void btnStop_Click(object sender, EventArgs e)
{
// Stop: data = TargetID(2 hex)
var targetID = selectedAGV.ToString("X2");
SendCommand(AGVCommandHE.Stop, targetID);
}
private void btnReset_Click(object sender, EventArgs e)
{
// Reset: data = TargetID(2 hex)
var targetID = selectedAGV.ToString("X2");
SendCommand(AGVCommandHE.Reset, targetID);
}
private void btnManual_Click(object sender, EventArgs e)
{
var but = sender as Button;
if (but.Tag == null) return;
var tagstr = but.Tag.ToString();
var targetID = selectedAGV.ToString("X2");
var direction = byte.Parse(tagstr);// //back
var speed = (byte)0;// cmbSpeed.SelectedIndex;
if (radSpdM.Checked) speed = 1;
else if (radSpdH.Checked) speed = 2;
var dataBytes = new byte[] { direction, speed };
var dataStr = targetID + string.Join("", dataBytes.Select(b => b.ToString("X2")));
SendCommand(AGVCommandHE.Manual, dataStr);
}
private void btnMarkStop_Click(object sender, EventArgs e)
{
// MarkStop: data = TargetID(2 hex) + MarkStop(1 byte)
var targetID = selectedAGV.ToString("X2");
var markStop = "01";// chkMarkStop.Checked ? "01" : "00";
SendCommand(AGVCommandHE.MarkStop, targetID + markStop);
}
private void btnLiftUp_Click(object sender, EventArgs e)
{
SendLiftCommand(1); // Up
}
private void btnLiftDown_Click(object sender, EventArgs e)
{
SendLiftCommand(2); // Down
}
private void btnLiftStop_Click(object sender, EventArgs e)
{
SendLiftCommand(0); // Stop
}
private void SendLiftCommand(byte liftCmd)
{
// LiftControl: data = TargetID(2 hex) + LiftCommand(1 byte)
var targetID = selectedAGV.ToString("X2");
var dataStr = targetID + liftCmd.ToString("X2");
SendCommand(AGVCommandHE.LiftControl, dataStr);
}
private void SendCommand(AGVCommandHE command, string dataHexString)
{
if (!serialPort.IsOpen)
{
AddLog("포트가 연결되지 않았습니다.", LogType.Error);
return;
}
try
{
// Hex 문자열을 byte 배열로 변환
byte[] dataBytes = new byte[dataHexString.Length / 2];
for (int i = 0; i < dataBytes.Length; i++)
{
dataBytes[i] = Convert.ToByte(dataHexString.Substring(i * 2, 2), 16);
}
// 패킷 생성 (ACS ID = 0)
byte[] packet = protocol.CreatePacket(0, (byte)command, dataBytes);
// 전송
serialPort.Write(packet, 0, packet.Length);
var hexString = string.Join(" ", packet.Select(b => b.ToString("X2")));
//정보를 조금더 추출한다.
var Sender = packet[2];
if (Sender == 0x00)
{
var Receiver = packet[4];
var strdata = System.Text.Encoding.Default.GetString(dataBytes, 1, dataBytes.Length - 1);// (dataHexString.Substring(2), 16);
AddLog($"{hexString}|{command}({(byte)command:X2}) From:{Sender} To:{Receiver} => {dataHexString} STR:{strdata}", LogType.TX);
}
else
{
AddLog($"{hexString}|{command}({(byte)command:X2}) From:{Sender} => {dataHexString}", LogType.TX);
}
}
catch (Exception ex)
{
AddLog($"전송 실패: {ex.Message}", LogType.Error);
}
}
private void UpdateAGVStatus(byte[] data)
{
if (data.Length < 12)
{
AddLog($"AGV 상태 데이터 길이 오류: {data.Length} bytes", LogType.Error);
return;
}
if (InvokeRequired)
{
BeginInvoke(new Action(() => UpdateAGVStatus(data)));
return;
}
try
{
// Mode[1]: 0=manual, 1=auto
lblModeValue.Text = data[0] == 0 ? "수동" : "자동";
lblModeValue.ForeColor = data[0] == 0 ? Color.Blue : Color.Green;
// RunSt[1]: 0=stop, 1=run, 2=error
switch (data[1])
{
case 0:
lblRunStValue.Text = "정지";
lblRunStValue.ForeColor = Color.Gray;
break;
case 1:
lblRunStValue.Text = "실행";
lblRunStValue.ForeColor = Color.Green;
break;
case 2:
lblRunStValue.Text = "에러";
lblRunStValue.ForeColor = Color.Red;
break;
default:
lblRunStValue.Text = "알 수 없음";
lblRunStValue.ForeColor = Color.Black;
break;
}
// Mot Direction[1]: 0=forward, 1:backward
switch (data[2])
{
case 0:
lblDirectionValue.Text = "전진";
break;
case 1:
lblDirectionValue.Text = "후진";
break;
default:
lblDirectionValue.Text = "??";
break;
}
// Direction[1]: 0=straight, 1=left, 2=right, 3=markstop
switch (data[3])
{
case 0:
lblDirectionValue.Text += "/직진";
break;
case 1:
lblDirectionValue.Text += "/좌회전";
break;
case 2:
lblDirectionValue.Text += "/우회전";
break;
default:
lblDirectionValue.Text += "/??";
break;
}
// Inposition[1]: 0=off, 1=on
lblInpositionValue.Text = data[4] == 0 ? "OFF" : "ON";
lblInpositionValue.ForeColor = data[4] == 0 ? Color.Gray : Color.Green;
// ChargeSt[1]: 0=off, 1=on
lblChargeStValue.Text = data[5] == 0 ? "OFF" : "ON";
lblChargeStValue.ForeColor = data[5] == 0 ? Color.Gray : Color.Orange;
// CartSt[1]: 0=off, 1=on, 2=unknown
switch (data[6])
{
case 0:
lblCartStValue.Text = "없음";
lblCartStValue.ForeColor = Color.Gray;
break;
case 1:
lblCartStValue.Text = "있음";
lblCartStValue.ForeColor = Color.Green;
break;
default:
lblCartStValue.Text = "??";
lblCartStValue.ForeColor = Color.Red;
break;
}
// LiftSt[1]: 0=down, 1=up, 2=unknown
switch (data[7])
{
case 0:
lblLiftStValue.Text = "하강";
lblLiftStValue.ForeColor = Color.Blue;
break;
case 1:
lblLiftStValue.Text = "상승";
lblLiftStValue.ForeColor = Color.Green;
break;
default:
lblLiftStValue.Text = "??";
lblLiftStValue.ForeColor = Color.Red;
break;
}
string lastTag = Encoding.ASCII.GetString(data, 8, 4);
lblLastTagValue.Text = lastTag;
lblLastTagValue.ForeColor = Color.Black;
}
catch (Exception ex)
{
AddLog($"AGV 상태 업데이트 실패: {ex.Message}", LogType.Error);
}
}
private enum LogType { TX, RX, Info, Error }
private void AddLog(string message, LogType type)
{
if (InvokeRequired)
{
BeginInvoke(new Action(() => AddLog(message, type)));
return;
}
var timestamp = DateTime.Now.ToString("HH:mm:ss");
var logMessage = $"[{timestamp}] {message}\r\n";
switch (type)
{
case LogType.TX:
txtTxLog.AppendText(logMessage);
txtTxLog.ScrollToCaret();
break;
case LogType.RX:
txtRxLog.AppendText(logMessage);
txtRxLog.ScrollToCaret();
break;
case LogType.Info:
txtInfoLog.AppendText(logMessage);
txtInfoLog.ScrollToCaret();
break;
case LogType.Error:
txtInfoLog.ForeColor = Color.Red;
txtInfoLog.AppendText(logMessage);
txtInfoLog.ForeColor = Color.Black;
txtInfoLog.ScrollToCaret();
break;
}
}
protected override void OnFormClosing(FormClosingEventArgs e)
{
if (serialPort != null && serialPort.IsOpen)
{
serialPort.Close();
}
base.OnFormClosing(e);
}
private void btAMove_Click(object sender, EventArgs e)
{
var targetID = selectedAGV.ToString("X2");
byte Motdirection = 0;// (byte)cmbMotDirection.SelectedIndex;
if (radForw.Checked) Motdirection = 1;
byte Magdirection = 0;
if (radLeft.Checked) Magdirection = 1;
else if (radRight.Checked) Magdirection = 2;
byte speed = 0;// (byte)cmbAutoSpeed.SelectedIndex;
if (radSpdM.Checked) speed = 1;
else if (radSpdH.Checked) speed = 2;
byte lidar = 2;
if (radLidarOff.Checked) lidar = 0;
var dataBytes = new byte[] { Motdirection, Magdirection, speed ,lidar};
var dataStr = targetID + string.Join("", dataBytes.Select(b => b.ToString("X2")));
SendCommand(AGVCommandHE.AutoMove, dataStr);
}
private void button2_Click(object sender, EventArgs e)
{
// Stop: data = TargetID(2 hex)
var targetID = selectedAGV.ToString("X2");
SendCommand(AGVCommandHE.Stop, targetID);
}
private void groupBox2_Enter(object sender, EventArgs e)
{
}
private void button6_Click(object sender, EventArgs e)
{
var targetID = selectedAGV.ToString("X2");
SendCommand(AGVCommandHE.Stop, targetID);
}
private void button7_Click(object sender, EventArgs e)
{
//lt180
var targetID = selectedAGV.ToString("X2");
SendCommand(AGVCommandHE.LTurn180, targetID);
}
private void button8_Click(object sender, EventArgs e)
{
//rt180
var targetID = selectedAGV.ToString("X2");
SendCommand(AGVCommandHE.RTurn180, targetID);
}
private void button9_Click(object sender, EventArgs e)
{
//l turn
var targetID = selectedAGV.ToString("X2");
SendCommand(AGVCommandHE.LTurn, targetID);
}
private void button10_Click(object sender, EventArgs e)
{
///r-turn
var targetID = selectedAGV.ToString("X2");
SendCommand(AGVCommandHE.RTurn, targetID);
}
}
}

View File

@@ -0,0 +1,133 @@
<?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>
<data name="richTextBox1.Text" xml:space="preserve">
<value>### 기본 패킷 구조
```
[STX][LEN][ID][CMD][DATA][CRC16][ETX]
```
- **STX (Start of Text)**: 0x02
- **LEN (Length)**: 데이터 길이 (1바이트) = {ID+CMD+DATA}
- **ID (Client ID)**: 데이터 길이 (1바이트) : 디바이스식별코드(=DeviceType)
- **CMD (Command)**: 명령어 코드 (1바이트)
- **DATA**: 명령어에 따른 데이터 (가변 길이)
- **CRC16**: 데이터 무결성 검사 (2바이트)
- **ETX (End of Text)**: 0x03</value>
</data>
</root>

View File

@@ -0,0 +1,16 @@
using System;
using System.Windows.Forms;
namespace Test_ACS
{
static class Program
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new MainForm());
}
}
}

View File

@@ -0,0 +1,19 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
[assembly: AssemblyTitle("Test_ACS")]
[assembly: AssemblyDescription("ACS Simulator for ENIG AGV Testing")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("ENIG")]
[assembly: AssemblyProduct("Test_ACS")]
[assembly: AssemblyCopyright("Copyright © 2025")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: ComVisible(false)]
[assembly: Guid("a1b2c3d4-e5f6-4a5b-8c9d-0e1f2a3b4c5d")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@@ -0,0 +1,63 @@
//------------------------------------------------------------------------------
// <auto-generated>
// 이 코드는 도구를 사용하여 생성되었습니다.
// 런타임 버전:4.0.30319.42000
//
// 파일 내용을 변경하면 잘못된 동작이 발생할 수 있으며, 코드를 다시 생성하면
// 이러한 변경 내용이 손실됩니다.
// </auto-generated>
//------------------------------------------------------------------------------
namespace Test_ACS.Properties {
using System;
/// <summary>
/// 지역화된 문자열 등을 찾기 위한 강력한 형식의 리소스 클래스입니다.
/// </summary>
// 이 클래스는 ResGen 또는 Visual Studio와 같은 도구를 통해 StronglyTypedResourceBuilder
// 클래스에서 자동으로 생성되었습니다.
// 멤버를 추가하거나 제거하려면 .ResX 파일을 편집한 다음 /str 옵션을 사용하여 ResGen을
// 다시 실행하거나 VS 프로젝트를 다시 빌드하십시오.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.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("Test_ACS.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,101 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 1.3
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">1.3</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1">this is my long string</data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
[base64 mime encoded serialized .NET Framework object]
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
[base64 mime encoded string representing a byte array form of the .NET Framework object]
</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="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>1.3</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@@ -0,0 +1,86 @@
//------------------------------------------------------------------------------
// <auto-generated>
// 이 코드는 도구를 사용하여 생성되었습니다.
// 런타임 버전:4.0.30319.42000
//
// 파일 내용을 변경하면 잘못된 동작이 발생할 수 있으며, 코드를 다시 생성하면
// 이러한 변경 내용이 손실됩니다.
// </auto-generated>
//------------------------------------------------------------------------------
namespace Test_ACS.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.9.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;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("COM1")]
public string LastPort {
get {
return ((string)(this["LastPort"]));
}
set {
this["LastPort"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("9600")]
public string LastBaudRate {
get {
return ((string)(this["LastBaudRate"]));
}
set {
this["LastBaudRate"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("0001")]
public string LastRFID {
get {
return ((string)(this["LastRFID"]));
}
set {
this["LastRFID"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("CHARGER1")]
public string LastAlias {
get {
return ((string)(this["LastAlias"]));
}
set {
this["LastAlias"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("11")]
public int LastAGV {
get {
return ((int)(this["LastAGV"]));
}
set {
this["LastAGV"] = value;
}
}
}
}

View File

@@ -0,0 +1,23 @@
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" GeneratedClassNamespace="Test_ACS.Properties" GeneratedClassName="Settings">
<Profiles>
<Profile Name="(Default)" />
</Profiles>
<Settings>
<Setting Name="LastPort" Type="System.String" Scope="User">
<Value Profile="(Default)">COM1</Value>
</Setting>
<Setting Name="LastBaudRate" Type="System.String" Scope="User">
<Value Profile="(Default)">9600</Value>
</Setting>
<Setting Name="LastRFID" Type="System.String" Scope="User">
<Value Profile="(Default)">0001</Value>
</Setting>
<Setting Name="LastAlias" Type="System.String" Scope="User">
<Value Profile="(Default)">CHARGER1</Value>
</Setting>
<Setting Name="LastAGV" Type="System.Int32" Scope="User">
<Value Profile="(Default)">11</Value>
</Setting>
</Settings>
</SettingsFile>

View File

@@ -0,0 +1,242 @@
# Test_ACS - ACS 시뮬레이터
ENIG AGV 프로젝트를 위한 ACS(중앙제어시스템) 시뮬레이터입니다.
## 프로젝트 개요
ACS는 AGV에게 명령을 내리는 중앙 제어 시스템입니다. 이 프로그램은 실제 ACS 대신 테스트 목적으로 AGV에 명령을 보낼 수 있는 시뮬레이터입니다.
### 통신 방식
- **프로토콜**: ENIG Protocol (ENIGProtocol 프로젝트 사용)
- **통신**: RS232 (Xbee 모듈)
- **ACS Xbee ID**: 0
- **AGV Xbee ID**:
- AGV1: 11
- AGV2: 12
## 프로젝트 구조
```
Test_ACS/
├── Test_ACS.csproj # 프로젝트 파일
├── Program.cs # 진입점
├── MainForm.cs # 메인 폼 로직
├── MainForm.Designer.cs # 메인 폼 디자이너
├── MainForm.resx # 메인 폼 리소스
├── Properties/ # 프로젝트 속성
│ ├── AssemblyInfo.cs
│ ├── Resources.Designer.cs
│ ├── Resources.resx
│ ├── Settings.Designer.cs
│ └── Settings.settings
└── app.config # 애플리케이션 설정
```
## 빌드 방법
1. Visual Studio 2022 또는 MSBuild 사용
2. .NET Framework 4.8 필요
3. ENIGProtocol 프로젝트 참조 필요
```bash
# Visual Studio에서 빌드
- 솔루션 탐색기에서 Test_ACS 프로젝트 선택
- 빌드 > 솔루션 빌드
# 또는 MSBuild 사용
msbuild Test_ACS.csproj /p:Configuration=Debug
```
## 사용 방법
### 1. 연결 설정
1. **COM 포트 선택**: Xbee 모듈이 연결된 COM 포트 선택
2. **보레이트 입력**: 기본값 9600 (Xbee 설정에 맞춰 조정)
3. **연결 버튼 클릭**: 포트 연결
**자동 저장**: 포트와 보레이트는 변경 시 자동으로 저장되며, 다음 실행 시 자동으로 불러옵니다.
### 2. AGV 선택
- **AGV1 (ID:11)**: 첫 번째 AGV 선택
- **AGV2 (ID:12)**: 두 번째 AGV 선택
**자동 저장**: 선택한 AGV는 자동으로 저장되며, 다음 실행 시 자동으로 선택됩니다.
### 3. 명령 전송
#### SetCurrent (현재 위치 설정)
- **RFID 번호 입력**: 예) 0001
- **SetCurrent 버튼 클릭**: AGV의 현재 위치를 지정한 RFID로 설정
- **자동 저장**: 입력한 RFID 번호는 자동으로 저장됩니다.
#### Goto (RFID 이동 명령)
- **RFID 번호 입력**: 목표 위치 RFID (예: 0001)
- **Goto 버튼 클릭**: AGV를 지정한 RFID 위치로 이동
- **자동 저장**: 입력한 RFID 번호는 자동으로 저장됩니다.
#### GotoAlias (별칭 이동 명령)
- **별칭(Alias) 입력**: 목표 위치 별칭 (예: CHARGER1, BUFFER2, STATION_A)
- **GotoAlias 버튼 클릭**: AGV를 지정한 별칭 위치로 이동
- **참고**: 별칭은 AGV에 미리 등록된 이름으로, RFID 대신 의미 있는 이름 사용
- **자동 저장**: 입력한 별칭은 자동으로 저장됩니다.
#### Stop (정지)
- **Stop 버튼 클릭**: AGV 즉시 정지
#### Reset (에러 리셋)
- **Reset 버튼 클릭**: AGV 에러 상태 초기화
#### Manual (수동 제어)
- **방향 선택**: 후진, 전진, 좌회전, 우회전
- **속도 선택**: 느림, 보통, 빠름
- **시간(초) 입력**: 이동 시간
- **수동 이동 실행 버튼 클릭**
#### MarkStop (마크센서 정지)
- **정지 설정 체크**: 마크센서 정지 활성화/비활성화
- **마크센서 정지 버튼 클릭**
#### LiftControl (리프트 제어)
- **리프트 상승**: 리프트 올리기
- **리프트 하강**: 리프트 내리기
- **리프트 정지**: 리프트 동작 중지
## AGV 상태 확인
프로그램 하단의 "AGV 상태" 그룹박스에서 실시간 AGV 상태를 확인할 수 있습니다:
- **모드**: 수동/자동
- **실행상태**: 정지/실행/에러
- **방향**: 직진/좌회전/우회전/마크정지
- **도달완료**: 목적지 도달 여부 (OFF/ON)
- **충전**: 충전 상태 (OFF/ON)
- **카트**: 카트 감지 상태 (없음/있음/알 수 없음)
- **리프트**: 리프트 위치 (하강/상승/알 수 없음)
- **현재태그**: 마지막으로 인식한 RFID 태그 번호
상태는 AGV가 주기적으로 전송하는 Status 메시지(cmd=3)를 수신하여 자동으로 업데이트됩니다.
## 로그 확인
프로그램 우측에 3개의 탭으로 로그를 확인할 수 있습니다:
- **송신 (TX)**: ACS에서 AGV로 보낸 명령
- **수신 (RX)**: AGV에서 ACS로 받은 응답
- **정보**: 연결 상태, 설정 저장/불러오기, 에러 메시지
## 설정 저장 위치
모든 설정은 실행 파일과 같은 폴더에 저장됩니다:
- **위치**: `Test_ACS.exe`와 같은 폴더의 `Test_ACS.config` 파일
- **형식**: JSON 형식으로 저장
- **저장 항목**:
- 마지막 사용 COM 포트
- 마지막 사용 보레이트
- 마지막 입력 RFID 번호
- 마지막 입력 별칭
- 마지막 선택 AGV (11 또는 12)
- **자동 저장**: 설정 변경 시 자동 저장
- **자동 불러오기**: 프로그램 시작 시 자동 불러오기
예시 설정 파일 (`Test_ACS.config`):
```json
{
"LastPort": "COM3",
"LastBaudRate": "9600",
"LastRFID": "0001",
"LastAlias": "CHARGER1",
"LastAGV": 11
}
```
## 프로토콜 상세
### 패킷 구조
```
STX (0x02) + Length + ID + Command + Data + CRC16 (2 bytes) + ETX (0x03)
```
### ACS 명령어 (AGVCommandHE)
| 명령 | 코드 | 데이터 형식 | 설명 |
|------|------|-------------|------|
| Goto | 100 | TargetID(2) + RFID(4) | RFID로 목표 위치로 이동 |
| Stop | 101 | TargetID(2) | 정지 |
| Reset | 102 | TargetID(2) | 에러 리셋 |
| SetCurrent | 103 | TargetID(2) + RFID(4) | 현재 위치 설정 |
| Manual | 104 | TargetID(2) + Direction(1) + Speed(1) + Runtime(1) | 수동 이동 |
| MarkStop | 105 | TargetID(2) + MarkStop(1) | 마크센서 정지 |
| LiftControl | 106 | TargetID(2) + LiftCommand(1) | 리프트 제어 |
| **GotoAlias** | **107** | **TargetID(2) + Alias(ASCII)** | **별칭으로 목표 위치로 이동** |
### 데이터 상세
#### Direction (Manual 명령)
- 0: 후진 (Back)
- 1: 전진 (Forward)
- 2: 좌회전 (Left)
- 3: 우회전 (Right)
#### Speed (Manual 명령)
- 0: 느림 (Slow)
- 1: 보통 (Normal)
- 2: 빠름 (Fast)
#### LiftCommand (LiftControl 명령)
- 0: 정지 (Stop)
- 1: 상승 (Up)
- 2: 하강 (Down)
## 참고 파일
- **프로토콜 정의**: `SubProject\EnigProtocol\enigprotocol\Commands.cs`
- **프로토콜 구현**: `SubProject\EnigProtocol\enigprotocol\EEProtocol.cs`
- **AGV 수신 처리**: `Project\StateMachine\_Xbee.cs`
## 개발자 노트
### 프로젝트 참조
- ENIGProtocol 프로젝트를 참조하여 프로토콜 기능 사용
- ProjectReference GUID: {499d8912-4b96-41e5-a70d-cfe797883d65}
### 주요 클래스
- `EEProtocol`: 패킷 생성 및 파싱
- `SerialPort`: RS232 통신 관리
- `MainForm`: UI 및 명령 전송 로직
### 디버깅 팁
1. 로그 탭에서 송수신 패킷의 HEX 값 확인
2. CRC 에러 발생 시 프로토콜 버전 확인
3. 응답이 없을 경우 Xbee 모듈 설정 확인 (PAN ID: 46A5, Channel: 17)
## 라이센스
ENIG AGV 프로젝트의 일부로, 내부 테스트 용도로 사용됩니다.
## 버전 이력
- v1.4.0 (2025-01-12): 설정 파일 저장 방식 변경
- 실행 폴더에 JSON 형식으로 설정 저장 (Test_ACS.config)
- 설정 파일 직접 편집 가능
- 프로그램 이동 시 설정 파일도 함께 이동
- v1.3.0 (2025-01-12): AGV 상태 실시간 표시 기능 추가
- AGV 상태 그룹박스 추가 (모드, 실행상태, 방향, 도달완료, 충전, 카트, 리프트, 현재태그)
- Status 메시지(cmd=3) 자동 수신 및 UI 업데이트
- 상태별 색상 표시로 직관적 모니터링
- 프로토콜 문서 업데이트 (LastTag 6바이트, CurrentPath 제거)
- v1.2.0 (2025-01-12): 설정 자동 저장/불러오기
- COM 포트, 보레이트, RFID, 별칭, AGV 선택 자동 저장
- 프로그램 시작 시 마지막 설정 자동 복원
- v1.1.0 (2025-01-12): GotoAlias 명령어 추가
- 별칭(Alias) 기반 이동 명령 지원
- UI 레이아웃 최적화
- v1.0.0 (2025-01-11): 초기 버전 생성
- ACS 시뮬레이터 기본 기능
- ENIGProtocol 연동
- 7가지 ACS 명령어 지원 (Goto, Stop, Reset, SetCurrent, Manual, MarkStop, LiftControl)

View File

@@ -0,0 +1,93 @@
<?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>{A1B2C3D4-E5F6-4A5B-8C9D-0E1F2A3B4C5D}</ProjectGuid>
<OutputType>WinExe</OutputType>
<RootNamespace>Test_ACS</RootNamespace>
<AssemblyName>Test_ACS</AssemblyName>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<Deterministic>true</Deterministic>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>..\..\..\..\..\..\Amkor\AGV4\Test\ACS\</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>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<ItemGroup>
<Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.13.0.4\lib\net45\Newtonsoft.Json.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.Deployment" />
<Reference Include="System.Drawing" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="AppSettings.cs" />
<Compile Include="MainForm.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="MainForm.Designer.cs">
<DependentUpon>MainForm.cs</DependentUpon>
</Compile>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
<DependentUpon>Settings.settings</DependentUpon>
</Compile>
<EmbeddedResource Include="MainForm.resx">
<DependentUpon>MainForm.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
<None Include="app.config" />
<None Include="packages.config" />
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\SubProject\EnigProtocol\enigprotocol\ENIGProtocol.csproj">
<Project>{499d8912-4b96-41e5-a70d-cfe797883d65}</Project>
<Name>ENIGProtocol</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

View File

@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
<section name="Test_ACS.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
</sectionGroup>
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8"/>
</startup>
<userSettings>
<Test_ACS.Properties.Settings>
<setting name="LastPort" serializeAs="String">
<value>COM1</value>
</setting>
<setting name="LastBaudRate" serializeAs="String">
<value>9600</value>
</setting>
<setting name="LastRFID" serializeAs="String">
<value>0001</value>
</setting>
<setting name="LastAlias" serializeAs="String">
<value>CHARGER1</value>
</setting>
<setting name="LastAGV" serializeAs="String">
<value>11</value>
</setting>
</Test_ACS.Properties.Settings>
</userSettings>
</configuration>

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Newtonsoft.Json" version="13.0.4" targetFramework="net48" />
</packages>

214
HMI/TestProject/Test_BMS/Form1.Designer.cs generated Normal file
View File

@@ -0,0 +1,214 @@
namespace Test_BMS
{
partial class Form1
{
/// <summary>
/// 필수 디자이너 변수입니다.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// 사용 중인 모든 리소스를 정리합니다.
/// </summary>
/// <param name="disposing">관리되는 리소스를 삭제해야 하면 true이고, 그렇지 않으면 false입니다.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form
/// <summary>
/// 디자이너 지원에 필요한 메서드입니다.
/// 이 메서드의 내용을 코드 편집기로 수정하지 마세요.
/// </summary>
private void InitializeComponent()
{
this.comboBox1 = new System.Windows.Forms.ComboBox();
this.button1 = new System.Windows.Forms.Button();
this.button2 = new System.Windows.Forms.Button();
this.comboBox2 = new System.Windows.Forms.ComboBox();
this.label1 = new System.Windows.Forms.Label();
this.label2 = new System.Windows.Forms.Label();
this.logTextBox1 = new arCtl.LogTextBox();
this.button3 = new System.Windows.Forms.Button();
this.btSendCV = new System.Windows.Forms.Button();
this.button5 = new System.Windows.Forms.Button();
this.logTextBox2 = new arCtl.LogTextBox();
this.SuspendLayout();
//
// comboBox1
//
this.comboBox1.FormattingEnabled = true;
this.comboBox1.Location = new System.Drawing.Point(27, 35);
this.comboBox1.Name = "comboBox1";
this.comboBox1.Size = new System.Drawing.Size(131, 20);
this.comboBox1.TabIndex = 0;
this.comboBox1.Text = "com6";
//
// button1
//
this.button1.Location = new System.Drawing.Point(301, 35);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(108, 20);
this.button1.TabIndex = 1;
this.button1.Text = "connect";
this.button1.UseVisualStyleBackColor = true;
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// button2
//
this.button2.Location = new System.Drawing.Point(415, 34);
this.button2.Name = "button2";
this.button2.Size = new System.Drawing.Size(106, 20);
this.button2.TabIndex = 1;
this.button2.Text = "close";
this.button2.UseVisualStyleBackColor = true;
this.button2.Click += new System.EventHandler(this.button2_Click);
//
// comboBox2
//
this.comboBox2.FormattingEnabled = true;
this.comboBox2.Items.AddRange(new object[] {
"9600",
"12800",
"25600",
"250000"});
this.comboBox2.Location = new System.Drawing.Point(164, 35);
this.comboBox2.Name = "comboBox2";
this.comboBox2.Size = new System.Drawing.Size(131, 20);
this.comboBox2.TabIndex = 2;
this.comboBox2.Text = "9600";
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(27, 13);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(26, 12);
this.label1.TabIndex = 3;
this.label1.Text = "port";
this.label1.Click += new System.EventHandler(this.label1_Click);
//
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(162, 13);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(33, 12);
this.label2.TabIndex = 3;
this.label2.Text = "baud";
//
// logTextBox1
//
this.logTextBox1.BackColor = System.Drawing.Color.WhiteSmoke;
this.logTextBox1.ColorList = new arCtl.sLogMessageColor[0];
this.logTextBox1.DateFormat = "yy-MM-dd HH:mm:ss";
this.logTextBox1.DefaultColor = System.Drawing.Color.LightGray;
this.logTextBox1.EnableDisplayTimer = true;
this.logTextBox1.EnableGubunColor = true;
this.logTextBox1.Font = new System.Drawing.Font("Consolas", 9F);
this.logTextBox1.ListFormat = "[{0}] {1}";
this.logTextBox1.Location = new System.Drawing.Point(27, 87);
this.logTextBox1.MaxListCount = ((ushort)(200));
this.logTextBox1.MaxTextLength = ((uint)(4000u));
this.logTextBox1.MessageInterval = 50;
this.logTextBox1.Name = "logTextBox1";
this.logTextBox1.Size = new System.Drawing.Size(368, 395);
this.logTextBox1.TabIndex = 4;
this.logTextBox1.Text = "";
//
// button3
//
this.button3.Location = new System.Drawing.Point(301, 61);
this.button3.Name = "button3";
this.button3.Size = new System.Drawing.Size(140, 20);
this.button3.TabIndex = 5;
this.button3.Text = "read status";
this.button3.UseVisualStyleBackColor = true;
this.button3.Click += new System.EventHandler(this.button3_Click);
//
// btSendCV
//
this.btSendCV.Location = new System.Drawing.Point(447, 60);
this.btSendCV.Name = "btSendCV";
this.btSendCV.Size = new System.Drawing.Size(140, 20);
this.btSendCV.TabIndex = 6;
this.btSendCV.Text = "read cellvoltage";
this.btSendCV.UseVisualStyleBackColor = true;
this.btSendCV.Click += new System.EventHandler(this.button4_Click);
//
// button5
//
this.button5.Location = new System.Drawing.Point(155, 61);
this.button5.Name = "button5";
this.button5.Size = new System.Drawing.Size(140, 20);
this.button5.TabIndex = 7;
this.button5.Text = "send query";
this.button5.UseVisualStyleBackColor = true;
this.button5.Click += new System.EventHandler(this.button5_Click);
//
// logTextBox2
//
this.logTextBox2.BackColor = System.Drawing.Color.WhiteSmoke;
this.logTextBox2.ColorList = new arCtl.sLogMessageColor[0];
this.logTextBox2.DateFormat = "yy-MM-dd HH:mm:ss";
this.logTextBox2.DefaultColor = System.Drawing.Color.LightGray;
this.logTextBox2.EnableDisplayTimer = true;
this.logTextBox2.EnableGubunColor = true;
this.logTextBox2.Font = new System.Drawing.Font("Consolas", 9F);
this.logTextBox2.ListFormat = "[{0}] {1}";
this.logTextBox2.Location = new System.Drawing.Point(401, 87);
this.logTextBox2.MaxListCount = ((ushort)(200));
this.logTextBox2.MaxTextLength = ((uint)(4000u));
this.logTextBox2.MessageInterval = 50;
this.logTextBox2.Name = "logTextBox2";
this.logTextBox2.Size = new System.Drawing.Size(368, 395);
this.logTextBox2.TabIndex = 8;
this.logTextBox2.Text = "";
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(779, 494);
this.Controls.Add(this.logTextBox2);
this.Controls.Add(this.button5);
this.Controls.Add(this.btSendCV);
this.Controls.Add(this.button3);
this.Controls.Add(this.logTextBox1);
this.Controls.Add(this.label2);
this.Controls.Add(this.label1);
this.Controls.Add(this.comboBox2);
this.Controls.Add(this.button2);
this.Controls.Add(this.button1);
this.Controls.Add(this.comboBox1);
this.Name = "Form1";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "Form1";
this.Load += new System.EventHandler(this.Form1_Load);
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.ComboBox comboBox1;
private System.Windows.Forms.Button button1;
private System.Windows.Forms.Button button2;
private System.Windows.Forms.ComboBox comboBox2;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Label label2;
private arCtl.LogTextBox logTextBox1;
private System.Windows.Forms.Button button3;
private System.Windows.Forms.Button btSendCV;
private System.Windows.Forms.Button button5;
private arCtl.LogTextBox logTextBox2;
}
}

View File

@@ -0,0 +1,129 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics.Eventing.Reader;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace Test_BMS
{
public partial class Form1 : Form
{
arDev.BMS bms;
public Form1()
{
InitializeComponent();
bms = new arDev.BMS();
bms.BMSDataReceive += Bms_BMSDataReceive;
bms.BMSCellDataReceive += Bms_BMSCellDataReceive;
bms.Message += Bms_Message;
this.Text = $"{Application.ProductName} ver{Application.ProductVersion}";
}
private void Bms_BMSCellDataReceive(object sender, arDev.BMSCelvoltageEventArgs e)
{
var valuestr = e.ToString();// string.Join(" ", e.voltage.Select(t => t.ToString()));
addmsg2($"{valuestr}");
}
private void Bms_BMSDataReceive(object sender, arDev.BMSInformationEventArgs e)
{
//최종 데이터가 수신되는 경우
addmsg(e.Data.ToString());
}
private void Bms_Message(object sender, arDev.BMSSerialComm.MessageEventArgs e)
{
var sb = new System.Text.StringBuilder();
if (e.Data != null)
{
foreach (var b in e.Data)
sb.Append(" " + b.ToString("X2"));
}
else sb.Append(e.Message);
if (e.MsgType == arDev.BMSSerialComm.MessageType.Error)
addmsg(e.Message);
else if(e.MsgType == arDev.BMSSerialComm.MessageType.Send)
{
addmsg($"Tx:{sb}");
}
else if(e.MsgType == arDev.BMSSerialComm.MessageType.Recv)
{
addmsg($"Rx:{sb}");
}
else
addmsg($"{e.MsgType}:{sb}");
}
void addmsg(string m)
{
if (logTextBox1.InvokeRequired)
{
logTextBox1.BeginInvoke(new Action(() => {
logTextBox1.AddMsg(m);
}));
}
else
{
logTextBox1.AddMsg(m);
}
}
void addmsg2(string m)
{
if (logTextBox2.InvokeRequired)
{
logTextBox2.BeginInvoke(new Action(() => {
logTextBox2.AddMsg(m);
}));
}
else
{
logTextBox2.AddMsg(m);
}
}
private void Form1_Load(object sender, EventArgs e)
{
this.comboBox1.Items.Clear();
foreach (var port in System.IO.Ports.SerialPort.GetPortNames())
this.comboBox1.Items.Add(port);
}
private void button1_Click(object sender, EventArgs e)
{
bms.BaudRate = int.Parse(this.comboBox2.Text);
bms.PortName = comboBox1.Text;
bms.Open();
addmsg($"open:{bms.IsOpen}");
}
private void button2_Click(object sender, EventArgs e)
{
bms.Close();
}
private void button3_Click(object sender, EventArgs e)
{
bms.SendQuery_ReadStatue();
}
private void label1_Click(object sender, EventArgs e)
{
comboBox1.Text = "COM41";
}
private void button4_Click(object sender, EventArgs e)
{
bms.SendQuery_ReadCellvoltage();
}
private void button5_Click(object sender, EventArgs e)
{
bms.SendQuery();
}
}
}

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>

View File

@@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
namespace Test_BMS
{
static class Program
{
/// <summary>
/// 해당 응용 프로그램의 주 진입점입니다.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
}

View File

@@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// 어셈블리에 대한 일반 정보는 다음 특성 집합을 통해
// 제어됩니다. 어셈블리와 관련된 정보를 수정하려면
// 이러한 특성 값을 변경하세요.
[assembly: AssemblyTitle("BMS Commnunication Module Test")]
[assembly: AssemblyDescription("BMS Commnunication Module Test")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("BMS Commnunication Module Test")]
[assembly: AssemblyProduct("BMS Test Software")]
[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("ce3fff9f-6aca-44bd-b64a-33ff4ad5e82e")]
// 어셈블리의 버전 정보는 다음 네 가지 값으로 구성됩니다.
//
// 주 버전
// 부 버전
// 빌드 번호
// 수정 버전
//
// 모든 값을 지정하거나 아래와 같이 '*'를 사용하여 빌드 번호 및 수정 번호가 자동으로
// 지정되도록 할 수 있습니다.
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("20.03.09.0")]
[assembly: AssemblyFileVersion("20.03.09.0")]

View File

@@ -0,0 +1,63 @@
//------------------------------------------------------------------------------
// <auto-generated>
// 이 코드는 도구를 사용하여 생성되었습니다.
// 런타임 버전:4.0.30319.42000
//
// 파일 내용을 변경하면 잘못된 동작이 발생할 수 있으며, 코드를 다시 생성하면
// 이러한 변경 내용이 손실됩니다.
// </auto-generated>
//------------------------------------------------------------------------------
namespace Test_BMS.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("Test_BMS.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 Test_BMS.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.4.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,8 @@
[22-12-27 14:32:49] open:True
[22-12-27 14:32:49] Send: DD A5 03 00 FF FD 77 0D
[22-12-27 14:32:50] Send: DD A5 03 00 FF FD 77 0D
[22-12-27 14:32:50] Recv:26.61v,81.4%
[22-12-27 14:32:50] Recv: 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
[22-12-27 14:32:50] Send: DD A5 03 00 FF FD 77 0D
[22-12-27 14:32:51] Recv:26.61v,81.4%
[22-12-27 14:32:51] Recv: 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

View File

@@ -0,0 +1,108 @@
<?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>{CE3FFF9F-6ACA-44BD-B64A-33FF4AD5E82E}</ProjectGuid>
<OutputType>WinExe</OutputType>
<RootNamespace>Test_BMS</RootNamespace>
<AssemblyName>Test_BMS</AssemblyName>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<Deterministic>true</Deterministic>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>x86</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>..\..\..\..\..\..\Amkor\AGV4\Test\BMS\</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>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<ItemGroup>
<Reference Include="arControl.Net4">
<HintPath>..\..\DLL\arControl.Net4.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.Deployment" />
<Reference Include="System.Drawing" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\..\Project\Device\BMS.cs">
<Link>BMS.cs</Link>
</Compile>
<Compile Include="..\..\Project\Device\BMSInformationEventArgs.cs">
<Link>BMSInformationEventArgs.cs</Link>
</Compile>
<Compile Include="..\..\Project\Device\BMSSerialComm.cs">
<Link>BMSSerialComm.cs</Link>
</Compile>
<Compile Include="Form1.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Form1.Designer.cs">
<DependentUpon>Form1.cs</DependentUpon>
</Compile>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<EmbeddedResource Include="Form1.resx">
<DependentUpon>Form1.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="app.config" />
<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>
<ProjectReference Include="..\..\SubProject\CommData\CommData.csproj">
<Project>{14e8c9a5-013e-49ba-b435-efefc77dd623}</Project>
<Name>CommData</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Content Include="Sample.txt" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<PostBuildEvent>
</PostBuildEvent>
</PropertyGroup>
</Project>

View File

@@ -0,0 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8"/></startup></configuration>

View File

@@ -0,0 +1,536 @@
namespace Test_BMS
{
partial class Form1
{
/// <summary>
/// 필수 디자이너 변수입니다.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// 사용 중인 모든 리소스를 정리합니다.
/// </summary>
/// <param name="disposing">관리되는 리소스를 삭제해야 하면 true이고, 그렇지 않으면 false입니다.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form
/// <summary>
/// 디자이너 지원에 필요한 메서드입니다.
/// 이 메서드의 내용을 코드 편집기로 수정하지 마세요.
/// </summary>
private void InitializeComponent()
{
this.comboBox1 = new System.Windows.Forms.ComboBox();
this.button1 = new System.Windows.Forms.Button();
this.button2 = new System.Windows.Forms.Button();
this.comboBox2 = new System.Windows.Forms.ComboBox();
this.label1 = new System.Windows.Forms.Label();
this.label2 = new System.Windows.Forms.Label();
this.logTextBox1 = new arCtl.LogTextBox();
this.button3 = new System.Windows.Forms.Button();
this.button4 = new System.Windows.Forms.Button();
this.button5 = new System.Windows.Forms.Button();
this.button6 = new System.Windows.Forms.Button();
this.button7 = new System.Windows.Forms.Button();
this.button8 = new System.Windows.Forms.Button();
this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
this.button9 = new System.Windows.Forms.Button();
this.button10 = new System.Windows.Forms.Button();
this.button11 = new System.Windows.Forms.Button();
this.button12 = new System.Windows.Forms.Button();
this.button13 = new System.Windows.Forms.Button();
this.button14 = new System.Windows.Forms.Button();
this.button15 = new System.Windows.Forms.Button();
this.button16 = new System.Windows.Forms.Button();
this.button17 = new System.Windows.Forms.Button();
this.button18 = new System.Windows.Forms.Button();
this.button19 = new System.Windows.Forms.Button();
this.panel1 = new System.Windows.Forms.Panel();
this.rt0 = new System.Windows.Forms.RichTextBox();
this.tableLayoutPanel2 = new System.Windows.Forms.TableLayoutPanel();
this.rt1 = new System.Windows.Forms.RichTextBox();
this.rt2 = new System.Windows.Forms.RichTextBox();
this.rt3 = new System.Windows.Forms.RichTextBox();
this.tableLayoutPanel3 = new System.Windows.Forms.TableLayoutPanel();
this.logTextBox2 = new arCtl.LogTextBox();
this.tableLayoutPanel1.SuspendLayout();
this.panel1.SuspendLayout();
this.tableLayoutPanel2.SuspendLayout();
this.tableLayoutPanel3.SuspendLayout();
this.SuspendLayout();
//
// comboBox1
//
this.comboBox1.FormattingEnabled = true;
this.comboBox1.Location = new System.Drawing.Point(46, 10);
this.comboBox1.Name = "comboBox1";
this.comboBox1.Size = new System.Drawing.Size(100, 20);
this.comboBox1.TabIndex = 0;
this.comboBox1.Text = "COM21";
//
// button1
//
this.button1.Location = new System.Drawing.Point(289, 10);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(108, 20);
this.button1.TabIndex = 1;
this.button1.Text = "connect";
this.button1.UseVisualStyleBackColor = true;
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// button2
//
this.button2.Location = new System.Drawing.Point(403, 10);
this.button2.Name = "button2";
this.button2.Size = new System.Drawing.Size(106, 20);
this.button2.TabIndex = 1;
this.button2.Text = "close";
this.button2.UseVisualStyleBackColor = true;
this.button2.Click += new System.EventHandler(this.button2_Click);
//
// comboBox2
//
this.comboBox2.FormattingEnabled = true;
this.comboBox2.Items.AddRange(new object[] {
"9600",
"12800",
"25600",
"250000"});
this.comboBox2.Location = new System.Drawing.Point(188, 10);
this.comboBox2.Name = "comboBox2";
this.comboBox2.Size = new System.Drawing.Size(95, 20);
this.comboBox2.TabIndex = 2;
this.comboBox2.Text = "57600";
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(15, 14);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(26, 12);
this.label1.TabIndex = 3;
this.label1.Text = "port";
//
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(150, 14);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(33, 12);
this.label2.TabIndex = 3;
this.label2.Text = "baud";
//
// logTextBox1
//
this.logTextBox1.BackColor = System.Drawing.Color.WhiteSmoke;
this.logTextBox1.ColorList = new arCtl.sLogMessageColor[0];
this.logTextBox1.DateFormat = "ss.fff";
this.logTextBox1.DefaultColor = System.Drawing.Color.LightGray;
this.logTextBox1.Dock = System.Windows.Forms.DockStyle.Fill;
this.logTextBox1.EnableDisplayTimer = true;
this.logTextBox1.EnableGubunColor = true;
this.logTextBox1.Font = new System.Drawing.Font("Consolas", 9F);
this.logTextBox1.ListFormat = "[{0}] {1}";
this.logTextBox1.Location = new System.Drawing.Point(3, 3);
this.logTextBox1.MaxListCount = ((ushort)(200));
this.logTextBox1.MaxTextLength = ((uint)(4000u));
this.logTextBox1.MessageInterval = 50;
this.logTextBox1.Name = "logTextBox1";
this.logTextBox1.Size = new System.Drawing.Size(335, 494);
this.logTextBox1.TabIndex = 4;
this.logTextBox1.Text = "";
//
// button3
//
this.button3.Dock = System.Windows.Forms.DockStyle.Fill;
this.button3.Location = new System.Drawing.Point(3, 3);
this.button3.Name = "button3";
this.button3.Size = new System.Drawing.Size(130, 49);
this.button3.TabIndex = 5;
this.button3.Text = "forward";
this.button3.UseVisualStyleBackColor = true;
this.button3.Click += new System.EventHandler(this.button3_Click);
//
// button4
//
this.button4.Dock = System.Windows.Forms.DockStyle.Fill;
this.button4.Location = new System.Drawing.Point(3, 58);
this.button4.Name = "button4";
this.button4.Size = new System.Drawing.Size(130, 49);
this.button4.TabIndex = 6;
this.button4.Text = "backward";
this.button4.UseVisualStyleBackColor = true;
this.button4.Click += new System.EventHandler(this.button4_Click);
//
// button5
//
this.button5.Dock = System.Windows.Forms.DockStyle.Fill;
this.button5.Location = new System.Drawing.Point(139, 3);
this.button5.Name = "button5";
this.button5.Size = new System.Drawing.Size(130, 49);
this.button5.TabIndex = 7;
this.button5.Text = "stop";
this.button5.UseVisualStyleBackColor = true;
this.button5.Click += new System.EventHandler(this.button5_Click);
//
// button6
//
this.button6.Dock = System.Windows.Forms.DockStyle.Fill;
this.button6.Location = new System.Drawing.Point(275, 3);
this.button6.Name = "button6";
this.button6.Size = new System.Drawing.Size(130, 49);
this.button6.TabIndex = 8;
this.button6.Text = "set f";
this.button6.UseVisualStyleBackColor = true;
this.button6.Click += new System.EventHandler(this.button6_Click);
//
// button7
//
this.button7.Dock = System.Windows.Forms.DockStyle.Fill;
this.button7.Location = new System.Drawing.Point(139, 58);
this.button7.Name = "button7";
this.button7.Size = new System.Drawing.Size(130, 49);
this.button7.TabIndex = 9;
this.button7.Text = "mark stop";
this.button7.UseVisualStyleBackColor = true;
this.button7.Click += new System.EventHandler(this.button7_Click);
//
// button8
//
this.button8.Dock = System.Windows.Forms.DockStyle.Fill;
this.button8.Location = new System.Drawing.Point(275, 58);
this.button8.Name = "button8";
this.button8.Size = new System.Drawing.Size(130, 49);
this.button8.TabIndex = 10;
this.button8.Text = "Run";
this.button8.UseVisualStyleBackColor = true;
this.button8.Click += new System.EventHandler(this.button8_Click);
//
// tableLayoutPanel1
//
this.tableLayoutPanel1.ColumnCount = 5;
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 20.0005F));
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 20.0005F));
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 20.0005F));
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 19.9985F));
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 20F));
this.tableLayoutPanel1.Controls.Add(this.button6, 2, 0);
this.tableLayoutPanel1.Controls.Add(this.button4, 0, 1);
this.tableLayoutPanel1.Controls.Add(this.button7, 1, 1);
this.tableLayoutPanel1.Controls.Add(this.button3, 0, 0);
this.tableLayoutPanel1.Controls.Add(this.button5, 1, 0);
this.tableLayoutPanel1.Controls.Add(this.button8, 2, 1);
this.tableLayoutPanel1.Controls.Add(this.button9, 0, 2);
this.tableLayoutPanel1.Controls.Add(this.button10, 1, 2);
this.tableLayoutPanel1.Controls.Add(this.button11, 2, 2);
this.tableLayoutPanel1.Controls.Add(this.button12, 3, 2);
this.tableLayoutPanel1.Controls.Add(this.button13, 3, 1);
this.tableLayoutPanel1.Controls.Add(this.button14, 3, 0);
this.tableLayoutPanel1.Controls.Add(this.button15, 4, 0);
this.tableLayoutPanel1.Controls.Add(this.button16, 4, 1);
this.tableLayoutPanel1.Controls.Add(this.button17, 0, 3);
this.tableLayoutPanel1.Controls.Add(this.button18, 1, 3);
this.tableLayoutPanel1.Controls.Add(this.button19, 2, 3);
this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Top;
this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 37);
this.tableLayoutPanel1.Name = "tableLayoutPanel1";
this.tableLayoutPanel1.RowCount = 4;
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 25.00062F));
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 25.00062F));
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 25.00062F));
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 24.99813F));
this.tableLayoutPanel1.Size = new System.Drawing.Size(683, 222);
this.tableLayoutPanel1.TabIndex = 11;
//
// button9
//
this.button9.Dock = System.Windows.Forms.DockStyle.Fill;
this.button9.Location = new System.Drawing.Point(3, 113);
this.button9.Name = "button9";
this.button9.Size = new System.Drawing.Size(130, 49);
this.button9.TabIndex = 11;
this.button9.Text = "충전시작";
this.button9.UseVisualStyleBackColor = true;
this.button9.Click += new System.EventHandler(this.button9_Click);
//
// button10
//
this.button10.Dock = System.Windows.Forms.DockStyle.Fill;
this.button10.Location = new System.Drawing.Point(139, 113);
this.button10.Name = "button10";
this.button10.Size = new System.Drawing.Size(130, 49);
this.button10.TabIndex = 12;
this.button10.Text = "충전종료";
this.button10.UseVisualStyleBackColor = true;
this.button10.Click += new System.EventHandler(this.button10_Click);
//
// button11
//
this.button11.Dock = System.Windows.Forms.DockStyle.Fill;
this.button11.Location = new System.Drawing.Point(275, 113);
this.button11.Name = "button11";
this.button11.Size = new System.Drawing.Size(130, 49);
this.button11.TabIndex = 12;
this.button11.Text = "도착알림(ON)";
this.button11.UseVisualStyleBackColor = true;
this.button11.Click += new System.EventHandler(this.button11_Click);
//
// button12
//
this.button12.Dock = System.Windows.Forms.DockStyle.Fill;
this.button12.Location = new System.Drawing.Point(411, 113);
this.button12.Name = "button12";
this.button12.Size = new System.Drawing.Size(130, 49);
this.button12.TabIndex = 13;
this.button12.Text = "도착알림(OFF)";
this.button12.UseVisualStyleBackColor = true;
this.button12.Click += new System.EventHandler(this.button12_Click);
//
// button13
//
this.button13.Dock = System.Windows.Forms.DockStyle.Fill;
this.button13.Location = new System.Drawing.Point(411, 58);
this.button13.Name = "button13";
this.button13.Size = new System.Drawing.Size(130, 49);
this.button13.TabIndex = 14;
this.button13.Text = "ERR-RESET";
this.button13.UseVisualStyleBackColor = true;
this.button13.Click += new System.EventHandler(this.button13_Click);
//
// button14
//
this.button14.Dock = System.Windows.Forms.DockStyle.Fill;
this.button14.Location = new System.Drawing.Point(411, 3);
this.button14.Name = "button14";
this.button14.Size = new System.Drawing.Size(130, 49);
this.button14.TabIndex = 15;
this.button14.Text = "set b";
this.button14.UseVisualStyleBackColor = true;
this.button14.Click += new System.EventHandler(this.button14_Click);
//
// button15
//
this.button15.Dock = System.Windows.Forms.DockStyle.Fill;
this.button15.Location = new System.Drawing.Point(547, 3);
this.button15.Name = "button15";
this.button15.Size = new System.Drawing.Size(133, 49);
this.button15.TabIndex = 16;
this.button15.Text = "manual f";
this.button15.UseVisualStyleBackColor = true;
this.button15.Click += new System.EventHandler(this.button15_Click);
//
// button16
//
this.button16.Dock = System.Windows.Forms.DockStyle.Fill;
this.button16.Location = new System.Drawing.Point(547, 58);
this.button16.Name = "button16";
this.button16.Size = new System.Drawing.Size(133, 49);
this.button16.TabIndex = 16;
this.button16.Text = "manual b";
this.button16.UseVisualStyleBackColor = true;
this.button16.Click += new System.EventHandler(this.button16_Click);
//
// button17
//
this.button17.Dock = System.Windows.Forms.DockStyle.Fill;
this.button17.Location = new System.Drawing.Point(3, 168);
this.button17.Name = "button17";
this.button17.Size = new System.Drawing.Size(130, 51);
this.button17.TabIndex = 17;
this.button17.Text = "Speed L";
this.button17.UseVisualStyleBackColor = true;
this.button17.Click += new System.EventHandler(this.button17_Click);
//
// button18
//
this.button18.Dock = System.Windows.Forms.DockStyle.Fill;
this.button18.Location = new System.Drawing.Point(139, 168);
this.button18.Name = "button18";
this.button18.Size = new System.Drawing.Size(130, 51);
this.button18.TabIndex = 17;
this.button18.Text = "Speed M";
this.button18.UseVisualStyleBackColor = true;
this.button18.Click += new System.EventHandler(this.button18_Click);
//
// button19
//
this.button19.Dock = System.Windows.Forms.DockStyle.Fill;
this.button19.Location = new System.Drawing.Point(275, 168);
this.button19.Name = "button19";
this.button19.Size = new System.Drawing.Size(130, 51);
this.button19.TabIndex = 17;
this.button19.Text = "Speed H";
this.button19.UseVisualStyleBackColor = true;
this.button19.Click += new System.EventHandler(this.button19_Click);
//
// panel1
//
this.panel1.Controls.Add(this.comboBox1);
this.panel1.Controls.Add(this.button1);
this.panel1.Controls.Add(this.button2);
this.panel1.Controls.Add(this.label2);
this.panel1.Controls.Add(this.comboBox2);
this.panel1.Controls.Add(this.label1);
this.panel1.Dock = System.Windows.Forms.DockStyle.Top;
this.panel1.Location = new System.Drawing.Point(0, 0);
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(1264, 37);
this.panel1.TabIndex = 12;
//
// rt0
//
this.rt0.Dock = System.Windows.Forms.DockStyle.Fill;
this.rt0.Location = new System.Drawing.Point(3, 3);
this.rt0.Name = "rt0";
this.rt0.Size = new System.Drawing.Size(284, 292);
this.rt0.TabIndex = 13;
this.rt0.Text = "";
//
// tableLayoutPanel2
//
this.tableLayoutPanel2.ColumnCount = 2;
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.tableLayoutPanel2.Controls.Add(this.rt0, 0, 0);
this.tableLayoutPanel2.Controls.Add(this.rt1, 1, 0);
this.tableLayoutPanel2.Controls.Add(this.rt2, 0, 1);
this.tableLayoutPanel2.Controls.Add(this.rt3, 1, 1);
this.tableLayoutPanel2.Dock = System.Windows.Forms.DockStyle.Right;
this.tableLayoutPanel2.Location = new System.Drawing.Point(683, 37);
this.tableLayoutPanel2.Name = "tableLayoutPanel2";
this.tableLayoutPanel2.RowCount = 2;
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 41.27424F));
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 58.72576F));
this.tableLayoutPanel2.Size = new System.Drawing.Size(581, 722);
this.tableLayoutPanel2.TabIndex = 14;
//
// rt1
//
this.rt1.Dock = System.Windows.Forms.DockStyle.Fill;
this.rt1.Location = new System.Drawing.Point(293, 3);
this.rt1.Name = "rt1";
this.rt1.Size = new System.Drawing.Size(285, 292);
this.rt1.TabIndex = 13;
this.rt1.Text = "";
//
// rt2
//
this.rt2.Dock = System.Windows.Forms.DockStyle.Fill;
this.rt2.Location = new System.Drawing.Point(3, 301);
this.rt2.Name = "rt2";
this.rt2.Size = new System.Drawing.Size(284, 418);
this.rt2.TabIndex = 13;
this.rt2.Text = "";
//
// rt3
//
this.rt3.Dock = System.Windows.Forms.DockStyle.Fill;
this.rt3.Location = new System.Drawing.Point(293, 301);
this.rt3.Name = "rt3";
this.rt3.Size = new System.Drawing.Size(285, 418);
this.rt3.TabIndex = 13;
this.rt3.Text = "";
//
// tableLayoutPanel3
//
this.tableLayoutPanel3.ColumnCount = 2;
this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.tableLayoutPanel3.Controls.Add(this.logTextBox1, 0, 0);
this.tableLayoutPanel3.Controls.Add(this.logTextBox2, 1, 0);
this.tableLayoutPanel3.Dock = System.Windows.Forms.DockStyle.Fill;
this.tableLayoutPanel3.Location = new System.Drawing.Point(0, 259);
this.tableLayoutPanel3.Name = "tableLayoutPanel3";
this.tableLayoutPanel3.RowCount = 1;
this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.tableLayoutPanel3.Size = new System.Drawing.Size(683, 500);
this.tableLayoutPanel3.TabIndex = 15;
//
// logTextBox2
//
this.logTextBox2.BackColor = System.Drawing.Color.WhiteSmoke;
this.logTextBox2.ColorList = new arCtl.sLogMessageColor[0];
this.logTextBox2.DateFormat = "ss.fff";
this.logTextBox2.DefaultColor = System.Drawing.Color.LightGray;
this.logTextBox2.Dock = System.Windows.Forms.DockStyle.Fill;
this.logTextBox2.EnableDisplayTimer = true;
this.logTextBox2.EnableGubunColor = true;
this.logTextBox2.Font = new System.Drawing.Font("Consolas", 9F);
this.logTextBox2.ListFormat = "[{0}] {1}";
this.logTextBox2.Location = new System.Drawing.Point(344, 3);
this.logTextBox2.MaxListCount = ((ushort)(200));
this.logTextBox2.MaxTextLength = ((uint)(4000u));
this.logTextBox2.MessageInterval = 50;
this.logTextBox2.Name = "logTextBox2";
this.logTextBox2.Size = new System.Drawing.Size(336, 494);
this.logTextBox2.TabIndex = 4;
this.logTextBox2.Text = "";
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(1264, 759);
this.Controls.Add(this.tableLayoutPanel3);
this.Controls.Add(this.tableLayoutPanel1);
this.Controls.Add(this.tableLayoutPanel2);
this.Controls.Add(this.panel1);
this.Name = "Form1";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "Form1";
this.Load += new System.EventHandler(this.Form1_Load);
this.tableLayoutPanel1.ResumeLayout(false);
this.panel1.ResumeLayout(false);
this.panel1.PerformLayout();
this.tableLayoutPanel2.ResumeLayout(false);
this.tableLayoutPanel3.ResumeLayout(false);
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.ComboBox comboBox1;
private System.Windows.Forms.Button button1;
private System.Windows.Forms.Button button2;
private System.Windows.Forms.ComboBox comboBox2;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Label label2;
private arCtl.LogTextBox logTextBox1;
private System.Windows.Forms.Button button3;
private System.Windows.Forms.Button button4;
private System.Windows.Forms.Button button5;
private System.Windows.Forms.Button button6;
private System.Windows.Forms.Button button7;
private System.Windows.Forms.Button button8;
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
private System.Windows.Forms.Panel panel1;
private System.Windows.Forms.Button button9;
private System.Windows.Forms.Button button10;
private System.Windows.Forms.Button button11;
private System.Windows.Forms.Button button12;
private System.Windows.Forms.Button button13;
private System.Windows.Forms.RichTextBox rt0;
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel2;
private System.Windows.Forms.RichTextBox rt1;
private System.Windows.Forms.RichTextBox rt2;
private System.Windows.Forms.RichTextBox rt3;
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel3;
private arCtl.LogTextBox logTextBox2;
private System.Windows.Forms.Button button14;
private System.Windows.Forms.Button button15;
private System.Windows.Forms.Button button16;
private System.Windows.Forms.Button button17;
private System.Windows.Forms.Button button18;
private System.Windows.Forms.Button button19;
}
}

View File

@@ -0,0 +1,218 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace Test_BMS
{
public partial class Form1 : Form
{
arDev.Narumi dev;
arUtil.Log log1 = new arUtil.Log();
arUtil.Log log2 = new arUtil.Log();
public Form1()
{
InitializeComponent();
dev = new arDev.Narumi();
dev.DataReceive += Dev_DataReceive;
dev.Message += Dev_Message;
log1.FileNameFormat = "{yyyyMMdd}_COM";
log2.FileNameFormat = "{yyyyMMdd}_STS";
this.FormClosed += Form1_FormClosed;
}
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
log1.Flush();
log2.Flush();
}
private void Dev_Message(object sender, arDev.NarumiSerialComm.MessageEventArgs e)
{
addmsg(e.MsgType.ToString(), e.Message);// $"{e.MsgType}:{e.Message}");
}
private void Dev_DataReceive(object sender, arDev.Narumi.DataEventArgs e)
{
//throw new NotImplementedException();
updatestatue();
}
void updatestatue()
{
if (this.rt0.InvokeRequired)
{
this.Invoke(new MethodInvoker(updatestatue));
return;
}
this.rt0.Text = $"system0-{dev.system0.Value:X2}\n" + dev.system0.ToString();
this.rt1.Text = $"system1-{dev.system1.Value:X2}\n" + dev.system1.ToString();
this.rt2.Text = $"error-{dev.error.Value:X2}\n" + dev.error.ToString();
this.rt3.Text = $"iosignal-{dev.signal1.Value:X2}\n" + dev.signal1.ToString() + "data\n" + dev.data.ToString();
//this.rt4.Text = "data\n" + dev.data.ToString();
}
private void Form1_Load(object sender, EventArgs e)
{
this.comboBox1.Items.Clear();
foreach (var port in System.IO.Ports.SerialPort.GetPortNames())
this.comboBox1.Items.Add(port);
}
void addmsg(string grp,string m)
{
if(m.Contains("STS"))
{
log2.Add(grp, m);
if (logTextBox2.InvokeRequired)
{
logTextBox2.BeginInvoke(new Action(() =>
{
logTextBox2.AddMsg(m);
}));
}
else
{
logTextBox2.AddMsg(m);
}
}
else
{
log1.Add(grp, m);
if (logTextBox1.InvokeRequired)
{
logTextBox1.BeginInvoke(new Action(() =>
{
logTextBox1.AddMsg(m);
}));
}
else
{
logTextBox1.AddMsg(m);
}
}
}
private void button1_Click(object sender, EventArgs e)
{
dev.BaudRate = int.Parse(this.comboBox2.Text);
dev.PortName = comboBox1.Text;
dev.Open();
addmsg("conn",$"open:{dev.IsOpen}");
}
private void button2_Click(object sender, EventArgs e)
{
dev.Close();
}
private void button6_Click(object sender, EventArgs e)
{
dev.AGVMoveSet(new arDev.Narumi.BunkiData
{
Bunki = arDev.Narumi.eBunki.Strate,
Direction = arDev.Narumi.eMoveDir.Forward,
PBSSensor = 1,
Speed = arDev.Narumi.eMoveSpd.Low,
});
}
private void button5_Click(object sender, EventArgs e)
{
dev.AGVMoveStop("form1-button5", arDev.Narumi.eStopOpt.Stop);
}
private void button7_Click(object sender, EventArgs e)
{
dev.AGVMoveStop("form1-button7",arDev.Narumi.eStopOpt.MarkStop);
}
private void button4_Click(object sender, EventArgs e)
{
dev.AGVMoveRun(arDev.Narumi.eRunOpt.Backward);
}
private void button3_Click(object sender, EventArgs e)
{
dev.AGVMoveRun(arDev.Narumi.eRunOpt.Forward);
}
private void button8_Click(object sender, EventArgs e)
{
dev.AGVMoveRun();
}
private void button9_Click(object sender, EventArgs e)
{
dev.AGVCharge(30, true);
}
private void button10_Click(object sender, EventArgs e)
{
dev.AGVCharge(30, false);
}
private void button11_Click(object sender, EventArgs e)
{
dev.AGVTowerLamp(true);
}
private void button12_Click(object sender, EventArgs e)
{
dev.AGVTowerLamp(false);
}
private void button13_Click(object sender, EventArgs e)
{
dev.AGVErrorReset();
}
private void button14_Click(object sender, EventArgs e)
{
dev.AGVMoveSet(new arDev.Narumi.BunkiData
{
Bunki = arDev.Narumi.eBunki.Strate,
Direction = arDev.Narumi.eMoveDir.Backward,
PBSSensor = 1,
Speed = arDev.Narumi.eMoveSpd.Low,
});
}
private void button15_Click(object sender, EventArgs e)
{
dev.AGVMoveManual(arDev.Narumi.ManulOpt.FS, arDev.Narumi.Speed.Low, arDev.Narumi.Sensor.AllOn);
}
private void button16_Click(object sender, EventArgs e)
{
dev.AGVMoveManual(arDev.Narumi.ManulOpt.BS, arDev.Narumi.Speed.Low, arDev.Narumi.Sensor.AllOn);
}
private void button17_Click(object sender, EventArgs e)
{
dev.AGVMoveSet(new arDev.Narumi.BunkiData(dev.data.Direction, dev.data.Sts, 'L'));
}
private void button18_Click(object sender, EventArgs e)
{
dev.AGVMoveSet(new arDev.Narumi.BunkiData(dev.data.Direction, dev.data.Sts, 'M'));
}
private void button19_Click(object sender, EventArgs e)
{
dev.AGVMoveSet(new arDev.Narumi.BunkiData(dev.data.Direction, dev.data.Sts, 'H'));
}
}
}

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>

View File

@@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
namespace Test_BMS
{
static class Program
{
/// <summary>
/// 해당 응용 프로그램의 주 진입점입니다.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
}

View File

@@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// 어셈블리에 대한 일반 정보는 다음 특성 집합을 통해
// 제어됩니다. 어셈블리와 관련된 정보를 수정하려면
// 이러한 특성 값을 변경하세요.
[assembly: AssemblyTitle("BMS Commnunication Module Test")]
[assembly: AssemblyDescription("BMS Commnunication Module Test")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("BMS Commnunication Module Test")]
[assembly: AssemblyProduct("BMS Test Software")]
[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("ce3fff9f-6aca-1234-b64a-33ff4ad5e82e")]
// 어셈블리의 버전 정보는 다음 네 가지 값으로 구성됩니다.
//
// 주 버전
// 부 버전
// 빌드 번호
// 수정 버전
//
// 모든 값을 지정하거나 아래와 같이 '*'를 사용하여 빌드 번호 및 수정 번호가 자동으로
// 지정되도록 할 수 있습니다.
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("20.03.09.0")]
[assembly: AssemblyFileVersion("20.03.09.0")]

View File

@@ -0,0 +1,63 @@
//------------------------------------------------------------------------------
// <auto-generated>
// 이 코드는 도구를 사용하여 생성되었습니다.
// 런타임 버전:4.0.30319.42000
//
// 파일 내용을 변경하면 잘못된 동작이 발생할 수 있으며, 코드를 다시 생성하면
// 이러한 변경 내용이 손실됩니다.
// </auto-generated>
//------------------------------------------------------------------------------
namespace Test_Narumi.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("Test_Narumi.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 Test_Narumi.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.4.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,14 @@
02 53 54 53 32 35 38 46 46 46 46 34 30 30 30 30 30 30 30 4C 53 46 30 30 30 30 30 30 33 41 03
02 53 54 53 32 35 38 46 46 46 46 34 30 30 30 30 30 30 30 4C 53 46 30 30 30 30 30 30 33 41 03
02 53 54 53 32 35 38 46 46 46 46 34 30 30 30 30 30 30 30 4C 53 46 30 30 30 30 30 30 33 41 03
02 53 54 53 32 35 38 46 46 46 46 34 30 30 30 30 30 30 30 4C 53 46 30 30 30 30 30 30 33 41 03
02 53 54 53 32 35 38 46 46 46 46 34 30 30 30 30 30 30 30 4C 53 46 30 30 30 30 30 30 33 41 03
02 53 54 53 32 35 38 46 46 46 46 34 30 30 30 30 30 30 30 4C 53 46 30 30 30 30 30 30 33 41 03
02 53 54 53 32 35 38 46 46 46 46 34 30 30 30 30 30 30 30 4C 53 46 30 30 30 30 30 30 33 41 03
02 53 54 53 32 35 38 46 46 46 46 34 30 30 30 30 30 30 30 4C 53 46 30 30 30 30 30 30 33 41 03
02 53 54 53 32 35 38 46 46 46 46 34 30 30 30 30 30 30 30 4C 53 46 30 30 30 30 30 30 33 41 03
02 53 54 53 32 35 38 46 46 46 46 34 30 30 30 30 30 30 30 4C 53 46 30 30 30 30 30 30 33 41 03
02 53 54 53 32 35 38 46 46 46 46 34 30 30 30 30 30 30 30 4C 53 46 30 30 30 30 30 30 33 41 03
02 53 54 53 32 35 38 46 46 46 46 34 30 30 30 30 30 30 30 4C 53 46 30 30 30 30 30 30 33 41 03
02 53 54 53 32 35 38 46 46 46 46 34 30 30 30 30 30 30 30 4C 53 46 30 30 30 30 30 30 33 41 03
02 53 54 53 32 35 38 46 46 46 46 34 30 30 30 30 30 30 30 4C 53 46 30 30 30 30 30 30 33 41 03

View File

@@ -0,0 +1,102 @@
<?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>{EB77976F-4DE4-46A5-8B25-D07226204C32}</ProjectGuid>
<OutputType>WinExe</OutputType>
<RootNamespace>Test_Narumi</RootNamespace>
<AssemblyName>Test_Narumi</AssemblyName>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<Deterministic>true</Deterministic>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>..\..\..\..\..\..\Amkor\AGV4\Test\AGV\</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>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<ItemGroup>
<Reference Include="arControl.Net4">
<HintPath>..\..\DLL\arControl.Net4.dll</HintPath>
</Reference>
<Reference Include="ArLog.Net4">
<HintPath>..\..\DLL\ArLog.Net4.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.Deployment" />
<Reference Include="System.Drawing" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Form1.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Form1.Designer.cs">
<DependentUpon>Form1.cs</DependentUpon>
</Compile>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<EmbeddedResource Include="Form1.resx">
<DependentUpon>Form1.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="app.config" />
<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>
<ProjectReference Include="..\..\SubProject\AGV\NARUMI.csproj">
<Project>{8bae0eac-3d25-402f-9a65-2ba1ecfe28b7}</Project>
<Name>NARUMI</Name>
</ProjectReference>
<ProjectReference Include="..\..\SubProject\CommData\CommData.csproj">
<Project>{14e8c9a5-013e-49ba-b435-efefc77dd623}</Project>
<Name>CommData</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Content Include="Sample.txt" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

View File

@@ -0,0 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8"/></startup></configuration>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8" />
</startup>
</configuration>

View File

@@ -0,0 +1,561 @@
using System;
using System.Linq;
using System.ComponentModel;
using System.Drawing.Design;
using System.Runtime.CompilerServices;
using System.Management;
using AR;
namespace Project
{
public class MyUITypeEditor : UITypeEditor
{
public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
{
using (var f = new System.Windows.Forms.Form
{
WindowState = System.Windows.Forms.FormWindowState.Normal,
StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen,
Size = new System.Drawing.Size(800, 400),
MaximizeBox = false,
MinimizeBox = false,
Text = "Select Port",
FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog
})
{
var lst = new System.Windows.Forms.ListBox
{
Font = new System.Drawing.Font("Consolas", 15, System.Drawing.FontStyle.Bold),
Dock = System.Windows.Forms.DockStyle.Fill,
};
lst.DoubleClick += (s1, e1) =>
{
if (lst.SelectedItem != null) f.DialogResult = System.Windows.Forms.DialogResult.OK;
};
using (var searcher = new ManagementObjectSearcher("SELECT * FROM WIN32_SerialPort"))
{
var portnames = System.IO.Ports.SerialPort.GetPortNames().OrderBy(t => t);
var ports = searcher.Get().Cast<ManagementBaseObject>().ToList();
foreach (var port in portnames)
{
var desc = "";
var portInfo = ports.Where(t => t["DeviceId"].ToString() == port).FirstOrDefault();
if (portInfo != null) desc = portInfo["Caption"].ToString();
lst.Items.Add(string.Format("{0} - {1}", port, desc));
}
}
f.Controls.Add(lst);
if (f.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
var name = lst.SelectedItem.ToString().Split('-');
return name[0].Trim();
}
else
{
return base.EditValue(context, provider, value);
}
}
}
public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
{
return UITypeEditorEditStyle.Modal;
}
}
public class CSetting : AR.Setting
{
#region "log"
[Category("System Log"), DisplayName("Digital Input/Output"),
Description("입/출력 장치의 상태 변화를 기록 합니다.")]
public Boolean Log_IO { get; set; }
[Category("System Log"), DisplayName("Network Alive Check(Ping)"),
Description("서버와의 통신검사 로그를 기록 합니다")]
public Boolean Log_Ping { get; set; }
[Category("System Log"), DisplayName("S/M Step Change"),
Description("상태머신의 변화 상태를 기록 합니다.")]
public Boolean Log_StepChange { get; set; }
[Category("System Log"), DisplayName("Socket Recv Message"),
Description("서버 수신 메세지를 기록 합니다.")]
public Boolean LOg_SocketRecv { get; set; }
#endregion
#region "Communication"
[Category("Commnunication Setting"), DisplayName("XBee PortName"), Editor(typeof(MyUITypeEditor), typeof(UITypeEditor))]
public string Port_XBE { get; set; }
[Category("Commnunication Setting"), DisplayName("RFID PortName"), Editor(typeof(MyUITypeEditor), typeof(UITypeEditor))]
public string Port_AGV { get; set; }
[Category("Commnunication Setting"), DisplayName("Xbee ID"), Editor(typeof(MyUITypeEditor), typeof(UITypeEditor))]
public byte XBE_ID { get; set; }
[Category("Commnunication Setting"), DisplayName("BMS PortName"), Editor(typeof(MyUITypeEditor), typeof(UITypeEditor))]
public string Port_BAT { get; set; }
public int ChargerID { get; set; }
public int Baud_AGV { get; set; }
public int Baud_BAT { get; set; }
//public int Baud_PLC { get; set; }
public int Baud_XBE { get; set; }
//public int QueryInterval_BAT { get; set; }
#endregion
#region "Debug"
[Category("Developer Setting"), DisplayName("Listening Port"),
Description("서버와의 통신을 위한 대기 포트(TCP) - 기본값 : 7979")]
public int listenPort { get; set; }
[Category("Developer Setting")]
public Boolean UseDebugMode { get; set; }
#endregion
#region "Count Reset Setting"
[Category("Count Reset Setting"), DisplayName("A/M Clear Enable"),
Description("오전 초기화 여부\n작업수량을 초기화 하려면 True 로 설정하세요")]
public Boolean datetime_Check_1 { get; set; }
[Category("Count Reset Setting"), DisplayName("P/M Clear Enable"),
Description("오후 초기화 여부\n작업수량을 초기화 하려면 True 로 설정하세요")]
public Boolean datetime_Check_2 { get; set; }
[Category("Count Reset Setting"), DisplayName("A/M Clear Time(HH:mm)"),
Description("오전 초기화 시간(시:분)\n예) 09:00")]
public string datetime_Reset_1 { get; set; }
[Category("Count Reset Setting"), DisplayName("P/M Clear Time(HH:mm)"),
Description("오후 초기화 시간(시:분)\n예) 19:00")]
public string datetime_Reset_2 { get; set; }
#endregion
#region "general"
[Category("General Setting"), DisplayName("Enable Popup Message"),
Description("오류 발생시 별도의 메세지 창으로 표시합니다. 사용하지 않을 경우에는 우측 상단의 결과창의 메세지를 확인합니다.")]
public Boolean ShowPopUpMessage { get; set; }
[Category("General Setting"), DisplayName("Asset Number"),
Description("자산번호(서버에 값 전송 시 사용됩니다)")]
public string Asset { get; set; }
[Category("General Setting"),
Description("데이터 자동 소거 기간(일) 비활성=0")]
public int AutoDeleteDay { get; set; }
[Category("General Setting"),
Description("데이터 자동 소거 조건(남은용량 %)")]
public int AutoDeleteThreshold { get; set; }
[Category("General Setting"), PasswordPropertyText(true)]
public string Password_Setup { get; set; }
[Category("General Setting"), Browsable(false)]
public string Language { get; set; }
[Category("General Setting"), DisplayName("Full Screen Window State"),
Description("화면을 전체화면으로 사용 합니다.")]
public Boolean FullScreen { get; set; }
public bool DetectManualCharge { get; set; }
public Boolean StartLog { get; set; }
#endregion
#region "TAGS"
public int TAGPOT { get; set; }
public int TAGNOT { get; set; }
public int TAG_F2_F3 { get; set; }
public int TAG_QC_F1 { get; set; }
public int TAG_F1_F2 { get; set; }
public int TAG_F3_F4 { get; set; }
public int TAG_F4_F5 { get; set; }
public int TAG_QA_QC { get; set; }
public int TAGQAB { get; set; }
public int TAGQAA { get; set; }
public int TAGQCB { get; set; }
public int TAGQCA { get; set; }
public int TAGF1A { get; set; }
public int TAGF2A { get; set; }
public int TAGF3A { get; set; }
public int TAGF4A { get; set; }
public int TAGF5A { get; set; }
public int TAGF1B { get; set; }
public int TAGF2B { get; set; }
public int TAGF3B { get; set; }
public int TAGF4B { get; set; }
public int TAGF5B { get; set; }
#endregion
#region "Charge"
public int chargerpos { get; set; }
public int ChargetWaitSec { get; set; }
public int ChargeEmergencyLevel { get; set; }
public int ChargeMaxLevel { get; set; }
public int ChargeStartLevel { get; set; }
public Boolean Enable_AutoCharge { get; set; }
public int ChargeRetryTerm { get; set; }
//public int ChargeIdleInterval { get; set; }
public int ChargeMaxTime { get; set; }
public int ChargeSearchTime { get; set; }
#endregion
#region "AGV"
public bool AutoModeOffAndClearPosition { get; set; }
public string musicfile { get; set; }
/// <summary>
/// FVI로 가능 방향이 Backward 인가?
/// Forward 방향이라면 false 를 한다
/// </summary>
public Boolean AGV_Direction_FVI_Backward { get; set; }
public Boolean Enable_Speak { get; set; }
//public Boolean Disable_BMS { get; set; }
//public Boolean Log_BMS_Tx { get; set; }
//public Boolean Log_BMS_Rx { get; set; }
//public double ChargeLimitLow { get; set; }
//public double ChargeLimitHigh { get; set; }
public string AGV_PANID { get; set; }
public string AGV_CHANNEL { get; set; }
public string AGV_ADDRESS { get; set; }
public int SCK { get; set; }
public int SSK { get; set; }
public int STT { get; set; }
public int SAD { get; set; }
public byte ZSpeed { get; set; }
public int SPD_L { get; set; }
public int SPD_M { get; set; }
public int SPD_H { get; set; }
public int SPD_DRIVE { get; set; }
public int SPD_S { get; set; }
public int SPD_R { get; set; }
public int PID_PH { get; set; }
public int PID_PM { get; set; }
public int PID_PL { get; set; }
public int PID_IH { get; set; }
public int PID_IM { get; set; }
public int PID_IL { get; set; }
public int PID_DH { get; set; }
public int PID_DM { get; set; }
public int PID_DL { get; set; }
public int PID_PS { get; set; }
public int PID_IS { get; set; }
public int PID_DS { get; set; }
public double WheelSpeedCharge { get; set; }
public byte HomePositionValue { get; set; }
public byte HomeKitNo { get; set; }
public Single interval_xbe { get; set; }
public int interval_bms { get; set; }
public int doorSoundTerm { get; set; }
public int musicvol { get; set; }
public bool Enable_Music { get; set; }
#endregion
[Category("Report"),
Description("상태기록시 장비 식별코드(4자리)"),
DisplayName("M/C ID")]
public string MCID { get; set; }
[Category("Report"),
Description("작업 기록을 장비기술(EE) Database 에 기록 합니다. 원격으로 장비 현황을 모니터링 할 수 있습니다"),
DisplayName("SAVE EE-DB")]
public Boolean Save_EEDatabase { get; set; }
[Category("Report"), Description("상태값을 전송하는 간격(초)")]
public int StatusInterval { get; set; }
[Category("AutoReboot"),
DisplayName("자동재부팅시간"),
Description("기본값 14:00:00~14:05:00 , 재부팅은 장비가 대기(IDLE)일 때에만 동작하며 지정 시간 범위를 벗어나면 동작하지 않습니다")]
public String AutoRebootTimeStart { get; set; }
[Category("AutoReboot")]
public string AUtoRebootLastTime { get; set; }
public bool SetAutoModeOn { get; set; }
public override void AfterLoad()
{
if (StatusInterval < 10) StatusInterval = 300; //5분간격
if (SAD == 0) SAD = 999;
if (TAGF1A == 0)
{
TAGNOT = 9000;
TAGQAB = 9200;
TAGQCB = 9300;
TAGF1B = 9400;
TAGF2B = 9500;
TAGF3B = 9600;
TAGF4B = 9700;
TAGF5B = 9800;
TAGQAA = 9201;
TAGQCA = 9301;
TAGF1A = 9401;
TAGF2A = 9501;
TAGF3A = 9601;
TAGF4A = 9701;
TAGF5A = 9801;
TAGPOT = 9900;
TAG_QA_QC = 9250;
TAG_QC_F1 = 9350;
TAG_F1_F2 = 9450;
TAG_F2_F3 = 9550;
TAG_F3_F4 = 9650;
TAG_F4_F5 = 9750;
}
if(TAG_F4_F5 == 0)
{
TAG_F4_F5 = 9750;
TAGF5B = 9800;
TAGF5A = 9801;
}
if (SCK == 0) SCK = 10;
if (SSK == 0) SSK = 10;
if (STT == 0) STT = 30;
if (ChargerID == 0) ChargerID = 203;
if (ChargerID < 200) ChargerID += 200;
//자동충전요건
if (ChargetWaitSec == 0) ChargetWaitSec = 3;
if (ChargeStartLevel == 0) ChargeStartLevel = 85;
if (ChargeMaxLevel == 0) ChargeMaxLevel = 85;
if (ChargeEmergencyLevel == 0) ChargeEmergencyLevel = 30;
if (interval_bms == 0) interval_bms = 10;
//충전은 10분간격으로 재시도 한다
if (ChargeRetryTerm == 0) ChargeRetryTerm = 600;
if (doorSoundTerm == 0) doorSoundTerm = 15; //기본 15초
if (ChargeSearchTime == 0) ChargeSearchTime = 25;
//최대 충전진행 시간(기본 1시간)
if (ChargeMaxTime == 0) ChargeMaxTime = 3600;
// if (interval_iostate == 0 || interval_iostate == 255) interval_iostate = 100;
if (ZSpeed == 0) ZSpeed = 20;
if (interval_xbe == 0) interval_xbe = 5.0f;
if (HomePositionValue == 0) HomePositionValue = 4;
if (HomeKitNo == 0) HomeKitNo = 2;
if (datetime_Reset_1 == "") datetime_Reset_1 = "00:00";
if (datetime_Reset_2 == "") datetime_Reset_2 = "00:00";
if (SPD_H == 0)
{
SPD_DRIVE = 200;
SPD_H = 110;
SPD_M = 70;
SPD_L = 30;
SPD_S = 61;
SPD_R = 70;
}
if (PID_PH == 0)
{
PID_PH = 180; PID_PM = 240; PID_PL = 260;
PID_IH = 610; PID_IM = 640; PID_IL = 660;
PID_DH = 110; PID_DM = 140; PID_DL = 160;
PID_PS = 200; PID_IS = 620; PID_DS = 120;
}
if (WheelSpeedCharge == 0) WheelSpeedCharge = 10;
if (AutoDeleteThreshold == 0) AutoDeleteThreshold = 20;
if (Asset == "") Asset = "DEV_SPLIT";
if (listenPort == 0) listenPort = 7979;
if (Port_XBE == "") Port_XBE = "COM8";
if (Language.isEmpty()) Language = "Kor";
if (Password_Setup.isEmpty()) Password_Setup = "0000";
if (musicfile.isEmpty()) musicfile = UTIL.CurrentPath + "music.mp3";
if (musicvol == 0) musicvol = 50;
if (string.IsNullOrEmpty(Port_AGV)) Port_AGV = "COM1";
// if (string.IsNullOrEmpty(Port_PLC)) Port_PLC = "COM2";
if (string.IsNullOrEmpty(Port_XBE)) Port_XBE = "COM4";
if (string.IsNullOrEmpty(Port_BAT)) Port_BAT = "COM7";
if (Baud_AGV == 0) Baud_AGV = 57600;
//if (Baud_PLC == 0) Baud_PLC = 19200;
if (Baud_XBE == 0) Baud_XBE = 9600;
if (Baud_BAT == 0) Baud_BAT = 9600;
}
public override void AfterSave()
{
//throw new NotImplementedException();
}
public void CopyTo(CSetting dest)
{
//이곳의 모든 쓰기가능한 속성값을 대상에 써준다.
Type thClass = this.GetType();
foreach (var method in thClass.GetMethods())
{
//var parameters = method.GetParameters();
if (!method.Name.StartsWith("get_")) continue;
string keyname = method.Name.Substring(4);
string methodName = method.Name;
object odata = GetType().GetMethod(methodName).Invoke(this, null);
var wMethod = dest.GetType().GetMethod(Convert.ToString("set_") + keyname);
if (wMethod != null) wMethod.Invoke(dest, new object[] { odata });
}
}
}
public class CounterSetting : AR.Setting, INotifyPropertyChanged
{
public DateTime CountReset { get; set; }
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
private int countUp1 = 0;
private int countUp2 = 0;
private int countUp3 = 0;
private int countUp4 = 0;
// private int countUp5 = 0;
private int countchgaerr = 0;
private int countchga = 0;
private int countchgm = 0;
//private int countdn = 0;
private int countqa = 0;
private int countqc = 0;
//메인카운터
public int CountUp1
{
get { return countUp1; }
set { if (value != countUp1) { countUp1 = value; NotifyPropertyChanged(); } }
}
public int CountUp2
{
get { return countUp2; }
set { if (value != countUp2) { countUp2 = value; NotifyPropertyChanged(); } }
}
public int CountUp3
{
get { return countUp3; }
set { if (value != countUp3) { countUp3 = value; NotifyPropertyChanged(); } }
}
public int CountUp4
{
get { return countUp4; }
set { if (value != countUp4) { countUp4 = value; NotifyPropertyChanged(); } }
}
//public int CountUp5
//{
// get { return countUp5; }
// set { if (value != countUp5) { countUp5 = value; NotifyPropertyChanged(); } }
//}
/// <summary>
/// 상차수량(FVI 1+2+3+4)
/// </summary>
public int CountUp
{
get
{
return CountUp1 + CountUp2 + CountUp3 + CountUp4;// + CountUp5;
}
}
public int CountChargeE
{
get { return this.countchgaerr; }
set { if (value != countchgaerr) { countchgaerr = value; NotifyPropertyChanged(); } }
}
public int CountChargeA
{
get { return this.countchga; }
set { if (value != countchga) { countchga = value; NotifyPropertyChanged(); } }
}
public int CountChargeM
{
get { return this.countchgm; }
set { if (value != countchgm) { countchgm = value; NotifyPropertyChanged(); } }
}
/// <summary>
/// 하차수량(QC+QA)
/// </summary>
public int CountDn
{
get { return this.countqa + this.countqc; }
//set { if (value != countdn) { countdn = value; NotifyPropertyChanged(); } }
}
public int CountQA
{
get { return this.countqa; }
set { if (value != countqa) { countqa = value; NotifyPropertyChanged(); } }
}
public int CountQC
{
get { return this.countqc; }
set { if (value != countqc) { countqc = value; NotifyPropertyChanged(); } }
}
public void CountClear()
{
CountUp1 = 0;
CountUp2 = 0;
CountUp3 = 0;
CountUp4 = 0;
// CountUp5 = 0;
CountQC = 0;
CountQA = 0;
//CountQa2 = 0;
CountReset = DateTime.Now;
PUB.log.Add("Count Clear");
this.Save();
}
public CounterSetting()
{
this.filename = AR.UTIL.CurrentPath + "counter.xml";
}
public override void AfterLoad()
{
if (CountReset == null) CountReset = DateTime.Parse("1982-11-23");
}
public override void AfterSave()
{
//throw new NotImplementedException();
}
}
}

View File

@@ -0,0 +1,225 @@
namespace Project
{
partial class Form1
{
/// <summary>
/// 필수 디자이너 변수입니다.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// 사용 중인 모든 리소스를 정리합니다.
/// </summary>
/// <param name="disposing">관리되는 리소스를 삭제해야 하면 true이고, 그렇지 않으면 false입니다.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form
/// <summary>
/// 디자이너 지원에 필요한 메서드입니다.
/// 이 메서드의 내용을 코드 편집기로 수정하지 마세요.
/// </summary>
private void InitializeComponent()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Form1));
this.label1 = new System.Windows.Forms.Label();
this.label2 = new System.Windows.Forms.Label();
this.cmbPortAGV = new System.Windows.Forms.ComboBox();
this.cmbPortBMS = new System.Windows.Forms.ComboBox();
this.tbBaudAGV = new System.Windows.Forms.TextBox();
this.tbBaudBMS = new System.Windows.Forms.TextBox();
this.btTestAGV = new System.Windows.Forms.Button();
this.btTestBMS = new System.Windows.Forms.Button();
this.rtLog = new System.Windows.Forms.RichTextBox();
this.btFindPort = new System.Windows.Forms.Button();
this.panel1 = new System.Windows.Forms.Panel();
this.toolStrip1 = new System.Windows.Forms.ToolStrip();
this.toolStripButton1 = new System.Windows.Forms.ToolStripButton();
this.toolStripButton2 = new System.Windows.Forms.ToolStripButton();
this.panel1.SuspendLayout();
this.toolStrip1.SuspendLayout();
this.SuspendLayout();
//
// label1
//
this.label1.Location = new System.Drawing.Point(16, 10);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(30, 20);
this.label1.TabIndex = 0;
this.label1.Text = "agv";
this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// label2
//
this.label2.Location = new System.Drawing.Point(16, 36);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(30, 20);
this.label2.TabIndex = 0;
this.label2.Text = "bms";
this.label2.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// cmbPortAGV
//
this.cmbPortAGV.FormattingEnabled = true;
this.cmbPortAGV.Location = new System.Drawing.Point(60, 10);
this.cmbPortAGV.Name = "cmbPortAGV";
this.cmbPortAGV.Size = new System.Drawing.Size(121, 20);
this.cmbPortAGV.TabIndex = 1;
//
// cmbPortBMS
//
this.cmbPortBMS.FormattingEnabled = true;
this.cmbPortBMS.Location = new System.Drawing.Point(60, 36);
this.cmbPortBMS.Name = "cmbPortBMS";
this.cmbPortBMS.Size = new System.Drawing.Size(121, 20);
this.cmbPortBMS.TabIndex = 1;
//
// tbBaudAGV
//
this.tbBaudAGV.Location = new System.Drawing.Point(187, 10);
this.tbBaudAGV.Name = "tbBaudAGV";
this.tbBaudAGV.Size = new System.Drawing.Size(100, 21);
this.tbBaudAGV.TabIndex = 2;
//
// tbBaudBMS
//
this.tbBaudBMS.Location = new System.Drawing.Point(187, 36);
this.tbBaudBMS.Name = "tbBaudBMS";
this.tbBaudBMS.Size = new System.Drawing.Size(100, 21);
this.tbBaudBMS.TabIndex = 2;
//
// btTestAGV
//
this.btTestAGV.Location = new System.Drawing.Point(294, 8);
this.btTestAGV.Name = "btTestAGV";
this.btTestAGV.Size = new System.Drawing.Size(75, 24);
this.btTestAGV.TabIndex = 3;
this.btTestAGV.Text = "Test";
this.btTestAGV.UseVisualStyleBackColor = true;
this.btTestAGV.Click += new System.EventHandler(this.btTestAGV_Click);
//
// btTestBMS
//
this.btTestBMS.Location = new System.Drawing.Point(294, 34);
this.btTestBMS.Name = "btTestBMS";
this.btTestBMS.Size = new System.Drawing.Size(75, 24);
this.btTestBMS.TabIndex = 3;
this.btTestBMS.Text = "Test";
this.btTestBMS.UseVisualStyleBackColor = true;
this.btTestBMS.Click += new System.EventHandler(this.btTestBMS_Click);
//
// rtLog
//
this.rtLog.Dock = System.Windows.Forms.DockStyle.Fill;
this.rtLog.Location = new System.Drawing.Point(0, 92);
this.rtLog.Name = "rtLog";
this.rtLog.Size = new System.Drawing.Size(450, 215);
this.rtLog.TabIndex = 4;
this.rtLog.Text = "";
//
// btFindPort
//
this.btFindPort.Location = new System.Drawing.Point(375, 11);
this.btFindPort.Name = "btFindPort";
this.btFindPort.Size = new System.Drawing.Size(71, 47);
this.btFindPort.TabIndex = 5;
this.btFindPort.Text = "find port";
this.btFindPort.UseVisualStyleBackColor = true;
this.btFindPort.Click += new System.EventHandler(this.btFindPort_Click);
//
// panel1
//
this.panel1.Controls.Add(this.cmbPortAGV);
this.panel1.Controls.Add(this.btFindPort);
this.panel1.Controls.Add(this.label1);
this.panel1.Controls.Add(this.label2);
this.panel1.Controls.Add(this.btTestBMS);
this.panel1.Controls.Add(this.cmbPortBMS);
this.panel1.Controls.Add(this.tbBaudAGV);
this.panel1.Controls.Add(this.tbBaudBMS);
this.panel1.Controls.Add(this.btTestAGV);
this.panel1.Dock = System.Windows.Forms.DockStyle.Top;
this.panel1.Location = new System.Drawing.Point(0, 25);
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(450, 67);
this.panel1.TabIndex = 6;
//
// toolStrip1
//
this.toolStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.toolStripButton1,
this.toolStripButton2});
this.toolStrip1.Location = new System.Drawing.Point(0, 0);
this.toolStrip1.Name = "toolStrip1";
this.toolStrip1.Size = new System.Drawing.Size(450, 25);
this.toolStrip1.TabIndex = 7;
this.toolStrip1.Text = "toolStrip1";
//
// toolStripButton1
//
this.toolStripButton1.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton1.Image")));
this.toolStripButton1.ImageTransparentColor = System.Drawing.Color.Magenta;
this.toolStripButton1.Name = "toolStripButton1";
this.toolStripButton1.Size = new System.Drawing.Size(53, 22);
this.toolStripButton1.Text = "Load";
this.toolStripButton1.Click += new System.EventHandler(this.toolStripButton1_Click);
//
// toolStripButton2
//
this.toolStripButton2.Alignment = System.Windows.Forms.ToolStripItemAlignment.Right;
this.toolStripButton2.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton2.Image")));
this.toolStripButton2.ImageTransparentColor = System.Drawing.Color.Magenta;
this.toolStripButton2.Name = "toolStripButton2";
this.toolStripButton2.Size = new System.Drawing.Size(52, 22);
this.toolStripButton2.Text = "Save";
this.toolStripButton2.Click += new System.EventHandler(this.toolStripButton2_Click);
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(450, 307);
this.Controls.Add(this.rtLog);
this.Controls.Add(this.panel1);
this.Controls.Add(this.toolStrip1);
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "Form1";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "AGV Port Scanner";
this.Load += new System.EventHandler(this.Form1_Load);
this.panel1.ResumeLayout(false);
this.panel1.PerformLayout();
this.toolStrip1.ResumeLayout(false);
this.toolStrip1.PerformLayout();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.ComboBox cmbPortAGV;
private System.Windows.Forms.ComboBox cmbPortBMS;
private System.Windows.Forms.TextBox tbBaudAGV;
private System.Windows.Forms.TextBox tbBaudBMS;
private System.Windows.Forms.Button btTestAGV;
private System.Windows.Forms.Button btTestBMS;
private System.Windows.Forms.RichTextBox rtLog;
private System.Windows.Forms.Button btFindPort;
private System.Windows.Forms.Panel panel1;
private System.Windows.Forms.ToolStrip toolStrip1;
private System.Windows.Forms.ToolStripButton toolStripButton1;
private System.Windows.Forms.ToolStripButton toolStripButton2;
}
}

View File

@@ -0,0 +1,715 @@
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;
using System.IO.Ports;
using System.IO;
using AR;
namespace Project
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
PUB.init();
// 현재 설치되어있는 시리얼포트목록을 조회해서 cmbPort... 컨트롤에 미리 입력한다.
RefreshPortList();
// 기본 BaudRate 설정
tbBaudAGV.Text = "115200";
tbBaudBMS.Text = "9600";
}
/// <summary>
/// 시리얼 포트 목록을 새로고침하여 콤보박스에 추가
/// </summary>
private void RefreshPortList()
{
try
{
string[] ports = SerialPort.GetPortNames();
cmbPortAGV.Items.Clear();
cmbPortBMS.Items.Clear();
foreach (string port in ports)
{
cmbPortAGV.Items.Add(port);
cmbPortBMS.Items.Add(port);
}
addLog($"포트 목록 새로고침 완료: {ports.Length}개 포트 발견");
}
catch (Exception ex)
{
addLog($"포트 목록 조회 오류: {ex.Message}");
}
}
/// <summary>
/// 설정파일에서 데이터를 읽어서 컨트롤에 설정한다
/// </summary>
void LoadSetting()
{
try
{
// AGV 설정
if (!string.IsNullOrEmpty(PUB.setting.Port_AGV))
{
this.cmbPortAGV.Text = PUB.setting.Port_AGV;
}
tbBaudAGV.Text = PUB.setting.Baud_AGV.ToString();
// BMS 설정
if (!string.IsNullOrEmpty(PUB.setting.Port_BAT))
{
cmbPortBMS.Text = PUB.setting.Port_BAT;
}
tbBaudBMS.Text = PUB.setting.Baud_BAT.ToString();
addLog("설정 파일 로드 완료");
}
catch (Exception ex)
{
addLog($"설정 로드 오류: {ex.Message}");
}
}
/// <summary>
/// 현재 설정된 값을 확인하고 셋팅파일에 기록한다
/// </summary>
void SaveSetting()
{
try
{
// 현재 UI 값을 설정 객체에 반영
PUB.setting.Port_AGV = cmbPortAGV.SelectedItem?.ToString() ?? "";
PUB.setting.Baud_AGV = int.TryParse(tbBaudAGV.Text, out int agvBaud) ? agvBaud : 115200;
PUB.setting.Port_BAT = cmbPortBMS.SelectedItem?.ToString() ?? "";
PUB.setting.Baud_BAT = int.TryParse(tbBaudBMS.Text, out int bmsBaud) ? bmsBaud : 9600;
// 파일에 저장
PUB.setting.Save();
addLog("설정 파일 저장 완료");
}
catch (Exception ex)
{
addLog($"설정 저장 오류: {ex.Message}");
}
}
private void Form1_Load(object sender, EventArgs e)
{
LoadSetting();
}
private void btLoadSetting_Click(object sender, EventArgs e)
{
LoadSetting();
}
private void btSaveSetting_Click(object sender, EventArgs e)
{
SaveSetting();
}
private void btTestAGV_Click(object sender, EventArgs e)
{
// AGV 용 프로토콜을 전송해서 올바르게 피드백이 오는지 확인한다
// AGV Protocol: STX(0x02) + Data + ETX(0x03)
if (cmbPortAGV.SelectedItem == null)
{
addLog("[AGV] 포트를 선택해주세요");
return;
}
if (!int.TryParse(tbBaudAGV.Text, out int baudRate))
{
addLog("[AGV] BaudRate가 올바르지 않습니다");
return;
}
try
{
addLog($"[AGV] 테스트 시작: {cmbPortAGV.SelectedItem} @ {baudRate}bps");
using (arDev.Narumi port = new arDev.Narumi())
{
port.PortName = cmbPortAGV.SelectedItem.ToString();
port.BaudRate = baudRate;
port.Message += (s1, e1) =>{
addLog($"[AGV] 응답 수신: {e1.Message}");
};
port.Open();
addLog($"[AGV] 포트 열기 성공");
DateTime sendtime = DateTime.Now;
port.AGVMoveStop("test");//
addLog($"[AGV] 테스트 명령 전송:");
// 응답 대기
System.Threading.Thread.Sleep(1200);
if (port.lastRecvTime > sendtime)
{
// STX, ETX 확인
//if (response.Length >= 2 && response[0] == 0x02 && response[response.Length - 1] == 0x03)
//{
addLog($"[AGV] ✓ 통신 성공 - 올바른 프로토콜 응답");
//}
//else
//{
// addLog($"[AGV] ⚠ 응답은 받았으나 프로토콜 형식이 다름");
//}
}
else
{
addLog($"[AGV] ⚠ 응답 없음 - 포트는 열렸으나 장치 응답 없음");
}
port.Close();
addLog($"[AGV] 포트 닫기 완료");
}
}
catch (Exception ex)
{
addLog($"[AGV] ✗ 오류 발생: {ex.Message}");
}
}
private void btTestBMS_Click(object sender, EventArgs e)
{
// BMS 용 프로토콜을 전송해서 올바르게 피드백이 오는지 확인한다
// BMS Protocol: STX(0xDD) + Data(32 bytes) + ETX(0x77)
if (cmbPortBMS.SelectedItem == null)
{
addLog("[BMS] 포트를 선택해주세요");
return;
}
if (!int.TryParse(tbBaudBMS.Text, out int baudRate))
{
addLog("[BMS] BaudRate가 올바르지 않습니다");
return;
}
try
{
addLog($"[BMS] 테스트 시작: {cmbPortBMS.SelectedItem} @ {baudRate}bps");
using (SerialPort port = new SerialPort())
{
port.PortName = cmbPortBMS.SelectedItem.ToString();
port.BaudRate = baudRate;
port.DataBits = 8;
port.Parity = Parity.None;
port.StopBits = StopBits.One;
port.ReadTimeout = 3000;
port.WriteTimeout = 3000;
port.Open();
addLog($"[BMS] 포트 열기 성공");
// 간단한 테스트 명령 전송
var testCmd = new List<byte>();
testCmd.Add(0xDD);
testCmd.Add(0xA5);
testCmd.Add(0x03);
testCmd.Add(0x00);
testCmd.Add(0xFF);
testCmd.Add(0xFD);
testCmd.Add(0x77);
testCmd.Add(0x0D);
port.Write(testCmd.ToArray(), 0, testCmd.Count);//.Length);
addLog($"[BMS] 테스트 명령 전송: {BitConverter.ToString(testCmd.ToArray())}");
// 응답 대기
System.Threading.Thread.Sleep(1200);
if (port.BytesToRead > 0)
{
byte[] response = new byte[port.BytesToRead];
port.Read(response, 0, response.Length);
addLog($"[BMS] 응답 수신 ({response.Length} bytes): {BitConverter.ToString(response)}");
// STX, ETX 확인
if (response.Length >= 2 && response[0] == 0xDD && response[response.Length - 1] == 0x77)
{
addLog($"[BMS] ✓ 통신 성공 - 올바른 프로토콜 응답");
if (response.Length == 34 || response.Length == 23)
{
addLog($"[BMS] ✓ 데이터 길이 확인 ({response.Length} bytes)");
}
}
else
{
addLog($"[BMS] ⚠ 응답은 받았으나 프로토콜 형식이 다름");
}
}
else
{
addLog($"[BMS] ⚠ 응답 없음 - 포트는 열렸으나 장치 응답 없음");
}
port.Close();
addLog($"[BMS] 포트 닫기 완료");
}
}
catch (Exception ex)
{
addLog($"[BMS] ✗ 오류 발생: {ex.Message}");
}
}
void addLog(string msg)
{
// rtLog 컨트롤에 메세지를 추가하고, 추가된 메세지에 맞게 커서가 자동이동되게 한다
if (rtLog.InvokeRequired)
{
rtLog.Invoke(new Action(() => addLog(msg)));
}
else
{
string timestamp = DateTime.Now.ToString("HH:mm:ss.fff");
rtLog.AppendText($"[{timestamp}] {msg}\r\n");
rtLog.SelectionStart = rtLog.Text.Length;
rtLog.ScrollToCaret();
}
}
private async void btFindPort_Click(object sender, EventArgs e)
{
// 버튼 비활성화 (중복 실행 방지)
btFindPort.Enabled = false;
try
{
await Task.Run(() => FindPortsAsync());
}
finally
{
// 버튼 재활성화
btFindPort.Enabled = true;
}
}
private void FindPortsAsync()
{
// AGV와 BMS의 응답 포트를 병렬로 동시에 찾는다
addLog("===== 포트 자동 검색 시작 (병렬 모드) =====");
string[] ports = SerialPort.GetPortNames();
if (ports.Length == 0)
{
addLog("사용 가능한 포트가 없습니다");
return;
}
addLog($"총 {ports.Length}개 포트 검색 중...");
// 병렬 검색을 위한 변수
object lockObj = new object();
string foundAGVPort = null;
string foundBMSPort = null;
int agvBaud = 115200;
int bmsBaud = 9600;
bool bothFound = false;
// 현재 설정된 포트 (우선순위 표시용)
string currentAGVPort = null;
string currentBMSPort = null;
this.Invoke(new Action(() =>
{
currentAGVPort = cmbPortAGV.SelectedItem?.ToString();
currentBMSPort = cmbPortBMS.SelectedItem?.ToString();
}));
// 현재 설정 확인 로그
addLog($"현재 AGV 설정: {(string.IsNullOrEmpty(currentAGVPort) ? "( )" : currentAGVPort)}");
addLog($"현재 BMS 설정: {(string.IsNullOrEmpty(currentBMSPort) ? "( )" : currentBMSPort)}");
// === 1단계: 현재 설정된 포트 우선 테스트 ===
addLog("--- 1단계: 현재 설정 포트 우선 테스트 ---");
// AGV 현재 포트 우선 테스트
if (!string.IsNullOrEmpty(currentAGVPort) && ports.Contains(currentAGVPort))
{
addLog($"[우선] AGV 현재 포트 테스트: {currentAGVPort}");
for (int retry = 1; retry <= 3; retry++)
{
if (TestAGVPort(currentAGVPort, agvBaud))
{
foundAGVPort = currentAGVPort;
addLog($"✓ 현재 설정 포트에서 AGV 발견: {currentAGVPort}");
break;
}
if (retry < 3) System.Threading.Thread.Sleep(500);
}
}
// BMS 현재 포트 우선 테스트
if (!string.IsNullOrEmpty(currentBMSPort) && ports.Contains(currentBMSPort))
{
addLog($"[우선] BMS 현재 포트 테스트: {currentBMSPort}");
for (int retry = 1; retry <= 3; retry++)
{
if (TestBMSPort(currentBMSPort, bmsBaud))
{
foundBMSPort = currentBMSPort;
addLog($"✓ 현재 설정 포트에서 BMS 발견: {currentBMSPort}");
break;
}
if (retry < 3) System.Threading.Thread.Sleep(500);
}
}
// 둘 다 찾았으면 즉시 종료
if (foundAGVPort != null && foundBMSPort != null)
{
addLog("현재 설정 포트에서 모두 발견! 검색 종료");
ApplyFoundPorts(foundAGVPort, foundBMSPort, agvBaud, bmsBaud);
addLog("===== 포트 자동 검색 완료 =====");
return;
}
// === 2단계: 나머지 포트 병렬 검색 ===
if (foundAGVPort == null || foundBMSPort == null)
{
addLog("--- 2단계: 나머지 포트 병렬 검색 ---");
}
// 모든 포트를 병렬로 테스트 (단, 이미 테스트한 포트 제외)
List<Task> tasks = new List<Task>();
foreach (string portName in ports)
{
string port = portName; // 클로저 캡처용
// 이미 우선 테스트에서 체크한 포트는 제외
if (port == currentAGVPort || port == currentBMSPort)
continue;
Task task = Task.Run(() =>
{
// 이미 둘 다 찾았으면 즉시 종료
if (bothFound) return;
addLog($"[{port}] 검사 시작...");
// AGV 테스트 (3회 재시도)
for (int retry = 1; retry <= 3; retry++)
{
// 첫 번째 시도에서는 조기 종료하지 않고 전체 대기 시간 보장
if (retry > 1 && bothFound) return;
try
{
if (foundAGVPort == null && TestAGVPort(port, agvBaud))
{
lock (lockObj)
{
if (foundAGVPort == null)
{
foundAGVPort = port;
addLog($"[{port}] ✓ AGV 발견! (재시도: {retry}/3)");
// 둘 다 찾았는지 확인
if (foundBMSPort != null)
{
bothFound = true;
addLog("AGV와 BMS 모두 발견! 검색 종료");
}
}
}
break;
}
}
catch { }
if (retry < 3 && foundAGVPort == null && !bothFound)
{
System.Threading.Thread.Sleep(500);
}
}
// BMS 테스트 (3회 재시도)
for (int retry = 1; retry <= 3; retry++)
{
// 첫 번째 시도에서는 조기 종료하지 않고 전체 대기 시간 보장
if (retry > 1 && bothFound) return;
try
{
if (foundBMSPort == null && TestBMSPort(port, bmsBaud))
{
lock (lockObj)
{
if (foundBMSPort == null)
{
foundBMSPort = port;
addLog($"[{port}] ✓ BMS 발견! (재시도: {retry}/3)");
// 둘 다 찾았는지 확인
if (foundAGVPort != null)
{
bothFound = true;
addLog("AGV와 BMS 모두 발견! 검색 종료");
}
}
}
break;
}
}
catch { }
if (retry < 3 && foundBMSPort == null && !bothFound)
{
System.Threading.Thread.Sleep(500);
}
}
// 둘 다 실패한 경우에만 로그
if (!bothFound && foundAGVPort != port && foundBMSPort != port)
{
addLog($"[{port}] ✗ 응답 없음");
}
});
tasks.Add(task);
}
// 나머지 포트가 있을 경우만 대기
if (tasks.Count > 0)
{
addLog("나머지 포트 테스트 진행 중...");
// 주기적으로 체크하면서 둘 다 찾았으면 즉시 종료
while (!Task.WaitAll(tasks.ToArray(), 100))
{
if (bothFound)
{
addLog("검색 조기 종료 - 모든 포트 발견");
break;
}
}
}
// 결과 적용
ApplyFoundPorts(foundAGVPort, foundBMSPort, agvBaud, bmsBaud);
addLog("===== 포트 자동 검색 완료 =====");
}
/// <summary>
/// 발견된 포트를 UI에 적용
/// </summary>
private void ApplyFoundPorts(string agvPort, string bmsPort, int agvBaud, int bmsBaud)
{
if (agvPort != null)
{
this.Invoke(new Action(() =>
{
int idx = cmbPortAGV.Items.IndexOf(agvPort);
if (idx >= 0)
{
cmbPortAGV.SelectedIndex = idx;
tbBaudAGV.Text = agvBaud.ToString();
}
}));
addLog($"✓ AGV 포트: {agvPort} (Baud: {agvBaud})");
}
else
{
addLog("⚠ AGV 포트를 찾지 못했습니다");
}
if (bmsPort != null)
{
this.Invoke(new Action(() =>
{
int idx = cmbPortBMS.Items.IndexOf(bmsPort);
if (idx >= 0)
{
cmbPortBMS.SelectedIndex = idx;
tbBaudBMS.Text = bmsBaud.ToString();
}
}));
addLog($"✓ BMS 포트: {bmsPort} (Baud: {bmsBaud})");
}
else
{
addLog("⚠ BMS 포트를 찾지 못했습니다");
}
}
/// <summary>
/// AGV 포트인지 테스트 (btTestAGV_Click 코드 사용)
/// </summary>
private bool TestAGVPort(string portName, int baudRate)
{
try
{
using (arDev.Narumi port = new arDev.Narumi())
{
port.PortName = portName;
port.BaudRate = baudRate;
addLog($" >> AGV 테스트 시작: {portName} @ {baudRate}bps");
port.Open();
addLog($" >> AGV 포트 열기 성공: {portName}");
DateTime sendtime = DateTime.Now;
port.AGVMoveStop("test");
addLog($" >> AGV 명령 전송: {portName} (시간: {sendtime:HH:mm:ss.fff})");
// 응답 대기 (더 길게, 주기적으로 체크)
int maxWait = 2000; // 최대 2초 대기
int waitStep = 100;
int totalWait = 0;
while (totalWait < maxWait)
{
System.Threading.Thread.Sleep(waitStep);
totalWait += waitStep;
// lastRecvTime 확인
if (port.lastRecvTime > sendtime)
{
addLog($" >> ✓✓✓ AGV 응답 수신: {portName} (응답시간: {port.lastRecvTime:HH:mm:ss.fff}, 대기: {totalWait}ms)");
addLog($" >> 응답 데이터: {port.LastRecvString}");
port.Close();
return true;
}
// LastRecvString도 확인 (lastRecvTime이 업데이트 안 될 수도 있음)
if (!string.IsNullOrEmpty(port.LastRecvString))
{
addLog($" >> ✓✓✓ AGV 응답 감지 (문자열): {portName} (대기: {totalWait}ms)");
addLog($" >> 응답 데이터: {port.LastRecvString}");
port.Close();
return true;
}
}
addLog($" >> AGV 응답 없음: {portName} (최종 대기: {totalWait}ms, 마지막수신: {port.lastRecvTime:HH:mm:ss.fff})");
port.Close();
}
}
catch (Exception ex)
{
addLog($" >> AGV 테스트 오류: {portName} - {ex.Message}");
}
return false;
}
/// <summary>
/// BMS 포트인지 테스트 (btTestBMS_Click 코드 사용)
/// </summary>
private bool TestBMSPort(string portName, int baudRate)
{
try
{
using (SerialPort port = new SerialPort())
{
port.PortName = portName;
port.BaudRate = baudRate;
port.DataBits = 8;
port.Parity = Parity.None;
port.StopBits = StopBits.One;
port.ReadTimeout = 500;
port.WriteTimeout = 500;
addLog($" >> BMS 테스트 시작: {portName} @ {baudRate}bps");
port.Open();
addLog($" >> BMS 포트 열기 성공: {portName}");
// BMS 테스트 명령 전송 (테스트 버튼과 동일한 명령)
var testCmd = new List<byte>();
testCmd.Add(0xDD);
testCmd.Add(0xA5);
testCmd.Add(0x03);
testCmd.Add(0x00);
testCmd.Add(0xFF);
testCmd.Add(0xFD);
testCmd.Add(0x77);
testCmd.Add(0x0D);
port.Write(testCmd.ToArray(), 0, testCmd.Count);
addLog($" >> BMS 명령 전송: {portName} - {BitConverter.ToString(testCmd.ToArray())}");
// 응답 대기
System.Threading.Thread.Sleep(300);
if (port.BytesToRead > 0)
{
byte[] response = new byte[port.BytesToRead];
port.Read(response, 0, response.Length);
addLog($" >> BMS 응답 수신: {portName} ({response.Length} bytes) - {BitConverter.ToString(response)}");
// BMS 프로토콜 확인 (STX=0xDD, ETX=0x77)
if (response.Length >= 2 && response[0] == 0xDD && response[response.Length - 1] == 0x77)
{
addLog($" >> ✓✓✓ BMS 프로토콜 확인: {portName}");
port.Close();
return true;
}
else
{
addLog($" >> BMS 프로토콜 불일치: {portName}");
}
}
else
{
addLog($" >> BMS 응답 없음: {portName}");
}
port.Close();
}
}
catch (Exception ex)
{
addLog($" >> BMS 테스트 오류: {portName} - {ex.Message}");
}
return false;
}
private void toolStripButton1_Click(object sender, EventArgs e)
{
LoadSetting();
}
private void toolStripButton2_Click(object sender, EventArgs e)
{
SaveSetting();
}
}
}

View File

@@ -0,0 +1,154 @@
<?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>
<metadata name="toolStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="toolStripButton1.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIFSURBVDhPpZLtS1NhGMbPPxJmmlYSgqHiKzGU1EDxg4iK
YKyG2WBogqMYJQOtCEVRFBGdTBCJfRnkS4VaaWNT5sqx1BUxRXxDHYxAJLvkusEeBaPAB+5z4Jzn+t3X
/aLhnEfjo8m+dCoa+7/C3O2Hqe0zDC+8KG+cRZHZhdzaaWTVTCLDMIY0vfM04Nfh77/G/sEhwpEDbO3t
I7TxE8urEVy99fT/AL5gWDLrTB/hnF4XsW0khCu5ln8DmJliT2AXrcNBsU1gj/MH4nMeKwBrPktM28xM
cX79DFKrHHD5d9D26hvicx4pABt2lpg10zYzU0zr7+e3xXGcrkEB2O2TNec9nJFwB3alZn5jZorfeDZh
6Q3g8s06BeCoKF4MRURoH1+BY2oNCbeb0TIclIYxOhzf8frTOuo7FxCbbVIAzpni0iceEc8vhzEwGkJD
lx83ymxifejdKjRNk/8PWnyIyTQqAJek0jqHwfEVscu31baIu8+90sTE4nY025dQ2/5FIPpnXlzKuK8A
HBUzHot52djqQ6HZhfR7IwK4mKpHtvEDMqvfCiQ6zaAAXM8x94aIWTNrLLG4kVUzgaTSPlzLtyJOZxbb
1wtfyg4Q+AfA3aZlButjSfxGcUJBk4g5tuP3haQKRKXcUQDOmbvNTpPOJeFFjordZmbWTNvMTHFUcpUC
nOccAdABIDXXE1nzAAAAAElFTkSuQmCC
</value>
</data>
<data name="toolStripButton2.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIFSURBVDhPpZLtS1NhGMbPPxJmmlYSgqHiKzGU1EDxg4iK
YKyG2WBogqMYJQOtCEVRFBGdTBCJfRnkS4VaaWNT5sqx1BUxRXxDHYxAJLvkusEeBaPAB+5z4Jzn+t3X
/aLhnEfjo8m+dCoa+7/C3O2Hqe0zDC+8KG+cRZHZhdzaaWTVTCLDMIY0vfM04Nfh77/G/sEhwpEDbO3t
I7TxE8urEVy99fT/AL5gWDLrTB/hnF4XsW0khCu5ln8DmJliT2AXrcNBsU1gj/MH4nMeKwBrPktM28xM
cX79DFKrHHD5d9D26hvicx4pABt2lpg10zYzU0zr7+e3xXGcrkEB2O2TNec9nJFwB3alZn5jZorfeDZh
6Q3g8s06BeCoKF4MRURoH1+BY2oNCbeb0TIclIYxOhzf8frTOuo7FxCbbVIAzpni0iceEc8vhzEwGkJD
lx83ymxifejdKjRNk/8PWnyIyTQqAJek0jqHwfEVscu31baIu8+90sTE4nY025dQ2/5FIPpnXlzKuK8A
HBUzHot52djqQ6HZhfR7IwK4mKpHtvEDMqvfCiQ6zaAAXM8x94aIWTNrLLG4kVUzgaTSPlzLtyJOZxbb
1wtfyg4Q+AfA3aZlButjSfxGcUJBk4g5tuP3haQKRKXcUQDOmbvNTpPOJeFFjordZmbWTNvMTHFUcpUC
nOccAdABIDXXE1nzAAAAAElFTkSuQmCC
</value>
</data>
</root>

View File

@@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Project
{
public static class PUB
{
public static AR.Log log;
public static Project.CSetting setting;
public static void init()
{
log = new AR.Log();
setting = new Project.CSetting();
setting.Load();
}
}
}

View File

@@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Project
{
static class Program
{
/// <summary>
/// 해당 응용 프로그램의 주 진입점입니다.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
}

View File

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

View File

@@ -0,0 +1,63 @@
//------------------------------------------------------------------------------
// <auto-generated>
// 이 코드는 도구를 사용하여 생성되었습니다.
// 런타임 버전:4.0.30319.42000
//
// 파일 내용을 변경하면 잘못된 동작이 발생할 수 있으며, 코드를 다시 생성하면
// 이러한 변경 내용이 손실됩니다.
// </auto-generated>
//------------------------------------------------------------------------------
namespace Project.Properties {
using System;
/// <summary>
/// 지역화된 문자열 등을 찾기 위한 강력한 형식의 리소스 클래스입니다.
/// </summary>
// 이 클래스는 ResGen 또는 Visual Studio와 같은 도구를 통해 StronglyTypedResourceBuilder
// 클래스에서 자동으로 생성되었습니다.
// 멤버를 추가하거나 제거하려면 .ResX 파일을 편집한 다음 /str 옵션을 사용하여 ResGen을
// 다시 실행하거나 VS 프로젝트를 다시 빌드하십시오.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.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("Project.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 Project.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.9.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,103 @@
<?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>{CCFA2CE7-A539-4ADC-B803-F759284C3463}</ProjectGuid>
<OutputType>WinExe</OutputType>
<RootNamespace>Project</RootNamespace>
<AssemblyName>Test_Port</AssemblyName>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<Deterministic>true</Deterministic>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>..\..\..\..\..\..\Amkor\AGV4\Test\PortScan\</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="arCommUtil">
<HintPath>..\..\DLL\arCommUtil.dll</HintPath>
</Reference>
<Reference Include="arControl.Net4">
<HintPath>..\..\DLL\arControl.Net4.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Management" />
<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.Net.Http" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="CSetting.cs" />
<Compile Include="Form1.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Form1.Designer.cs">
<DependentUpon>Form1.cs</DependentUpon>
</Compile>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="PUB.cs" />
<EmbeddedResource Include="Form1.resx">
<DependentUpon>Form1.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>
<None Include="App.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\SubProject\AGV\NARUMI.csproj">
<Project>{8bae0eac-3d25-402f-9a65-2ba1ecfe28b7}</Project>
<Name>NARUMI</Name>
</ProjectReference>
<ProjectReference Include="..\..\SubProject\CommData\CommData.csproj">
<Project>{14e8c9a5-013e-49ba-b435-efefc77dd623}</Project>
<Name>CommData</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>