BLE에 대해 잘 설명된 블로그 :
https://devzone.nordicsemi.com/tutorials/37/ nordic에서 제공하는 강의로 제일 잘 설명되어 있는 듯하다.
http://blog-kr.zoyi.co/bluetooth-low-energy-ble/ 한글 블로그인데 괜찮다.
http://blog.naver.com/PostView.nhn?blogId=juke45ef&logNo=220834142021&redirect=Dlog&widgetTypeCall=true 비컨이 보내는 데이터 형식에 대해 설명해줌.
자, 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이다.
또한 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, NULL, NULL); //뒤에 3,4번째 NULL값은 scan response data를 넣어주면 됨(나는 안 넣음) } static void advertising_start(void)//advertising 설정을 다룸 { ble_gap_adv_params_t m_adv_params; memset(&m_adv_params, 0, sizeof(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 여기에 나와있으니 참고 바란다.
하나의 데이터를 넣을 경우 1.데이터의 길이, 2.데이터 타입, 3.데이터 값 이 순서로 넣어주면 된다. 여러개의 데이터를 넣는 경우 위 형식을 그대로 나열해서 넣으면 된다. 데이터 타입에 대해서는 https://www.bluetooth.com/specifications/assigned-numbers/generic-access-profile 여기에 나와있으니 참고 바란다.
댓글 없음:
댓글 쓰기