파일정리
This commit is contained in:
67
HMI/TestProject/Test_ACS/AppSettings.cs
Normal file
67
HMI/TestProject/Test_ACS/AppSettings.cs
Normal 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)
|
||||
{
|
||||
// 저장 실패 시 무시
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
162
HMI/TestProject/Test_ACS/CHANGELOG.md
Normal file
162
HMI/TestProject/Test_ACS/CHANGELOG.md
Normal 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 포트 관리 (연결/해제/새로고침)
|
||||
1177
HMI/TestProject/Test_ACS/MainForm.Designer.cs
generated
Normal file
1177
HMI/TestProject/Test_ACS/MainForm.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
613
HMI/TestProject/Test_ACS/MainForm.cs
Normal file
613
HMI/TestProject/Test_ACS/MainForm.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
133
HMI/TestProject/Test_ACS/MainForm.resx
Normal file
133
HMI/TestProject/Test_ACS/MainForm.resx
Normal 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>
|
||||
16
HMI/TestProject/Test_ACS/Program.cs
Normal file
16
HMI/TestProject/Test_ACS/Program.cs
Normal 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());
|
||||
}
|
||||
}
|
||||
}
|
||||
19
HMI/TestProject/Test_ACS/Properties/AssemblyInfo.cs
Normal file
19
HMI/TestProject/Test_ACS/Properties/AssemblyInfo.cs
Normal 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")]
|
||||
63
HMI/TestProject/Test_ACS/Properties/Resources.Designer.cs
generated
Normal file
63
HMI/TestProject/Test_ACS/Properties/Resources.Designer.cs
generated
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
101
HMI/TestProject/Test_ACS/Properties/Resources.resx
Normal file
101
HMI/TestProject/Test_ACS/Properties/Resources.resx
Normal 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>
|
||||
86
HMI/TestProject/Test_ACS/Properties/Settings.Designer.cs
generated
Normal file
86
HMI/TestProject/Test_ACS/Properties/Settings.Designer.cs
generated
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
23
HMI/TestProject/Test_ACS/Properties/Settings.settings
Normal file
23
HMI/TestProject/Test_ACS/Properties/Settings.settings
Normal 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>
|
||||
242
HMI/TestProject/Test_ACS/README.md
Normal file
242
HMI/TestProject/Test_ACS/README.md
Normal 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)
|
||||
93
HMI/TestProject/Test_ACS/Test_ACS.csproj
Normal file
93
HMI/TestProject/Test_ACS/Test_ACS.csproj
Normal 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>
|
||||
30
HMI/TestProject/Test_ACS/app.config
Normal file
30
HMI/TestProject/Test_ACS/app.config
Normal 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>
|
||||
4
HMI/TestProject/Test_ACS/packages.config
Normal file
4
HMI/TestProject/Test_ACS/packages.config
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Newtonsoft.Json" version="13.0.4" targetFramework="net48" />
|
||||
</packages>
|
||||
Reference in New Issue
Block a user