: 이 프로젝트는 BLE 위에서 Serial 포트를 구현한 예제로 NUS (Nordic Uart Service) 어플리케이션이다.
목차
0> 개요
:이 프로젝트는 BLE 를 통해 들어온 데이타를 시리얼로 데이터 전송및
Serial 로 들어온 데이타를 BLE 로 보내는 예제입니다.advertise 시 이름은 "nRF UART" 이고
스마프폰에 nRF Connect 이나 nRF Toolbox 앱을 설치해서 제어가 가능합니다.
1> 프로젝트 위치
: <InstallFolder>\examples\ble_peripheral\ble_app_uart
2> 노르딕 다큐먼트
https://infocenter.nordicsemi.com/topic/sdk_nrf5_v17.0.2/ble_sdk_app_nus_eval.html
3> UART 통신 테스트
3-1> nRF Toolbox 사용하기
▶ nRF52 DK 보드 리셋시 시리얼 메시지
▶ nRF Toolbox 실행후 Utils services 의 UART 를 선택해 줍니다.
▶ Nordic_UART 를 선택해 줍니다.
▶ Serial 창에 한개 실행후 양쪽에서 데이타를 보내면 동작 확인 가능합니다.
3-2> nRF Connect 사용해 UART 통신하기
▶ nRF Connect 앱 실행후 Nordic_UART 를 찾아 연결해 줍니다.
▶ 연결완료후 Nordic UART Service 선택하기
▶ TX 테스트 는 RX Characteristic 의 Write 버튼을 클릭후 데이타를 전송해 봅니다.
==> PC 의 터미널창에 들어오는 데이타 확인하기
▶RX 테스트 는 TX Characteristic 의 notify 를 Enable 한후 PC에서 데이타(asdf) 를 전송해 봅니다.
==> 시리얼창에 엔터키를 넣어야 화면에 표시가 됩니다.
4> 상세분석
▶ UART 및 nus (Nordic UART Service) 초기화
static void uart_init(void)
{
app_uart_comm_params_t const comm_params =
{
.rx_pin_no = RX_PIN_NUMBER,
.tx_pin_no = TX_PIN_NUMBER,
.rts_pin_no = RTS_PIN_NUMBER,
.cts_pin_no = CTS_PIN_NUMBER,
.flow_control = APP_UART_FLOW_CONTROL_DISABLED,
.use_parity = false,
.baud_rate = NRF_UART_BAUDRATE_115200
};
APP_UART_FIFO_INIT(&comm_params, UART_RX_BUF_SIZE, UART_TX_BUF_SIZE,
uart_event_handle,
APP_IRQ_PRIORITY_LOWEST, err_code);
}
static void services_init(void)
{
~~~~ 중략 ~~~~
nus_init.data_handler = nus_data_handler;
err_code = ble_nus_init(&m_nus, &nus_init);
}
▶ Nordic UART Service 등록
==> ble_nus_init() 함수 중 일부 발췌
// 1> Add a custom base UUID.
sd_ble_uuid_vs_add(&nus_base_uuid, &p_nus->uuid_type);
// 2> Add the service.
ble_uuid.type = p_nus->uuid_type;
ble_uuid.uuid = BLE_UUID_NUS_SERVICE;
sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY,&ble_uuid,&p_nus->service_handle);
▶ Nordic UART Service characteristic 등록
tx /rx characteristics 관련코드
// 해석의 편의를 위해 불필요한 코드는 제거 했습니다.
// 1> Add the RX Characteristic.
add_char_params.uuid = BLE_UUID_NUS_RX_CHARACTERISTIC;
add_char_params.uuid_type = p_nus->uuid_type;
add_char_params.max_len = BLE_NUS_MAX_RX_CHAR_LEN;
add_char_params.init_len = sizeof(uint8_t);
add_char_params.is_var_len = true;
add_char_params.char_props.write = 1;
add_char_params.char_props.write_wo_resp = 1;
add_char_params.read_access = SEC_OPEN;
add_char_params.write_access = SEC_OPEN;
characteristic_add(p_nus->service_handle, &add_char_params, &p_nus->rx_handles);
// 2> Add the TX Characteristic.
add_char_params.uuid = BLE_UUID_NUS_TX_CHARACTERISTIC;
add_char_params.uuid_type = p_nus->uuid_type;
add_char_params.max_len = BLE_NUS_MAX_TX_CHAR_LEN;
add_char_params.init_len = sizeof(uint8_t);
add_char_params.is_var_len = true;
add_char_params.char_props.notify = 1;
add_char_params.read_access = SEC_OPEN;
add_char_params.write_access = SEC_OPEN;
add_char_params.cccd_write_access = SEC_OPEN;
characteristic_add(p_nus->service_handle, &add_char_params, &p_nus->tx_handles);
▶ RX data flow ( BLE ==> UART TX)
void ble_nus_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context)
{
~~~~ 중략 ~~~~
switch (p_ble_evt->header.evt_id)
~~~~ 중략 ~~~~
}
// ble_nus.c
void on_write(ble_nus_t * p_nus, ble_evt_t const * p_ble_evt)
{
~~~~ 중략 ~~~~
evt.type = BLE_NUS_EVT_RX_DATA;
evt.params.rx_data.p_data = p_evt_write->data;
evt.params.rx_data.length = p_evt_write->len;
p_nus->data_handler(&evt);
~~~~ 중략 ~~~~
}
void nus_data_handler(ble_nus_evt_t * p_evt)
{
~~~~ 중략 ~~~~
app_uart_put(p_evt->params.rx_data.p_data[i]);
~~~~ 중략 ~~~~
}
▶ TX data flow ( UART RX ==> BLE )
void uart_event_handle(app_uart_evt_t * p_event)
{
~~~~ 중략 ~~~~~
case APP_UART_DATA_READY:
app_uart_get(&data_array[index])
~~~~ 중략 ~~~~~
ble_nus_data_send(&m_nus, data_array, &length, m_conn_handle);
~~~~ 중략 ~~~~~
}
uint32_t ble_nus_data_send(ble_nus_t *p_nus, uint8_t *p_data, uint16_t *p_length, uint16_t conn_handle)
{
~~~~ 중략 ~~~~~
ble_gatts_hvx_params_t hvx_params;
hvx_params.handle = p_nus->tx_handles.value_handle;
hvx_params.p_data = p_data;
hvx_params.p_len = p_length;
hvx_params.type = BLE_GATT_HVX_NOTIFICATION;
return sd_ble_gatts_hvx(conn_handle, &hvx_params);
}
< 기타 >
A> NUS 예제에 사용되는 UUID
6E400001-B5A3-F393-E0A9-E50E24DCCA9E ==> Service
6E400002-B5A3-F393-E0A9-E50E24DCCA9E ==> Rx Characteristic
6E400003-B5A3-F393-E0A9-E50E24DCCA9E ==> Tx Characteristic
B> LED 표시
▶ Advertising mode : LED1 깜박임
▶ Connected mode : LED1 ON
C> Advertise data
==> 위 그림의 네모박스의 Service UUID 를 보고 앱이 동작합니다.
'Nordic_nRF52' 카테고리의 다른 글
[nRF52] radio_test 프로젝트에 button 기능 넣기 (0) | 2023.04.12 |
---|---|
[nRF52] ble_app_hids_keyboard 에 NUS 추가하기 (0) | 2023.03.23 |
[nRF52 ] error: 'NRFX_TIMER0_INST_IDX' undeclared here (0) | 2023.02.08 |
[nRF52 ] gzll_ack_payload device 프로젝트 (0) | 2023.01.02 |
[nRF52 ] gzll_ack_payload host 프로젝트 (0) | 2023.01.02 |