레이블이 Intel인 게시물을 표시합니다. 모든 게시물 표시
레이블이 Intel인 게시물을 표시합니다. 모든 게시물 표시

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

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













에디슨에서 아두이노 스케치 지우기

Arduino IDE로 스케치를 작성해 에디슨에서 실행하면 이 스케치는 에디슨을 재부팅 해도 매번 자동으로 실행되어 버리기 때문에 추후 eclipse나 node.js에서 프로그램을 작성해 실행을 하면 GPIO 포트등을 사용하는데 충돌이 나기 쉽다.

예를 들어 먼저 Arduino에서 아래의 스케치를 에디슨에 업로드한다.



void setup()
{
  pinMode(13, OUTPUT);
}

void loop()
{
  digitalWrite(13, HIGH);
  delay(500);
  digitalWrite(13, LOW);
  delay(500);
}



이 스케치가 실행되면 LED가 깜빡이게 될 것이다. 하지만 이후 보드를 리부팅 한 후 다음의 명령을 입력해 보자.

# python
>>> import mraa
>>> led13 = mraa.Gpio(13)
>>> led13.dir(mraa.DIR_OUT)
>>> led13.write(0)

이렇게 하면 LED는 꺼져야 하지만 이전에 설치되어 있는 아두이노 스케치 때문에 LED는 계속 깜빡이고 있게 된다.

에디슨에서 아두이노 스케치는 독립적으로 실행되는 프로세스로 구현되어 있다. 그러므로 이 문제의 해결책으로 첫번째는 빈 스케치를 업로드 해 주는 것이다.



void setup()
{
}

void loop()
{
}

위의 스케치를 업로드 해 주면 된다. 하지만 이 경우 아무 일도 하지 않는 loop() 함수를 무한 호출하게 되어 비효율적이다.

다른 방법으로는 에디슨에 업로드 되어 있는 스케치 프로세스 파일을 아예 삭제해 부팅시 프로세스가 만들어 지지 않게 해 버리는 것이다.

# cd /sketch
# ls
sketch.elf      sketch.elf.old

/sketch 디렉토리에 보면 sketch.elf 파일이 들어있다. 이 파일이 arduino IDE에서 컴파일 한 후 업로드 한 것이다. 이 파일이 부팅될 때마다 자동으로 실행되게 되기 때문에 이 파일을 삭제해 주면 다음번에 재부팅 할 때는 스케치가 실행되지 않게 된다.

# rm sketch.elf

하지만 이 파일을 삭제해도 이미 프로세스로 실행되고 있는 스케치는 종료되지 않는다. 현재 실행되고 있는 스케치 프로세스를 삭제하려면 다음 명령을 입력해주면 된다.

# ps | grep sketch
  173 root     19824 S    /sketch/sketch.elf /dev/pts/0
  175 root      1792 S    /opt/edison/sketch_reset -i 207 -o 215 -s /opt/ediso
  510 root      2420 S    grep sketch
# kill -9 173

(위에서 173, 175, 510 같이 줄의 맨 앞에 있는 숫자는 매번 다르게 나올 것이다. 'kill -9 173'에서 173 대신 /sketch/sketch.elf /dev/pts/0 줄의 맨 앞에 있는 숫자로 바꿔줘야 한다. )

이제 실행되고 있던 스케치 프로세스가 종료되어 LED의 깜빡임이 멈춘걸 확인할 수 있을 것이다.

Edison을 iBeacon으로 사용하기

인텔 에디슨 보드에는 블루투스 모듈이 기본으로 들어있기 때문에 에디슨을 iBeacon 발신기로 사용할 수 있다.

디폴트로 에디슨에는 블루투스가 비활성화 되어 있다.

# rfkill list
0: phy0: wlan
        Soft blocked: no
        Hard blocked: no
1: brcmfmac-wifi: wlan
        Soft blocked: no
        Hard blocked: no
2: bcm43xx Bluetooth: bluetooth
        Soft blocked: yes
        Hard blocked: no

그러므로 먼저 블루투스를 활성화 시켜줘야 한다.

# rfkill unblock bluetooth
# hciconfig hci0 up
# rfkill list
0: phy0: wlan
        Soft blocked: no
        Hard blocked: no
1: brcmfmac-wifi: wlan
        Soft blocked: no
        Hard blocked: no
2: bcm43xx Bluetooth: bluetooth
        Soft blocked: no
        Hard blocked: no
