본문 바로가기
IT

#9/12 아두이노 로봇 HowTo

by 소혜민 2022. 11. 4.
반응형

스텝 2. 업그레이드

1차로 자율 주행 로봇을 만들고 나서 아쉬운 점을 나열을 했었다. 센서의 한계로 인해서 장애물을 감지 못하여 예상했던 대로 움직이지 못하는 경우가 꽤나 있었다. 거실에서 자율 주행을 시작해 놓으면 한 동안 이리저리 왔다 갔다를 반복하다가 주방의 어딘가에서 아이방 어딘가에서 헛바퀴만 도는 경우가 많았다. 그래서 조금 업그레이드를 해 보려고 몇 가지 주문을 했다.

  • 블루투스 모듈 (HC-06)
  • 적외선 거리 측정 모듈 (HS-IRSM)
  • LCD 모듈

자율 주행보다는 수동으로 조정을 하는 것도 재미있겠다 싶어 블루투스 모듈을 주문을 했다. 사실 리모콘 모듈을 가지고 먼저 테스트를 해 봤는데 실수로 리모콘 입력부(IR)가 쇼트가 나서 탄 이유도 있었지만 리모콘은 IR이 입력이 수신부 정면 방향에서만 가능하다는 이유가 큰 몫을 했다. TV 리모콘을 생각하면 쉽게 이해가 될 것 같다. 리모콘이 TV 정면에서는 동작을 잘 하지만 TV 뒷편에으로 가서는 동작을 하지 않으니 말이다. 이에 비해 블루투스는 약 10미터까지 데이터를 송수신 할 수 있기 때문에 무선리모콘으로 사용하기에 무리가 없어 보였다. 그리고 확인해 보니 여러 사람들이 만든 스마트폰용 아두이노 제어 애플리케이션이 있었다. 스마트폰 용 애플리케이션은 직접 제작하지 않고 다른 분들이 만든 것을 이용해 보고자 한다.

다음은 적외선 거리 측정 모듈이다. 저렴하게 구할 수 있는 이 모듈은 거리가 있는지 없는지만을 디지털 핀으로 반환을 한다. 즉, ‘장애물이 있네’ 혹은 ‘장애물 없어’를 알려줄 뿐 거리가 얼마라고 알려주지는 않는다. 그래서 거리를 변경할 수 있는 가변저항이 보드에 달려 있다. 십자 드라이버로 돌리면서 원하는 거리를 테스트 하면서 설정을 해야 한다. 이 센서는 최대 30센티미터까지의 장애물 존재 여부를 판단할 수 있다. 보드상의 빨간 LED가 더 밝아지면 장애물이 감지된 것이다. 로봇의 하단부에 달아서 초음파 센서가 거리 측정을 할 때의 오류를 보정하는데 사용하고자 한다. 로봇의 위쪽에는 초음파 센서, 하단은 적외선을 사용하는 모듈을 사용하고자 한다.

마지막은 LCD 모듈이다. 사실 자율주행 로봇에 굳이 필요없을 수 있긴 한데 현재의 모드를 알려주고 자동차의 동작을 출력해 보면 어떨까 해서 장착을 했다. LCD는 두 줄만 표현이 되고 각각 16글자씩 출력을 할 수 있다. 그리고 한글은 출력이 되지 않는 것으로 알고 있다.

블루투스 모듈

HC-06은 다음과 같이 생겼고 VCC 및 GND 이외에 RX와 TX 라인을 가지고 있다. RX는 신호를 받기 위한 핀이고 TX는 데이터를 전송하기 위한 핀이다. 총 4개의 핀을 연결하면 된다.

 

 

RX와 TX가 각각 신호를 받고 보내는 핀이므로 아두이노 보드의 RX는 HC-06의 TX로 TX는 RX로 연결이 되어야 함을 주의해야 한다.

시리얼 통신

블루투스에 대해서 설명을 하기 이전에 시리얼 통신이라는 것에 대해서 알아보도록 하자. 왜냐하면 블루투스를 이용해서 우리는 시리얼 통신을 하기 때문이다. 시리얼 통신(Serial Communication)은 직렬통신으로 번역이 된다. 일반적으로 하나 또는 두 개의 선을 이용해서 단일 방향으로 데이터를 전송하는 것을 이야기 한다. 시리얼 통신의 방법에도 다양한 표준이 있으나 여기서 사용을 할 방법은 전원 관련 VCC와 GND를 빼고 앞서 설명을 한 바와 같이 RX와 TX 두 개의 라인을 사용한다. 단일 방향으로 데이터를 전송한다고 했으니 HC-06 블루투스 보드의 입장에서 보자면 데이터를 읽는 RX는 받기만 하는 단일 통신을 하고, TX는 보내는 기능만 담당을 한다. 따라서 한쪽으로는 받기만 하고 한쪽으로는 보내기만 한다. 데이터를 보낼 때와 받을 때에는 0과 1을 이용해 하나의 비트씩을 보내고 받게 된다. 영문자 하나가 8비트로 구성이 되어 있으니 문자 하나를 보내기 위해서는 8개의 데이터를 순차적으로 보내야 한다. 그 외에 데이터가 제대로 전달이 되었는지 등과 같은 부가적인 정보를 같이 보내는 옵션이 있다. 그래서 하나의 문자를 보내는데 더 많은 횟수의 데이터 전송이 필요하다. 그리고 받는 쪽과 보내는 쪽의 속도가 정확하게 일치되어야만 정보를 주고 받을 수 있다.

