반응형

로봇을 제작하면서 전자부의 구성은 라즈베리파이 + 아두이노를 사용하기로 계획했다.

일단 사양과 활용도가 높은 라즈베리파이로 각종 데이터 분석과 추후 AI를 위한기능들을 구현하고

실제 구동부의 동작은 아두이노로 제어를 하는 구조다. 물론 요즘 새로 출시된 아두이노들은 웬만한

ML 처리는 가능하지만 아무래도 활용도라든지 관리 차원에서는 라즈베리파이가 조금 더 접근하기

쉬운 것은 사실이다.

 

게다가 일반적인 아두이노 호환 컨트롤러들은 워낙에 저가여서 모터나 센서 등을 조합해서 다양한

구동부를 만들고 이것을 라즈베리파이와 연동한다면 다양한 형태의 로봇이나 차량 혹은 드론을

만들 수 있을 것이라 생각했다. 그래서 프로젝트 이름도 MORS(MOdular Robot System)이라고

지었다.

 

계획은 세웠으니 이제 구현만 하면 되는데…라즈베리파이와 아두이노를 어떻게 연결하는 것이 좋을까?

아직 한번도 해본 적이 없는 구성이라 일단 열심히 검색을 해보았다.

 

일단 가장 기본적으로 알 수 있는 방법은 우리가 PC에서 아두이노 스케치를 개발하듯이 라즈베리파이를

호스트 PC로 만들고 거기서 스케치를 코딩하고 아두이노에 업로드하여 동작하도록 하는 것이다. 하지만

이 방식으로는 아두이노의 PIN에 대해 라즈베리파이가 직접 컨트롤 할 수 없다는 문제가 있다. 즉, 라즈베리

파이가 사용자의 신호를 받았을 때 그 신호를 실시간으로 아두이노에게 전달해야 하는데 이 방식으로는

그것이 불가능하다. 

 

사실상 라즈베리파이와 아두이노가 따로 노는 상황

 

그렇다면 라즈베리파이와 아두이노의 역할을 아예 분리하는 방식을 생각해볼 수도 있다. 라즈베리파이는

부하가 큰 데이터나 ML 처리의 연산만 담당하고 아두이노는 모터나 센서등의 동작을 담당하는 식이다.

하지만 이렇게 되면 사용자가 라즈베리파이와 아두이노를 이원화 하여 컨트롤해야 하고 또 다수의 아두이노

기반 구동부를 연결하는 경우 구조가 매우 복잡해진다(사실 첫 번째 경우와 동일한 케이스인데 다만

아두이노쪽에 사용자와 통신할 수 있는 모듈(ESP, 블루투스, nRF 등)을 추가하여 아두이노를 별도로

제어한다는 점이 다를 뿐이다).

 

쌍둥이를 키우는(?) 입장이랄까?

 

그러다 찾아낸 것이 바로 Firmata이다. 앞으로 얼마간 이 Firmata에 대해 알아보고자 한다.

 

바로 이거지~

 

이 글은 비록 개발자로 일하고 있지만 태생이 문돌이인 블로그 주인의 글이니 보다 정확한 자료를 원하시는

분들은 아래 링크로 이동하여 참고하시면 되겠다. 다만 영어의 압박은 감수하셔야…

 

Firmata 문서 Git : GitHub - firmata/protocol: Documentation of the Firmata protocol.

 

Firmata는 프로토콜이다.

 

프로토콜은 잘 아시다시피 하나의 규약이다. 통신을 할 때 지켜야 할 약속으로 우리가 가장 잘 알고있는

프로토콜은 바로 워키토키를 이용하여 통신을 할 때 자신이 할 말을 마쳤으니 상대방이 말하라고 하는

의미의 “오버”를 들 수 있겠다.

 

하지만 디지털 장치로 그 영역을 옮겨오면 그렇게 단순하지는 않다. 위의 예도 사람의 입장에서 적으니

단순하게 보일 뿐 실제 워키토키가 처리하는 것은 디지털화 된 음성 데이터를 두 대의 워키토키 사이에

전달하기 위해 채널을 확인해야 하고 데이터의 순서나 손실 여부를 체크해야 한다. 이 역시 중요한 부분만

언급했을 뿐 실제로는 더 많은 내용이 오고 갈 것이다.

 

아주 간단한 프로토콜

 

이렇게 디지털 기기에서 양자간에 데이터를 주고받기 위한 규칙을 프로토콜이라고 한다. 우리가 잘

아는 TCP/IP, SMTP, HTTP, FTP 등이 모두 프로토콜이며 각각의 목적에 따라 그 규칙이 모두 다르다.

지금 공부하고자 하는 Firmata 역시 이러한 프로토콜이며 Firmata의 목적은 호스트 컴퓨터와 마이크로

컨트롤러간에 직접 통신을 할 수 있도록 하기 위한 것이다.

 

Firmata는 midi message format을 기반으로 만들어졌다고 하는데 일단 midi message format이

무엇인지까지 파고드는 것은 범위가 너무 넓어지므로 관련 링크만 걸어두겠다.

 

