만져보는 임베디드 시스템/아두이노 소프트웨어

아두이노 소프트웨어-xvii. 아두이노 Serial 클래스 - Serial Class

hanjinee 2021. 1. 5. 13:24

안녕하세요 제타지니입니다. 오늘은 시리얼 통신에 대해서 보겠습니다. 

*시리얼 통신이란 무엇일까?(Serial communication)

 Serial(직렬) 통신. RS 232통신이라고 합니다. 직렬통신이라고 함은 컴퓨터와 기기의 1:1 통신입니다. 한번에 한 비트씩 통신을 합니다. Serial 통신은 USART(Universal Synchronous Asynchronous Receiver Transmitter, 동기 + 비동기 방식 통신) 또는 UART(Universal Asynchronous Receiver Transmitter)로 알려진 방식으로 RS-232C 프로토콜에 정의된 내용 중에서 데이터 송수신을 위한 세 개의 핀, RXD(receive data, 수신 데이터), TXD(Transmit data, 송신 데이터), GND(Ground, 접지)을 사용해서 통신을 수행합니다. 

이에 대해서 자세하게 설명하는 것은 다른 포스트에서 하겠습니다. (Serial 통신에 관해서 더 알고 싶으시다면 vvvvvv를 눌러주세요!)

아두이노 보드에는 'Serial'이라는 이름의 최소 하나의 시리얼 포트가 포함되어 있습니다. 우노의 경우 디지털 0번 핀(RX)과 디지털 1번 핀(TX)을 통해서 시리얼 통신을 합니다. 

 

 

 

*Serial 클래스란?(Serial Class?)

그 동안 포스트에서 올린 것을 복습해 보시죠.

1. 아두이노는 C/C++ 기반

2. C++ 클래스 ==> 객체 추상화 시켜 표현

 = 구체적 동작 과정 숨김

 = 함수 호출을 통해 결과값만을 도출

 

다음과 같이 클래스의 쉬운 사용 때문에, 아두이노의 라이브러리들은 대부분 '클래스로 구현'이 되어 있습니다. 

대부분의 아두이노 스케치에서 사용되는 Serial과 String 클래스의 사용 방법에 관해 배워 보겠습니다. 

[Serial Class] ==> Serial 통신을 위한 클래스

[String Class] ==> 문자열 처리를 위한 클래스

'기본 클래스에 포함이 되어 있어 라이브러리들 처럼 #include 구문을 사용 해서 헤더 파일을 포함시키지 않아도 사용이 가능'합니다.

Serial Class의 함수는 다음과 같이 사용합니다. [Serial._] Serial 클래스의 객체로 Serial이 USBAPI.h에 정의되어 있습니다. 

 

1. Serial Class

​표의 마지막 밑에 Serial 클래스에 대한 예제가 준비되어 있으니 참고하세요! 

  Class

 사용 

 특징 및 의미 

 사용 예제

if

if(Serial 클래스)

시리얼 포트 준비 검사

1. 준비 시 true 반환

2. 그렇지 않으면 false 반환

[*ATmega32u4 마이크로 컨트롤러를 사용하는 보드는 '가상 시리얼 포트의 생성을 대기하기 위해 사용' ==> ex) 아두이노 레오나르도 같은 보드는 가상의 시리얼 포트를 통해 통신이 이루어지기 때문]

if(   )

available

int availabe(void)

 매개변수: 없음  

반환값: 시리얼 포트 수신 데이터 버퍼에 저장된 데이터의 바이트 수

읽기 가능한 바이트 수를 반환

if( Serial.available() > 0){}

//수신 데이터가 있는 경우

begin

void begin(unsigned long baud)

void begin(unsigned long baud, byte 

config) 

 baud: 보율. 변조속도, 데이터 전송 속도

(300, 600, 1200, 2400, 4800, 9600, 14400, 19200, 28800, 

38400, 57600, 115200 中 하나 설정)

config: 데이터 비트 수, 패리티(parity), 정지 비트 설정

(default 값: SERIAL_8N1 

의미: SERIAL_ABC

A: 5,6,7,8 데이터비트

B: 패리티 비트, N: 없음, E: 짝수 패리티, O: 홀수 패리티

C: 정지 비트, 1, 2

)

반환값: 없음

*전송 속도와 옵션 설정

*Serial 포트 초기화를 위해서도 쓰임

*setup에서 한번만 써도 됨

Serial.begin(9600);

//통신 속도 9600 baudrate

end

void end(void) 

매개변수: 없음

반환값: 없음

시리얼 통신을 종료 -> 종료되면 RX 와 TX 핀은 일반 입출력을 위해 사용 가능

시리얼을 다시 시작하려면 begin 함수 사용 

 

find

bool find(char *target)

target: 탐색 문자열

반환값: 발견 여부

Serial 통신 수신 버퍼에서 주어진 문자열 target이 발견될 때까지 데이터를 읽음

주어진 문자열 발견 ==> true 반환

검색 시간 초과시 ==> false 반환

(검색 시간 default ==> 1초)

Serial.find()

findUntil

bool findUntil(char *target, char 

*terminator) 

 target: 탐색 문자열

terminator: 종료 문자열

반환값: 발견 여부

