본문 바로가기

IT관련/arduino

소리로 데이터를 보내자!! - 스마트폰(iOS, Android)의 이어마이크폰 단자를 이용한 data 통신


















몇년전에 이슈가 되었던 아이폰 또는 아이패드의 이어마이크폰 단자(4Pin)에 특정 장비를 끼워 

신용카드 결제를 할 수 있게 하는 기사를 본적이 있었는데요.


미국에서는 아주 활발히 사용하고 있다고 합니다.







국내(한국)에서도 비슷한 개념의 제품이 몇개 나왔는데

아이폰과 안드로이드 폰을 지원하는 기기입니다. 



뭐 국내(한국)제품은 어떤 방식을 사용했는지는 정확히 모르겠으나,

아마도 FSK방식을 사용하여 smart phone과 장치간 통신을 하는 방식으로 구성되어있을것이라...추측이 됩니다.

(저는 이번 프로젝트를 진행하면서 기계음을  하도 많이 들어서 이어폰 꽂고 들어보면

대략 어떤 방식으로 만들었는지 알 수도 있을것 같아요 ㅎㅎㅎㅎㅎㅎ)



1. 공개된 소스 코드 및 기반 자료


Arduino 와  iOS 기기간의 소리를 이용한 통신에 대한 정리는 아주 오래전(2010년 쯤)에 나왔습니다.

일본에서 다방면에 재주를 갖고 계신듯한 개발자의 블로그에 해당 내용이 올라와 있습니다.


なんでも作っちゃう、かも。




위 링크를 따라가 보면 대략 어떤 원리로 소리에 데이터를 싣는지 알 수 있습니다.

(일본어 페이지이지만, 구글 번역을 이용하면 훌륭한 번역 결과를 볼 수 있습니다.)



저도 이번에 회사일때문에.. 장치와 스마트폰(iPhone, iPad, Android)과 FSK로 통신하는 펌웨어와 앱을 동시에 만들게 되었는데요.

iOS 의 경우 위에 언급한 링크인 "なんでも作っちゃう、かも。" 블로그의 자료를 아주 훌륭하게 쓸 수 있습니다.


iOS 4.x인지 3.x인지에 초안을 잡아서 공개된 소스코드가 최근 Xcode 에서는 바로 돌아가진 않긴 한데요.

이부분은 설정을 어떻게 하라고 공개가 되어 있으니 잘 따라하시면 쉽게 할 수 있으리라 생각됩니다.


문제는 안드로이드 계열입니다. 

안드로이드 용은 이번에 만들면서 짜증이 많이 났었어요.


안드로이드용으로 최근에 공개한 소스가 있긴 있는데,

제가 보기에는 그다지 정상적으로 돌아가진 않는듯 했습니다.


단순히 숫자 한 문자를 주고 / 받고 하는 수준의 코드인것 판단되었고

심각한 문제는 315 baud로 하드코딩을 했다는 점입니다.


안드로이드 관련 공개 코드는 : https://code.google.com/p/androino/wiki/AndroinoTerminal

를 참고하세요


なんでも作っちゃう、かも。 블로그의 저자도 "안드로이드에서는 315baud가 한계?" 라는 식의 멘트를 인터넷 어디엔가 남긴글을 본적이 있는데요.  왜 그런말을 했는지 모르겠지만 실제로 1225 baud로도 구현이 가능했습니다.



[아이폰 스크린샷이 들어갈 자리] [안드로이드 스크린샷이 들어갈 자리]

[이미지를 곧 올리겠습니다.]


2. 구현 방법


2-1. Android


처음 테스트 했던 폰은 LG 전자의 옵티머스 마하 와 삼성전자의 갤럭시 네오 였습니다.

쥬라기 시대에 삼엽충들이나 쓸법한 폰이긴 하지만..안드로이드 개발용으로는 괜찮았습니다. -_-;


두 폰 모두 안드로이드 2.3버전 기반이었고 그냥 막 쓰기에 편해서 택했었습니다.

하지만 갤럭시네오는 너무 느려서..도저히 짜증이 나서 중도에 포기하고 ^^;


옵티머스 마하를 주로 개발툴에 연결해서 사용했었습니다.


FSK 신호를 송신하는것은 아주 간단합니다.


HighBit를 대략 40ms 정도 쏴주고 (이부분이 신호 안정화를 위한 Precarrier 입니다.)

그 뒤에 data를 붙여 보내고

다 쏜다음에는

Post Carrier를 쏴주면 됩니다.


별로 이론적인 생각을 하기 싫으면

Javascript로 구현한 코드를 Java로 포팅만 해서 쓰시면 초고속으로 구현 가능합니다.


https://github.com/NeoCat/FSK-Serial-Generator-in-JavaScript/blob/master/fsk-gen.html


문제는 수신입니다.


수신단 처리는 대박 까다롭습니다.


1) 우선 현재 들어오는 신호가 잡시그널인지 정상신호인지 파악해야하고




