반응형
화면 구성
PLC CONNECTED - 현재 연결 상태 표시
READ - D1000의 데이터를 읽어 온다 (D1000~1009)
SEND - D1000에 데이터를 기록 한다 (문자열의 길이만큼)
LISTBOX - 읽기 쓰기 기록 (sheepone을 SEND 한뒤에 READ로 읽어온 사진)
//sInt = new short[10]; 문자열이 ""일때는 10개만 초기화하고 읽어올때도 10비트인데 이건 수정해서 쓰세요
필요 라이브러리
Interop.ActUtlTypeLib.dll
참조 - 참조추가 - 찾아보기 - Interop.ActUtlTypeLib.dll
Form 구성
using System;
using System.Configuration;
using System.Windows.Forms;
namespace MxComponentV4
{
public partial class Form1 : Form
{
public static Plc_MxComponentV4 mxComponent ;
public Form1()
{
InitializeComponent();
int iNo = int.Parse(Option.Plc_MxComponentNo);
mxComponent = new Plc_MxComponentV4(iNo);
}
private void timer1_Tick(object sender, EventArgs e)
{
if(mxComponent != null)
{
bool bIsOnline = mxComponent.IsOnline();
if(!bIsOnline) lbConnected.Text = "PLC DISCONNECTED";
else lbConnected.Text = "PLC CONNECTED";
}
}
private void button2_Click(object sender, EventArgs e)
{
//int iRead = 0 ; //비트로 읽을때
//bool bCheck = mxComponent.GetDevice(Option.Plc_AddReadBit, out iRead);
string sRead = ""; //블럭으로 읽을때
mxComponent.ReadDeviceBlock(Option.Plc_AddRead, out sRead);
listBox1.Items.Add("Read Block : " + sRead);
}
private void button1_Click(object sender, EventArgs e)
{
//mxComponent.SetDevice(Option.Plc_AddReadBit,0); //비트로 쓸때
string sWrite = textBox1.Text ; //블럭으로 쓸때
mxComponent.WriteDeviceBlock(Option.Plc_AddRead, sWrite);
listBox1.Items.Add("Write Block : " + sWrite);
}
}
public static class Option
{
public static string Plc_MxComponentNo{ get; } = ConfigurationManager.AppSettings["Plc_MxComponentNo" ];
public static string Plc_AddRead { get; } = ConfigurationManager.AppSettings["Plc_AddRead" ];
public static string Plc_AddReadBit { get; } = ConfigurationManager.AppSettings["Plc_AddReadBit" ];
public static string Plc_AddWrite { get; } = ConfigurationManager.AppSettings["Plc_AddWrite" ];
}
}
MxComponent 모듈 구성
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Timers;
using System.Windows.Forms;
namespace MxComponentV4
{
//ActProgTypeLib 로 하면 Communication Setup Utility 안쓰고 오픈 할수 있다
//ActUtlTypeLib 로 하면 Communication Setup Utility 로 등록하고 써야 한다 0~
public class Plc_MxComponentV4
{
public enum CpuStsType
{
RUN = 0,
STOP = 1,
PAUSE = 2
}
private int iErrorCode = 0 ;
private string sErrorCode = "";
private int iLogicalStationNumber = 0;
// public bool m_IsOnline = false;
private Object thisLock = new Object();
private ActUtlTypeLib.ActUtlType actUtlType;
//private ActProgTypeLib.ActMLProgType ActMLProgType ;
private bool bConnected = false ;
public bool BConnected { get => bConnected; }
public string SErrorCode { get => sErrorCode; }
public int IErrorCode { get => iErrorCode; }
System.Timers.Timer timer = new System.Timers.Timer();
public Plc_MxComponentV4(int iLogicalStationNumber)
{
actUtlType = new ActUtlTypeLib.ActUtlType();
actUtlType.OnDeviceStatus += new ActUtlTypeLib._IActUtlTypeEvents_OnDeviceStatusEventHandler(OnDeviceStatusEvent);
this.iLogicalStationNumber = iLogicalStationNumber ;
timer.Interval = 1000;
timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elasped);
timer.Enabled = true ;
}
void timer_Elasped(object sender, System.Timers.ElapsedEventArgs e)
{
timer.Enabled = false;
if (!IsOnline())
{
Debug.WriteLine("!IsOnline() ReOpen Stt");
Open(iLogicalStationNumber);
Debug.WriteLine("!IsOnline() ReOpen End");
}
timer.Enabled = true;
}
//-------------------------------------------------------------------------------------------
//비전 폴더 이름 넘기고 받기
//-------------------------------------------------------------------------------------------
//int [] iInt = new int [100];
short[] sInt = new short[100];
public bool WriteDeviceBlock(string _sAdd, string _str)
{
if(_str == "")
{
sInt = new short[10];
Array.Clear(sInt, 0, sInt.Length);
bool bCheck1 = WriteDeviceBlock2(_sAdd,sInt.Length,ref sInt[0]);
return bCheck1;
}
//if(!_str.Contains(Option.Save_Path)) return false ;
//
////
////string sStr = @"D:\DWAMSaveImage\2020Y\12M\17D\131511_K30" ;
//int iStt = _str.IndexOf(Option.Save_Path) ;
//int iLen = Option.Save_Path.Length;
//string sStr = _str.Substring(iStt + iLen,20);
string str = _str;
string[] str_temp ;
if (str.Length % 2 == 0)
{
str_temp = new string[str.Length / 2];
sInt = new short [str_temp.Length];
for (int i = 0; i < str.Length / 2; i++)
{
str_temp[i] = str.Substring(i * 2, 2);
}
for (int i = 0; i < str_temp.Length; i++)
{
byte[] bytes = Encoding.ASCII.GetBytes(str_temp[i]);
short sh = BitConverter.ToInt16(bytes, 0);
sInt[i] = sh;
}
}
else
{
str_temp = new string[(str.Length / 2) + 1];
sInt = new short [str_temp.Length];
for (int i = 0; i < str.Length / 2 + 1; i++)
{
if (i < (str.Length - 1) / 2)
str_temp[i] = str.Substring(i * 2, 2);
else
str_temp[i] = str.Substring(i * 2, 1);
}
for (int i = 0; i < str_temp.Length; i++)
{
if (i < str_temp.Length - 1)
{
byte[] bytes = Encoding.ASCII.GetBytes(str_temp[i]);
short sh = BitConverter.ToInt16(bytes, 0);
sInt[i] = sh;
}
else
{
char data = Convert.ToChar(str_temp[i].Substring(0, 1));
sInt[i] = (short)data;
}
}
}
bool bCheck2 = WriteDeviceBlock2(_sAdd,sInt.Length,ref sInt[0]);
return bCheck2 ;
}
public bool ReadDeviceBlock(string _sAdd, out string _str)
{
sInt = new short[10];
Array.Clear(sInt, 0, sInt.Length);
bool bCheck = ReadDeviceBlock2(_sAdd, sInt.Length, out sInt[0]);
_str = "";
if (bCheck)
{
for (int i = 0; i < sInt.Length; i++)
{
byte[] bytes = BitConverter.GetBytes(sInt[i]);
_str += Encoding.Default.GetString(bytes);
}
}
return bCheck ;
//_str = "" ;
//Array.Clear(sInt, 0, sInt.Length);
//bool bCheck = ReadDeviceBlock2(_sAdd, sInt.Length,out sInt[0]);
//for (int i = 0; i < sInt.Length; i++)
//{
// if(sInt[i] != 0) _str += Convert.ToChar(sInt[i]);
//}
//return bCheck ;
}
public int Initialization(int iLogicalStationNumber)
{
this.iLogicalStationNumber = iLogicalStationNumber;
return 0;
}
public bool IsOnline()
{
//SM400 항상 ON • 항상 ON한다. S (매회END) M9036
//SM401 항상 OFF • 항상 OFF한다. S (매회END) M9037
int iRst = -1;
int iData = 0;
lock (thisLock)
{
try
{
iRst = actUtlType.GetDevice("SM400" , out iData);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
if (iRst == 0 && iData == 1)
{
bConnected = true ;
return true;
}
bConnected = false ;
return false;
}
public bool Open(int iLogicalStationNumber)
{
int iRst = -1;
this.iLogicalStationNumber = iLogicalStationNumber;
actUtlType.ActLogicalStationNumber = this.iLogicalStationNumber;
actUtlType.ActPassword = "";
Debug.WriteLine("!IsOnline() ReOpen 1");
lock (thisLock)
{
try
{
//ActMLProgType.ActUnitType = iact
//ActMLProgType.Open();
actUtlType.Close();
iRst = actUtlType.Open();
}
catch (Exception ex)
{
Debug.WriteLine("!IsOnline() ReOpen 2");
MessageBox.Show(ex.Message);
}
}
Debug.WriteLine("!IsOnline() ReOpen 3");
if (iRst == 0)
{
//int[] arrDeviceValue = { 1 };
//EntryDeviceStatus("SM400",1,1,ref arrDeviceValue[0]);
//actUtlType.OnDeviceStatus += new ActUtlTypeLib._IActUtlTypeEvents_OnDeviceStatusEventHandler(OnDeviceStatusEvent);
return true;
}
else
{
//SetError(iRst);
return false;
}
}
private void SetError(int _iErrorCode)
{
/*
0xF0000001 라이선스 없음 에러 PC 에 라이선스가 부여되지 않았다 . • 라이선스 키 FD 에서 PC 에 라이선스를 부여하십시오 .
0xF0000002 설정 데이터 읽기 에러 논리 국번의 설정 데이터 읽기에 실패하였다 . • 올바른 논리 국번을 지정하십시오 . • 통신 설정 유틸리티에서 논리 국번을 설정하십시오 .
0xF0000003 오픈 완료 에러 오픈 상태에서 Open 메소드를 실행하였다 . • 통신 대상 CPU를 변경하는 경우, Close 후 Open 메소드를 실행 하십시오 .
0xF0000004 미오픈 에러 Open 메소드를 실행하고 있지 않다 . • Open 메소드 실행 후 해당 메소드를 실행하십시오 .
0xF0000005 초기화 에러 MX Component 내부 유지 오브젝트의 초기화에 실 패하였다 . • 프로그램을 종료하고 나서 PC 를 재기동하십시오 . • MX Component 를 재인스톨하십시오 .
0xF0000006 메모리 확보 에러 MX Component 내부 메모리의 확보에 실패하였 다 . • 프로그램을 종료하고 나서 PC 를 재기동하십시오 . • 다른 프로그램을 종료하여 사용 가능 메모리를 확보하십시오 .
*/
//0x01809001 GX Simulator2 미기동 에러 GX Simulator2 가 기동되어 있지 않다 • GX Simulator2 를 기동하십시오 .
sErrorCode = String.Format("0x{0:x8} [HEX]", iErrorCode);
iErrorCode = _iErrorCode ;
MessageBox.Show("MxComponent Error" + sErrorCode);
//MessageBox.Show(sErrorCode);
}
public bool Close()
{
timer.Enabled = false;
if(!bConnected) return true ;
int iRst = -1;
lock (thisLock)
{
try
{
iRst = actUtlType.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
if (iRst == 0) return true;
SetError(iRst);
return false ;
}
/// <summary>
/// 디바이스 1 점을 설정합니다 .
/// </summary>
/// <param name="szDevice"></param>
/// <param name="lData"></param>
/// <returns></returns>
public bool SetDevice(string sDevice, int iData)
{
if(!bConnected) return false ;
int iRst = -1;
lock (thisLock)
{
try
{
iRst = actUtlType.SetDevice(sDevice, iData);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
if (iRst == 0) return true;
SetError(iRst);
return false;
}
public bool GetDevice(string sDevice, out int lplData)
{
lplData = 0;
if(!bConnected) return false ;
int iRst = -1;
lock (thisLock)
{
try
{
iRst = actUtlType.GetDevice(sDevice, out lplData);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
if (iRst == 0) return true;
SetError(iRst);
return false;
}
/// <summary>
/// 2 바이트 데이터로 디바이스 1 점을 설정합니다 .
/// </summary>
/// <param name="szDevice"></param>
/// <param name="lData"></param>
/// <returns></returns>
public bool SetDevice2(string szDevice, short lData)
{
if (!bConnected) return false ;
int iRst = -1;
lock (thisLock)
{
try
{
iRst = actUtlType.SetDevice2(szDevice, lData);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
if (iRst == 0) return true;
SetError(iRst);
return false;
}
public bool GetDevice2(string szDevice, out short lplData)
{
lplData = 0;
if (!bConnected) return false ;
int iRst = -1;
lock (thisLock)
{
try
{
iRst = actUtlType.GetDevice2(szDevice, out lplData);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
if (iRst == 0) return true;
SetError(iRst);
return false ;
}
public bool ReadDeviceBlock(string szDevice, int iSize, out int lplData)
{
lplData = 0 ;
if (!bConnected) return false ;
int iRst = -1;
lock (thisLock)
{
try
{
iRst = actUtlType.ReadDeviceBlock(szDevice, iSize, out lplData);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
if (iRst == 0) return true;
SetError(iRst);
return false ;
}
/// <summary>
/// 디바이스의 일괄 쓰기를 실행합니다 .
/// </summary>
/// <param name="szDevice">디바이스 명</param>
/// <param name="iSize">쓰기 점수</param>
/// <param name="iData">쓰기 디바이스 값</param>
/// <returns></returns>
public bool WriteDeviceBlock(string szDevice, int iSize, ref int iData)
{
if (!bConnected) return false ;
int iRst = -1;
lock (thisLock)
{
try
{
iRst = actUtlType.WriteDeviceBlock(szDevice, iSize, ref iData);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
if (iRst == 0) return true;
SetError(iRst);
return false ;
}
public bool ReadDeviceBlock2(string szDevice, int iSize, out short lplData)
{
lplData = 0;
if (!bConnected) return false ;
int iRst = -1;
lock (thisLock)
{
try
{
iRst = actUtlType.ReadDeviceBlock2(szDevice, iSize, out lplData);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
if (iRst == 0) return true;
SetError(iRst);
return false ;
}
/// <summary>
/// 2 바이트 데이터로 디바이스의 일괄 쓰기를 실행합니다 .
/// </summary>
/// <param name="szDevice"></param>
/// <param name="iSize"></param>
/// <param name="iData"></param>
/// <returns></returns>
public bool WriteDeviceBlock2(string szDevice, int iSize, ref short iData)
{
if (!bConnected) return false ;
int iRst = -1;
lock (thisLock)
{
try
{
iRst = actUtlType.WriteDeviceBlock2(szDevice, iSize, ref iData);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
if (iRst == 0) return true;
SetError(iRst);
return false ;
}
public bool ReadBuffer(int lStartIO, int lAddress, int lSize, out short lplData)
{
lplData = 0;
if (!bConnected) return false ;
int iRst = -1;
lock (thisLock)
{
try
{
iRst = actUtlType.ReadBuffer(lStartIO, lAddress, lSize, out lplData);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
if (iRst == 0) return true;
SetError(iRst);
return false ;
}
/// <summary>
/// 특수 기능 모듈 버퍼메모리의 값을 씁니다 .
/// </summary>
/// <param name="lStartIO"></param>
/// <param name="lAddress"></param>
/// <param name="lSize"></param>
/// <param name="lpsData"></param>
/// <returns></returns>
public bool WriteBuffer(int lStartIO, int lAddress, int lSize, ref short lpsData)
{
if (!bConnected) return false ;
int iRst = -1;
lock (thisLock)
{
try
{
iRst = actUtlType.WriteBuffer(lStartIO, lAddress, lSize, ref lpsData);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
if (iRst == 0) return true;
SetError(iRst);
return false ;
}
public bool SetCpuStatus(int iOperation)
{
if (!bConnected) return false ;
int iRst = -1;
lock (thisLock)
{
try
{
iRst = actUtlType.SetCpuStatus(iOperation);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
if (iRst == 0) return true;
SetError(iRst);
return false ;
}
/// <summary>
/// EntryDeviceStatus FreeDeviceStatus OnDeviceStatusEvent 셋트
/// </summary>
/// <param name="szDeviceList"></param>
/// <param name="lSize"></param>
/// <param name="lMonitorCycle">• iMonitorCycle 은 1 초 ~1 시간의 범위 (1~3600 의 초 단위로 설정 ) 로 지정하십시오 .</param>
/// <param name="lplData"></param>
/// <returns></returns>
public bool EntryDeviceStatus(string szDeviceList, int lSize, int lMonitorCycle, ref int lplData)
{
if (!bConnected) return false ;
int iRst = -1;
lock (thisLock)
{
try
{
iRst = actUtlType.EntryDeviceStatus(szDeviceList, lSize, lMonitorCycle, ref lplData);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
if (iRst == 0) return true;
SetError(iRst);
return false ;
}
public bool FreeDeviceStatus()
{
if (!bConnected) return false ;
int iRst = -1;
lock (thisLock)
{
try
{
iRst = actUtlType.FreeDeviceStatus();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
if (iRst == 0) return true;
SetError(iRst);
return false ;
}
public virtual void OnDeviceStatusEvent(String szDevice, int iData, int iReturnCode)
{
if (iReturnCode == 0)
{
return;
}
sErrorCode = String.Format("0x{0:x8} [HEX]", iReturnCode);
MessageBox.Show(sErrorCode);
iErrorCode = iReturnCode;
}
//-------------------------------------------------------------------------------------------
//필요할까 해서 해놧더니 필요 없네
public string StringToHex(string str)
{
var sb = new StringBuilder();
var bytes = Encoding.Unicode.GetBytes(str);
foreach(var t in bytes)
{
sb.Append(t.ToString("X2"));
}
return sb.ToString();
}
public string HexToString(string hexString)
{
var bytes = new byte[hexString.Length / 2];
for(var i = 0; i < bytes.Length; i++)
{
bytes[i] = Convert.ToByte(hexString.Substring(i*2,2),16);
}
return Encoding.Unicode.GetString(bytes);
}
public string IntToHex(int _int)
{
string sHex = _int.ToString("X");
return sHex;
}
public int HexToInt(string _string)
{
int iInt = int.Parse(_string,System.Globalization.NumberStyles.HexNumber);
return iInt;
}
//----------------------------------------------------------------------------------
}
}
실제 사용한 소스 파일 포함
반응형
'MCU & PLC' 카테고리의 다른 글
XG5000 LS산전 PLC 반전 접점 이해 완벽 정리!!! (0) | 2021.10.28 |
---|---|
C# Melsec MxComponent V4 #3 코딩편 (double word 단위로 보내기 받기) (1) | 2021.07.06 |
C# Melsec MxComponent V4 #1 연결하기 (설정편) (0) | 2021.07.05 |
MCU(TM4C) ROM에 데이터 기억하기 (feat UARTprintf 사용하기) (0) | 2021.05.31 |
MCU보드에 24V 입력을 받아보자 (24V -> 3V 레귤레이터) (0) | 2021.05.21 |