[제품종류] IEC1000
[개발환경] Visual Studio 2008 C#
=============== 질 문 ===============SmartSerialPort로 RS-485 통신을 구현하여 송/수신이 되는 것을 확인하였습니다. (None-Frame, 비동기-Event 방식)
그러나 한 함수내에서 송신을 여러번 하는 경우 각각의 송신에 대한 수신이 정상적으로 되지 않습니다.
OnReadQueueEvent 함수가 호출되는 시점은 언제이며 , Case 2의 경우에도 정상 동작을 하기 위해서 어떤 처리를 해야하는지요?
<예제 코드>
byte[] send, receive;
...
private void sendCommand()
{
...
smartSerialPort1.WriteNoneFrame(send);
}
private void smartSerialPort1_OnReadQueueEvent()
{
smartRS485.ReadQueue(out receive);
...
}
// Case 1 : 정상 동작
private void button1_Click(object sender, EventArgs e)
{
sendCommand();
}
// Case 2 : 비정상 동작 (sendCommand 함수 사이에 sleep 함수를 적용해도 비정상적으로 동작합니다.)
private void button2_Click(object sender, EventArgs e)
{
sendCommand();
sendCommand();
sendCommand();
...
}
=============== 답 변 ===============
안녕하세요.
RS-485 통신으로 송/수신을 사용하실 경우에는 비동기-Event 방식이 아닌 동기-Poling 방식을 사용하셔야 합니다. 이유는 RS-485 통신의 경우 Request-Response 통신 구조이기 때문에 Event 방식은 적합하지 않습니다. 또한 None-Frame 구조를 사용하실 경우 수신부의 ReadTimeout 속성의 값을 꼭 설정하시기 바랍니다. 아래에 예시코드를 첨부하니 확인하시어 참고하시기 바랍니다.
<예시 코드>
private void btnSerialOpen_Click(object sender, EventArgs e)
{
// 보드레이트를 설정합니다.
smartSerialPort1.Baud_Rate = SmartX.SmartSerialPort.BAUDRATE._9600bps;
// 통신 포트를 설정합니다.
smartSerialPort1.PortNo = SmartX.SmartSerialPort.COMPORTNO.COM3;
// 에러 체크와 관련된 속성을 설정합니다.
smartSerialPort1.ErrorCheckCodeType = SmartX.SmartSerialPort.ERRORCHECKCODETYPES.ASCIICODE;
smartSerialPort1.ErrorCheckMode = SmartX.SmartSerialPort.ERRORCHECK.NONE;
smartSerialPort1.ErrorCode_Location = SmartX.SmartSerialPort.ERRORCODELOCATION.TAIL;
// 수신받은 프레임에서 데이터만 표시합니다.
smartSerialPort1.ReceiveFrameDebugMode = false;
// RS485 소프트웨어 감지를 사용하지 않습니다.
smartSerialPort1.RS485SoftwareDetection = false;
// 버퍼의 크기를 설정합니다.
smartSerialPort1.FrameBufferSize = 50000;
// 통신 환경에 맞는 ReadTimeOut값으로 조절하여 사용하시기 바랍니다.
smartSerialPort1.ReadTimeOut = 100;
// 프레임 구조를 NONEFRAME_READTIMEOUT으로 설정
smartSerialPort1.FrameSeparationType = SmartX.SmartSerialPort.FRAMESEPARATIONTYPES.NONEFRAME_READTIMEOUT;
// 데이터 수신 방식을 Polling 방식으로 설정
smartSerialPort1.ReciveDetect = SmartX.SmartSerialPort.RECEIVEDETECT.POLLING_NONEQUEUE;
if (smartSerialPort1.IsOpen == true)
{
smartSerialPort1.Open();
}
}
private void btnPolling _Click(object sender, EventArgs e)
{
if(smartSerialPort1.IsOpen == true)
{
byte[] bReadByte;
string strSendData = "www.hnsts.co.kr";
// 초기 수신 데이터 상태를 Empty로 설정
SmartX.SmartSerialPort.FRAMEDATAREADSTATUS eStatus = SmartX.SmartSerialPort.FRAMEDATAREADSTATUS.EMPTY;
smartSerialPort1.WriteNoneFrame(strSendData); // NoneFrame 구조로 데이터를 전송하여 요청함
eStatus = smartSerialPort1.ReadNoneFrame(out bReadByte); // NoneFrame 구조로 수신받음
switch (eStatus)
{
case SmartX.SmartSerialPort.FRAMEDATAREADSTATUS.EMPTY:
// 수신된 데이터가 없을 경우
break;
case SmartX.SmartSerialPort.FRAMEDATAREADSTATUS.FAILDATA:
// 비정상적인 데이터가 수신된 경우
break;
case SmartX.SmartSerialPort.FRAMEDATAREADSTATUS.VALIDDATA:
// 정상적인 데이터가 수신된 경우
string strRead = SmartX.SmartSerialPort.ConvertASCIIByteToString(bReadByte);
break;
}
}
}
감사합니다.