반응형

Raspberry Pi 3와 BLE( Bluetooth Low Energy )  디바이스(여기선 Arduino 101) 간에 BLE 통신을 연결해서 사용할 수 있게 해주는 gattlib 라이브러리를 테스트해보았습니다.


최종 수정 - 2017.8.3


gattlib 라이브러리 설치


1. libbluetooth-dev 패키지를 비롯해 필요한 것들을 설치합니다.


pi@raspberrypi:~ $ sudo apt-get install libbluetooth-dev libreadline-dev cmake




2. gattlib를 컴파일하여 설치합니다.


pi@raspberrypi:~ $ git clone https://github.com/labapart/gattlib.git
pi@raspberrypi:~ $ cd gattlib && mkdir build && cd build
pi@raspberrypi:~/gattlib/build $ cmake ..
pi@raspberrypi:~/gattlib/build $ make && sudo make install
pi@raspberrypi:~/gattlib/build $ sudo ldconfig




3. 진행하기 전에  다음 포스팅에 소개한 대로 Arduino 101에 LED 예제를 업로드 해야 합니다.


Arduino 101의 Bluetooth Low Energy(BLE) 예제를 안드로이드 폰과 테스트

http://webnautes.tistory.com/901




4. hcitool로  Arduino 101의 맥어드레스를 확인해둡니다.


pi@raspberrypi:~/gattlib/build $ sudo hcitool -i hci0 lescan
LE Scan ...
03:95:CE:50:22:EC (unknown)
FC:F1:36:2B:34:32 (unknown)
98:4F:EE:0F:4E:1E LED
^Cpi@raspberrypi:~/gattlib/build $




gattlib 라이브러리 예제 테스트

1. gattlib 라이브러리에서는 6개의 예제 코드를  제공하고 있습니다.

여기에서는 이중에 3가지만 테스트해보았습니다.

현재 위치에는 컴파일된 바이너리 파일이 있고 실제 코드 위치는 ~/gattlib/examples/입니다.


pi@raspberrypi:~/gattlib/build $ cd examples/
pi@raspberrypi:~/gattlib/build/examples $ ls
ble_scan  discover  gatttool  nordic_uart  notification  read_write




2. ble_scan

BLE 디바이스 검색 및 제공하는 서비스와 characteristic를 출력해줍니다.

여기선 서비스 이름이 안나오지만 98:4F:EE:0F:4E:1E가 앞에서 검색했던 Arduino 101의 맥어드레스입니다.


pi@raspberrypi:~/gattlib/build/examples/ble_scan $ sudo ./ble_scan
Discovered 98:4F:EE:0F:4E:1E
Scan completed
------------START 98:4F:EE:0F:4E:1E ---------------
Succeeded to connect to the bluetooth device.
service[0] start_handle:01 end_handle:07 uuid:0x1800
service[1] start_handle:08 end_handle:08 uuid:0x1801
service[2] start_handle:09 end_handle:ffff uuid:19b10000-e8f2-537e-4f6c-d104768a1214
characteristic[0] properties:02 value_handle:0003 uuid:0x2a00
characteristic[1] properties:02 value_handle:0005 uuid:0x2a01
characteristic[2] properties:02 value_handle:0007 uuid:0x2a04
characteristic[3] properties:0a value_handle:000b uuid:19b10001-e8f2-537e-4f6c-d104768a1214
------------DONE 98:4F:EE:0F:4E:1E ---------------




3. discover

지정한 맥어드레스를 가진 디바이스에서 제공하는 서비스와 characteristic를 출력해줍니다.


pi@raspberrypi:~/gattlib/build/examples/discover $ ./discover 98:4F:EE:0F:4E:1E
service[0] start_handle:01 end_handle:07 uuid:0x1800
service[1] start_handle:08 end_handle:08 uuid:0x1801
service[2] start_handle:09 end_handle:ffff uuid:19b10000-e8f2-537e-4f6c-d104768a1214
characteristic[0] properties:02 value_handle:0003 uuid:0x2a00
characteristic[1] properties:02 value_handle:0005 uuid:0x2a01
characteristic[2] properties:02 value_handle:0007 uuid:0x2a04
characteristic[3] properties:0a value_handle:000b uuid:19b10001-e8f2-537e-4f6c-d104768a1214




3. read_write

characteristic에 값을 기록하거나 값을 읽어오는 예제입니다.


