i2c에서 통신은 프로토콜 특성상 항상 마스터에서 요구하며. 마스터에서 전송할 때도 그렇고 슬레이브에서 읽어올 때도 마스터에서 먼저 요구하면 슬레이브에서 그 요구를 받아서 데이터를 전송한다.


 아두이노의 Wire라이브러리를 이용하면 Wire.onReceive() 함수와 Wire.onRequest() 함수를 이용하여 핸들러 함수를 등록해야 한다.


Wire.onReceive( _onReceive ); #데이터를 받는다.
Wire.onRequest( _onRequest ); #데이터를 보낸다.

smbus의 관련함수들은 다음과 같다.


read_i2c_block_data(addr, cmd [, length] )
write_i2c_block_data(addr, cmd, lst)

smbus의 write_2ic_block_data() 함수는 다음과 같이 데이터를 전송하기 위해서 _onReceive()함수를 호출하게 된다. 전송되는 데이터의 첫 바이트가 cmd라는 것을 유의해야 한다. _onReceive( len)함수의 인수도 cmd까지 고려한 길이가 인수로 넘어간다.


cmd

lst[0]

lst[1]

...

lst[-1]


 그런데 smbus의 read_2ic_block_data()함수는 cmd 한 바이트를 먼저 전송한 후 데이터를 읽는다. 즉, 실제 동작은 _onReceive()함수가 먼저 호출되고 그 다음 _onRequest()함수를 호출한다. 따라서 예를 들면 아두이노의 핸들러 함수는 다음과 같이 작성해야 한다.


byte _cmd_i2c;
byte _rcvBuf[32];

void _onReceive(int count) {
   _cmd_i2c = Wire.read(); // 첫 바이트는 *항상* command

   //만약 smbus.read_i2c_block_data()호출이라면 여기서 종료되고
   //바로 _onRequest() 함수가 호출된다.
   if (count > 1) {
       _rcvBuf[0] = _cmd_i2c;
       _idx = 1;
       while(Wire.available())
           _rcvBuf[_idx++] = Wire.read();
   }
}

void _HRP_::_onRequest() {
   switch(_cmd_i2c) {
       // _cmd_i2c 에 따라 해당 데이터를 전
   }
}

위와 같이 작성하면 master에서 전송된 데이터는 command까지 포함해서 모두 _rcvBuf 배열에 저장되고 데이터를 전송하는 경우에는 _cmd_i2c 변수의 내용에 따라 각기 다른 데이터를 전송할 수 있다.

n{rp005}


'연구 > Ardpy' 카테고리의 다른 글

Ardpy API reference  (0) 2016.10.23
Ardpy examples  (0) 2016.10.23
Ardpy setup  (0) 2016.10.23
About Ardpy  (0) 2016.10.23
ardpy 개발 동기  (0) 2016.05.02
Posted by 살레시오
,

여기에서는 LED를 켜고 끄는 실험을 해 보도록 한다. LED는 파이썬 코드가 GPIO를 동작시키는 것을 시각적으로 확인할 수 있는 가장 간단한 도구이다. 다음 그림과 같이 LED를 저항과 직결한 뒤 12번 핀에 연결한다. 저항은 200Ω (혹은 그 이상) 이고 이것은 LED에 과전류가 흐르는 것을 막아주는 역할을 한다. LED는 극성이 있는 소자이다. 다리가 긴 쪽이 anode(+극), 짧은 쪽이 cathod(-극)이므로 연결할 때 방향을 주의해야 한다. 잘못 연결하면 LED가 켜지지 않는다. 짧은 다리는 저항과 직결하여 6번 핀(GND)에 연결하고 긴 쪽은 12번 핀과 연결하면 된다.


그림 9.2.1 LED 결선도 (긴 다리를 12번 핀에 연결)


 GPIO핀으로 LED를 제어하기 위해서 이 핀을 먼저 GPIO.setup()를 이용하여 출력으로 설정해야 한다. 그 이후에 GPIO.output()함수로 GPIO.HIGH 신호를 내보내면 LED가 켜지고 GPIO.LOW 신호를 내보내면 LED가 꺼진다.


blink.py

import RPi.GPIO as GPIO
import time

led = 12
GPIO.setmode(GPIO.BOARD)
GPIO.setup(led, GPIO.OUT)

