닭치고 아두이노 5 시리얼통신(Serial Communication)
좋아요 구독 해 주세요. 이제는 학원을 다니지 않아도 충분히 학습할 수 있는 아두이노 영상들이 많으니 차근차근 공부하시면 좋은 결과가 나올 겁니다.
기초적인 아두이노 코딩과 작동을 해보는 시간입니다. 교재 내용을 꼼꼼히 읽어보시기 바랍니다. 아두이노 설치부터 차근 차근 공부해서 나중에 자율자동차, 드론제작 등을 실습을 해 보도록 해봅시다. 프로그램 언어는 C 언어입니다. 교재는 네이버 카페 백년지계 에 올리도록 하겠습니다. 책과 아두이노 키트를 구매코자 하시는 분은 시중에서 파는 아두이노, 상상을 현실로 만드는 프로젝트 입문편을 사시면 모두 구매 하실 수 있습니다.
[동영상강의]
시리얼통신(Serial Communication)
아두이노 보드와 PC는 시리얼 모니터(Serial monitor)를 이용해 통신할 수 있습니다.
이것을 시리얼 통신(Serial Communication)이라고 부릅니다.
아두이노 보드의 센서 값을 확인하거나 아두이노 보드로 명령을 보낼 때 주로 사용합니다.
뒷 부분 강의에서는 다소 C 언어를 접한 초보자들을 위해 다양한 방법으로 시리얼 통신으로 앞 강의에서 구현하였던 Blink.ino 를 수정해서 여러가지로 구현해 보도록 하겠습니다.
시리얼 통신
serial 은 직렬이라는 뜻으로 시리얼 통신은 직렬 통신을 말합니다.
연속적으로 통신 채널을 거쳐 한 번에 하나의 비트 단위로 데이터를 전송하는 과정을 말합니다.
아두이노 우노는 통신채널로 RX(0번핀 : Receiver X-tal : 수신단자)와 TX(1번핀 : Transmitter : 송신단자)을 물리적 통신 채널로 1개 가지고 있습니다.
그러므로 아두이노 우노는 0번 핀, 1번 핀, USB 연결을 통해서 통신을 할 수 있습니다.
시리얼 통신을 사용하는 경우 0번과 1번 핀을 디지털 입출력으로 사용할 수 없습니다.
소스코드를 컴파일하고 USB를 통해 아두이노 보드로 업로드하는 과정 역시 시리얼 통신을 통해 이루어지며, 컴퓨터의 가상 시리얼 포트와 아두이노의 Serial 을 통해 통신이 이루어집니다.
시리얼모니터 선택
잠깐 여기서 PC 와 USB B 선이 연결되지 않은 상태이면 에러를 냅니다.
USB B선을 PC와 연결한다음 시리얼모니터 메뉴를 다시 선택해 하세요.
시리얼모니터(Serial monitor)
전송옵션
-
line ending 없음
-
CR/LF 모두 사용하지 않는다
-
-
새 줄
-
LF만 사용
-
-
캐리지 리턴
-
CR만 사용
-
-
Both NL & CR
-
CR/LF 모두 사용합니다.
-
전송옵션과 CR/LF 에 관한 이론은 뒷부분에서 코딩할 PC에서 아두이노보드로 메시지 보내기 에서 다루도록 하고 지금은 line ending없음 을 선택합니다.
통신 속도(Baud Rate : 보드레이트)
Baud Rate 는 시리얼 라인으로 전송되는 데이터 속도를 말합니다.
Bits-per-second(bps)단위로 표시하는데 이 값을 바탕으로 1 bit 가 전송되는데 필요한 시간을 알 수 있습니다.
Baud Rate 값은 여러가지 값으로 설정할 수 있지만 통신속도에 크게 영향을 받지 않는 경우 일반적으로 9600 bps 를 사용합니다.
Baud Rate 값이 높을수록 송수신 속도가 빠르지만 값이 너무 높거나 양쪽의 설정값이 다른 경우 데이터 수신에 문제가 발생합니다. 아두이노에서는 300 ~ 250000 bps까지 지원하지만,
Serial 라이브러리에서는 115200 bps 까지 지원하므로 115200 bps 를 초과하지 않도록 주의해야 합니다.
아두이노 보드에서 PC로 메세지 보내기
파일->예제->SoftwareSerial->SoftwareSerialExample 를 열어서 [다른이름으로 저장]을 합니다.
아래와 같이 수정을 합니다. 필요없는 부분들은 다 지워야 깔끔하겠죠.
SoftwareSerialExample_01
void setup() {
// Open serial communications and wait for port to open:
Serial.begin(9600); //시리얼통신 설정
//begin(매개변수)
//9600 : 보드레이트(Baud rate : bit per second 단위)
//보드레이트는 시리얼 통신할 때 통신 속도를 뜻합니다.
//아두이노 보드와 PC쪽에 보드레이트를 동일하게 설정해야 정상적인 통신을 할 수 있습니다.
}
void loop() { // run over and over
Serial.println("Hello my PC!");//마지막에 줄을 바꿔 출력합니다.
//아두이노보드가 PC로 메세지를 보내는 부분
//숫자, 글자
delay(1000);
}
아두이노에서 PC로 메세지를 1초 간격으로 보냅니다.
void setup() {
// Open serial communications and wait for port to open:
Serial.begin(9600); //시리얼통신 설정
}
void loop() { // run over and over
//Serial.println("Hello my PC!");//마지막에 줄을 바꿔 출력합니다.
Serial.print("Hello my PC!"); //줄을 바꾸지 않고 출력합니다.
//아두이노보드가 PC로 메세지를 보내는 부분
//숫자, 글자
delay(1000);
}
PC에서 아두이노보드로 메시지 보내기
SoftwareSerialExample_02
void setup() {
Serial.begin(9600); //시리얼통신 설정
}
void loop() { // run over and over
if(Serial.available()){ //아두이노가 상대방으로부터 받은 데이터가 있는지 확인
char c=Serial.read();
//시리얼 통신으로 들어온 데이터 중 한 바이트를 잘라내 읽는 명령어
if(c == 'a'){
//들어온 문자가 a와 같다면
Serial.println("A"); //PC에게 A라는 글자를 보냅니다.
}
}
}
-
line ending 없음
-
CR/LF 모두 사용하지 않는다
-
입력한 메세지 뒤에 아무것도 붙이지 않고 전송을 합니다.
-
-
새 줄(Newline)
-
LF만 사용
-
입력한 메세지 뒤에 새 줄, 즉, 줄 바꿈 문자(LF=0x0A or \n) 가 추가되어 전송을 합니다.
-
-
캐리지 리턴
-
CR만 사용
-
입력한 메세지 뒤에 캐리지 리턴 문자(CR=0x0D or \r)가 추가되어 전송을 합니다.
-
-
Both NL & CR
-
CR/LF 모두 메세지 뒤에 붙여 전송을 합니다.
-
ASCII코드
ASCII 코드는 영문 알파벳 대소문자 52개, 숫자 10개, 특수 문자 32개, 널 문자 1개로 이루어져 있으며 나머지는 제어 문자입니다.
10 진수16 진수
0 | 0x00 |
1 | 0x01 |
2 | 0x02 |
3 | 0x03 |
4 | 0x04 |
5 | 0x05 |
6 | 0x06 |
7 | 0x07 |
8 | 0x08 |
9 | 0x09 |
10 | 0x0A |
11 | 0x0B |
12 | 0x0C |
13 | 0x0D |
14 | 0x0E |
15 | 0x0F |
CR(Carriage return)
타자기 시절 CR 은 현재 라인에서 커서의 위치를 맨 앞으로 옮기는 동작을 의미합니다.
\r 을 사용합니다.
LF(Line Feed)
타자기 시절 LF 는 커서의 위치는 그대로 두고 종이를 한 라인 위로 올리는 동작입니다.
\n 을 사용합니다.
CR/LF
커서를 다음 라인의 맨 앞으로 옮겨주는 것을 의미합니다.
입력한 문자를 출력하는 코딩을 해 봅시다.
SoftwareSerialExample_04
void setup() {
// Open serial communications and wait for port to open:
Serial.begin(9600);
}
void loop(){
if (Serial.available()){
Serial.write(Serial.read());
}
}
1 글을 입력하고 전송하고
2 글, 3 글을 차례로 계속 해 봅니다.
이렇게 line ending 없음은 다음 글 입력하고 전송을 하면 줄바꿈 자체가 안되고 앞 글에 띄움 없이 이어서 붙여서 나옵니다.
새 줄 을 선택한 다음 1 글, 2글, 3 글을 차례로 전송을 해보면 다음 줄에 출력되는 것을 볼 수 있습니다.
참,,,참고로 화면에 나타난 글들을 지우고 싶으면 출력지우기 로 화면을 깨끗하게 지우면 됩니다.
캐리지리턴 을 선택해서 입력을 계속해보면 line ending 없음 과 같은 출력을 볼 수 있습니다.
Both NL & CR 은 새 줄 과 같은 결과를 출력합니다.
차이점을 알고 싶으니 16진수로 출력하는 코딩을 짜 봅시다.
HexOutput.ino
void setup() {
Serial.begin(9600); //시리얼 통신 초기화
}
void loop() {
if (Serial.available()){
char c = Serial.read();
Serial.print(c,HEX); // 입력한 값을 ASCII 코드 16진수로 출력
}
}
전송옵션을 line ending 없음 으로 하고 CRLF 를 입력해 봅시다.
문자 출력 맨 뒤에 새줄 0x0A 의 A, 캐리지 리턴 0x0D 의 D 가 붙어 있지 않습니다.
전송옵션을 새 줄 로 하고 CRLF 를 입력해 봅시다.
문자 출력 맨 뒤에 새줄 0x0A 의 A 가 붙어서 출력됩니다.
전송옵션을 캐리지 리턴 으로 하고 CRLF 를 입력해 봅시다.
문자 출력 맨 뒤에 캐리지 리턴 의 D 가 붙어서 출력됩니다.
전송옵션을 Both NL & CR 으로 하고 CRLF 를 입력해 봅시다.
문자 출력 맨 뒤에 CR/LF 의 순서대로 캐리지 리턴 0x0D 의 D, 새줄 0x0A 의 A 가 붙어서 출력됩니다.
이제 전송옵션에 따라 메세지 끝에 무엇이 붙어서 같이 전송되는지 확실히 알게 되었습니다.
시리얼 통신을 이용하면 아두이노 보드로 특정 글자를 전송함에 따라 원하는 동작을 할 수 있도록 만들 수 있습니다.
Blink.ino 를 수정하여 시리얼 통신으로 on 을 입력하면 내장 LED 가 켜지고
off 를 입력하면 내장 LED 가 꺼지는 것을 코딩해 봅시다.
Blink3.ino
void setup() {
Serial.begin(9600); //Serial Communication Start
pinMode(13, OUTPUT); // 13 : LED_BUILTIN
}
void loop() {
if(Serial.available()){ // data input
String s; // s 변수를 문자열로 선언
s = Serial.readString(); // 데이터를 문자열로 읽어들여 s 에 넣음
if(s == "on") //읽어 들인 문자열이 on 이면
digitalWrite(LED_BUILTIN, HIGH); //내장 LED 를 켠다
else if(s == "off") // 읽어 들인 문자열이 off 이면
digitalWrite(LED_BUILTIN, LOW); //내장 LED 를 끈다
}
}
전송옵션은 line ending 없음 을 선택하고 on 을 입력하고 [전송] 을 합니다.
그리고 off 를 입력하고 [전송] 을 합니다.
잘 되는 것을 볼 수 있습니다.
이젠 on 이나 off 를 타이핑 한 다음 [전송] 버튼을 누르지 않고 엔터키를 눌렀을 때 켜고 끄는 것을 해 봅시다.
loop 를 돌면서 엔터를 치기 전까지 문자를 전부 합쳐서 on 인지 off 인지 판별해서 LED 를 켜고 끄는 거을 만들어 봅시다. 다른 문자열로 엔터를 치면 문자열을 비워 LED를 제어 못하게 합니다.
Blink4.ino
String s; //값을 가지고 있어야 하므로 전역변수로 문자열 변수 선언
void setup() {
Serial.begin(9600); //Serial Communication Start
pinMode(13, OUTPUT); // 13 : LED_BUILTIN
}
void loop() {
if(Serial.available() > 0 ){ // data input
char c;
c = Serial.read();
if(c == '\n'){ //줄이 바뀌면 (엔터를 눌렀을 경우)
if(s == "on"){ //문자열이 on 이라면
digitalWrite(13, HIGH); //내장 LED 를 켜라
s = ""; //문자열을 비운다
}
else if(s == "off"){ //문자열이 off라면
digitalWrite(13, LOW); //내장 LED 를 끔
s = "";
}
else //on이나 off 이외의 문자가 들어왔을 경우
s = ""; //문자열을 비움
}
else //엔터가 눌리기 전 까지는
s = s + c; // 입력된 문자를 문자열ㄹ로 합친다.
// s += c;
}
}
엔터키(새줄: \n)를 인식하기 위해 전송옵션을 새 줄 로 변경해 줍니다.
on 을 입력하고 엔터키를 누릅니다. LED가 켜집니다.
off 를 입력하고 엔터키를 누릅니다. LED가 끄집니다.
다른 문자들을 입력하고 엔터키를 누릅니다. 아무 반응이 없습니다.
조금 더 개선해서 화면에 LED ON OFF 메세지를 출력을 해 봅시다.
Blink5.ino
String s; //값을 가지고 있어야 하므로 전역변수로 문자열 변수 선언
boolean ledOnOff = false; // LED 초기값 0 끄짐
void setup() {
Serial.begin(9600); //Serial Communication Start
pinMode(13, OUTPUT); // 13 : LED_BUILTIN
}
void loop() {
if(ledOnOff){ // LED On
digitalWrite(13, HIGH);
}
else{ // LED Off
digitalWrite(13, LOW);
}
}
void serialEvent(){
while(Serial.available())
{
char inChar = (char)Serial.read();// 1 byte 를 읽어들임
if(inChar == '\n' || inChar == '\r') // 문자열 종료 검사
{
if(s.equals("on")) // on
{
ledOnOff = true; //LED on
Serial.println("LED_BUILTIN ON");
s = ""; // 문자열을 비움
}
else if(s.equals("off")){ // off
ledOnOff = false; //LED off
Serial.println("LED_BUILTIN OFF");
s = ""; // 문자열을 비움
}
else {
// ledOnOff = false; //LED off
// Serial.println("LED_BUILTIN OFF");
s = ""; // 문자열을 비움
}
}
else{
s += inChar;
}
}
}
on 을 입력하고 엔터키를 누릅니다. LED가 켜집니다. 화면에 LED_BUILTIN ON이 출력됩니다.
off 를 입력하고 엔터키를 누릅니다. LED가 끄집니다. 화면에 LED_BUILTIN OFF가 출력됩니다.
다른 문자들을 입력하고 엔터키를 누릅니다. 아무 반응이 없습니다.
'Arduino > 닭치고 Arduino' 카테고리의 다른 글
닭치고 아두이노 6 LED 켜기(LED) (2) | 2020.04.06 |
---|---|
닭치고 아두이노 4 아두이노구조와 프로그램설명(Arduino About) (0) | 2020.03.01 |
닭치고 아두이노 3강 기본LED깜빡이기(Arduion LED Blink) (0) | 2020.03.01 |
닭치고 아두이노 2강 IDE 살펴보기(Arduino IDE) (0) | 2020.03.01 |
닭치고 아두이노 1강 아두이노 설치(Arduion Setup) (0) | 2020.03.01 |
댓글