2015년 1월 30일 금요일

HM-10 iBeacon 제작

이전 포스트(HM-10 Bluetooth 모듈을 iBeacon으로 사용하기)에서 소개한대로 CR2032 배터리를 사용해 소형 iBeacon 모듈을 제작해 보았다.



만능기판 위에 HM-10 모듈을 약간 두께가 있는 양면테입으로 붙여주고 뒷면에 배터리 홀더를 붙여 주었다. 위쪽 사진 우측 상단의 커넥터는 모듈에 명령을 주기 위해 USB-to-Serial 컨버터를 연결하기 위한 것이고 설정이 끝나면 케이블은 분리하고 모듈 자체적으로 동작하게 된다.


제작한 iBeacon의 크기 비교이다. 위의 사진처럼 500원짜리 동전보다 조금 큰 정도의 크기이다. 이렇게 만든 경우 배터리 한개로 대략 55일 정도 동작하게 된다.

커넥터를 연결하고 컴퓨터에서 시리얼 터미널 에뮬레이터를 동작시켜 명령을 내려준다. (통신 파라미터는 9600-N81)


이전 포스트에서 이야기 했던것처럼 명령어 입력이 끝난걸 엔터키로 확인하는게 아니고 타이밍을 가지고 하기 때문에 위와 같이 줄바꿈이 되지 않고 명령어, 응답이 계속 붙어 보이게 된다.

AT+VERR?HMSoft V533AT+RENEWOK+RENEWAT+RESETOK+RESETATOKAT+MARJ0x1234OK+Set:0x1234AT+MINO0xFA01OK+Set:0xFA01AT+ADVI5OK+Set:5AT+NAMEARSVIATOROK+Set:ARSVIATORAT+ADTY3OK+Set:3AT+IBEA1OK+Set:1AT+DELO2OK+DELO2AT+PWRM0OK+Set:0AT+RESETOK+RESET

쉽게 볼 수 있게 색깔로 구분해 놓은 것이다. 빨간색 볼드는 입력한 명령어, 파란색 이태릭체는 모듈의 응답이다. 

명령 입력이 끝났으면 이제 케이블을 분리해도 된다. 

실제로 정상 동작하는지 확인해 보겠다.



 아이폰에서 Locate 앱을 실행시켜 본 결과이다. 디폴트 UUID는 변경하지 않았으므로 Apple AirLocate로 보인다. 모듈에 설정해 준 대로의 Major 0x1234 (십진수로 4660), Minor 0xFA01 (십진수로 64001)를 확인할 수 있다.


Apple AirLocate.... 부분을 클릭하면 상세정보를 볼 수 있다. 


2015년 1월 28일 수요일

HM-10 Bluetooth 모듈을 iBeacon으로 사용하기

Aliexpress등에서 매우 저렴하게 구입할 수 있는 Bluetooth 4.0 Low Energy (BLE) 모듈인 HM-10을 iBeacon으로 사용할 수 있다. 물론 HM-10은 데이터 통신 또는 단독 센서, 디바이스 제어등의 용도로 사용할수도 있지만 여기서는 그것들에 대한 설명은 생략한다. 

HM-10은 TI의 CC2540 또는 CC2541 BLE SoC 기반의 Bluetooth 4.0 모듈이다. 개당 약$6~7 정도의 가격이다. 펌웨어 버젼은 2014년 9월 기준으로 펌웨어 버젼 531이 나와있다.



모듈은 위의 사진에서 볼 수 있는것처럼 매우 작다. 접촉패드 간격은 1.5mm이라 일반 브레드보드나 만능기판등에서 바로 사용하기는 힘들다. 전원에 연결하거나, 모듈을 iBeacon으로 설정하기 위해 PC에 연결된 USB-to-Serial 케이블에 납땜을 할 때 매우 주의해야만 한다. HM-10은 2.0~3.7V에서 동작하고 I/O핀은 3.3V tolerant이다.

Hardware Connections


모듈에 전원을 공급하기 위해 두가닥의 선이 필요하고, USB-to-Serial adapter를 통해 모듈을 설정하기 위해 임시로 3개의 선이 필요하다. 



위의 사진은 모듈이 3개의 NiMH 충전 배터리가 들어있는 배터리 팩(1.2V * 3 = 3.6V) 과 USB-to-Serial adapter에 연결되어 있는걸 보여준다. Arduino를 사용하고 있다면 아마도 이런 류의 adapter를 이미 가지고 있을것이고, 그렇지 않다면 약 $15정도로 구입할 수 있을 것이다. 만일 구입해야 한다면 3.3V/5V 점퍼나 선택 스위치가 있는 것으로 구입하길 권한다. 



HM-10은 평균적으로 약 0.18mA의 전류를 사용한다. 사진의 배터리팩은 약 1800mAh의 용량을 가지고 있으므로 약 10000시간(즉 1년 이상) 지속될 수 있다. 만일 매우 작은 iBeacon을 만든다면 240mAh 용량의 CR2032 코인셀을 사용할 수도 있고, 이 경우 약 55일정도 사용할 수 있다. 



위의 다이어그램은 케이브블을 어떻게 연결해야 하는지 보여준다. 배터리는 모듈의 12(+), 13(-)번 핀에 연결되어 있다. RS232 adapter의 RxD는 1번핀에, TxD는 2번핀에 연결한다. Adapter의 그라운드 핀은 모듈의 14번 핀에 연결한다. 

Using a Terminal Emulator to talk to the HM-10