for k in range(10):
   GPIO.output(led, GPIO.HIGH)
   time.sleep(0.5)
   GPIO.output(led, GPIO.LOW)
   time.sleep(0.5)

GPIO.cleanup()


이 프로그램은 LED를 10번 점멸시키고 난 뒤 종료된다. 이것을 실행하려면 다음과 같이 하면 된다.


sudo python3 blink.py


전에 언급한 바와 같이 반드시 앞에 sudo 명령을 붙여야 한다는 것이 유의하자.


 한 가지 언급할 것은 저항 값을 선택하는 방법이다. 데이터 쉬트에 의하면 LED에는 10mA 정도 흐르도록 하면 되고 이때 LED의 전압 강하가 1.7V 정도이다. 따라서 오옴의 법칙에 의해서 R = (3.3-1.7)/0.01 = 160Ω  을 얻을 수 있다. 이 결과로부터 160Ω 이상의 저항을 선택하되 너무 저항 값이 크면 불빛을 눈으로 확인하기 어려우므로 160~500Ω 범위의 저항을 선택하면 된다.

원문링크

Posted by 살레시오
,

 라즈베리파이 2에는 40개의 헤더 핀(header pin)이 있는데 이것을 외부의 장치들을 연결하여  제어할 수 있다. 다음 그림에 그 구조를 도시하였다.



BCM

핀 번호

BOARD

BCM



3.3V

1

2

5V


SDA1

GPIO2

3

4

5V


SCL1

GPIO3

5

6

GND



GPIO4

7

8

GPIO14

TxD


GND

9

10

GPIO15

RxD


GPIO17

11

12

GPIO18



GPIO27

13

14

GND



GPIO22

15

16

GPIO23



3.3V

17

18

GPIO24


MOSI

GPIO10

19

20

GND


MISO

GPIO9

21

22

GPIO25


SCLK

GPIO11

23

24

GPIO8

CE0


GND

25

26

GPIO7

CE1

SDA0

GPIO0

27

28

GPIO1

SCL0


GPIO5

29

30

GND



GPIO6

31

32

GPIO12



GPIO13

33

34

GND



GPIO19

35

36

GPIO16



GPIO26

37

38

GPIO20



GND

39

40

GPIO21



그림 9.1.1 라즈베리파이 B+, A+, 2B의 GPIO 헤더핀들


라즈베리파이 초기 모델에는 26핀만 있었다. 라즈베리파이 B+ 을 포함한 이후의 모델은 (A+, 2 model B, zero) 이것이 확장되어 40핀 GPIO핀을 갖는데 26번 핀까지는 동일한 배치이고 27번부터 40번까지가 더 추가되었다.


  그림 9.1을 보면 40개 중 대부분이 GPIO라고 이름이 붙어 있는데 이는 디지털 신호(digital signal)를 입출력 할 수 있는 포트핀 (port pin)으로 사용할 수 있다는 의미이다. 디지털 신호란 두 가지 상태만을 갖는 신호를 의미하며 하나의 비트로 표시되며 0 혹은 1 값만을 가질 수 있다. 물리적으로는 전압으로 구별되며 라즈베리파이에서  0은 0V(GND), 1은 3.3V 전압을 의미한다. (라즈베리파이의 내부 로직은 3.3V로 동작한다. 반면 아두이노는 보통 5V로 동작하는데 따라서 이 둘을 직접 연결할 경우 라즈베리파이가 손상될 가능성이 있다.) 포트핀은 츨력 혹은 입력 기능을 수행할 수 있는데 출력으로 사용되면 0V 혹은 3.3V 전압값을 갖도록 할 수 있으며 입력으로 사용된다면 포트핀의 전압이 0V인지 3.3V인지를 감지할 수 있다. 이 기능을 이용하면 예를 들어 LED를 점멸한거나 혹은 연결된 버튼의 눌렸는지 여부를 알아낼 수 있다.


 이외에도 5V/3.3V/0V(GND)는 외부에 전원을 공급할 때 사용되는 전원핀이고,  시리얼 통신/SPI 통신/I2C통신을 할 수 있으며 PWM 기능을 갖는 핀도 있다. 하지만 아날로그 입력을 받을 수 있는 핀은 없으며 이를 위해서는 별도의 외부 장치를 이용해야 한다.


 라즈베리파이에는 헤더핀만 나와있어서 빵판을 이용하여 실험하고자 할 때는 조금 불편하다. 이를 개선하기 위해서 다양한 연결 부품이 시중에 시판되고 있다.