3: hci0: bluetooth
        Soft blocked: no
        Hard blocked: no

블루투스가 활성화 되고 hci0 인터페이스가 만들어진걸 볼 수 있다.

이제 패키지를 추가 설치 해 줘야 한다. 먼저 /etc/opkg/base-feeds.conf 파일을 에디터에서 오픈한 다음 아래 내용을 추가한 다음 저장해준다.

src/gz all http://repo.opkg.net/edison/repo/all
src/gz edison http://repo.opkg.net/edison/repo/edison
src/gz core2-32 http://repo.opkg.net/edison/repo/core2-32

추가한 내용을 저장했으면 아래 명령으로 opkg를 업데이트 한 후 필요한 패키지를 설치해 준다.

# opkg update
# opkg install bluez5-dev
# npm install -g async
# npm install noble
# npm install bleno

여기까지 진행했으면 에디슨을 iBeacon 발신기로 설정하는데 필요한 모든 준비가 끝난 것이다.

이제 실제 iBeacon으로 동작시켜 보겠다.

# node
> bleno = require('bleno')
{ state: 'unknown',
...
        rssiUpdate: [Function] } } }
> bleno.startAdvertisingIBeacon('e2c56db5dffb48d2b060d0f5a71096e0', 0, 0, -59);
undefined
>

에디슨은 UUID e2c56db5-dffb-48d2-b060-d0f5a71096e0, Major 0, Minor 0인 iBeacon 으로 동작하고 있다.

실제 동작하고 있는지 확인해 보도록 하겠다. 여기서는 아이폰에서 Locate 라는 앱을 사용하지만 iBeacon을 검색할 수 있는 앱이면 아무거나 상관 없다.


Locate 앱을 실행했을 때 초기화면이다.


여기서 Locate iBeacons 를 선택한다.


위의 화면은 이미 iBeacon UUID를 설정해 놓았기 때문에 Apple AirLocate .... 라는 항목이 보이지만 기본적으로는 보이는 beacon이 없을 것이다. 먼저 에디슨 beacon 정보를 설정해줘야 하기 때문에 Tap here to configure visible iBeacon UUIDs. 를 선택한다.


이런 목록이 나오면 우측 상단의 '+' 버튼을 눌러 새 항목을 추가한다. (위의 화면은 이미 설정을 해 놓은 상태라 Edison beacon 같은 항목이 보이고 있다)


여기에 자신의 에디슨 beacon 정보를 넣어주면 된다.

bleno.startAdvertisingIBeacon('e2c56db5dffb48d2b060d0f5a71096e0', 0, 0, -59); 에서 파라미터는 순서대로 UUID, Major, Minor, RSSI이므로 각각의 값을 제 위치에 넣어주면 된다. 저장하고 나와서 확인해 보면 이제 자신의 에디슨 iBeacon이 목록에 보일 것이다.


목록에서 Apple AirLocate E2C56DB5 를 선택하면 그에 대한 상세한 정보를 확인할 수 있다.



2015년 1월 21일 수요일

맥에서 에디슨을 쉽게 사용하자. BLOOP!

Bloop은 맥에서 인텔 에디슨 보드를 사용한다면 좀 더 쉽게 사용할 수 있게 해 주는 유틸리티이다.

시리얼포트로 콘솔에 접속하려면 screen /dev/cu.usbserial-XXXXX 115200 -L 같은 식으로 긴 명령을 입력해 줘야 하고 device 이름이 길기 때문에 매번 확인해야 하기 쉽상이다. 그리고 ssh로 연결하거나 에디슨 보드로 파일을 복사할 때도 커맨드 라인에서 명령을 입력하려면 여러모로 귀찮다. bloop을 이용하면 이런 작업들을 짧은 명령으로 쉽게 사용할 수 있다.

맥에서 bloop을 설치하려면 터미널 창에서 다음 명령을 입력하면 된다.

$ sudo npm install -g bloop

