본문 바로가기

Info

RaspberryPi - 라즈베리파이에서 블루투스 사용하기

라즈베리파이에서 블루투스 동글을 사용하여 블루투스 기능을 활성화시키고, C언어 소스로 블루투스를 제어하고 통신하는법을 정리한다.


우선 터미널 상에서 제어.


1. 패키지 설치

apt-get install bluetooth bluez-utils bluez-tools blueman


2. 블루투스 동글 인식 확인

root@raspberrypi:/home/pi# lsusb
Bus 001 Device 002: ID 0424:9514 Standard Microsystems Corp. 
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp. 
Bus 001 Device 004: ID 0a12:0001 Cambridge Silicon Radio, Ltd Bluetooth Dongle (HCI mode)


3. 라즈베리파이 블루투스 검색 허용하기

root@raspberrypi:/dev# hciconfig hci0 piscan


4. 블루투스 상태 확인

root@raspberrypi:/home/pi# hciconfig 
hci0: Type: BR/EDR  Bus: USB
 BD Address: 00:15:83:E3:28:63  ACL MTU: 310:10  SCO MTU: 64:8
 UP RUNNING PSCAN 
 RX bytes:4356 acl:0 sco:0 events:119 errors:0
 TX bytes:1326 acl:0 sco:0 commands:80 errors:0


5. 블루투스 활성화

root@raspberrypi:/home/pi# hciconfig hci0 up


6. 주변 장치 스캔

root@raspberrypi:/home/pi# hcitool scan
Scanning ...
 00:1A:7D:DA:71:14 HONG-PC
 00:01:95:23:96:32 SD1000Uv2.0.3-239632


7. 페어링

bluez-simple-agent hci0 [연결할장치의MAC주소]

...핀번호 인증 진행...

bluez-test-device trusted [연결할장치의MAC주소]

bluez-test-input connect [연결할장치의MAC주소]


bluez-simple-agent hci0 [연결할장치의MAC주소] 에서 잘 안될 때는 아래의 파일을 수정한다.

/usr/bin/bluez-simple-agent


 capability = "KeyboardDisplay"    =>    capability = "DisplayYesNo"


페어링한 장치 제거

bluez-simple-agent hci0 [연결할장치의MAC주소] remove


다음으로 소스에서 제어.


일단 소스에서 블루투스 기능을 사용하려면 bluez 라이브러리가 필요하다.


apt-get install libbluetooth-dev



client.c

// gcc -o client client.c -l bluetooth


#include <stdio.h>

#include <unistd.h>

#include <sys/socket.h>

#include <bluetooth/bluetooth.h>

#include <bluetooth/rfcomm.h>


int main(int argc, char **argv)

{

struct sockaddr_rc addr = { 0 };

int s, status;

// NEXT DONGLE

//char dest[18] = "00:1A:7D:DA:71:14";

// Note10

char dest[18] = "34:BE:00:AA:80:5B";


// allocate a socket

s = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);


// set the connection parameters (who to connect to)

addr.rc_family = AF_BLUETOOTH;

addr.rc_channel = (uint8_t) 1;

str2ba( dest, &addr.rc_bdaddr );


// connect to server

status = connect(s, (struct sockaddr *)&addr, sizeof(addr));


// send a message

if( status == 0 ) {

status = write(s, "hello!", 6);

}


if( status < 0 ) perror("uh oh");


close(s);

return 0;

}


server.c

// gcc -o server server.c -l bluetooth


#include <stdio.h>

#include <unistd.h>

#include <sys/socket.h>

#include <bluetooth/bluetooth.h>

#include <bluetooth/rfcomm.h>


int main(int argc, char **argv)

{

struct sockaddr_rc loc_addr = { 0 }, rem_addr = { 0 };

char buf[1024] = { 0 };

int s, client, bytes_read;

int opt = sizeof(rem_addr);


// allocate socket

s = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);


// bind socket to port 1 of the first available 

// local bluetooth adapter

loc_addr.rc_family = AF_BLUETOOTH;

loc_addr.rc_bdaddr = *BDADDR_ANY;

loc_addr.rc_channel = (uint8_t) 1;

bind(s, (struct sockaddr *)&loc_addr, sizeof(loc_addr));


// put socket into listening mode

listen(s, 1);


// accept one connection

client = accept(s, (struct sockaddr *)&rem_addr, &opt);


ba2str( &rem_addr.rc_bdaddr, buf );

fprintf(stderr, "accepted connection from %s\n", buf);

memset(buf, 0, sizeof(buf));


// read data from the client

bytes_read = read(client, buf, sizeof(buf));

if( bytes_read > 0 ) {

printf("received [%s]\n", buf);

}


// close connection

close(client);

close(s);

return 0;

}



다른 리눅스에 블루투스 동글 끼우고, 라즈베리파이와 통신하니까 된다.


근데, 라즈베리파이랑 안드로이드랑 시험을 해보니까 자꾸 안되는데..


안드로이드쪽에서 지정하는 UUID 관련해서 문제인 듯한데, 일단 나중에 다시 해봐야겠다.