ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Raspberry Pi 3에서 Arduino 101 BLE 제어 및 정보 가져오기 ( C 언어 라이브러리 사용 )
    Arduino 101/Bluetooth( BLE ) 2017. 8. 3. 20:43

    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와 접속 끊어짐








    포스트 작성시에는 문제 없었지만 이후 문제가 생길 수 있습니다.
    댓글로 알려주시면 빠른 시일내에 답변을 드리겠습니다.

    여러분의 응원으로 좋은 컨텐츠가 만들어집니다. 지금 본 내용이 도움이 되었다면 유튜브 구독 부탁드립니다. 감사합니다 : )

    유튜브 구독하기


    댓글 25

    • 꾸꾸꾸 2016.11.29 15:55


      요 페이지와서 차근차근 따라하고잇는데 현재 cmake 설치중에 있습니다만

      아래 ./a.out은 위의 gcc discover.c `pkg-config --cflags --libs glib-2.0 gattlib` -lpthread 이걸 컴파일 한 결과물인가요?

      • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2016.11.29 16:35 신고


        cmake를 이용하는게 라이브러리를 컴파일 후 설치하는 거구요

        그아래 한줄은 라이브러리를 이용하여 컴파일을 진행하여 a.out를 생성하는 겁니다.

        a.out를 실행하여 블루투스 통신을 해보는 겁니다

    • 꾸꾸꾸 2016.11.29 17:27


      하... 따라해도 안되는게 왜케 많은지 모르겟네요 ㅠㅠ

      cmake 까지 처리한상태인데

      make 단계에서 bluetooth/uuid.h 파일이 없다고 자꾸 에러가뜨는데 이는 어떻게 처리하셧나요?

      블루투스 라이브러리 다운받고했는데도 계속 에러가떠서 미치겟네용 ㅠ

      libbluetooth-dev 버전 떄문인거같은데..
      최신판이 5.x 인데 요기에 bluetooth안에 uuid.h가 없네요 요기에 파일을 어떻게 다운해야할지 모르겟습니다...
      혹시 다운받으실 때 버전 몇인지 알수잇을까요?

    • 꾸꾸꾸 2016.11.30 00:12


      답변해주시는거에 항상 감사드립니다... 여기에 대한 지식이하나도없다보니... 검색을 해도 나오지도 않고 해서 계속 여쭤보게 되네요...

      새로 포스팅된 글 잘보았고 다행히 설치까지는 문제가 없습니다만 위 코드들을 제 맥주소에 맞게 재컴파일하는 과정에서 여러 문제들이 발생하는데
      혹시 이에 대한 해결방법도 알 수 있으련지요..
      에러는 요런것들이있습니다.
      connect.c 에서는 hci_관련함수 및 변수들이 없다고뜨고 read.c 에서는 특정 헤더파일이 없다고뜨네요..

      찾아본결과 libgatt/src 의 헤더파일은 위와 같이 복사하고 남은 목적파일 및 c 파일은 그대로 존재하는것을 확인했는데
      왜 컴파일과정에서는 없는 함수라고 뜨는건지모르겟습니다.
      매번 정말죄송합니다 ㅠ

      • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2016.11.30 01:18 신고


        글을 새로 업데이트 하는 도중에 보셨군요..
        한참 안되서 헤매는 과정이라....

        이미 눈치채신것처럼 bluez 예전 버전을 다운로드 받아서 설치하니 잘되는군요..

      • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2016.11.30 01:19 신고


        동작 여부까지 확인하고 최종 업데이트 한거니 확인해보세요..

    • 꾸꾸꾸 2016.12.05 05:23


      gcc discover.c `pkg-config --cflags --libs glib-2.0 gattlib` -lpthread
      요기서 에러가나네요..
      `pkg-config --cflags --libs glib-2.0 gattlib` 얘가없다고하는데...

      그리고 게시글 3번에 있는 characteristic 이용한것은 실제로 블루투스를 통해 아두이노와 데이터를 송수신한건지 알고싶습니다

      • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2016.12.05 11:44 신고


        컴파일 명령에는 문제가 없어보이는데.. 에러메시지를 적어줘보세요.. glib-2.0가 없어서 나는 에러라면 아래 명령으로 해결됩니다.

        sudo apt-get install libglib2.0-dev

        블루투스와 통신하는게 맞습니다. 보통 시리얼 통신을 하는데 이건 characteristic 를 이용하더라구요..


    • UsbMaster 2017.03.22 14:00


      Android와 usb로 연결하여 endpoint로 데이터 전송하고 받는거 혹시 포스팅 가능 한가요??

      • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2017.03.22 20:48 신고


        안드로이드에서 usb로 외부 장치 제어가 바로 안되는 걸로 알고 있습니다.. 그래서 ioio 보드 같은걸 이용하는 걸로 알고 있는데.. 최근에 새로운게 나왔나 모르겠네요

      • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2017.03.22 23:53 신고


        네이버 opencv 카페 갔다가 가능하다는 글을 봤내요 . 잘못 알고 있었군요.. usb 장치 인경우에는 가능하군요.. 해당글에 있던 링크인데. 테스트 해볼시간을 내봐야 겠습니다

        http://devguru.co.kr/blog/5851/

      • UsbMaster 2017.03.23 14:30


        저도 해당 사이트 글을 보고 진행했었는데

        EndPoint받아오는거 까진 했는데

        데이터 값 주고받는 부분에서 막혔네요 ㅠㅠ

        시간 나실때 포스팅 부탁드리겠습니다.ㅠ

      • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2017.03.25 03:01 신고


        관련 자료를 찾아보는 중인데 대부분 안드로이드와 Arduino Mega ADK 위주의 자료네요..

        Arduino UNO의 경우에는 추가로 USB Host Shield가 필요하는거 같구요..

        라즈베리파이랑도 하는거 같기도하고..

        어떤 것과 안드로이드폰 사이의 통신인가요??

        라즈베리파이3나 에디슨에 Android Things을 설치해서 하는 방법도 있네요..

    • firmware 2017.03.24 15:07


      VMware Ubuntu 상에서 하드웨어 보드에 firmware 이미지를 전송시켜 설치하는 소스를 찾았는데

      그 소스가 QT를 이용해야 돼서 Andorid에서 돌아가기가 까다로운데

      혹시 Java코드로 파일 전송해서 설치까지 하는게 가능할까요??

      • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2017.03.25 02:51 신고


        하드웨어 보드가 어떤 건지와 피시와 안드로이드폰 중 어느 쪽에서 진행할지 알려주셔야 답변이 가능할듯합니다.

      • firmware 2017.03.28 17:47


        하드웨어보드는

        연구실에서 자체적으로 만든 보드이구요

        Andorid와 그 보드를 OTG젠더를 통해서 USB통신을 시도 해보려하는데

        현재 진행된 상태는

        테스트 기기는 갤럭시 노트2인데
        USB미연결 상태에서 연결된값 읽어오게 해봤더니
        내장된 뭘 읽는건지 읽드라구요
        보드 연결 후에 다시 읽어오게 하면 보드에 대한 정보도 잘 읽어오고..

        Android기기 파일시스템에
        펌웨어 img파일이 있고 그걸 이제
        넘겨주면서 설치를 하려하는데
        여기서 막히네요 ㅠㅠ

      • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2017.03.28 19:13 신고


        android adk인가요? 이 부분은 아직 제가 공부하지 않아서 도움을 못드리겠네요

    • 정문석 2017.03.31 11:22


      안녕하세요, 좋은 글 잘봤습니다.
      하던 중에 질문이 있어서 이렇게 글 남깁니다.
      make && sudo make install 시 이런 에러 메시지가 나와서 문의드립니다.

      pi@raspberrypi:~/gattlib/build $ make && sudo make install
      [ 2%] Building C object bluez/CMakeFiles/gattlib.dir/bluez5/btio/btio.c.o
      /home/pi/gattlib/bluez/bluez5/btio/btio.c: In function 'set_le_imtu':
      /home/pi/gattlib/bluez/bluez5/btio/btio.c:642:38: error: 'BT_RCVMTU' undeclared (first use in this function)
      if (setsockopt(sock, SOL_BLUETOOTH, BT_RCVMTU, &imtu,
      ^
      /home/pi/gattlib/bluez/bluez5/btio/btio.c:642:38: note: each undeclared identifier is reported only once for each function it appears in
      /home/pi/gattlib/bluez/bluez5/btio/btio.c: In function 'sco_set':
      /home/pi/gattlib/bluez/bluez5/btio/btio.c:774:18: error: storage size of 'bt_voice' isn't known
      struct bt_voice bt_voice;
      ^
      /home/pi/gattlib/bluez/bluez5/btio/btio.c:800:38: error: 'BT_VOICE' undeclared (first use in this function)
      if (setsockopt(sock, SOL_BLUETOOTH, BT_VOICE, &bt_voice,
      ^
      /home/pi/gattlib/bluez/bluez5/btio/btio.c:774:18: warning: unused variable 'bt_voice' [-Wunused-variable]
      struct bt_voice bt_voice;
      ^
      /home/pi/gattlib/bluez/bluez5/btio/btio.c: In function 'l2cap_get':
      /home/pi/gattlib/bluez/bluez5/btio/btio.c:1013:39: error: 'BT_RCVMTU' undeclared (first use in this function)
      if (getsockopt(sock, SOL_BLUETOOTH, BT_RCVMTU,
      ^
      /home/pi/gattlib/bluez/bluez5/btio/btio.c:1118:40: error: 'BT_SNDMTU' undeclared (first use in this function)
      if (getsockopt(sock, SOL_BLUETOOTH, BT_SNDMTU,
      ^
      bluez/CMakeFiles/gattlib.dir/build.make:238: recipe for target 'bluez/CMakeFiles/gattlib.dir/bluez5/btio/btio.c.o' failed
      make[2]: *** [bluez/CMakeFiles/gattlib.dir/bluez5/btio/btio.c.o] Error 1
      CMakeFiles/Makefile2:75: recipe for target 'bluez/CMakeFiles/gattlib.dir/all' failed
      make[1]: *** [bluez/CMakeFiles/gattlib.dir/all] Error 2
      Makefile:137: recipe for target 'all' failed
      make: *** [all] Error 2

      • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2017.03.31 12:22 신고


        gattlib 라이브러리가 업데이트 되면서 uuid.h가 필요 없어 진듯합니다.

        bluez 5.3을 컴파일해서 사용하는 대신에 libbluetooth-dev 패키지를 설치하세요..

        sudo apt-get install libbluetooth-dev

      • 정문석 2017.03.31 19:43


        답변 감사합니다!
        선생님께서 알려주신 것처럼 libbluetooth-dev 패키지를 설치한 후 다시 make && sudo make install을 했지만, 동일한 문제가 발생했습니다. 혹시 다른 해결책 있을까요?
        만약, 이 라이브러리를 이용할 수 없다면 C언어로 BLE 통신을 해야하는 방법에 대해서 알려주실 수 있으신가요? 혹시 C언어로 BLE 통신을 할 수 있는 참고 자료가 있으시면 URL을 알려주시면 감사하겠습니다.(구글링을 해도 찾을 수가 없네요..)

      • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2017.03.31 19:51 신고


        sudo rm -rf /usr/local/include/bluetooth/

        위 명령으로 소스코드로 설치한 라이브러리를 지우고

        sudo apt-get install --reinstall libblooth-dev 로 패키지 재설치하세요

        그리고 build 디렉토리 지우고 build디렉토리 생성부터 다시하세요..

        소스컴파일해서 설치한 라이브러리를 참조하고 있어서 그래요

      • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2017.03.31 19:57 신고


        libbluetooth-dev 패키지 재설치해서 gattlib 예제 코드 컴파일하는 거 까지는 잘되는거 확인됬습니다..

        관련 c/c++라이브러리가 거의 없습니다..

    • ㅂㅈㄷ 2017.11.08 18:44



      pi@raspberrypi:~/gattlib/build $ cmake ..

      ...

      Configuring incomplete. errors occured!
      See also "/home/pi/gattlib/build/CMakeFiles/CmakeOutput.log"/
      pi@raspberrypi:~/gattlib/build $ make && sudo make install
      make: ***타켓이 지정되지 않았고 메이크파일이 없습니다. 멈춤.
      어떠한 현상인가요?

      • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2017.11.08 19:24 신고


        다음 메시지가 보이는것으로 봐서는
        Configuring incomplete. errors occured!

        cmake로 OpenCV 컴파일 설정시(makefile생성) 필요한 패키지가 설치되지 않은거 같습니다.

        cmake 실행결과 전체를 올려줘보세요

    • ㅇㄴ 2019.09.22 00:04


      안녕하세요 저도 위의 분과 같은 문제가 생겼는데요

      pi@pi:~/gattlib/build $ cmake ..
      Build DBus gattlib for Bluez v5.50
      CMake Error at /usr/share/cmake-3.13/Modules/FindPackageHandleStandardArgs.cmake:137 (message):
      Could NOT find Doxygen (missing: DOXYGEN_EXECUTABLE)
      Call Stack (most recent call first):
      /usr/share/cmake-3.13/Modules/FindPackageHandleStandardArgs.cmake:378 (_FPHSA_FAILURE_MESSAGE)
      /usr/share/cmake-3.13/Modules/FindDoxygen.cmake:615 (find_package_handle_standard_args)
      docs/CMakeLists.txt:5 (find_package)


      -- Configuring incomplete, errors occurred!
      See also "/home/pi/gattlib/build/CMakeFiles/CMakeOutput.log".
      pi@pi:~/gattlib/build $ make
      make: *** No targets specified and no makefile found. Stop.
      pi@pi:~/gattlib/build $ sudo make install
      make: *** No rule to make target 'install'. Stop.


      이렇게 나옵니다 어떻게 해야하는지 알려주시면 감사하겠습니다.

Designed by Tistory.