bloop에서 사용할 수 있는 명령은 다음과 같다.


  • bloop c - 시리얼포트로 콘솔에 연결해준다. 'screen /dev/cu.usbserial.XXXXX 115200 -L'과 동일한 기능을 함
  • bloop list - USB serial을 통해 연결되어 있는 에디슨 보드 목록을 출력한다.
  • bloop scan - 로컬 네트웍에 연결되어 있는 에디슨 보드 목록을 출력한다. 로컬 네트웍에 여러대의 에디슨이 있으면 첫번째 발견된 보드만 출력해 준다. 만일 전체 목록을 다 보고 싶으면 '-r' 옵션을 붙이면 된다.
  • bloop ssh - 로컬 네트웍에 연결되어 있는 에디슨 보드에 ssh로 연결해 준다. 로컬 네트웍에 여려대의 에디슨이 연결되어 있는 경우 '-e' 옵션으로 보드를 지정할 수 있다. ssh연결에 디폴트로는 root 계정으로 연결하도록 되어 있는데 만일 다른 계정으로 접속하려고 하면 '-u' 옵션을 사용하면 된다.
  • bloop push - 현재 디렉토리의 내용을 에디슨의 ~/node_app_slot/ 디렉토리에 복사한다. 여기도 bloop ssh와 동일하게 '-e', '-u' 옵션을 사용할 수 있다.
  • bloop clean - bloop c를 사용하는 경우 screen 프로세스가 떨어져 재접속 하려고 할 때 "Could not find a PTY"나 "Resource Busy" 에러가 나는 경우가 있다. 이럴때 bloop clean 명령을 내리면 떨어져 나간 세션을 전부 삭제해 bloop c로 다시 접속할 수 있게 해 준다. 또는  'bloop c -f' 명령을 내리면 bloop clean + bloop c 와 같은 효과를 낸다.

Python으로 Intel Edison의 GPIO를 제어하기

여러가지 라이브러리가 있지만 libmraa가 에디슨에 이미 설치가 되어 있으므로 mraa를 사용하는것이 가장 편하다.

# python
Python 2.7.3 (default, Oct  9 2014, 11:20:30)
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import mraa
>>> mraa.getVersion()
'v0.4.4'
>>> 

사용법은 아주 간단하고 API에 대한 문서는 다음 링크에서 볼 수 있다.

http://iotdk.intel.com/docs/master/mraa/python/mraa.html

Digital I/O


디지털 입출력 핀을 사용하려면 Gpio 클래스 오브젝트를 만든 다음 입력으로 사용할지, 출력으로 사용할지를 dir() 메소드로 지정해주면 된다. 

Ex1) Digital 13번 핀을 출력으로 사용하고자 하는 경우
>>> led = mraa.Gpio(13)        # Gpio object 생성
>>> led.dir(mraa.DIR_OUT)  # 출력으로 설정

Ex2) Digital 4번 핀을 입력으로 사용하고자 하는 경우
>>> sw = mraa.Gpio(4)           # Gpio object 생성
>>> sw.dir(mraa.DIR_IN)       # 입력으로 설정

출력으로 설정된 경우 출력값을 변경할 때는 write() 메소드를 사용하고, 입력으로 설정된 경우 상태값을 읽으려면 read() 메소드를 사용하면 된다.

Ex3) 13번 핀에 연결되어 있는 led를 on/off
>>> led.write(1)      # LED On
>>> led.write(0)      # LED off



Ex4) 4번핀에 연결되어 있는 스위치의 상태를 읽기



>>> sw.read()          # SW 상태 읽기
0

즉 blink.py란 파일을 만들어 다음의 내용을 넣고 실행하면 에디슨 보드에 붙어 있는 LED가 0.5초 간격으로 깜빡이는걸 확인할 수 있을 것이다.

# cat blink.py
import mraa
import time

led = mraa.Gpio(13)
led.dir(mraa.DIR_OUT)

while 1:
  led.write(1)
  time.sleep(0.5)
  led.write(0)
  time.sleep(0.5)
# python blink.py
^CTraceback (most recent call last):
  File "blink.py", line 9, in <module>
    time.sleep(0.5)
KeyboardInterrupt
#

프로그램의 실행을 중단하려면 Ctrl-C를 누르면 된다. 

Gpio핀이 입력으로 설정된 경우 인터럽트를 사용할 수도 있다. 이 경우 언제 인터럽트가 발생할지를 mode로 결정할 수 있다. (mraa.EDGE_BOTH, mraa.EDGE_RISING, mraa.EDGE_FALLING) 인터럽트가 발생하면 지정된 처리함수(ISR)가 자동으로 호출된다. 

아래와 같은 예제 코드를 실행하면 4번 핀에 연결되어 있는 버튼을 누르거나 뗄 때마다 화면에 'wooo'라는 글자가 출력된다. 즉 버튼을 한번 눌러주면 wooo가 두번 출력되게 된다. (눌려질 때 한번, 누른 손을 뗄 때 한번)

