아두이노 시리얼 통신( PC <-> 아두이노 )
Software/Arduino2023. 1. 17. 10:44
반응형
아두이노와 외부 디바이스 또는 PC 와 RS232 통신을 하기위한 방법을 설명합니다.
제 블로그에서는 가급적 실사용 위주를 중심으로 코드를 올립니다. 큰 틀은 가져가시고 세부적인 부분만 수정하셔도 동작에 지장이 없으실 겁니다.
하기의 코드는 실제 개발 제품에 사용했던 것으로 PC가 Master 이고 아두이노가 Slave 인 구성에서의 코드입니다.
아두이노가 Master 가 되는 상황에서 다른 디바이스를 제어할 경우는 코드 구성이 좀 틀립니다.
또한 하기 코드의 프로토콜에는 별도의 오류 체크를 포함하지 않았지만 통신 오류를 줄이기 위해 Check Sum 이나 CRC 등의 오류 체크를 포함할 수도 있습니다.
#define STX 0x02
#define ETX 0x03
#define BUFFER_MAX 20 // 수신버퍼 최대 용량
const int COMM_CTRL = 3 ; // MAX485 RX/TX Control
volatile int Comm_Index = 0 ; // Receive buffer Index Pointer
volatile boolean stringComplete = false ; // 수신 데이타가 다 들어왔는지 확인한다.
volatile boolean serial_start = false ;
char Receive_Buffer[BUFFER_MAX] ;
char Send_Buffer[7] = {STX, 0x30, 0x31, 'I', 'O', 'K', ETX} ; // Serial 송신 버퍼
//--------------------------------------------------------------------------------
void setup()
{
Serial.begin(9600); // set serial communication (9600 bps)
pinMode(COMM_CTRL, OUTPUT) ; // RS485 통신의 경우 송,수신 전환 단자제어
digitalWrite(COMM_CTRL, LOW);
}
//--------------------------------------------------------------------------------
void loop()
{
if(stringComplete == true) // 통신 패킷이 모두 들어왔다.
{
if(Receive_Buffer[1] == 0x30 && Receive_Buffer[2] == 0x31) // 자신의 데이타가 맞다.
{
switch(Receive_Buffer[3]) // 수신된 명령어???
{
case 'I' : Initialize() ; // initialize
break ;
case 'P' : function1() ;
break ;
case 'R' : function2() ;
break ;
case 'T' : function3() ;
break ;
case 'S' : function4() ;
break ;
default : Error() ;
break ;
}
Send_Action_Result() ; // 수신에 대한 응답 메시지 송신
}
memset(Receive_Buffer, 0x00, sizeof(Receive_Buffer)) ; // 수신 버퍼 Clear
stringComplete = false ; // 시리얼 입력에 대한 작업이 종료 되었다.
}
}
//--------------------------------------------------------------------------------
void Send_Action_Result(void)
{
/****************************************
function : 시리얼 포트로 수신결과에 대한 응답을 보낸다.
****************************************/
int count ;
digitalWrite(COMM_CTRL, HIGH) ; // RS485 통신칩의 송/수신 컨트롤 단자 제어용입니다.
// 경우에 따라 없을 수도 있습니다.
for (count = 0 ; count < 7 ; count++)
{
Serial.write(Send_Buffer[count]) ; // 송신 버퍼의 내용을 시리얼로 전송합니다.
}
delay(10) ; // RS485 통신의 경우 이걸 해 주어야만 컨트롤 단자가 LOW 로 떨어지지 않는다.
digitalWrite(COMM_CTRL, LOW) ;
}
//------------------------------------------------------------------------------------
void function1() {}
void function2() {}
void function3() {}
void function4() {}
//------------------------------------------------------------------------------------
void Error(void)
{
Send_Buffer[3] = 'N' ; // NAK 반송
Send_Buffer[4] = 'A' ;
Send_Buffer[5] = 'K' ;
}
//--------------------------------------------------------------------------------
void Initialize(void)
{
/* 명령어 수행 루틴 작성 */
Send_Buffer[3] = 'I' ; // 반송 명령어
Send_Buffer[4] = 'O' ; // OK : 명령을 정상적으로 수행했다.
Send_Buffer[5] = 'K' ;
}
//--------------------------------------------------------------------------------
void serialEvent() // 시리얼 포트의 입력 인터럽트
{
if (stringComplete == false)
{
char inChar = (char)Serial.read() ;
if (inChar == STX && serial_start == false) // 시리얼 포트로 데이타가 들어오기 시작
{
serial_start = true ;
Comm_Index = 0 ;
}
Receive_Buffer[Comm_Index] = inChar ;
if (Receive_Buffer[Comm_Index] == ETX) // 시리얼 포트로 데이타가 모두 들어왔다.
{
stringComplete = true ;
serial_start = false ;
}
Comm_Index ++ ;
if (Comm_Index >= BUFFER_MAX) Comm_Index = 0 ;
}
}
//--------------------------------------------------------------------------------
반응형
'Software > Arduino' 카테고리의 다른 글
아두이노 74HC573 Latch 사용방법 (0) | 2023.04.17 |
---|---|
아두이노 타이머 사용 방법 (0) | 2023.02.06 |
아두이노 EEPRom 읽고 쓰기 (0) | 2023.02.06 |
아두이노 비트필드(bit field)를 이용한 버튼입력 처리 (0) | 2023.01.17 |
댓글()