그림 9.1.2 GPIO 핀을 빵판에 편리하게 연결해주는 제품의 예


이러한 확장 보드를 이용하면 앞으로의 실험을 좀 더 편하게 실행할 수 있다.

원문링크

Posted by 살레시오
,

 며칠간 라즈베리파이와 아두이노간 i2c 통신을 위해서 python3-smbus 라이브러리를 사용하였는데 여기에 몇 가지를 기록한다. 설치하는 법은 다음과 같다.


sudo apt-get update (먼저 반드시 수행해야 한다.)
sudo apt-get install python3-smbus


라즈베리파이 B+와 ver. 2 에는 i2c 포트가 두 개가 있는데 각각 i2c-0, i2c-1 이다. 만약 1번을 사용한다면 다음과 같이 초기화 할 수 있다.


import smbus
dev = smbus.SMBus(1)


smbus 레퍼런스에 보면 cmd (command) 파라메터가 있는데 이것은 단순히 보내는 데이터의 맨 앞에 먼저 보내지는 데이터이다. 보통 슬레이브는 이것을 보고 어떤 명령인지(또는 어떤 데이터가 따르는지)를 판별한다.


 그리고 함수들 중에 i2c 가 붙은 것들이 있는데 이것이 더 효율적이라고 한다.


read_i2c_block_data(addr, cmd [, length] )
write_i2c_block_data(addr, cmd, lst)


write_2ic_block_data()함수는 다음과 같이 데이터를 전송한다.


cmd

lst[0]

lst[1]

...

lst[-1]


read_2ic_block_data()함수는 cmd 한 바이트를 먼저 전송한 후 데이터를 읽어온다.


smbus에는 write_block_data()라는 함수도 있는데 write_i2c_block_data()와의 차이점은 전송되는 데이터가 하나 다르다는 것이다. 두 번째 바이트에 데이터의 길이를 전송한다.



cmd

size

lst[0]

lst[1]

...

lst[-1]


만약 i2c 통신을 사용하는 것이라면 read_i2c_block_data(), write_i2c_block_data() 함수를 사용하는 것이 좋다.





'연구 > Ardpy' 카테고리의 다른 글

Ardpy API reference  (0) 2016.10.23
Ardpy examples  (0) 2016.10.23
Ardpy setup  (0) 2016.10.23
About Ardpy  (0) 2016.10.23
ardpy 개발 동기  (0) 2016.05.02
Posted by 살레시오
,

라즈베리파이1에서는 netbeans 를 설치할 수는 있지만 사용이 불가할 정도록 느렸다. 라즈베리파이2에서는 어떤지 궁금해서 설치를 진행해보았다. 설치 방법은 정말 간단한데 오라클 홈페이지에서 리눅스용으로 다운로드를 받는다.


[그림 1] 홈페이지에서 리눅스용으로 선택한 후 JAVA SE 버전을 다운받는다.


그러면 사용자의 Download 디렉토리에 netbeans-8.0.2-javase-linux.sh 라는 파일이 다운로드되는데 명령창에서 다음과 같이 한다. (이 파일을 다 타이핑할 필요 없이 ne 까지만 치고 tab키를 누르면 자동완성된다.)


$sudo sh netbeans-8.0.2-javase-linux.sh


그러면 설치 대화창이 화면에 나타나고 그대로 진행하면 된다.


 설치가 끝났다면 사용자 디렉토리에 netbeans-8.0.2 디렉토리가 생성되고 그 안에 실행파일이 있다. <userHome>/netbeans-8.0.2/bin/netbeans 파일을 실행하면 IDE가 실행된다.


 잠깐 사용해 본 느낌은 의외로 잘 동작한다는 것이다. JDK8과 JVM도 무난하게 깔리고 잘 동작한다. 윈도에서 개발하던 도구 그대로 라즈베리파이(2)의 데비안 OS에서 사용할 수 있다는 것이 무척 신기하다.