하드웨어가 준비되었으면 HM-10이 동작하는지 확인할 수 있다. 배터리와 serial adapter가 HM-10에 연결되었으면 adapter의 USB케이블을 PC에 연결한다. 처음으로 adapter를 사용하는 것이면 adapter의 디바이스 드라이버를 설치하도록 요구받을 수도 있다. 대부분의 경우 OS가 자동으로 드라이버를 찾아준다. 

HM-10은 AT 명령셋을 사용하는데 매우 특이한 타이밍을 요구한다. 명령은 CR이나 LF로 끝나는것이 아니고, 명령이 완전히 다 입력된 다음의 매우 짧은 딜레이에 의존한다. 그러므로 arduino 소프트웨어의 시리얼 모니터를 이용하기를 권장한다. 이 글을 읽는 대다수는 arduino IDE가 이미 설치되어 있을것이라고 생각한다.



Tools 메뉴에서 Serial Port를 선택하고 거기에서 자신의 serial adapter에 해당하는 COM 포트를 선택한다. 대부분의 경우 가장 아래쪽의 COM포트이다. 위의 스크린샷에서는 COM3이다. 

그 다음에 Tools 메뉴에서 Serial Monitor를 실행한다. 아래 메뉴에서 “9600 Baud”와 “No line ending”을 선택한다. 이제 HM-10과 이야기 할 수 있다. “AT” 뒤에 엔터키를 타이핑 해 본다. HM-10이 “OK”라고 응답해야 한다. HM-10은 출력하는 내용 뒤에 LF로 끝나지 않기 때문에 모든 응답 메시지는 뒤에 계속 추가된다.



다음으로 HM-10의 펌웨어 버젼을 확인한다. “AT+VERR?”를 입력한다. 최근에 HM-10을 구입했으면 버젼은 526 또는 그 이후 버젼일것이다. 그렇다면 아래의 Firmware Update 부분은 건너 뛰고 iBeacon Configuration을 가도 된다.

Firmware update

펌웨어 업데이트가 필요하면, 먼저 JNHuaMao 사이트에서 적합한 버젼을 다운로드 받아야 한다. 자신이 가지고 있는 HM-10 모듈이 어떤 칩(2540인지 2541인지)을 사용하는가를 확인한다.  초기모듈은 CC2540을 사용했고 신형 모듈은 CC2541을 사용한다. (최근에 구입했다면 대부분은 CC2541을 사용했을 것이다.)


위의 링크에서 펌웨어를 다운받으면 된다. 다운받았으면 압축을 해제해준다. 최소 3개의 파일이 있을 것이다. readme.txt 파일에는 업데이트 하는 설명이 들어있다. .bin으로 끝나는 파일이 업데이트 할 실제 펌웨어이다. 그리고 .exe로 끝나는 실행파일은 펌웨어를 업데이트 해 주는 프로그램이다. 

1. Arduino 시리얼 모니터에서 ‘AT+SBLUP’를 입력해 준다. 그러면 ‘OK+SBLUP’라고 응답할 것이다. 이제 HM-10은 펌웨어 업데이트를 할 준비가 된 것이다.
2. 시리얼 모니터를 종료한다.
3. 펌웨어 업데이트 프로그램을 실행한다. 
4. COM 포트에 HM-10이 연결되어 있는 시리얼 포트 번호를 설정한다.
5. ‘…’ 버튼을 클릭해 다운로드 한 .bin 파일을 선택한다.
6. 마지막으로 ‘Load Image’ 버튼을 클릭한다.
7. 펌웨어 업데이트는 몇분이 걸린다. 업데이트 하는 도중에는 중단하면 안된다. 
8. Verification이 끝나면 ‘Download completed successfully’라는 메시지가 나올 것이다.



이제 업데이트가 끝났으니 펌웨어 업데이트 프로그램을 종료하면 된다.

iBeacon Configuration


HM-10을 iBeacon으로 설정하려면 몇가지 명령을 입력해 줘야 한다. Arduino Serial Monitor 프로그램을 사용해 명령을 입력해 준다. 아래 리스트에서 볼드로 되어 있는 부분이 실제 입력해줘야 하는 명령이고 그 뒷부분은 각 명령이 어떤 동작을 하는지에 대한 설명으로 입력하면 안된다. 각 명령은 “OK …”으로 ack 되어야 한다. 

1.  AT+RENEW       Factory default로 복구
2.  AT+RESET       Reboot
3.  AT             OK를 기다림
4.  AT+MARJ0X1234  Major no.를 0x1234로 설정
5.  AT+MINO0XFA01  Minor no.를 0xfa01로 설정
6.  AT+ADVI5       Advertising interval을 5(546.25 ms)로 설정
7.  AT+NAMEDOPEY   HM-10 모듈 이름을 DOPEY로 설정
8.  AT+ADTY3       non-connectable로 설정 (전원 절약)
9.  AT+IBEA1       iBeacon 모드 활성화
10. AT+DELO2       iBeacon broadcast-only로 설정 (전원 절약)
11. AT+PWRM0       Auto-sleep 활성화. 8에서 0.18mA로 전력소비를 줄여줌
12. AT+RESET       Reboot