# cat intr.py
import mraa
import time

class Counter:
  count = 0

c = Counter()

# inside a python interupt you cannot use 'basic' types so you'll need to use objects
def test(args):
  print("wooo")
  c.count+=1

x = mraa.Gpio(4)
x.dir(mraa.DIR_IN)
x.isr(mraa.EDGE_BOTH, test, test)

time.sleep(500)
# python intr.py
wooo
wooo
^CTraceback (most recent call last):
  File "intr.py", line 19, in <module>
    time.sleep(500)
KeyboardInterrupt
#

단, 주의할 것은 파이선의 ISR(여기서는 test() 함수) 내에서는 기본 타입(int, boolean 등)의 변수를 사용할 수가 없다. 그래서 위의 예제에서도 오브젝트를 사용하고 있다.

Analog Input

온도센서나 조도센서같이 물리량을 전압값으로 변환해주는 센서를 사용하는 경우 ADC(Analog-to-Digital Converter)를 사용해 전압값을 읽으면 된다. 이 때는 Aio 클래스 오브젝트를 만들어 준 다음 read() 메소드로 값을 읽으면 되기 때문에 사용하기가 매우 간편하다. 

Ex5) 조도센서가 Analog In 0에 연결되어 있는 경우



>>> brightness = mraa.Aio(0)       # Aio object 생성
>>> brightness.read()              # 조도센서의 전압값 읽기

Analog Output (PWM)

에디슨에 DAC(Digital-to-Analog Converter)는 없지만 PWM(Pulse Width Modulation)을 이용해 DAC와 유사한 효과를 낼 수 있다. 이 경우 Pwm 클래스 오브젝트를 만들어 준 다음 write() 메소드를 사용해 듀티비(duty ratio)를 조정할 수 있다. 듀티비는 0~1 사이의 부동소수점 값을 사용한다. Pwm는 오브젝트가 만들어진다고 바로 출력이 나오지 않으므로 enable() 메소드로 활성화를 시켜줘야 한다. 

Ex6) 9번핀에 연결된 LED의 밝기 조절



>>> led1 = mraa.Pwm(9)
>>> led1.period_us(700)
>>> led1.enable(True)
>>> led1.write(0)
>>> led1.write(0.5)
>>> led1.write(1)

다음의 예제코드를 실행해 보면 LED가 서서히 밝아졌다가 꺼지고 다시 서서히 밝아지는걸 반복하는걸 확인할 수 있을 것이다.

# cat pwmdemo.py
import mraa
import time

x = mraa.Pwm(9)
x.period_us(700)
x.enable(True)
value= 0.0

while True:
    x.write(value)
    time.sleep(0.05)
    value = value + 0.01
    if value >= 1:
        value = 0.0
# python pwmdemo.py







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

인텔 에디슨을 OSC 프로토콜을 사용해 스마트폰이나 PC, 또는 다른 에디슨에서 제어해 보도록 하겠다. 스마트폰에서는 Mrmr, TouchOSC, Control (OSC+MIDI)같은 앱을 사용하면 된다.

먼저 에디슨에 OSC 라이브러리를 설치한다. 여러 종류가 있지만 여기서는 liblo를 사용한다.  Liblo는 Steve Harris가 만든 경량 OSC 라이브러리로 LGPL을 따르기 때문에 추후 제품 개발에 사용하더라도 저작권 문제가 없다.

http://liblo.sourceforge.net/

먼저 liblo를 다운받는다. 여러가지 방법이 있지만 git를 사용해 클론을 하는게 편하다.

# git clone git://liblo.git.sourceforge.net/gitroot/liblo/liblo
Cloning into 'liblo'...
remote: Counting objects: 2561, done.
remote: Compressing objects: 100% (1218/1218), done.
remote: Total 2561 (delta 2001), reused 1657 (delta 1341)
Receiving objects: 100% (2561/2561), 663.60 KiB | 104.00 KiB/s, done.
Resolving deltas: 100% (2001/2001), done.
Checking connectivity... done.
#

만일 위와 같은 출력 대신 git가 설치되어 있지 않다는 에러가 나오면 (초기 상태는 git가 설치되어 있지 않음) 먼저 아래 명령으로 git를 설치하고 다시 위의 명령을 입력해 주면 된다.

# opkg install git

git clone이 정상적으로 실행되었으면 현재 디렉토리에 liblo라는 디렉토리가 만들어 졌을 것이다. 소스코드 다운로드가 된 것이므로 라이브러리를 빌드한다.