3-1.예전과 다르게 동작해서 진행하기 전에 Arduino 101의 LED 예제 코드의 일부를 다음처럼 수정해서 다시 업로드해야 합니다.

  // 라즈3와 연결되어 있는 동안 루프를 돈다.
   while (central.connected()) {

     
     // LED 제어를 위한 characteristic에 기록한 값이 있다면
     if (switchCharacteristic.written()) {

       //값을 한바이트 읽어온다.
       unsigned char ch = switchCharacteristic.value();
       Serial.println(ch);
       
       if (ch=='1') {   // 1이면 LED를 켠다.
         
         Serial.println("LED on");
         digitalWrite(ledPin, HIGH);         
         
       } else if ( ch=='0' ){  // 0이면 LED를 끈다.
         
         Serial.println(F("LED off"));
         digitalWrite(ledPin, LOW);         
         
       }
     }
   }




3-2. ~/gattlib/examples/read_write/read_write.c에 있는 코드도 일부 수정했습니다.

노란색 줄부분이 빠진 듯해서 추가해주었습니다.


       if (strcmp(argv[2], "read") == 0) {
               g_operation = READ;
       } else if ((strcmp(argv[2], "write") == 0) && (argc == 5)) {
               g_operation = WRITE;

               if ((strlen(argv[4]) >= 2) && (argv[4][0] == '0') && (argv[4][0] == 'x')) {
                       value_data = strtol(argv[4], NULL, 0);
               } else {
                       value_data = strtol(argv[4], NULL, 16);
               }
               printf("Value to write: 0x%lx %d\n", value_data, value_data);
               sprintf(buffer, "%d", value_data);
               printf( "%s\n", buffer );
       } else {




3-3. 라즈베리파이 3에서 예제 컴파일을 진행해줍니다.


pi@raspberrypi:~/gattlib/examples/read_write $ mkdir build
pi@raspberrypi:~/gattlib/examples/read_write $ cd build/
pi@raspberrypi:~/gattlib/examples/read_write/build $ cmake ..
pi@raspberrypi:~/gattlib/examples/read_write/build $ make




3-4. 이제 Arduino IDE에서 시리얼 모니터를 실행시켜 둡니다.

Arduino 101의 동작을 모니터링하기 위해서입니다.




3-5. 라즈베리파이에서 LED 제어를 위한 Characteristic에 1을 기록하면


pi@raspberrypi:~/gattlib/examples/read_write/build $ ./read_write 98:4F:EE:0F:4E:1E write 19b10001-e8f2-537e-4f6c-d104768a1214 1
Value to write: 0x1 1
1




시리얼 모니터에서 Arduino 101에서 처리한 상황을 확인할 수 있습니다.


Connected to central: B8:27:EB:DA:FA:66     라즈3와 연결됨
49     ASCII 코드 49번인 숫자 1이 입력되었으며  
LED on    13번에 연결되어 있는 LED를 켠다.
Disconnected from central: B8:27:EB:DA:FA:66  라즈3와 접속 끊어짐




3-6. write를 read로 바꾸면 Characteristic 상태값을 읽어올 수 있습니다.


pi@raspberrypi:~/gattlib/examples/read_write/build $ ./read_write 98:4F:EE:0F:4E:1E read 19b10001-e8f2-537e-4f6c-d104768a1214
Read UUID completed: 31    ASCII 코드 49번을 16진수로 바꾸면 31입니다.




3-7. 라즈베리파이에서 LED 제어를 위한 Characteristic에 0을 기록하고


pi@raspberrypi:~/gattlib/examples/read_write/build $ ./read_write 98:4F:EE:0F:4E:1E write 19b10001-e8f2-537e-4f6c-d104768a1214 0
Value to write: 0x0 0
0




시리얼 모니터에서 확인해봅니다.


Connected to central: B8:27:EB:DA:FA:66     라즈3와 연결됨
48     ASCII 코드 48번인 숫자 0이 입력되었으며  
LED off    13번에 연결되어 있는 LED를 끈다.
Disconnected from central: B8:27:EB:DA:FA:66  라즈3와 접속 끊어짐








반응형

문제 발생시 지나치지 마시고 댓글 남겨주시면 가능한 빨리 답장드립니다.

도움이 되셨다면 토스아이디로 후원해주세요.
https://toss.me/momo2024


제가 쓴 책도 한번 검토해보세요 ^^

+ Recent posts