위의 명령들을 다 입력했다면 HM-10은 아이폰이나 안드로이드에서 iBeacon으로 보여야 한다. 4~5단계에서 적절한 major와 minor no.를 선택할 수 있다. Major no.는 특정 범위(스토어 또는 빌딩)내에서 동일하고, minor no.가 iBeacon을 유일하게 식별한다. 위의 프로시져는 HM-10의 디폴트 UUID(표준 proximity UUID)는 변경하지 않는다. UUID를 변경하고 싶으면 AT+IBE0, AT+IBE1, AT+IBE2, AT+IBE3 명령을 사용할 수 있다. 16버이트 UUID는 4바이트 단위로 나뉘어 각각은 다른 명령으로 바꿀 수 있다. 아래 테이블은 UUID를 4개의 명령으로 각각 어느 부분을 변경할 수 있는지 보여준다. 



Removing the Programming Cable


HM-10이 정상적으로 iBeacon으로 동작하는게 확인되었으면 serial adapter에 납땜질 된 케이블을 제거하고, 전원 케이블만 연결해 놓으면 된다. 



배터리 팩과 모듈을 보호하기 위해 케이스에 집어넣어 준다.



Simple iBeacon Scan

아이폰이나 안드로이드 폰에서 iBeacon 스캔을 할 수 있는 앱을 실행시켜 본 결과이다. 위와 같이 정상 동작하고 있음을 확인할 수 있다. 단 iBeacon과의 거리는 RSSI값을 가지고 계산한 것이기 때문에 상대적인 거리이지 정확한 거리는 아님을 주의해야 한다. 

Using the HM-10 as an iBeacon Proximity Device


다음의 8개 UUID는 Apple AirLocate에 proximity device로 들어있다. AirLocate를 사용하는 iOS app과 호환성을 보장하기 위해 이 값을 사용한다.




Waking Up the HM-10


HM-10이 auto-sleep 모드로 설정되어 있으면 전원이 들어오거나 리부팅 될 때 빨리 sleep모드로 갈 수 있다. AT+PWRM0 명령을 보낸 뒤에 재시작하면 MH-10은 더이상 AT 명령에 응답하지 않는다. 디바이스를 깨우려면 80글자 이상의 랜덤 알파벳을 보내면 된다. 그러면 모듈이 깨어나 OK+WAKE라고 응답한다. 한동안 디바이스에 명령을 내려야 하면 잠들지 않게 하기 위해 먼저 AT+PWRM1 명령을 보내준다. 명령이 끝나면 전력소비를 줄이기 위해 AT+PWRM0을 보내면 된다. 


To be continued....   HM-10 iBeacon 제작

2015년 1월 27일 화요일

ESP8266 동작시키키 2

이제 실제 PC와 데이터를 주고받아 보겠다.
먼저 ESP8266이 클라이언트가 되어 PC쪽으로 데이터를 전달하는 예제이다.

PC에서 먼저 netcat을 사용해 서버 포트를 열어준다.

mac: ~$ nc -l 9999

그리고 시리얼 터미널 에뮬레이터에서 ESP8266에 명령을 실행한다. (검은색 볼드체로 된 부분이 직접 입력해야 하는 내용임. 입력할 명령 뒤쪽에 빨간색 이탤릭체는 명령에 대한 설명 부분임)

AT

OK
AT+GMR
00200.9.5(b1)
compiled @ Dec 25 2014 21:40:28
AI-THINKER Dec 25 2014

OK
AT+RST