Posted by 살레시오
,

 라즈베리파이2에서 무선랜을 설정하는 방법을 알아보자. 라즈비안에 무선랜을 반자동으로 설정해주는 Wifi_Config 가 없어서 쉘명령어로 설정을 해야하는데 비교적 간단히 할 수 있다.


 무선랜 동글을 꼽고 먼저 다음과 같은 명령어로 이것이 인식이 되는지 확인한다.


$sudo iwlist wlan0 scan


그러면 랜카드가 인식한 와이파이 리스트가 나오는데 검색된 무선 공유기의 ESSID 를 확인한다. 그리고 다음과 같은 화일을 nano 에디터로 연다.


$sudo nano /etc/network/interfaces


이 파일에 다음과 같이 내용을 추가한다.



여기서 wpa-ssid 옆에 문자열로 방금 전 검색한 ESSID를 입력하고 wap-psk 옵션에는 비밀번호를 입력한다.


이 파일을 저장하고 나오면 자동으로 설정이 적용되는데 만약 인터넷에 여전히 연결이 안 된다면 다음과 같이 무선랜을 껐다가 켠다.


$sudo ifdown wlan0

$sudo ifup wlan0


그러면 새로운 설정이 적용되어 무선 인터넷에 연결이 된다.



Posted by 살레시오
,

 인벤터로 블럭을 다시 설계하였다. 이번에 홀을 모두 육각 모양으로 바꾸었다. (나머지는 동일함) 홀의 중심은 모두 10mm간격이고 너트의 변과 변의 폭은 6mm, 볼트홀은 3.5mm이다. 전체 사이즈는 60x100x4mm 이다.



다음 그림은 이것을 세 장 출력하여 볼트-너트롤 체결한 것이다.



이렇게 세 장을 붙여서 단위 블럭을 만든 다음 이것을 다시 여러 개 연결해 붙여서 기타 몸체를 구성할 계획이다. 여기에 부착되는 PCB나 장식 부품도 이 치수를 가지는 홀들을 내어서 체결하기 쉽게 만들면 될 것 같다. 일단 코드를 조합하는 터치 패드 부분부터 만들어야 한다.



Posted by 살레시오
,

 기타 몸체를 구성하기 위한 단위 블럭을 다시 설계해 보았다. 블럭들은 (레고와의 결합은 포기하고) 볼트와 너트를 이용하여 단단히 체결할 수 있어야 한다. 개념도는 다음과 같다. 가로 세로는 60x100mm이고 결합 유격은 0.5mm로 주었다.



두께 4mm 블럭을 세 개 엇갈리게 겹쳐서 단위 블럭을 구성하며 아래 치수의 볼트와 너트를 사용한다. (표의 수량은 천원으로 구매할 수 있는 개수)



 다음 그림은 인벤터로 설계한 결과물이다.


보다시피 가로와 세로 줄에 짝수 개의 홀을 엊갈리게 위치시켜 뒤집어서 결합시키면 볼트 구멍과 너트 구멍이 서로 일치되도록 설계 되어 있다.



직접 두 장 프린팅을 해 보니 원형 홀과 육각 홀로 굳이 구분할 필요가 없다. 왜냐면 육각 홀에도 볼트 머리가 딱 들어가니까. 따라서 모두 육각홀로 내면 이리 저리 결합하기 훨씬 수월해진다. (이렇게 간단한 것을 미리 알아내지 못했다니…)  다시 만들어야 겠다.




Posted by 살레시오
,

 라스베리파이(이하 RPi)의 GPIO 핀들은 파이썬으로 제어할 수 있다는 점에서 무척 매력적이지만 GPIO 자체의 기능이 아두이노에 비해서도 빈약하다. 포트핀으로 흘릴 수 있는 전류가 수mA 정도로 제한되어 있으며 특히 PWM핀은 하나이고 아날로그 핀(ADC)은 없어서 아쉽다.

 

 그래서 아두이노의 기능을 얹은 RPi 인터페이스 보드들이 이러한 단점을 상쇄해 줄 수 있으리라 기대가 되어서 구글링 해보니 다음과 같이 몇 가지가 눈에 띄어서 정리해 보았다.