Serial 통신 수신 버퍼에서 주어진 문자열 target이나 종료 문자열 terminator가 발견될 때 까지 데이터를 읽음

주어진 문자열 발견 ==> true 반환

종료 문자열 발견 ==> true 반환

검색 시간 초과시 ==> false 반환

(검색 시간 default ==> 1초)

Serial.findUntil()

flush

void flush(void)

매개변수: 없음

반환값: 없음

Serial 통신 송신 버퍼에 있는 데이터가 전송 완료할 때까지 대기 

Serial.flush()

parseInt

int parseInt(void) 

매개변수: 없음

반환값: 수신 버퍼에서 발견된 첫 번째 유효한 Int형 데이터

Serial 통신 수신 버퍼에서 [첫 번째 유효한 정수] 반환

수신 버퍼가 비어있거나 정수가 발견되지 않으면 0 반환

Serial.parseInt

parseFloat

float parseFloat(void)

매개변수: 없음

반환값: 수신 버퍼에서 발견된 첫 번째 유효한 float형 데이터

Serial 통신 수신 버퍼에서 [첫 번째 유효한 실수] 반환

수신 버퍼가 비어있거나 실수가 발견되지 않으면 0 반환

Serial.parseFloat;

peek

int peek(void) 

매개변수: 없음

반환값: Serial 통신 수신 버퍼의 첫 번째 바이트 데이터 또는 -1 

Serial 통신 수신 버퍼의 [첫 번째 바이트 데이터 반환]

데이터를 수신 버퍼에서 제거하지 않고 peek 함수를 여러번 호출 시에 버퍼 내 첫 번째에 위치한 동일한 문자가 계속적 반환

수신 버퍼가 비어있을 시에 -1 반환

==> 반환 형식은 byte 가 아닌 int 형

Serial.peek

print

size_t print(value, format) 

value: 출력값

(char, char 배열, String, 정수, 실수 등등)

format: 출력형식

(2진수:BIN, 8진수: OCT, 10진수:DEC, 16진수:  HEX

실수의 경우 숫자를 쓰면, 소수점 이하 자릿수 지정, default 값으로 소수점 이하 두 자리 출력)

반환값: Serial 포트로 출력된 바이트 수

출력값 value를 ASCII형식으로 Serial 포트로 출력

비동기적으로 동작 ==> 실제 전송이 일어나기 전에 함수에서 반환

Serial.print(val)

println

size_t println(value, format)

value: 출력값

format: 출력형식

(value, format 모두 print함수와 동일)

반환값: Serial 포트로 출력된 바이트 수

문자열 출력 이후 개행 문자를 추가로 출력

(*개행문자: \r와 \n으로 이루어짐)

Serial.println(val)

read

int read(void)

매개변수: 없음

반환값: Serial 통신 수신 버퍼에서  첫 번째 문자를 읽어 반환

수신 버퍼가 비어 있으면 -1 반환

(수신 버퍼에서 반환한 문자 제거-peek 함수와는 다름!)

Serial.read()

readBytes

size_t readBytes(char *buffer, size_t length) 

buffer: 입력 문자를 저장한 버퍼

length: 입력받을 최대 문자 수

반환값: 입력받은 문자 수

Serial 통신 수신 버퍼의 문자를 읽어 버퍼에 저장

length에 지정한 바이트 수의 문자를 읽었음 or 시간 초과가 발생==> 종료 & 입력받은 문자의 수를 반환

Serial.readBytes()

readBytesUntil

size_t readBytesUntil(char terminator, 

char *buffer, size_t length)

terminator: 종료문자

buffer: 입력 문자를 저장한 버퍼

length: 입력 받은 최대 문자 수 

반환값: 입력받은 문자 수

Serial 통신 수신 버퍼의 문자를 읽어 버퍼에 저장

length에 지정한 바이트 수의 문자를 읽었음 or 시간 초과가 발생 or 종료 문자가 발견된 경우==> 종료 & 입력받은 문자의 수를 반환

Serial.readBytesUntile() 

setTimeout

void setTimeout(unsigned long timeout)

timeout: 대기 시간

반환값 없음

readBytes나 readBytesUntil 함수를 통해 데이터를 읽어 들일 때의 대기 시간을 밀리초(milli-second)단위로 설정

대기 시간 초과시 입력 함수는 종료

default값은 1초 

Serial.setTimeout(100);

write

size_t write(uint8_t ch)

size_t write(const  char *str)

size_t write(const uint8_t *buffer, size_t 

size) 

ch: 출력 문자

str: 출력 문자열

buffer: 출력 데이터 열

size: 버퍼의 크기

반환값: 출력한 바이트 수

2진 데이터를 Serial 포트로 출력 & 출력된 바이트 수를 반환

(숫자를 출력하고자 하면, print 혹은 println함수를 사용해야 함. 

문자열의 경우 print함수와 write 함수 동일한 결과)

Serial.write(ch)

serialEvent

void serialEvent(void)

매개변수: 없음

반환값: 함수

*Serial Class 멤버 함수가 아님!

수신 버퍼에 데이터가 수신된 경우 호출되는 함수

인터럽트 방식이 아닌 폴링 방식!

 

밑의 예제를 보시면 이해가 빠르실 것입니다! 

728x90