OK
c_..R[.fJ[:fJSj...W.G.W.j..H.U...K.....
.............5Rj.4Ej
.U...Z.K.r.r.B..Jj.4...W....$('QY,H.MH..14, 21:50:58
ready
AT+CWMODE?
+CWMODE:3

OK
AT+CWLAP   현재 사용가능한 네트웍 목록 검색
+CWLAP:(4,"KT_WLAN_C0BD",-49,"00:27:1c:c0:9b:d4",1)
+CWLAP:(3,"TESTWIFI",-43,"00:1d:93:3a:47:a8",13)
+CWLAP:(0,"iptime",-91,"00:26:66:33:35:46",11)
+CWLAP:(0,"iptime",-83,"00:26:66:b3:f6:bc",11)
+CWLAP:(0,"kor",-81,"00:18:4d:84:f7:20",11)

OK
AT+CWJAP="TESTWIFI","mypassword"   SSID가 TESTWIFI인 공유기에 암호 mypassword를 사용해 연결 

OK
AT+CIPMUX=1        Multiple connection 기능 켬

OK
AT+CIPSTART=4,"TCP","192.168.1.3",9999   192.168.1.3의 9999번 포트로 TCP 연결을 함, 커넥션 id는 4번
4,CONNECT

OK
AT+CIPSEND=4,5     4번 커넥션으로 5바이트를 전송
> TEST             보낼 데이터 입력
SEND OK

여기서 SEND OK가 나오면 ESP8266에서 데이터를 보냈다는 것이다. 다시 PC화면의 터미널 에뮬레이터로 돌아와 보면 다음과 같이 전송된 데이터가 표시되어 있을 것이다.

mac: ~$ nc -l 9999
TEST
^C
mac: ~$ 

반대로 ESP8266이 서버로 동작할수도 있다. 이 경우 먼저 ESP8266에 서버를 동작시켜야 한다.

AT+CIFSR     ESP8266의 IP주소 확인
+CIFSR:APIP,"192.168.4.1"
+CIFSR:APMAC,"1a:fe:34:98:83:35"
+CIFSR:STAIP,"192.168.1.4"
+CIFSR:STAMAC,"18:fe:34:98:83:35"

OK
AT+CIPSERVER=1,9999       9999번 포트로 TCP 연결을 기다림

OK

이제 ESP8266의 9999번 포트가 연결을 기다리고 있는 상태이다. 터미널 에뮬레이터에서 netcat을 이용해 접속한다.

mac: ~$ nc 192.168.1.4 9999     ESP8266(ip:192.168.1.4)의 9999번 포트로 연결
test from mac      전송할 데이터 입력
^C
mac: ~:$ 

'test from mac'이라는 스트링을 전송했으니 터미널 에뮬레이터 화면을 보면 다음과 같이 출력되어 있을 것이다.

0,CONNECT         nc 192.168.1.4 9999 명령으로 소켓이 연결되었음

+IPD,0,14:test from mac       0번 커넥션으로 14바이트를 전송받았음. 내용은 'test from mac'

OK
0,CLOSED     PC에서 nc가 종료되어 소켓 연결이 닫혔음

이렇게 ESP8266은 네트웍 클라이언트 또는 서버로 동작시킬 수 있다.

To be continued.... ESP8266 동작시키기 3

ESP8266 동작시키기

하드웨어 연결


ESP8266은 1.7~3.6V에서 동작하기 때문에 3.3V 전원을 사용한다. PC에 연결하기 위해 사용할 USB-to-Serial 컨버터도 3.3V 버젼을 사용하면 된다. 여기서는 FTDI사의 FT232R 칩을 이용한 컨버터를 사용했다.


ESP8266 보드의 8핀 커넥터의 신호는 다음과 같다.


Vcc와 CH_PD에는 +3.3V, RX에는 FT232R 보드의 TX-O를, TX에는 FT232R 보드의 RX-O를 연결해 준다. GPIO0는 부팅시 동작 모드를 결정하는 핀으로 Vcc에 연결되어 있으면 일반 모드로 동작하고, GND에 연결되어 있으면 flash rewriting 모드로 동작한다. 펌웨어를 업데이트 하는 경우가 아니면 평소 동작시는 Vcc(3.3V)에 연결시켜 놓으면 된다.
커넥터가 브레드보드(빵판)에 사용하기 힘들기 때문에 간단하게 컨버팅 보드를 땜질로 만들었다.


전체 연결은 다음과 같이 된다.


동작시켜 보기

이제 PC에 USB케이블을 연결하고 시리얼 터미널 에뮬레이터을 실행한다. (여기서는 Mac에서 CoolTerm을 사용했지만 아무 시리얼 터미널 에뮬레이터나 상관없다. Windows에서는 putty를 추천한다.)
디폴트 통신 파라미터는 115200-N-8-1이다.


통신 파라미터를 설정했으면 디바이스에 연결한 다음 엔터키를 눌러보면 'Error'라는 글자가 나올 것이다. 이게 출력되면 정상적으로 통신이 되고 있다는 것이다. 이제 다양한 명령을 입력해 볼 수 있다.

AT
OK
AT+GMR
00160901
OK
AT+RST
OK
 ets Jan  8 2013,rst cause:4, boot mode:(3,7)

wdt reset
load 0x40100000, len 24444, room 16
tail 12
chksum 0xe0
ho 0 tail 12 room 4
load 0x3ffe8000, len 3168, room 12
tail 4
chksum 0x93
load 0x3ffe8c60, len 4956, room 4
tail 8
chksum 0xbd
csum 0xbd

ready
AT+CWMODE=3
OK
AT+CWLAP
+CWLAP:(0,"",0)
+CWLAP:(3,"TEST",-83)
+CWLAP:(3,"FOO_NET",-64)
+CWLAP:(3,"BAR_NET",-75)
+CWLAP:(3,"MYWIFI",-70)
OK
AT+CWJAP="MYWIFI","mypassword"
OK
AT+CIFSR


192.168.1.5

명령은 기본적으로 'AT'로 시작한다.
AT+GMR로 버젼을 확인, AT+RST로 모듈을 리셋시킬 수 있다.
ESP8266 모듈은 디바이스(station)으로 동작할수도 있고 AP로 동작할 수도 있기 때문에 여기서는 AT+CWMODE 명령으로 station 모드로 설정해줬다.
AT+CWLAP 명령은 무선랜을 스캔해 현재 사용할 수 있는 무선랜 목록(SSID, RSSI)을 보여준다.
여기서 사용하려는 무선랜을 선택해 AT+CWJAP 명령으로 연결해주면 된다. 연결된 후 AT+CIFSR 명령으로 할당받은 IP 주소를 확인할 수 있다.
여기까지 정상적으로 진행되었다면 동일한 공유기에 연결된 PC에서 무선 모듈로 ping을 날려 실제 동작하고 있는지 확인해 볼 수 있다.

mymac:~$ ping 192.168.1.5
PING 50.50.0.55 (192.168.1.5): 56 data bytes
64 bytes from 192.168.1.5: icmp_seq=0 ttl=255 time=116.131 ms
64 bytes from 192.168.1.5: icmp_seq=1 ttl=255 time=5.368 ms
64 bytes from 192.168.1.5: icmp_seq=2 ttl=255 time=10.549 ms
^C
--- 192.168.1.5 ping statistics ---
3 packets transmitted, 3 packets received, 0.0% packet loss

round-trip min/avg/max/stddev = 5.368/44.016/116.131/51.037 ms


ESP8266에서 사용할 수 있는 AT 명령어 목록은 다음과 같다.
CommandsDescriptionTypeSet/ExecuteInquirytestParametersExamples
AT+RSTrestart the modulebasic----
AT+CWMODEwifi modewifiAT+CWMODE=<mode>AT+CWMODE?AT+CWMODE=?1= Sta, 2= AP, 3=both
AT+CWJAPjoin the APwifiAT+ CWJAP =<ssid>,< pwd >AT+ CWJAP?-ssid = ssid, pwd = wifi password
AT+CWLAPlist the APwifiAT+CWLAP
AT+CWQAPquit the APwifiAT+CWQAP-AT+CWQAP=?
AT+ CWSAPset the parameters of APwifiAT+ CWSAP= <ssid>,<pwd>,<chl>, <ecn>AT+ CWSAP?ssid, pwd, chl = channel, ecn = encryptionConnect to your router: :AT+CWJAP="YOURSSID","helloworld"; and check if connected: AT+CWJAP?
AT+ CIPSTATUSget the connection statusTCP/IPAT+ CIPSTATUS
AT+CIPSTARTset up TCP or UDP connectionTCP/IP1)single connection (+CIPMUX=0) AT+CIPSTART= <type>,<addr>,<port>; 2) multiple connection (+CIPMUX=1) AT+CIPSTART= <id><type>,<addr>, <port>-AT+CIPSTART=?id = 0-4, type = TCP/UDP, addr = IP address, port= portConnect to another TCP server, set multiple connection first: AT+CIPMUX=1; connect: AT+CIPSTART=4,"TCP","X1.X2.X3.X4",9999
AT+CIPSENDsend dataTCP/IP1)single connection(+CIPMUX=0) AT+CIPSEND=<length>; 2) multiple connection (+CIPMUX=1) AT+CIPSEND= <id>,<length>AT+CIPSEND=?send data: AT+CIPSEND=4,15 and then enter the data
AT+CIPCLOSEclose TCP or UDP connectionTCP/IPAT+CIPCLOSE=<id> or AT+CIPCLOSEAT+CIPCLOSE=?
AT+CIFSRGet IP addressTCP/IPAT+CIFSRAT+ CIFSR=?
AT+ CIPMUXset mutiple connectionTCP/IPAT+ CIPMUX=<mode>AT+ CIPMUX?0 for single connection 1 for mutiple connection
AT+ CIPSERVERset as serverTCP/IPAT+ CIPSERVER= <mode>[,<port> ]mode 0 to close server mode, mode 1 to open; port = portturn on as a TCP server: AT+CIPSERVER=1,8888, check the self server IP address: AT+CIFSR=?
+IPDreceived data

