2015년 1월 21일 수요일

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







댓글 1개:

  1. 글 잘보았습니다. 궁금한점이 있어서 댓글남깁니다.
    제가 Sparkfun 보드를 이용해서 라인트레이서를 인텔에디슨으로 만드려고하는데 아두이노보드처럼 GPIO랑 PWM이 같이 있는게 아니라 하나하나 나눠져 있어서요. 그리고 이거는 PWM보드를 사용안하고 DC모터 제어를 위한 Dual H-bridge라는 블락을 사용하는데 여기에는 핀번호가 없고 그냥 A0A1,B0B1이렇게만 되있어서요.. 혹시 모터를 움직이려면 어떻게 프로그램을 짜야되는지 혹시 아시나해서요.. 답변 좀 부탁드립니다ㅠㅠ

    답글삭제