Post List

2017년 11월 29일 수요일

nRF 51 DK ble_app_beacon 예제 및 BLE 구조

beacon 은 단순히 pairing 하지 않고 advertising 만 하는 것을 말한다. beacon 예제를 하기전에 먼저 BLE에 대해서 공부하고 하는 게 좋다.

BLE에 대해 잘 설명된 블로그 :

https://devzone.nordicsemi.com/tutorials/37/ nordic에서 제공하는 강의로 제일 잘 설명되어 있는 듯하다.
http://blog-kr.zoyi.co/bluetooth-low-energy-ble/ 한글 블로그인데 괜찮다.

자, BLE에 대해 대충 공부했으면 이를 nRF 칩에서 어떻게 구현되는지가 정말 중요하다. nordic에서 제공해주는 강의를 보면 잘 나와 있다. 
softdevice라는 소프트웨어를 통해 복잡한 블루투스 protocol stack을 구현해주고 우리는 단순히 softdevice에서 제공해주는 api함수를 이용해 설정을 변경하면 된다. 따라서 api의 사용법을 잘 익혀야 한다.

바로 beacon 예제를 보면 엄청나게 복잡한데 LED를 깜빡거리게 해주는 timer, 디버깅을 위한 debugger, UICR 메모리의 사용 등 beacon 자체에 필요없는 코드를 싹 빼버린 코드가 아래와 같다.(s130을 기준으로 짠 코드, peripheral 과 central 모두 지원해주는 softdevice이다. peripheral만을 사용할거면 s110을 쓰면 되는데 이는 SDK v10 까지 지원한다.)
또한 sd_xxx 로 시작되는 함수들이 softdevice에서 제공해주는 api이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#include <stdbool.h>
#include <stdint.h>
#include "ble_advdata.h"
#include "softdevice_handler.h"
#include "bsp.h"
 
#define CENTRAL_LINK_COUNT              0                                 /**< Number of central links used by the application. When changing this number remember to adjust the RAM settings*/
#define PERIPHERAL_LINK_COUNT           0                                 /**< Number of peripheral links used by the application. When changing this number remember to adjust the RAM settings*/
 
static void advertising_init(void)//여기서는 advertising data만 다룸
{
 
    uint8_t adv_data[15= {0x08,0x09,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x02,0x01,0x04};//(8길이,9번째타입,'ABCDEFG' HEX값) + (2길이, 1번째 타입(flag), flag값)
    uint8_t adv_data_length = 15;
 
    sd_ble_gap_adv_data_set(adv_data, adv_data_length, NULLNULL); //뒤에 3,4번째 NULL값은 scan response data를 넣어주면 됨(나는 안 넣음)
}
 
 
static void advertising_start(void)//advertising 설정을 다룸
{
    ble_gap_adv_params_t m_adv_params;
 
    memset(&m_adv_params, 0sizeof(m_adv_params));
 
    m_adv_params.type        = BLE_GAP_ADV_TYPE_ADV_NONCONN_IND; //advertising type이 4가지가 있는데 Keil에서 정의부분을 참고하면 이해될 겁니다.
       m_adv_params.p_peer_addr = NULL;                             // Undirected advertisement.
       m_adv_params.fp          = BLE_GAP_ADV_FP_ANY;                 //
       m_adv_params.interval    = MSEC_TO_UNITS(100, UNIT_0_625_MS);//advertising 간격. millisec 단위다.
       m_adv_params.timeout     = 0;                                 //몇초 뒤에 advertising을 멈출지 설정. 0이면 계속하는 것
    ble_gap_adv_ch_mask_t        ch_mask;                         //broadcasting 주파수 채널 설정
 
    ch_mask.ch_37_off = 0;//37,38,39채널에서 브로드캐스팅
    ch_mask.ch_38_off = 0;
    ch_mask.ch_39_off = 0;
    m_adv_params.channel_mask = ch_mask;
 
    sd_ble_gap_tx_power_set(0);//tx power 설정 -30, -20, -16, -12, -8, -4, 0, 4
 
    sd_ble_gap_adv_start(&m_adv_params);
}
 
 
static void ble_stack_init(void//bluetooth protocol stack 이니셜라이징 하는 부분으로 수정하지 않는게 좋음.
{
    nrf_clock_lf_cfg_t clock_lf_cfg = NRF_CLOCK_LFCLKSRC;
 
    // Initialize the SoftDevice handler module.
    SOFTDEVICE_HANDLER_INIT(&clock_lf_cfg, NULL);
 
    ble_enable_params_t ble_enable_params;
    softdevice_enable_get_default_config(CENTRAL_LINK_COUNT,PERIPHERAL_LINK_COUNT,&ble_enable_params);
 
    //Check the ram settings against the used number of links
    CHECK_RAM_START_ADDR(CENTRAL_LINK_COUNT,PERIPHERAL_LINK_COUNT);
 
    // Enable BLE stack.
    softdevice_enable(&ble_enable_params);
}
 
static void power_manage(void//다음 event가 발생할 때까지 저전력모드를 유지해주는 함수
{
    sd_app_evt_wait();
}
 
int main(void)
{
    ble_stack_init();
    advertising_init();
    advertising_start();
 
    for (;; )
    {
          power_manage();
    }
}
cs

이 코드에서 부가 설명할 부분은 advertising_start()함수 내에서 adv_data 변수에 데이터를 넣는 방법이다. 사실 기존 SDK 예제 코드는 장황하게 여러 클래스들을 사용하여 좀더 편리?하게 데이터를 넣을 수 있다. 그치만 코드의 간단함을 위해 raw하게 넣어 봤다.
하나의 데이터를 넣을 경우 1.데이터의 길이, 2.데이터 타입, 3.데이터 값 이 순서로 넣어주면 된다. 여러개의 데이터를 넣는 경우 위 형식을 그대로 나열해서 넣으면 된다. 데이터 타입에 대해서는 https://www.bluetooth.com/specifications/assigned-numbers/generic-access-profile 여기에 나와있으니 참고 바란다.

댓글 없음:

댓글 쓰기