To be continued.... ESP8266 동작시키기 2



2015년 1월 26일 월요일

초저가 IoT 플랫폼 - ESP8266

ESP8266은 Espressif systems에서 출시한 Wifi(무선랜) 솔루션이다. ESP8266은 원칩 솔루션으로 SoC 내에 프로세서를 포함해 메모리, wifi controller가 모두 들어있어 최소한의 외부 부품만으로 무선랜 모듈을 구성할 수 있다.



초기에는 Wifi to serial 모듈로 나왔지만 시리얼 포트를 통해 AT 명령어로 GPIO를 제어할수도 있고, 직접 펌웨어 개발을 위한 cross compiler와 라이브러리가 제공되고, 심지어 LUA 인터프리터도 개발되어 매우 쉽게 프로그래밍이 가능해졌다.

그리고 무엇보다 가장 큰 장점은 이렇게 모든게 다 들어있음에도 불구하고 매우 저렴하다는 것이다. Aliexpress에서 모듈이 개당 $2.5~3 정도면 구입이 가능하다. 아두이노에 무선랜 기능을 추가할 때도 cc3000 wifi shield같은것(현재 $20~30)보다 거의 1/10 정도의 가격으로 가능하다.

하지만 제어해야 할 제품에 GPIO가 많이 필요하지 않으면 아두이노나 다른 별도의 프로세서를 사용하지 않고 ESP8266만으로 모든것을 해결할 수 있다. IoT의 특성상 여러 종류의 센서나 액튜에이터를 여러개 설치해야 하는 경우 특히 유용하다.


초기에는 위와 같은 타입의 모듈이었지만 현재는 ESP-01, ESP-07, ESP-12등 다양한 형태의 모듈이 판매되고 있다.

ESP-03

ESP-12


새로 구입을 하려면 ESP-01 보다는 ESP-07, ESP-03, ESP-12등을 구입하는것이 좋다. ESP-01은 브레드보드에 사용하기 쉽지 않다. 각 모듈들은 폼팩터나 커넥터 위치, 안테나 종류(내장형, 칩안테나, 외부 안테나 등)등이 다를 뿐 사용법은 동일하다.

ESP8266의 스펙은 다음과 같다.

Specifications

  • 802.11 b/g/n
  • Wi-Fi Direct (P2P), soft-AP
  • Integrated TCP/IP protocol stack
  • Integrated TR switch, balun, LNA, power amplifier and matching network
  • Integrated PLLs, regulators, DCXO and power management units
  • +19.5dBm output power in 802.11b mode
  • Power down leakage current of <10uA
  • Integrated low power 32-bit CPU could be used as application processor
  • SDIO 1.1/2.0, SPI, UART
  • STBC, 1×1 MIMO, 2×1 MIMO
  • A-MPDU & A-MSDU aggregation & 0.4ms guard interval
  • Wake up and transmit packets in < 2ms
  • Standby power consumption of < 1.0mW (DTIM3)