블루투스 초기화

블루투스가 시리얼 통신을 사용하기 때문에 우리는 SoftwareSerial이라고 정의된 소프트웨어 라이브러리 모듈을 이용할 것이다. #include <SoftwareSerial.h>와 같이 헤더 파일을 직접 소스 코드의 맨 위에 추가해도 되고 스케치→ 라이브러리 포함하기에서 SoftwareSerial을 선택하면 자동으로 헤더 파일을 소스코드에 추가를 해 준다.

 

 

다음으로는 시리얼 통신을 위해서 HC-06보드의 RX와 TX를 아두이노의 핀에 연결을 해야 한다. 여기서 주의할 점은 HC-06 보드 기준으로 데이터를 읽는 RX는 아두이노 보드에서 보내는 신호인 TX와 연결이 되어야 한다는 점이다. 반대로 TX는 아두이노의 RX와 연결이 되어야 제대로 기능을 할 수 있다. 이 내용을 주의해서 연결을 하도록 한다.

 

 

그래서 SoftwareSerial로 BT를 선언해 주고 RX, TX를 각각 10,11에 할당을 했다. 10번 핀은 HC-06의 TX에 11번은 RX에 연결을 하면 된다.


#include <SoftwareSerial.h>

//Bluetooth setup
SoftwareSerial BT(10,11); //rx, tx

// 리모컨을 사용할 것인지, 자동 주행을 할 것인지?
// 디폴트는 리모컨 사용
bool Auto_Drive = false;

void setup() {
	// 디버깅 메시지를 보기 위한 Serial 초기화
	Serial.begin(9600);
	//Serial.println("");
	while(!Serial);
	BT.begin(9600);
}

지금까지는 전원을 넣고나면 초음파 센서를 이용해서 자율 주행 모드로만 동작을 했었다. 그런데 블루투스를 이용해서는 자율 주행 모드와 사용자가 스마트폰의 블루투스 앱을 이용해 수동으로 조작하는 모드를 추가하려고 한다. 그래서 지금의 운행 모드가 자율주행 모드인지 수동 모드인지를 지정하기 위해서 Auto_Drive라는 변수를 하나 만들었다. 시작을 할 때는 false로 주었으니 전원이 들어오면 수동 모드로 시작을 하는 것이다.

다음으로 setup 함수에서는 BT의 속도를 9600으로 지정을 했다. 이로서 아두이노와 HC-06은 9600이라는 속도로 통신을 하게 된다. 9600의 의미는 9600 bit per second의 의미로 1초에 9600개의 비트를 보낼 수 있다는 의미이다.

 

AT 커맨드

AT 명령어라는 것은 윈래는 모뎀을 제어하는데 사용하는 언어였는데 요즘은 모든 통신의 표준이 되어 있습니다. HC-06도 이 명령을 통해서 제어를 할 수 있습니다.

우선 loop함수의 맨 위에 다음과 같이 코딩을 합니다. 핀이 제대로 연결되었다는 가정하에 블루투스 모듈과의 통신을 확인하기 위함입니다.

코딩의 내용은 BT가 사용가능하면 시리얼 통신 창에 BT로 입력되는 것을 출력하라는 것이 첫 번째의 if 문입니다.

두 번째 if문은 디버그 용도로 사용을 하던 Serial이 사용가능하면 시리얼의 입력창에 입력된 것을 블루투스 BT로 보내라는 것입니다.

 


void loop() {
	if (BT.available()) {
		Serial.write(BT.read());
	}

	if (Serial.available()) {
		BT.write(Serial.read());
	}
	return;
	.
	.
	.
}

코딩이 완료되었다면 스케치에서 업로드를 눌러 컴파일을 하고 바이너리를 올립니다. 그리고 를 내려 받습니다. 그리고 시리얼 모니터를 엽니다. 맨 아래에서 Both NL & CR과 속도를 9600 baud로 변경을 합니다.

 

 

이제 블루투스를 이용해서 컴퓨터와 아두이노와 통신을 할 준비가 되었습니다. 여기서 통신이 완료되고 나면 스마트폰과 연결을 해 보도록 하겠습니다.