arduberry

 RPi 위에 장착하여 RPi에서 아두이노 IDE를 이용하여 프로그래밍 가능하다. getting start 를 대충 읽어보았는데 이것은 PC대신 RPi 로 프로그래밍한다는 개념인 것 같다. 필요한 프로그램을 설치하면 아두이노 IDE 의 다운로더 메뉴에 'Arduino GPIO' 메뉴가 생기고 이것을 선택하여 RPi에서 직접 코딩을 하고 컴파일과 다운로딩을 할 수 있다.



단순히 PC대신 RPi를 사용할 수 있도록 설계되었기 때문에 PC가 없는 환경이라면 초저가 아두이노 프로그래머를 RPi로 꾸밀 수 있겠으나,  PC를 이미 가진 사용자들에게 어떤 장점을 가지는 지는 의문이다.

 

2. alamode

 RPi 위에 장착가능한 아두이노 호환보드이며 아듀베리와 유사하게 시리얼포트가 연결되어서 RPi가 호스트가 되어 alamode 를 프로그래밍 할 수 있다.

그 뿐만 아니라 alamode 가 RPi를 이더넷쉴드로 사용할 수 있는 등 양방향 통신을 한다고 한다.

3. RPino GOGO

  아듀베리와 비숫한 개념의 국산 아두이노 보드이다. 특이한 점은 전용 스케치로더를 이용하면 독립적인 아두이노보드로 사용할 수 있다는 점이다. RPi 연결모드와 독립 사용 모드를 설정할 수 있다. RPi와 I2C 통신을 하기 위한 전압 레벨 변환기도 내장하고 있다. 개인적으로 구입해서 구동해 보았는데 잘 동작한다.

하지만 아듀베리와 마찬가지로 단순히 PC대신 RPi를 사용할 수 있도록 설계되었기 때문에 PC가 없는 환경이라면 초저가 아두이노 프로그래머를 RPi로 꾸밀 수 있겠으나,  PC를 이미 가진 사용자들에게 어떤 장점을 가지는 지는 의문이다.

 위의 세 가지 제품들은 라즈베리파이가 단순히 컴파일/다운로드를 수행하는 PC대신으로 사용하는 방식인데 사실 보통의 아두이노보드를 라즈베리파이와 USB로 연결해서 프로그램할 수 있으므로 확장보드로서의 의미가 크지 않다는게 필자의 생각이다. 단지 usb케이블을 이용하지 않고 깔끔하게 결합된다는 점과, alamode 의 경우 라즈베리파이를 이더넷쉴드 대용으로 사용할 수 있다는 점은 장점이라 할 수 있다.

4. piFace

 아두이노 호환은 아니지만 RPi GPIO핀에 장착하여 여러가지 IO실험을 할 수 있는 확장보드로 해외에서는 교육용으로 많이 사용되는 것 같다. 영국 맨체스터대에서 교육용으로 개발하였으며 파이썬 모듈을 제공하며 스크래치 언어와의 통합기능을 제공한다. 스크래치 언어를 지원한다는 것은 저학년 아이들의 교육에 무척 유용할 것이라는 예상을 할 수 있다.

piFace (왼쪽) 와 아두이노에 장착한 모습(오른쪽)


 입출력에 RPi의 GPIO 핀을 직접 사용하지 않고 MCP23S17 칩을 사용하며 I2C로 이를 제어하므로 대전류 구동이 가능하며 arduberry, alamode, RPino 와 다르게 독립적으로 구동되지 않고 반드시 RPi쪽에서 제어 프로그램을 구동하여야 한다.

 

5. pcDuino / 갈릴레오 보드 / udoo neo 보드

 이것들은 종류가 다른 보드이지만 리눅스 머신과 아두이노를 아예 하나의 보드 위에 섞어놓은 것이다. 아예 리눅스 보드 위에 아두이노 호환 핀들이 있는 것들이다. 따라서 아두이노가 지원하는 아날로그 핀이나 pwm 등을 바로 사용할 수 있다.

pcDuino3 nano : 아두이노 핀과 호환되기 때문에 아두이노 쉴드들을 바로 사용할 수 있다.