Power
ModeMinTypicalMaxUnits
802.11b, CCK 1Mbps, POUT=+19.5dBm215mA
802.11b, CCK 11Mbps, POUT=+18.5dBm197mA
802.11g, OFDM 54Mbps, POUT=+16dBm145mA
802.11n, MCS7, POUT =+14dBm135mA
802.11b, packet size of 1024 bytes, -80dBm60mA
802.11b, packet size of 1024 bytes, -70dBm60mA
802.11b, packet size of 1024 bytes, -65dBm62mA
Standby0.9uA
Deep sleep10mA
Saving mode DTIM 11.2mA
Saving mode DTIM 30.86mA
Shutdown0.5uA
RF
DescriptionMinTypicalMaxUnits
Input Frequency24122484MHz
Input resistance50Ω
Input reflection-10dB
At 72.2Mbps, PA output power141516dBm
11b mode, PA output power17.518.519.5dBm
Sensitivity
CCK, 1Mbps -98dBm
CCK, 11Mbps -91dBm
6Mbps (1/2 BPSK) -93dBm
54Mbps (3/4 64-QAM) -75dBm
HT20, MCS7 (65Mbps, 72.2Mbps)  -71dBm
Adjacent suppression
OFDM, 6Mbps37dB
OFDM, 54Mbps21dB
HT20, MCS037dB
HT20, MCS720dB
Digital I/O
VariablesSymbolMinMaxUnits
Input Low VoltageVil-0.30.25xV10V
Input High VoltageVih0.75xV103.6V
Input leakage currentIIL-50nA
Output Low VoltageVOL-0.1xV10V
Output High VoltageVOH0.8xV10-V
Input pin capacitanceCpad-2pF
VDDIOV101.73.6V
CurrentImax-12mA
TemperatureTamb-20100C

ESP8266은 station 모드(즉 공유기에 접속하는 디바이스로 동작) 뿐 아니고 AP 모드(공유기로 동작)도 지원한다. 그리고 UART를 통해 AT 명령어로 칩을 쉽게 제어할 수 있어 복잡한 디바이스 드라이버가 없어도 아두이노등에서 사용하기도 매우 편리하다. 

다음에는 ESP8266 모듈을 PC에 연결해 직접 동작시켜 보도록 하겠다.

2015년 1월 24일 토요일

OSC(Open Sound Control) in Intel Edison - part 2

이전 포스트(OSC(Open Sound Control) in Intel Edison - part 1)에서 에디슨에서 OSC를 사용하기 위해 필요한 liblo, pyliblo를 설치하는 방법을 설명했다.

이제 실제로 OSC를 통해 메시지를 주고받아 보겠다. 여기서는 TouchOSC를 사용했는데 다른 OSC 클라이언트(mrmr 등)를 사용해도 상관없다.


TouchOSC를 실행하면 아래와 같은 설정화면이 뜨게 된다.


여러개의 샘플 레이아웃이 들어있지만 여기서는 Simple 을 사용한다. Connections의 OSC: ... 부분을 클릭해 OSC 서버의 네트웍 정보 (여기서는 에디슨의 네트웍 정보)를 넣어줘야 한다.


에디슨의 Host 에는 무선랜 IP 주소를, Port (outgoing)에는 에디슨에서 실행한 OSC 서버 프로그램 포트번호를 넣어주고 Enable을 On으로 해 주면 된다. 설정을 다 입력했으면 왼쪽 위의 '< TouchOSC' 를 눌러 초기화면으로 돌아간다.


이제 모든 설정이 끝났으니 오른쪽 위의 'Done'을 눌러 Simple 레이아웃 화면으로 넘어간다.

현재 화면에는 5개의 슬라이더(또는 fader)와 4개의 토글 버튼이 있다. 슬라이더를 움직여 값을 바꾸거나 (0.0~1.0), 토글 버튼을 눌러 값을 0.0 또는 1.0으로 바꿔 줄 수 있다. 값에 변화가 생길 때 마다 지정된 OSC 서버에 OSC 메시지가 전송되게 된다.


각 UI들에 해당하는 path는 위와 같이 되어 있다. 즉 왼쪽 아래 버튼을 누르면 '/1/toggle1 1.0', 또 한번 더 누르면  '/1/toggle1 0.0'이란 메시지가 전달된다.

이제 실제 메시지를 확인해 보도록 하겠다. Liblo가 설치되었다면 다음 명령을 실행하고 TouchOSC 화면의 슬라이더를 움직이거나 버튼을 눌러보면 전달되는 메시지가 화면에 출력된다.

# oscdump 9001
/1/fader1 f 0.004219
/1/fader1 f 0.012658
...
/1/fader1 f 0.109705
/1/fader1 f 0.109705
/1/toggle2 f 1.000000
/1/toggle4 f 1.000000
/1/toggle1 f 1.000000
/1/fader5 f 0.011152
...
/1/fader5 f 0.107807
^C


이제 동작하는게 확인되었으니 pyliblo를 사용해 간단한 서버 프로그램을 만들어본다.

# cat svrsimple.py
#!/usr/bin/env python

import liblo, sys

try:
    server = liblo.Server(9001)
except liblo.ServerError, err:
    print str(err)
    sys.exit()

def slide_cb(path, args):
    f = args[0]
    id = int(path.split('fader')[1])
    print "Slider%d moved to %f" % (id, f)
#    print "received message '%s' with arguments '%f'" % (path, f)

def sw_cb(path, args):
    f = args[0]
    sid = int(path.split('toggle')[1])
    if f == 0.0:
      print "SW%d turned OFF" % sid
    else:
      print "SW%d turned ON" % sid