우선 시리얼 화면의 입력창에 AT를 입력하게 엔터를 치면 OK라는 것이 아래에 나와야 합니다. AT라는 명령을 블루투스로 보내면 OK라는 회신이 HC-06에서 오는 것입니다. 만일 OK가 뜨지 않는다면 핀의 연결이나 설정에 문제가 있는 것입니다. BT의 이름을 확인하기 위해서 AT+NAME?를 입력해 보시기 바라고, 마지막으로 비밀번호가 기본적으로 설정이 되어 있으니 AT+PIN?를 입력해서 비밀번호를 확인하시기 바랍니다. 내 구미에 맞게 이름을 바꾸기 위해서는 AT+NAME에 바로 붙여서 이름을 쓰면 됩니다. HYEMIN으로 바꾸려면 AT+NAMEHYEMIN인거죠. 비밀번호도 마찬가지 입니다. AT+PIN7777과 같이 입력을 하면 됩니다.

한가지 당황스러운 것은 워낙 BT 모듈이 많아서 그런지 버전의 차이 때문인지는 몰라도 구글링을 해서 얻은 AT 명령이 안되는 경우가 많았습니다. 그리고 꼭 다음 그림의 아래 부분처럼 Both NL & CR과 보드 레이트를 꼭 맞춰주

 

 

스마트폰과 아두이노 연결

스마트폰의 애플리케이션 마켓에 들어가 “arduino bluetooth”로 검색을 해서 arduino bluetooth controller를 다운로드 받는다.

 

 

앞의 좌측부터 순서대로 안드로이드 앱 마켓에서 검색한 결과이고, 다음은 설치를 완료한 후에 로봇의 전원이 들어온 상태에서 돋보기 버튼을 눌러 디바이스를 검색한 결과이다. 여기에 우리가 지정한 이름의 디바이스가 보인다. 이상하게 뒤에 숫자가 붙어서 보이지만 그 다음에 비밀번호를 입력하는 부분의 디바이스 이름에서는 제대로 출력이 된다. 비밀번호가 맞으면 앞의 두 번째 줄 맨 왼쪽 그림처럼 어떤 모드로 시작을 할 것인가 묻는다. 맨 위의 Controller 모드를 선택하면 아래의 두 번째 그림과 같다.

Controller를 설정하지 않았기 때문에 우측 상단의 설정 버튼을 눌러 아래의 맨 우측 그림과 같이 각각을 눌러 설정을 해 주면 된다. 그러면 방향 버튼을 이용해서 로봇을 제어할 수 있으며 수동 모드로도 전환이 가능하다. 다음과 같이 key를 할당해 줍니다.

좌측의 앞으로 전진은 d, 후진은 e, 좌측은 b, 우측은 c로 각각 할당을 합니다. 그리고 우측 버튼의 ㅁ은 정지로 a를, 삼각형은 o로 매뉴얼 모드, O로 표시된 것은 p로 할당을 해서 자율 주행으로 각각 설정을 합니다.

설정을 마쳤으면 스마트폰의 컨트롤러에서 하나씩 버튼을 눌러가며 아두이노와 연결된 시리얼 화면에 각각의 문자들 d,e,b,c,a,o,p가 각각 잘 출력이 되는지 확인을 합니다. 이렇게 들어온 문자들을 이용을 해서 로봇의 주행을 제어하려고 합니다.

로봇 수동 제어

로봇 제어를 위한 코드는 다음과 같습니다. 우선 데이터를 주고 받았던 앞쪽의 코드는 주석처리를 했습니다. 이미 모두 테스트를 했기 때문에 삭제하셔도 무방하겠습니다.

여기서 중요한 부분은 Auto_Drive라는 변수입니다. 앞서 Auto_Drive는 false로 선언을 해서 수동 운전 모드입니다. 이 변수가 true로 변경이 되면 자율 주행 모드로 변경이 되겠죠. 따라서 크게 보면 자율 주행이냐 수동 주행이냐에 따라서 크게 두 부분으로 loop 함수는 나눠지게 됩니다.

수동 모드를 보면 BT.read() 함수를 통해서 어떤 명령이 들어왔는지를 찾습니다. switch문은 처음 사용하게 되는데 여러개의 if 문을 쉽게 써 놨다고 보시면 됩니다. switch()문의 괄호안의 조건에 따라서 맞는 case로 이동을 합니다. case 이하의 부분을 모두 수행을 하고 break 구문을 만나면 switch 구문의 맨 뒤로 이동을 합니다.