# cd liblo
# ./autogen.sh
'README' -> 'README.MD'
...
Now type 'make' to compile.
# make
...
# make install
...
# 

여기까지 에러가 없이 진행되었다면 라이브러리가 빌드되어 정상적으로 설치 된 것이다. 다만 라이브러리가 설치된 위치가 /usr/lib가 아니고 /usr/local/lib이므로 라이브러리를 검색할 디렉토리를 설정해 주는것이 편하다. 먼저 텍스트 에디터로 /etc/ld.so.conf 파일을 열어보면 파일 내용이 비어있는데 아래의 내용을 추가하고 저장한다.

# vi /etc/ld.so.conf

/lib
/usr/lib
/usr/local/lib

ld.so.conf 파일을 수정했으면 다음의 명령을 입력해 준다.

# ldconfig

이것으로 liblo 라이브러리 설치가 완전히 끝났다. 라이브러리 뿐 아니고 이 라이브러리를 사용하는 기본 툴(oscdump, oscsend)도 함께 설치되어 있어 이 툴들을 이용하면 임의의 OSC 메시지를 보내거나 메시지를 받아 내용을 화면에 출력할 수 있다.

# oscdump
oscdump version 0.28
Copyright (C) 2008 Kentaro Fukuchi

Usage: oscdump <port>
or     oscdump <url>
Receive OpenSound Control messages and dump to standard output.

Description
port    : specifies the listening port number.
url     : specifies the server parameters using a liblo URL.
          e.g. UDP        "osc.udp://:9000"
               Multicast  "osc.udp://224.0.1.9:9000"
               TCP        "osc.tcp://:9000"

# oscsend
oscsend version 0.28
Copyright (C) 2008 Kentaro Fukuchi

Usage: oscsend hostname port address types values...
or     oscsend url address types values...
Send OpenSound Control message via UDP.

Description
hostname: specifies the remote host's name.
port    : specifies the port number to connect to the remote host.
url     : specifies the destination parameters using a liblo URL.
          e.g. UDP        "osc.udp://localhost:9000"
               Multicast  "osc.udp://224.0.1.9:9000"
               TCP        "osc.tcp://localhost:9000"

address : the OSC address where the message to be sent.
types   : specifies the types of the following values.
          i - 32bit integer
          h - 64bit integer
          f - 32bit floating point number
          d - 64bit (double) floating point number
          s - string
          S - symbol
          c - char
          m - 4 byte midi packet (8 digits hexadecimal)
          T - TRUE (no value required)
          F - FALSE (no value required)
          N - NIL (no value required)
          I - INFINITUM (no value required)
values  : space separated values.

Example
$ oscsend localhost 7777 /sample/address iTfs 1 3.14 hello
#

examples 디렉토리에는 이 라이브러리를 사용한 c와 c++ 예제 프로그램들을 찾아볼 수 있다.

C나 C++로 개발을 하는 경우는 이걸로 충분하고 파이선을 사용하고 싶으면 python wrapper를 설치해줘야 한다. 여기서는 pyliblo를 사용한다.

# wget http://das.nasophon.de/download/pyliblo-0.9.2.tar.gz
--2015-01-21 00:42:04--  http://das.nasophon.de/download/pyliblo-0.9.2.tar.gz
Resolving das.nasophon.de... 83.151.28.113
Connecting to das.nasophon.de|83.151.28.113|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 100079 (98K) [application/x-gzip]
Saving to: 'pyliblo-0.9.2.tar.gz'

100%[======================================>] 100,079     43.4KB/s   in 2.3s

2015-01-21 00:42:08 (43.4 KB/s) - 'pyliblo-0.9.2.tar.gz' saved [100079/100079]

# tar zxvf pyliblo-0.9.2.tar.gz
pyliblo-0.9.2/
...
pyliblo-0.9.2/COPYING
# cd pyliblo-0.9.2
# ./setup.py build
...
# ./setup.py install
...
# 

여기까지 에러 없이 진행되면 pyliblo도 정상 설치가 된 것이다. Pyliblo를 사용한 간단한 예제 코드는 홈페이지(http://das.nasophon.de/pyliblo/examples.html)에서 찾을 수 있다. 

다음번에는 실제로 스마트폰에서 OSC 프로토콜을 사용해 에디슨의 하드웨어를 직접 제어하도록 해 보겠다.

OSC in Intel Edison - Part 2