2) 정상신호라면..그때부터 주파수가 High인지 Low인지 파악을 해야합니다





3) 여기서 첫 Low signal이 나오는 부분 부터 실제 데이터가 시작되는 부분입니다.


아두이노와 iOS용 소프트모뎀을 개발하신 일본 개발자는 처음에 PreCarrier구간을 두어 data의 안정화를 했습니다. 

이런 점을 이용하여 첫 로우 비트가 잡음으로 인해 너무 빨리 나온다면 해당 비트는 무시해야합니다.

(패킷 설계를 아주 적절하게 잘 하셨어요~ 멋진 분입니다. 저는 덕분에 잘 써먹었어요~)




4) data 시작부분이 나왔다면 매 10 비트 마다 주파수를 가늠하여 High인지 Low인지 판단하고

해당 비트를 비트시프트연산으로 반복적으로 채워주면 됩니다.

(위에 이미지는 알파벳 "U"를 보낸 패킷입니다. 알파벳 U 는 ASCII-HEX로 0x55 의 값을 가지고 있습니다.

0x55 를 2진수로 바꾸면 0b01010101 이라...이런 저런 통신 패킷 테스트용으로 아주 좋더군요.

위에 그림을 보면 DATA부분이 L H L H L H L H L H 의 10 비트로 구성되는데요 

처음의 L은 데이터 시작을 의미하는 스타트 비트이고 마지막 H는 data의 끝을 알려주는 stop 비트입니다.

두 비트를 빼면 실제 데이터는  HLHLHLHL로 나오는데 순서대로 넣으면 10101010 = 0xaa  가 되지만...

맨처음 나오는 비트를 LSB(0번비트)부터 넣어주면 01010101 = 0x55가됩니다.)


2-2. Firmware


이번 프로젝트에는 STMicro 사의 CPU 를 사용했는데요. 

(안드로이드는 1주일을 거의 밤새워 했었는데, 펌웨어는 포팅하고 테스트 하고 삽질을 하느라 2주씩이나 걸렸습니다. -_-;)


빠른 개발을 위해서는 Arduino와 같은 계열의 CPU를 사용하시는 편이 좋을것 같습니다.

아두이노의 CPU가 atmega 328 , atmega 2560뭐 이런 시리즈 이니...아두이노 호환보드를 만들어서

그위에 아두이노를 올려서 기존에 공개된 코드를 그대로 붙여 쓰는 방법이 아무래도 가장 빠른 방법일 것 같네요


펌웨어 레벨에서는 엣지 디텍팅 과 카운터를 통해 시그널을 검출해야합니다.


아두이노 소스코드를 보면 아날로그 검출기로 임계값 이상의 데이터가 있는지 확인을 하고

해당 신호가 있으면 그 때 부터 하이인지 로우인지 체크하는 루틴을 타게 되어 있습니다.


high bit / low bit 의 판단은 타이머를 특정주기로 돌려가면서

해당주기내에 high signal 과 low signal의 개수를 파악하여 주기내에 많은 주파수의 값을 취해 비트를 판별하는 구조입니다.


비트 판별은 안드로이드 앱에 설명드린대로 10 비트 구조로 분석하면 됩니다.



3. 잡소리 (개발후기)



옵티머스 마하를 타겟으로 개발과정을 어느정도 마친후

갤럭시 S3, 갤럭시노트 8, 옵티머스 G등 주위에 있는 폰과 태블릿으로 테스트를 했었는데...

날벼락을 맞았습니다. ㅎㅎ


기존에 테스트 했던 코드로는 엉뚱한 결과가 나오거나 돌아가지 않더군요.

안드로이드는 아이폰 처럼 벤더가 하나가 아니여서 장치별로 소리를 녹음하는 장비의 특성이 달랐습니다.


그래서 해당 특성값을 반영하여 장치에 따라 설정을 해주는 부분이 들어가게 되더군요 -_-;

이부분은 폰마다 사맛디 아니할세 이기 때문에 제가 구현한 방식으로는 폰별로 테스트를 한뒤에 임계값을 조절해야만

정상 작동을 하게 되는 한계가 있었습니다.


(제가 위쪽에 구글코드에 올린 안드로이드 터미널이 하드코딩되어 있어서 문제가 많다고 궁시렁거리긴 했으나,

저 역시 1주일만에 만드느라... ㅎㅎ

대박 하드 코딩으로 구현을 한 관계로...코드는 개판입니다. -_-; ㅋㅋㅋ)


이런 장치별 다른점이 안드로이드용 액세서리 또는 앱 시장의 발전을 저해하는 요소일지도 모르겠네요~


※ 소니에릭슨의  일부 기종은 (익스페리아 시리즈) MIC와  GROUND가 다른폰과는 반대로 되어 있으니,

소니폰을 개발도구로 삼는 분들은 참고하시기 바랍니다~



'IT관련 > arduino' 카테고리의 다른 글

아두이노(arduino)와 WIFI의 만남~!!  (22) 2011.04.12
arduino IDE for windows  (2) 2011.04.11