Official MIDI Specifications : Specs

 

여기서 midi란 우리가 잘 알고 있는 디지털 악기가 맞다(Musical Instrument Digital Interface)

 

Firmata의 구성 - 소프트웨어 관점에서

 

Firmata는 호스트 PC쪽의 Firmata Client와 마이크로컨트롤러쪽의 Firmata 라이브러리로 구성

되어 있다. 

 

Firmata Client의 경우 웬만한 언어는 모두 사용 가능한데 대표적으로 Python, java, javascript로부터

iOS, Android까지 모두 사용 가능하다. 또한 각 언어로 구현된 클라이언트도 각각의 특성에 따라 여러

버전이 있어 필요에 따라 선택하여 사용 가능하다.

 

아두이노 라이브러리는 말 그대로 아두이노에서 사용 가능한 라이브러리 형태로 되어있으며 가장 기본적인

라이브러리는 아두이노 스케치의 예제에 포함이 되어있다. 파일 > 예제 > Firmata 항목으로 들어가면 

다양한 Firmata 목록을 볼 수 있는데 가장 기본적인 것은 StandardFirmata이다.

 

아두이노 스케치에서 Firmata 라이브러리 불러오기

 

아두이노에 Firmata 스케치를 업로드하고 클라이언트에서 API를 호출하면 Firmata 프로토콜을 통해

아두이노의 해당 API가 호출되는 식이다(자세한 것은 다음에 소스 분석을 통해 알아보겠다).

 

Firmata의 구성 - 프로토콜 관점에서

 

앞서도 이야기 했듯이 프로토콜이란 통신을 위해 지켜야 할 일종의 약속이다. 즉 FirmataClient에서

약속된 형태의 데이터를 전달해야 아두이노의 Firmara 라이브러리에서 데이터를 받아들이고 처리할 수

있다. 이러한 약속들은 아래 문서에 정의되어 있다.

 

Firmata protocol : protocol/protocol.md at master · firmata/protocol · GitHub

 

 

문돌이들의 경우 몇몇 개념이 헷갈릴 수 있으나 이 약속을 지키기 위한 대부분의 처리는 이미 API로 모두

구현이 되어있으며 다양한 샘플도 존재하니 그저 API를 호출해서 사용하면 된다. 조금 더 이해의 폭을

넓히자면 이 약속이라는 것이 그저 API 호출 시 넘겨주어야 할 파라미터를 정의하는 것이라 생각하면

조금 더 이해가 쉬울 것이다.

 

예를들어 위 링크된 문서의 Message Type 중 set digital pin value라는 항목을 살펴보자

테이블을 보면 우선 command 항목은 0xF5이다. 즉, 아두이노의 특정 디지털 핀에 값을 전달하기 

위해서는 0xF5라는 값으로 시작하는 데이터를 보내야 한다. 다음 열은 비어있고 세 번째 열에

1~127 사이의 핀 번호를 입력해야 하고 마지막으로 1 또는 0으로 해당 핀에 전달할 값을 지정해야

한다. 만일 9번 핀에 디지털 신호를 보내기 위해서는 0xF5, 9, 1 또는 0xF5, 9, 0으로 구성된 3개의

데이터를 보내면 되는데 command에 해당하는 값들은 상수로 지정하여 API에서 처리를 해주므로

실제 API를 호출할 때는 command를 제외한 9, 1 또는 9, 0만을 파라미터로 하여 다음과 같이

보내면 된다.

 

digital_pin_write(pin, 1) 
digital_pin_write(pin, 0)

 

이 중에서 특히 중요한 것이 Sysex Message Format인데 이 부분은 다음 포스팅에서 다뤄보기로 하겠다.

 

정리

 

사실 Firmata에 대해 굳이 이렇게까지 알지 않아도 대충 예제를 보면서 구현하는 것은 그리 어렵지 않다.

그런데 로봇을 만들면서 서보모터를 컨트롤하는데 I2C 기반으로 통신을 하는 PCA9685 PWM 서보모터

드라이버를 사용하려고 보니 아두이노에서 전용 라이브러리를 사용해야 하고 Firmata에서는 이러한 특정

라아브러리에 대한 message format까지 모두 지정해놓은 것은 아니라서 현재로서는 사용이 어렵다.

결국 어떻게 커스터마이징 좀 안될까 하고 조금 더 파고들어가 보기로 한 것이다.

 

물론 다른 방법으로는 I2C에 대한 message format은 정의가 되어있으므로 관련 API를 이용해서 제어하는

방법도 있을 것 같은데 그 또한 그리 만만하지는 않을 것 같아서 우선은 Firmata쪽을 보기로 하였다. 만일

이 시도가 실패한다면 아마도 I2C를 이용한 PCA9685 제어에 도전하게 될지도 모르겠다.

 

다음 포스팅에서는 Sysex Message Format에 대해 알아보고 본격적으로 API와 샘플코드에 대한 분석을

진행해보고자 한다. 

 

#블로그/로봇개발

+ Recent posts