VIC-D 시리즈 (엠에프씨코리아 ) 제어 클래스 C#
Software/C#2023. 3. 22. 10:17
반응형
엠에프씨코리아 업체의 Digital MFC 제품인 VIC - D 시리즈의 통신 제어를 위한 클래스 코드 입니다.
시리얼 통신을 통해 유량을 제어하고 현재 유량값을 읽어 올수 있습니다.
public class CVIC_DSeries
{
/*******************************************************************************
* CLASS: CVIC_DSeries
* Version : 1.0.0
* MFC (Flow Controller) Program (Manufactured by MFC Korea)
* Programed by Sihwan Kim
* Copyright (C) 2019 Photondays, Inc. All rights reserved.
* PROTOCOL : START, ADDRESS, COMMAND, DATA TYPE, DATA, CHECKSUM, END (ASCII 형식)
* Bytes Num. : 1 2 2 2 0~64 2 1
*******************************************************************************/
private SerialPort m_ComPort;
private byte[] m_Address = new byte[2];
private float m_MaxFlow;
public float MaxFlow
{
get { return m_MaxFlow; }
}
public CVIC_DSeries(SerialPort ComPort, byte Address)
{
m_ComPort = ComPort;
m_Address = ByteToHexAscii(Address);
}
private byte[] ByteToHexAscii(byte value) // 1바이트를 2바이트 아스키로 변환
{
string strHex = value.ToString("X2");
byte[] StrByte = Encoding.UTF8.GetBytes(strHex);
return StrByte;
}
private byte[] CheckSum(byte[] Data, int Count)
{
byte[] result = new byte[2];
byte checksum = Data[0];
for (int loop = 1; loop < Count; loop++)
{
checksum = (byte)(checksum ^ Data[loop]);
}
result = ByteToHexAscii(checksum);
return result;
}
public bool Initialize()
{
bool result = true ;
byte[] bTemp = new byte[2];
byte[] send_buffer = new byte[] { 0x3a, m_Address[0], m_Address[1], 0x32, 0x31, 0x30, 0x30, 0x33, 0x39, 0x0d };
byte[] Receive_Buff = new byte[50];
bTemp = CheckSum(send_buffer, 7);
send_buffer[7] = bTemp[0];
send_buffer[8] = bTemp[1];
m_ComPort.Write(send_buffer, 0, 10);
Thread.Sleep(200);
try
{
m_ComPort.Read(Receive_Buff, 0, 50);
if (Receive_Buff[0] == 0x3A && Receive_Buff[2] == m_Address[1]) result = true;
else result = false;
}
catch
{
result = false;
}
return result;
}
public bool Serial_Mode()
{
bool result = true;
byte[] bTemp = new byte[] { 0x00, 0x00 };
byte[] send_buffer = new byte[] { 0x3A, m_Address[0], m_Address[1], 0x35, 0x38, 0x30, 0x32, 0x30, 0x31, 0x33, 0x38, 0x0D };
byte[] Receive_Buff = new byte[50];
bTemp = CheckSum(send_buffer, 9);
send_buffer[9] = bTemp[0];
send_buffer[10] = bTemp[1];
m_ComPort.Write(send_buffer, 0, 12);
Thread.Sleep(50);
try
{
m_ComPort.Read(Receive_Buff, 0, 50);
}
catch { }
return result;
}
public bool Set_Flow_Point(int FlowValue)
{
bool result = false;
int index = 7;
float percentage;
byte[] bTemp = new byte[2];
byte[] send_buffer = new byte[] { 0x3A, m_Address[0], m_Address[1], 0x30, 0x31, 0x30, 0x37, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d};
byte[] Receive_Buff = new byte[50];
percentage = ((float)FlowValue * 100.0f) / m_MaxFlow; // 유량설정은 퍼센트로 한다.
byte[] dByte = BitConverter.GetBytes(percentage); // IEEE754 형식의 float
for (int loop = 3; loop > -1; loop--)
{
bTemp = ByteToHexAscii(dByte[loop]);
send_buffer[index++] = bTemp[0];
send_buffer[index++] = bTemp[1];
}
bTemp = CheckSum(send_buffer, 15);
send_buffer[15] = bTemp[0];
send_buffer[16] = bTemp[1];
m_ComPort.Write(send_buffer, 0, 18);
Thread.Sleep(100);
try
{
m_ComPort.Read(Receive_Buff, 0, 50); // 라즈베리파이는 데이타가 들어오지 않으면 예외를 발생시킨다.
if (Receive_Buff[0] == 0x3A && Receive_Buff[17] == 0x0D)
{
result = true;
}
}
catch
{
result = false;
}
return result;
}
public int Read_Flow_Value(ref float flowValue)
{
int result = 0;
byte[] send_buffer = new byte[] { 0x3A, m_Address[0], m_Address[1], 0x30, 0x33, 0x30, 0x30, 0x33, 0x39, 0x0D };
byte[] bcheck = CheckSum(send_buffer, 7);
send_buffer[7] = bcheck[0];
send_buffer[8] = bcheck[1];
System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
m_ComPort.Write(send_buffer, 0, send_buffer.Count());
sw.Start();
try
{
while (true)
{
Thread.Sleep(10);
if (m_ComPort.BytesToRead > 0)
{
Thread.Sleep(10);
byte[] Receive_Buff = new byte[m_ComPort.BytesToRead + 2];
m_ComPort.Read(Receive_Buff, 0, m_ComPort.BytesToRead);
if (Receive_Buff[0] == 0x3A && Receive_Buff[17] == 0x0D)
{
byte[] bTemp = new byte[8];
Array.Copy(Receive_Buff, 7, bTemp, 0, 8);
try
{
var percentage = FromHexString(Encoding.Default.GetString(bTemp)); // IEEE754 -> float
flowValue = (percentage * m_MaxFlow) / 100.0f;
if (flowValue <= 0) flowValue = 0f;
}
catch
{
flowValue = 0f;
result = -2;
}
}
break;
}
var time = (int)(sw.ElapsedMilliseconds / 1000);
if (time > 5) // Timeout 5sec 시간 경과
{
result = -1;
break;
}
}
}
finally
{
sw.Stop();
}
return result;
}
public int Get_Max_Flow()
{
int result = 0;
byte[] bTemp = new byte[8];
byte[] send_buffer = new byte[] { 0x3A, m_Address[0], m_Address[1], 0x33, 0x33, 0x30, 0x30, 0x33, 0x39, 0x0D };
byte[] Receive_Buff = new byte[50];
byte[] bcheck = CheckSum(send_buffer, 7);
send_buffer[7] = bcheck[0];
send_buffer[8] = bcheck[1];
m_ComPort.Write(send_buffer, 0, send_buffer.Count());
Thread.Sleep(100);
try
{
m_ComPort.Read(Receive_Buff, 0, 50);
if (Receive_Buff[0] == 0x3A && Receive_Buff[17] == 0x0D)
{
Array.Copy(Receive_Buff, 7, bTemp, 0, 8);
try
{
m_MaxFlow = FromHexString(Encoding.Default.GetString(bTemp)); // IEEE754 -> float
}
catch
{
m_MaxFlow = -999.99f;
result = -2;
}
}
}
catch
{
m_MaxFlow = -999.99f;
result = -1;
}
return result;
}
private float FromHexString(string s)
{
var i = Convert.ToInt32(s, 16);
var bytes = BitConverter.GetBytes(i);
return BitConverter.ToSingle(bytes, 0);
}
}
반응형
'Software > C#' 카테고리의 다른 글
시리얼 통신에서의 async await 사용 - C# (0) | 2023.03.28 |
---|---|
Cool Muscle(마쓰루) 모터제어 클래스 C# (0) | 2023.03.22 |
OpenCVSharp 카메라 제어 #4 ( Pattern Matching ) (0) | 2023.03.21 |
OpenCVSharp 카메라 제어 #3 ( Image Capture ) (0) | 2023.03.20 |
OpenCVSharp 카메라 제어 #2 ( Line Generator) (0) | 2023.03.06 |
댓글()