def fallback(path, args, types, src):
    print "got unknown message '%s' from '%s'" % (path, src.url)
    for a, t in zip(args, types):
        print "argument of type '%s': %s" % (t, a)

# register method taking an int and a float
server.add_method("/1/fader1", 'f', slide_cb)
server.add_method("/1/fader2", 'f', slide_cb)
server.add_method("/1/fader3", 'f', slide_cb)
server.add_method("/1/fader4", 'f', slide_cb)
server.add_method("/1/fader5", 'f', slide_cb)

server.add_method("/1/toggle1", 'f', sw_cb)
server.add_method("/1/toggle2", 'f', sw_cb)
server.add_method("/1/toggle3", 'f', sw_cb)
server.add_method("/1/toggle4", 'f', sw_cb)
# register a fallback for unhandled messages
server.add_method(None, None, fallback)

# loop and dispatch messages every 100ms
while True:

    server.recv(100)
# chmod +x svrsimple.py
# ./svrsimple.py
Slider1 moved to 0.831224
Slider1 moved to 0.789030
Slider1 moved to 0.767932
...
SW1 turned ON
SW4 turned ON
SW3 turned ON
SW2 turned ON
SW3 turned OFF
Slider5 moved to 0.724907
Slider5 moved to 0.736059
Slider5 moved to 0.747212
^C
#

이제 mraa 라이브러리를 사용하고 slide_cb, sw_cb의 코드를 수정하면 에디슨에 연결된 LED의 밝기나 모터의 속도 제어, 가전제품의 ON/OFF 등을 스마트폰에서 바로 제어가 가능해진다.



2015년 1월 22일 목요일

에디슨이 갑자기 이상동작을 할 때 해결책

에디슨을 사용하다 보면 어느 순간 갑자기 보드가 이상한 동작들을 하는 경험을 하게 된다. 무선랜에 정상 연결 되었는데도 ping google.com 같은 명령도 실행이 안되고, 아두이노 IDE나 XDK에서 프로그램을 업로드 하려고 해도 이상한 에러가 나는 등의 증상이 발생한다.
이 경우 원인은 journal log 때문이다.

# df
Filesystem           1K-blocks      Used Available Use% Mounted on
/dev/root               475080    358764     79620  82% /
devtmpfs                491736         0    491736   0% /dev
tmpfs                   492048         0    492048   0% /dev/shm
tmpfs                   492048       496    491552   0% /run
tmpfs                   492048         0    492048   0% /sys/fs/cgroup
tmpfs                   492048       496    491552   0% /etc/machine-id
systemd-1                 5638      5184       454  92% /boot
tmpfs                   492048        56    491992   0% /tmp
systemd-1              2337308     96656   2224268   4% /home
tmpfs                   492048         0    492048   0% /var/volatile
/dev/mmcblk0p5            1003        19       913   2% /factory
/dev/mmcblk0p10        2337308     96656   2224268   4% /home
/dev/mmcblk0p7            5638      5184       454  92% /boot

위의 결과를 보면 알겠지만 루트 파티션 (/)이 약 470MB 정도인데 시스템 파일들을 제외하면 여유 공간은 80MB가 채 안되는데 불구하고 journal log가 기록되는 /var 디렉토리가 루트 파티션에 있다. 그런데 journal log는 약 10~11초 간격으로 471bytes를 기록하다 보니 약 하루 반 정도면 80MB가 다 차 버리게 되는 것이다.
루트 파티션이 full이 되어 여유 공간이 없으면 위에서 말한 이상한 현상들이 발생하게 된다.
해결책은 일단 로그 파일을 다 지워 루트 파티션에 빈 공간을 만들어 주면 된다.

# cd /var/log/journal
# rm -r *

하지만 이렇게 해도 다시 시간이 지나면 또 동일한 현상이 발생하게 된다.

그래서 이 문제가 반복적으로 발생하는걸 방지하려면 로그 자체를 꺼 버리거나 로그파일의 최대 크기를 제한해 주는 방법이 있다.

# cat /etc/systemd/journald.conf
...
#RateLimitInterval=30s
#RateLimitBurst=1000
#SystemMaxUse=
#SystemKeepFree=
#SystemMaxFileSize=
...
#MaxLevelWall=emerg

/etc/systemd/journald.conf 파일의 내용중 '#SystemMaxUse=' 부분에서  맨 앞의 '#'을 빼고 저널 로그의 최대 크기를 지정해주면 된다. 즉 'SystemMaxUse=20M'로 바꿔주면 저녈 로그로 최대 20MB만 사용하게 되므로 루트 파티션이 full이 되는걸 방지할 수 있다.

아니면 아예 저널 로그 기능을 꺼 버릴수도 있다.

# systemctl disable edison_config
rm '/etc/systemd/system/default.target.wants/edison_config.service'

로그 기능을 껐어도 지금까지 만들어 진 로그파일은 남아 있으므로 위에서처럼 /var/log/journal 디렉토리 내의 내용을 삭제해준다. (디렉토리 안의 내용은 삭제해도 /var/log/journal 디렉토리는 삭제하면 안된다)




에디슨에서 부팅할 때 원하는 프로그램을 실행시키기

시스템이 시작할 때 스크립트를 실행하는데는 몇가지 방법이 있다. 하지만 Edison에서 가장 쉬운 방법은 /etc/init.d 디렉토리를 사용하는 것이다. 

만일 init.d를 처음 사용하는 것이면 먼저 이 디렉토리를 만들어야 한다.

