회사에서 개발하고 있는 어플리케이션에 mvvm 아키텍처를 적용하면서 여러 시행착오를 겪고있는데, 이번에 해결한 문제가 가장 어이없고 짜증났던 것 같다.
기존의 백그라운드 서비스와 액티비티 간의 통신 방식을 브로드캐스트에서 event bus로 바꾸기 위해 코드를 수정하였다. 필요없는 코드들을 다 지우고 빌드를 해봤더니 error: cannot find symbol method setModel(BleServiceViewModel) 이 에러가 발생하는거다... 그래서 다른 부분에 문제가 있겠거니 해서 다른거 하고 다시 빌드했더니 같은 오류...
도저히 뭐가 문제인지 몰라 구글링도 해보고 같은 프로그램의 정상 작동하는 다른 view-viewmodel 코드와 비교해도 오류가 발생할 껀덕지를 못 찾겠더라... 그렇게 몇 일을 날리다가 xml에서 class 이름을 커스터마이징했더니 깔끔하게 동작한다. 에러에 대한 힌트도 없고, 자료도 없고, 심지어 내가 뭘 잘못한 것도 아니라 해결을 하고도 굉장히 허무한 것 같다.
회사 연구소에서 RF팀이 spectrum analyzer와 PC를 연결해서 dB를 측정하는 프로그램을 사용하더라. 옆에서 RF팀 형을 도와드렸었는데 솔직히 프로그램 사용 방법도 너무 구식이고 불편한 점이 많은 것 같았다. 그래서 내가 직접 만들어보자!! 라는 생각을 하게 되었는데, 하... 생각보다 귀찮고 알아야할 내용들이 많았다. 일단 여기에 간단하게 핵심 개념들만 정리해보고 다음부터 개발에 들어가야할 것 같다.
현재 사용하고 있는 장비들의 정보는 아래와 같다.
Spectrum Analyzer : [Agilent] ESA-L SERIES E4403B
GPIB : [NATIONAL INSTRUMENTS] GPIB-USB-B
GPIB(IEEE 488.2)란
GPIB(General Purpose Interface Bus)는 전자 전기 엔지니어 협회(IEEE)에서 ANSI/IEEE 표준 488로 인정한 산업 표준이다. GPIB는 PC를 프로그램 가능한 계측기로 연결하는 인터페이스 시스템의 전자, 기계, 기능 및 소프트웨어 스펙을 규정한다.
라고 National Instruments라는 회사의 GPIB 소개란에 써있었다. 그냥 계측 장비와의 통신 프로토콜 같은 것이라고 생각하면 될 것 같다. IEEE 488.2는 488에 업그레이드 버전이다.
이 회사가 GPIB 같은 계측 장비 통신과 관련해서 메이저한 기업인 것 같다. 관련 자료 찾아보면 대부분 이 회사꺼고 LabView도 그렇고... 어쨌든 GPIB는 저런 개념이고 자세한 내용은 굳이 알 필요도 없을 것 같아서 아래의 링크들로 대체하겠다.
VISA란?
카드사 이름이 아니다. 일반적으로 NI-VISA라고 지칭되는 VISA(Virtual Instrument Software Architecture API)를 이용하여 GPIB, USB, 시리얼, 그리고 이더넷 같은 대부분의 instrumentation bus와 통신할 수 있다. VISA는 일관되고 사용하기 쉬운 command set을 제공하여 다양한 계측장비와 통신한다.
VISA는 플랫폼, 버스 및 환경과 독립적이다. 다시 말해, Windows에 설치된 LabVIEW를 이용하여 USB 디바이스와 통신하는 프로그램이나, Mac OS X에서 C를 이용하여 GPIB 디바이스와 통신하는 프로그램이던, 관계없이 동일한 API를 사용할 수 있다는 것이다.
정리하자면, GPIB, IEEE 488.2는 계측장비와 PC간의 프로토콜이고, VISA는 이 프로토콜을 여러 플랫폼에서 동일한 방법으로 사용할 수 있도록 추상화시킨 API이다. 아마 개발은 이 VISA라는 것을 사용하여 하게 될 것 같다.
원격 디바이스에 한번만 연결할지(false), 아니면 사용 가능하게 되면 즉시 자동으로 연결될 디바이스 white list에 주소를 추가할지(true)를 반환한다. 후자의 경우, 블루투스 어댑터가 enable 되면 white list에 있는 디바이스들을 주기적으로 스캔하고, advertising packet을 수신하게 되면 그 디바이스에 연결하려고 시도한다. 연결이 끊겼을 때, 시스템은 그 디바이스에 재연결을 하려고 시도할 것이다. 이 함수가 true를 반환하고 디바이스 연결이 끊기면 BleManagerCallbacks의 onDeviceDisconnected 대신 onLinklossOccur 콜백 함수가 호출된다.
* 이 기능은 최신 기종의 안드로이드 디바이스에서 더 잘 작동하며, 오래된 디바이스는 동작하지 않을 가능성이 높다.
* 이 메서드는 bonded 디바이스만 사용되어야 한다. 그렇지 않은 디바이스들은 주소가 바뀔 수 있다. It will however work also with non-bonded devices with private static address. A connection attempt to a device with private resolvable address will fail(이 부분은 어떤 내용인지 잘 모르곘음)
* 디바이스의 첫 번째 연결은 항상 autoConnect 플래그가 false가 된다(BluetoothDevice의 connectGatt 함수 참고). 대부분의 사용자가 빠른 응답을 기대하고 있기 때문에 이러한 방법을 사용한다. 그러나 처음 연결하는 동안 이 메서드가 true로 반환되고 링크가 손실된 경우 manager 객체는 autoConnect를 true로 강제하는 BluetoothGatt의 connect 함수를 사용하여 reconnect 하도록 시도할 것이다.