인텔 갈릴레오 gen 2 보드 : 피씨두이노와 마찬가지로 아두이노 쉴드를 바로 장착하여 사용할 수 있다.

 갈릴레오보드는 특이하게도 리눅스를 OS로 사용하지만 비디오 아웃풋 포트가 없으며, 호스트PC를 이용하여 아두이노IDE 와 동일한 인터페이스를 사용하여 프로그래밍할 수 있다는 것이 특징이다. 보드 자체는 아두이노에 비해서 훨씬 고성능이지만 포트핀들의 동작 속도는 아두이노보다 더 떨어지는 단점이 있다. ( 따라서 당연하게도 그렇다면 왜 궂이 이것을 사용해야 하는 지 의문이 드는 제품이다.)


 그리고 현재 (2015년 5월) udoo neo 라는 보드가 킥스타터에서 캠페인을 진행 중이다.



리눅스 보드인데 아두이노 호환 외부핀을 가지고 있으며 와이파이, 블루투스, 9축 가속센서를 내장하면서 $49불 정도의 가격에 판매될 거라고 한다.

6. 비글본블랙(beaglebone black)

  라즈베리파이를 사용하고 있는데 아두이노의 기능이 필요하다면 필자는 개인적으로 비글본블랙을 추천하고 싶다.

비글본 블랙 보드. 저 넘치도록많은 gpio 핀들에서 알 수 있듯이 왠만한 기능은 다 가지고 있다.

 최근에 출시된 dev C는 아예 데비안리눅스가 내장된 eMMC 플래시메모리(용량은 4G)에 올려져서 출시된다. 따라서 추가적인 외부메모리가 필요치 않다. 사진에서 보듯이 GPIO핀이 많을 뿐만 아니라 PWM과 ADC 핀도 넉넉하다. 라즈베리파이보다 약간 고성능인데다 개발에 편리한 기능(예를 들면 usb로 연결하면 바로 터미널 접속이 가능하다던지)들이 있다. 또한 파이썬으로 GPIO핀들을 제어할 수 있으므로 보다 복잡한 제어 알고리듬을 바로 적용해 볼 수 있다. 단 가격은 $55 정도로 라즈베리파이보다는 비싸고 USB포트도 하나 밖에 없는 것이 조금은 불편하다.




Posted by 살레시오
,

 실험을 위해서 여러 하드웨어 보드들을 구해서 잠깐씩 살펴보았는데, 하드웨어를 제어하는 (주로 오픈소스)보드들이 공통적으로 가지고 있는 필수 기능으로 다음과 같은 것들이 있다.


  • (디지털) In/Out 포트            : on/off 입출력
  • 인터럽트 (interrupt)             : 이벤트 처리
  • PWM                                : 아날로그 (처럼) 출력
  • A/D 변환기                         : 아날로그 입력 (주로 센서의 입력)
  • 통신 (주로 시리얼 통신)       : (주로) PC 혹은 다른 보드와의 통신
  • D/A 변환기                      : 아날로그 전압 출력


보드에 따라서 이러한 기능을 구현하는데 사용하는 언어도 다르다.


  • 아두이노는 C++
  • 넷두이노는 (매우 특이하게) C#.Net
  • R-Pi는 주력 언어가 파이썬 (하지만 리눅스 보드이므로 다른 언어도 가능함)
  • 비글본블랙은 자바스크립트 (마찬가지로 C++, JAVA 등도 가능). 비글본블랙은 D/A변환기도 내장하고 있으며 주변기기가 가장 풍부하게 마련되어 있다.


 어떤 보드의 기능과 프로그래밍을 살펴볼 때 위의 기능들을 사용 언어로 어떻게 구현하는지를 파악할 수 있다면 반 이상은 아는 것이라고 봐도 될 것 같다. 많이 사용되는 라즈베리 파이는 GPIO에 A/D변환기가 없으며 PWM기능도 매우 빈약하다.


  언어의 난이도 순으로 배열해 보면 (순전히 주관적인 생각임) 다음과 같다, 


  • C++ >  JAVA, C# > javascript > python


C++이 제일 어렵고 파이썬이 상대적으로 제일 난이도가 낮은 편에 속한다.


얼마 전까지만 해도 임베디드는 닥치고 C/C++ 이었는데 요즘에는 고수준 언어나 심지어 스크립트 언어로도 프로그래밍할 수 있는 보드들이 출시되고 있어서 비전문가들이 좀 더 쉽게 접근할 수 있는 환경이 되고 있다.

[#00093]


Posted by 살레시오
,