Arduino
준비물
- Arduino Uno
- 배터리
- L298N 모듈
- TT 모터 + 바퀴 4ea
- hm-10
- 점퍼케이블 넉넉히
전체 구성도
모든 모터는 선이 바깥쪽을 향하도록 조립해야합니다.
로봇 조립
코드 업로드
코드를 업로드 할 때 배터리와 아두이노의 전원을 꼭 분리해주세요
Arduino IDE 다운로드 및 실행
Arduino IDE에 접속해서 각자 PC에 맞는 버전을 다운받습니다.
Arduino 연결
컴퓨터와 Arudino를 연결합니다.
연결 확인하기
다음으로는 Arduino에 코드가 정상적으로 업로드 되고 시리얼 모니터가 잘 동작하는지 확인해보겠습니다. Arduino IDE에서 해당 코드를 입력합니다.
void setup() {
// 시리얼 통신 시작 (9600bps)
Serial.begin(9600);
Serial.println("hello, world!");
}
void loop() {
// 1초(1000ms)마다 "hi" 출력
Serial.println("hi");
delay(1000);
}
Arduino에서 보내는 데이터를 확인하기 위해 "Tools" > "Serial Monitor" 를 눌러 시리얼 모니터를 켭니다.
상단의 "Verify" 버튼을 눌러 코드의 문제가 없는지 확인하고 "Upload" 버튼을 눌러 Arduino에 코드를 업로드 합니다.
만약 코드에 문제가 있다면 Verify 버튼을 눌렀을 경우 다음과 같이 에러가 발생합니다.
Upload 이후 시리얼 모니터에 내용들이 잘 출력이 된다면 성공입니다.
모터 동작 확인하기
이제 연결된 모터가 잘 동작하는지 확인해보겠습니다.
Arduino IDE에서 해당 코드를 입력하고 실행합니다. 4개의 모터가 다 동작하며, 로봇이 한 바퀴 도는 동작을 하면 모터가 정상적으로 연결된겁니다.
void setup() {
Serial.begin(9600);
Serial.println("hello, world!");
// 핀 모드 설정: 8~13번 핀을 출력으로 설정
pinMode(8, OUTPUT);
pinMode(9, OUTPUT);
pinMode(10, OUTPUT);
pinMode(11, OUTPUT);
pinMode(12, OUTPUT);
pinMode(13, OUTPUT);
// 초기 핀 상태 설정
digitalWrite(8, HIGH); // 8번 핀 HIGH
digitalWrite(11, HIGH); // 11번 핀 HIGH
digitalWrite(9, LOW); // 9번 핀 HIGH
digitalWrite(10, HIGH); // 10번 핀 LOW
digitalWrite(12, HIGH); // 12번 핀 HIGH
digitalWrite(13, LOW); // 13번 핀 LOW
// 1초(1000ms) 대기
delay(1000);
// 8번과 11번 핀 상태 변경
digitalWrite(8, LOW);
digitalWrite(11, LOW);
Serial.println("hello");
}
void loop() {
Serial.println("hi");
delay(1000);
}
BLE 데이터 수신하기
BLE는 Bluetooth Low Energy의 약자로, 저전력 블루투스라고도 불립니다. 이는 기존 블루투스 기술의 변형으로, 낮은 전력 소비를 특징으로 합니다. 주요 특징은 다음과 같습니다
- 저전력 소비: BLE는 매우 적은 전력을 사용하여 작동합니다. 이로 인해 배터리 수명이 크게 연장됩니다.
- 빠른 연결: 기기 간 연결 속도가 빠르며, 데이터 전송도 신속합니다.
- 작은 데이터 패킷: 작은 양의 데이터를 주기적으로 전송하는 데 최적화되어 있습니다.
- 광범위한 호환성: 대부분의 현대 스마트폰, 태블릿, 컴퓨터에서 지원됩니다.
- 다양한 응용: 웨어러블 기기, 스마트홈 장치, 의료기기, 비콘 등 다양한 분야에서 사용됩니다.
CoPlay는 Web Bluetooth API를 사용하여 로봇과 통신하는데 이 API가 BLE만 지원해서 CoPlay에 로봇을 연동하기 위해서는 BLE를 사용해야 합니다.
The Web Bluetooth API provides the ability to connect and interact with Bluetooth Low Energy peripherals. By mdn web docs
이 예제에서는 HM-10을 이용하여 BLE 데이터를 수신합니다. 다음과 같이 코드를 작성하고 Upload 합니다.
#include <SoftwareSerial.h>
// SoftwareSerial 객체 생성. 0번 핀은 TX, 1번 핀은 RX로 설정
SoftwareSerial hm10(0, 1);
// HM-10으로부터 수신한 데이터를 저장할 문자열
String receivedString = "";
void setup() {
Serial.begin(9600);
Serial.println("hello, world!");
// HM-10과의 통신 시작 (9600bps)
hm10.begin(9600);
}
void loop() {
// HM-10으로부터 데이터가 수신되면 실행
while (hm10.available()) {
// 수신된 문자를 읽음
char inChar = (char)hm10.read();
// '$'는 명령어의 끝을 나타내는 구분자
if (inChar == '$') {
// 수신된 문자열이 있으면 처리
if (receivedString.length() > 0) {
processCommand(receivedString);
// 처리 후 문자열 초기화
receivedString = "";
}
} else {
// '$'가 아닌 경우 문자를 문자열에 추가
receivedString += inChar;
}
}
}
// 수신된 명령어를 처리하는 함수
void processCommand(String command) {
// 수신된 명령어를 시리얼 모니터에 출력
Serial.println("Received: " + command);
}
로봇 테스트 페이지에 접속해서 로봇 연결 버튼을 클릭하고 키보드를 입력해 시리얼 모니터에 데이터가 잘 출력되는지 확인합니다.
BLE로 모터 동작하기
이제 HM-10으로부터 받은 문자열로 모터를 동작해보겠습니다.
#include <SoftwareSerial.h>
SoftwareSerial hm10(0, 1); // TX, RX
String receivedString = "";
boolean stringComplete = false;
void setup() {
Serial.begin(9600);
Serial.println("hello, world!");
hm10.begin(9600);
}
void loop() {
while (hm10.available()) {
char inChar = (char)hm10.read();
if (inChar == '$') {
if (receivedString.length() > 0) {
processCommand(receivedString);
receivedString = "";
}
} else {
receivedString += inChar;
}
}
}
void processCommand(String command) {
Serial.println("Received: " + command);
//반은 문자열에 따라 모터를 다르게 동작시킵니다.
if (command == "N") {
Serial.println("North");
digitalWrite(8, HIGH);
digitalWrite(11, HIGH);
digitalWrite(9, LOW);
digitalWrite(10, HIGH);
digitalWrite(12, LOW);
digitalWrite(13, HIGH);
} else if (command == "S") {
Serial.println("South");
digitalWrite(8, HIGH);
digitalWrite(11, HIGH);
digitalWrite(9, HIGH);
digitalWrite(10, LOW);
digitalWrite(12, HIGH);
digitalWrite(13, LOW);
} else if (command == "CCW") {
Serial.println("CCW");
digitalWrite(8, HIGH);
digitalWrite(11, HIGH);
digitalWrite(9, LOW);
digitalWrite(10, HIGH);
digitalWrite(12, HIGH);
digitalWrite(13, LOW);
} else if (command == "CW") {
Serial.println("CW");
digitalWrite(8, HIGH);
digitalWrite(11, HIGH);
digitalWrite(9, HIGH);
digitalWrite(10, LOW);
digitalWrite(12, LOW);
digitalWrite(13, HIGH);
} else if (command == "STOP") {
Serial.println("STOP");
digitalWrite(8, LOW);
digitalWrite(11, LOW);
}
}
다시 위의 테스트 페이지에서 로봇을 연결하고 키보드 입력을 통해 모터가 동작하는지 확인합니다.
전체 코드
#include <SoftwareSerial.h>
SoftwareSerial hm10(0, 1); // TX, RX
String receivedString = "";
boolean stringComplete = false;
void setup() {
Serial.begin(9600);
hm10.begin(9600);
pinMode(8, OUTPUT);
pinMode(9, OUTPUT);
pinMode(10, OUTPUT);
pinMode(11, OUTPUT);
pinMode(12, OUTPUT);
pinMode(13, OUTPUT);
digitalWrite(8, HIGH);
digitalWrite(11, HIGH);
digitalWrite(9, LOW);
digitalWrite(10, HIGH);
digitalWrite(12, HIGH);
digitalWrite(13, LOW);
delay(1000);
digitalWrite(8, LOW);
digitalWrite(11, LOW);
Serial.println("hello");
}
void loop() {
while (hm10.available()) {
char inChar = (char)hm10.read();
if (inChar == '$') {
if (receivedString.length() > 0) {
processCommand(receivedString);
receivedString = "";
}
} else {
receivedString += inChar;
}
}
}
void processCommand(String command) {
Serial.println("Received: " + command);
if (command == "N") {
Serial.println("North");
digitalWrite(8, HIGH);
digitalWrite(11, HIGH);
digitalWrite(9, LOW);
digitalWrite(10, HIGH);
digitalWrite(12, LOW);
digitalWrite(13, HIGH);
} else if (command == "S") {
Serial.println("South");
digitalWrite(8, HIGH);
digitalWrite(11, HIGH);
digitalWrite(9, HIGH);
digitalWrite(10, LOW);
digitalWrite(12, HIGH);
digitalWrite(13, LOW);
} else if (command == "CCW") {
Serial.println("CCW");
digitalWrite(8, HIGH);
digitalWrite(11, HIGH);
digitalWrite(9, LOW);
digitalWrite(10, HIGH);
digitalWrite(12, HIGH);
digitalWrite(13, LOW);
} else if (command == "CW") {
Serial.println("CW");
digitalWrite(8, HIGH);
digitalWrite(11, HIGH);
digitalWrite(9, HIGH);
digitalWrite(10, LOW);
digitalWrite(12, LOW);
digitalWrite(13, HIGH);
} else if (command == "STOP") {
Serial.println("STOP");
digitalWrite(8, LOW);
digitalWrite(11, LOW);
}
}