$ cd /etc
$ mkdir init.d

이제 만들어 진 디렉토리로 이동한다.

$ cd init.d

다음은 부팅하면서 실행할 명령들이 들어있는 bash 스크립트 파일을 만들어 주는 것이다. 여기서는 edison의 wifi 설정을 자동화하는 스크립트를 예로 해 보겠다. 텍스트에디터를 열어 wifi.sh 라는 이름으로 파일을 만들어 준다.

$ vi wifi.sh

파일에는 다음의 내용이 들어가야 한다.

#!/bin/sh

wpa_supplicant -B -Dnl80211 -iwlan0 -c/etc/wpa_supplicant/wpa_supplicant.conf
busybox udhcpc -i wlan0

내용을 저장하고 에디터를 종료했으면 chmod 명령으로 이 파일이 실행 가능하도록 해 줘야 한다.

$ chmod a+x wifi.sh

이 단계에서 스크립트가 정상 동작하는지 먼저 확인해 보는것이 좋다. 스크립트를 실행하고 출력이 아래와 같이 나오는지 확인한다. 

$ ./wifi.sh
Successfully initialized wpa_supplicant
udhcpc (v1.22.1) started
Sending discover...
Sending discover...
Sending discover...
Sending select for 192.168.0.34...
Lease of 192.168.0.34 obtained, lease time 86400
/etc/udhcpc.d/50default: Adding DNS 192.168.0.1
/etc/udhcpc.d/50default: Adding DNS 205.171.2.25

스크립트가 정상 실행되는걸 확인했으면, 실제로 google을 ping 해 동작을 확인해 본다. 

$ ping google.com
PING google.com (74.125.224.40): 56 bytes
64 bytes from 74.125.224.40: seq=0 ttl=57 time=43.711 ms
64 bytes from 74.125.224.40: seq=1 ttl=57 time=60.668 ms
^C
— google.com ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 43.711/52.189/60.668 ms

위와 같이 나오면 모든것이 정상 동작하는 것이다.

이제 이 스크립트가 linux가 부팅할 때 마다 매번 자동 실행되게 해 주기 위해 아래의 명령을 실행하고 아래와 같은 출력이 나오는걸 기다린다.

$ update-rc.d wifi.sh defaults
Adding system startup for /etc/init.d/wifi.sh

기본적으로 위의 명령은 스크립트에 대해 디폴트 rc.d 디렉토리 0~6에 심볼릭 링크를 만들어 준다. 생성된 디렉토리는 아래 명령으로 확인해 볼 수 있다.

$ ls -l /etc/rc?.d/*wifi*
lrwxrwxrwx    1 root    root     17 Sep 10 19:29  /etc/rc0.d/K20wifi.sh -> ../init.d/wifi.sh
lrwxrwxrwx    1 root    root     17 Sep 10 19:29  /etc/rc0.d/K20wifi.sh -> ../init.d/wifi.sh
lrwxrwxrwx    1 root    root     17 Sep 10 19:29  /etc/rc0.d/S20wifi.sh -> ../init.d/wifi.sh
lrwxrwxrwx    1 root    root     17 Sep 10 19:29  /etc/rc0.d/S20wifi.sh -> ../init.d/wifi.sh
lrwxrwxrwx    1 root    root     17 Sep 10 19:29  /etc/rc0.d/S20wifi.sh -> ../init.d/wifi.sh
lrwxrwxrwx    1 root    root     17 Sep 10 19:29  /etc/rc0.d/S20wifi.sh -> ../init.d/wifi.sh
lrwxrwxrwx    1 root    root     17 Sep 10 19:29  /etc/rc0.d/K20wifi.sh -> ../init.d/wifi.sh

디폴트로 0, 1, 6 디렉토리는 kill 동작을 위해 예약되어 있기 때문에 심볼릭 링크의 이름이 “K”로 시작한다. 이와 유사하게 2, 3, 4, 5 디렉토리는 start 동작을 위해 예약되어 있기 때문에 “S”로 시작한다. S 또는 K 뒤의 20이라는 숫자는 프로세스 hierachy를 정의한다. 20보다 작은 숫자를 가진 프로세스는 이 프로세스보다 먼저 시작되고 20보다 큰 숫자를 가진 프로세스는 이 프로세스 이후에 실행된다. 참고로 init.d 스크립트는 커널 부팅 과정중에 가장 마지막으로 실행된다. 부팅 순서에 관한 자세한 내용은 여기를 참고하면 된다.

모든것이 확인되었으면 시스템을 리부팅해서 정상동작 하는지 확인해본다.

$ reboot

Connection to 192.168.2.15 closed by remote host.

Connection to 192.168.2.15 closed.

잠시 기다린 후 다시 ssh로 연결한다.

$ ssh root@192.168.2.15

무선랜을 통해 ssh로 연결했으면 더 이상 확인할 필요 없이 정상동작 하는 것이고, 만일 dongle을 통해 ssh로 연결했으면 wpa_supplicant가 프로세스로 실행되고 있는지 확인해야 한다.


그리고 google.com으로 ping을 해 본다. 

$ ping google.com
PING google.com (74.125.224.40): 56 bytes
64 bytes from 74.125.224.40: seq=0 ttl=57 time=32.892 ms
64 bytes from 74.125.224.40: seq=1 ttl=57 time=47.575 ms
^C
— google.com ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 32.892/40.233/47.575 ms

여기까지 되었다면 모든것이 완료된 것이다.