예를 들면 a라는 문자가 들어오면 시리얼 창에 “Stop Btn”을 출력하고 Robot_Stop을 이용해 멈추고 끝이 납니다. 로봇의 움직임과 관련된 코드들은 쉽게 이해가 되실 것이라 믿습니다. 이미 한번씩은 봤던 함수들입니다. 다만 매뉴얼 모드 o와 자율 주행 모드 p가 들어오면 Auto_Drive라는 변수를 바꿔줍니다. 그래서 다음번에 loop 함수로 들어올 때는 변경된 Auto_Drive 변수를 보고 자율 주행 혹은 수동 주행을 판단하게 되는 것입니다.

else 문은 자율 주행 모드입니다. 자율 주행 모드에서는 수동 모드로 변경하라는 명령 이외에는 모두 무시가 됩니다. 그래서 if 문을 하나 두어 수동 모드 명령 ‘o’가 들어왔는지를 체크합니다. 수동 모드 전환 명령이 들어오면 로봇을 멈추고 수동 모드로 전환하기 위해서 Auto_Drive를 false로 변경을 합니다. 그러면 다음번 loop가 시작될 때는 수동 모드가 되는 것입니다.


void loop() {
	/*
	if (BT.available()) {	
		Serial.write(BT.read());
	}

	if (Serial.available()) {
		BT.write(Serial.read());
	}

	return;
	*/

	if(!Auto_Drive)
	{
		switch(BT.read())
		{
			case 'a':
				Serial.println("Stop Btn");
				Robot_Stop();
				break;
			case 'b':
				Serial.println("Right Btn");
				Robot_RightTurn();
				break;
			case 'c':
				Serial.println("Left Btn");
				Robot_LeftTurn();
				break;
			case 'd':
				Serial.println("Go Btn");
				Robot_Go();
				break;
			case 'e':
				Serial.println("Back Btn");
				Robot_Back();
				break;
			case 'o':
				Serial.println("o Btn / 매뉴얼 모드");
				Auto_Drive = false;
				break;
			case 'p':
				Serial.println("p Btn / 오토 모드");
				Robot_Stop();
				Detect_Object();
				Auto_Drive = true;
				break;
		}
	} else {
		if('o' == BT.read()){
			Serial.println("o Btn / 매뉴얼모드");
			Auto_Drive = false;
			Robot_Stop();
			return;
		}
		//기존 자율 주행 코드
		.
		.
		.
	{
}

코딩을 모두 마무리 했다면 로봇 주행을 해 봅니다. USB를 통해서 프로그램이 다운로드 되고 나면 로봇은 아무런 움직임이 없습니다. 수동 모드이기 때문이죠. 이제 블루투스를 스마트폰에서 연결을 하고 controller 모드로 들어가면 수동으로 로봇을 움직이거나 자동 주행 모드로 변경을 할 수 있습니다. 그런데 한가지 이상한 동작이 있습니다. 전진을 누르면 조금 앞으로 가다가 멈추는 것인데요. 이러면 스톱 버튼도 필요 없을 뿐더러 운전하는 재미가 없습니다. 그래서 다음과 같이 Robot_Go() 함수를 변경해 줬습니다.


void Robot_Go(){
	Serial.println("로봇 전진");
	digitalWrite(LeftWheel_D1, HIGH);
	digitalWrite(LeftWheel_D2, LOW);	
	digitalWrite(RightWheel_D3, HIGH);
	digitalWrite(RightWheel_D4, LOW);
	if(Auto_Drive)
	{
		delay(300);
		Robot_Stop();
	}
}

어떤 의미인지 이해가 되시나요?

if문이 추가가 되었습니다. 의미는 자율 주행모드일 때만 300 미리 세컨드 만큼 주행을 하고 로봇을 멈추라는 것입니다. 즉 수동 모드에서는 전진 버튼을 한 번 누르면 다른 버튼이 눌리기 전까지 계속 전진을 하게 되는 것입니다.

추가 모듈의 전원 연결

블루투스를 사용하기 전까지 우리가 사용했던 센서들로 인해서 아두이노에서 각 센서로 연결하는 전원핀은 모두 사용을 했다. 그래서 블루투스 부터 전원의 연결은 아두이노에 직접하지 않고 L298N의 5v 아웃을 이용을 해야 했다. 12v 입력단자와 그 옆의 GND만을 사용했는데 맨 우측의 5V 출력단자를 이용한다. 그리고 아두이노로는 데이터 라인만 연결을 한다.

 

 

앞의 그림과 같이 298N의 전원부에는 7v 입력과 GND 그리고 세 번째는 5v 출력에 여러 개의 전원 라인들이 각 모듈과 센서로 연결이 된다.

반응형

'IT' 카테고리의 다른 글

#11/12 아두이노 로봇 HowTo  (2) 2022.11.04
#10/12 아두이노 로봇 HowTo  (0) 2022.11.04
#8/12 아두이노 로봇 HowTo  (0) 2022.11.04
#7/12 아두이노 로봇 HowTo  (0) 2022.11.04
#6/12 아두이노 로봇 HowTo  (0) 2022.11.04

댓글