: Cycling Speed and Cadence Application 으로 SoftDevice 가 필요합니다.
Cycling Speed and Cadence profile 안의 2개의 서비스
Cycling Speed and Cadence Service , Device Information Service 가 포함되어 있고,
기본적으로 3분동안 advertising이 진행되고 이후 연결이 되지 않을경우 system-off 모드에 들어갑니다.
Button1 을 눌러 Wakeup 을 시키고, Button2 는 bonding 정보를 지울때 사용합니다.
(Button2 + 리셋 버튼)
1> Nordic document 는 아래 링크 참조하세요.
https://infocenter.nordicsemi.com/topic/sdk_nrf5_v17.1.0/ble_sdk_app_csc.html
2> 프로젝트 위치
: <InstallFolder>\examples\ble_peripheral\ble_app_cscs
3> nRF Connect 앱을 통한 연결 && 서비스 && 특성
3-1> 디바이스 스캔 및 연결
▶ "Nordic_CSC" 장비 검색후 CONNECT 버튼을 눌러줍니다.
3-2> 서비스
▶ 5개의 서비스가 발견이 됩니다.
(Generic Access / Generic Attribute/ Cycling Speed and Cadence/ Battery Service/ Device Information)
3-3> 각 서비스 항목별 특성
▶ Generic Access 서비스 아래의 4개의 특성
(Device Name/ Appearance/ PPCP / Central Address Resolution )
▶ CSC 서비스 아래의 4개의 특성 및 2개의 descriptor
( CSC Measurement / CSC Feature / Sensor Location / SC Control Point )
▶ Battery 서비스 아래의 1개의 특성 및 1개의 descriptor
(Battery Level)
▶ Device Information 서비스 아래의 1개의 특성
( Manufacturer Name String)
4> nRF Logger 메시지 ( nRF Connect 앱 통한 Connect 완료시 까지)
nRF Connect, 2022-06-30 Nordic_CSC (D0:8E:FB:B9:09:43)
V 19:44:57.931 Connecting to D0:8E:FB:B9:09:43...
D 19:44:57.931 gatt = device.connectGatt(autoConnect = false, TRANSPORT_LE, preferred PHY = LE 1M)
D 19:44:58.145 [Callback] Connection state changed with status: 0 and new state: CONNECTED (2)
I 19:44:58.145 Connected to D0:8E:FB:B9:09:43
V 19:44:58.149 Discovering services...
D 19:44:58.149 gatt.discoverServices()
D 19:44:58.161 [Broadcast] Action received: android.bluetooth.device.action.ACL_CONNECTED
I 19:44:58.369 Connection parameters updated (interval: 7.5ms, latency: 0, timeout: 5000ms)
D 19:44:58.646 [Callback] Services discovered with status: 0
I 19:44:58.646 Services discovered
V 19:44:58.652 Generic Access (0x1800)
- Device Name [R W] (0x2A00)
- Appearance [R] (0x2A01)
- Peripheral Preferred Connection Parameters [R] (0x2A04)
- Central Address Resolution [R] (0x2AA6)
Generic Attribute (0x1801)
Cycling Speed and Cadence (0x1816)
- CSC Measurement [N] (0x2A5B)
Client Characteristic Configuration (0x2902)
- CSC Feature [R] (0x2A5C)
- Sensor Location [R] (0x2A5D)
- SC Control Point [I W] (0x2A55)
Client Characteristic Configuration (0x2902)
Battery Service (0x180F)
- Battery Level [N R] (0x2A19)
Client Characteristic Configuration (0x2902)
Device Information (0x180A)
- Manufacturer Name String [R] (0x2A29)
D 19:44:58.652 gatt.setCharacteristicNotification(00002a5b-0000-1000-8000-00805f9b34fb, true)
D 19:44:58.654 gatt.setCharacteristicNotification(00002a55-0000-1000-8000-00805f9b34fb, true)
D 19:44:58.656 gatt.setCharacteristicNotification(00002a19-0000-1000-8000-00805f9b34fb, true)
I 19:44:58.715 Connection parameters updated (interval: 35.0ms, latency: 0, timeout: 5000ms)
I 19:45:03.791 Connection parameters updated (interval: 980.0ms, latency: 0, timeout: 4000ms)
D 20:18:23.173 [Callback] Connection state changed with status: 0 and new state: DISCONNECTED (0)
I 20:18:23.184 Disconnected
D 20:18:23.302 [Broadcast] Action received: android.bluetooth.device.action.ACL_DISCONNECTED
5> nRF Toolbox 앱을 통한 연결 및 동작 영상
7> Testing
: 문서에 보면 총 7단계로 되어 있습니다.
7-1> 프로그램 빌드 && 다운로드
▶ 다른 예제 내용 참고하세요.
정상적으로 다운로드후 부팅이 되면 Fast advertising을 시작하고 LED1 이 깜박입니다.
7-2> nRF Connect for Desktop 을 통한 "Nordic_CSC" 장치 연결 && Bond
< 원문>
Connect to the device from nRF Connect (the device is advertising as 'Nordic_CSC'),
then bond to the device. To bond, click the settings button for the device in nRF Connect,
select "Pair", check "Perform Bonding", and click "Pair".
Wait until the bond is established before you continue.
Observe that the BSP_INDICATE_CONNECTED state is indicated.
▶ nRF Connect for Desktop 실행 && Bluetooth Low Energy 열기
▶ SELECT DEVICE 에서 nRF52 DK 선택하기
: 여기부터는 한대의 다른장비가 필요합니다.
▶ Start Scan 및 "Nordic_CSC" Connect 하기
==> 아래그림처럼 Start scan 버튼 클릭
==> "Nordic_CSC" 장치가 검색되면 Connect 버튼 클릭해 줍니다.
▶ 연결완료 화면에서 설정버튼 클릭
▶ "Pair..." 버튼 클릭
▶ "Perform bonding" 체크 && "Pair" 버튼 클릭
▶ 아래그림처럼 Pairing 화면이 나오면 Close 버튼을 눌러줍니다.
▶ 정상적으로 연결이 완료되면 Nordic_CSC 장치의 LED1 불이 켜져 있어야 합니다.
7-3> 서비스 내용 중 CSC 서비스 아래의 CSC Measurement notification 을 enable 하고
배터리 notification 또한 Enable 합니다.
< 원문>
Observe that the services are shown in the connected device and
that you can start receiving values by clicking the 'Play' button.
Cycling Speed and Cadence notifications are received every second, and
Battery Level notifications are received every two seconds.
▶ 서비스 5개는 3-2번 항목에서 설명했습니다.
▶ Notification을 받기위해 아래 그림의 Play 버튼 클릭
▶ CSC measurement 값이 1초간격으로 업데이트 됩니다.
▶ 배터리값을 받기 위해서는 아래그림처럼 Battery Service 아래의 Battery Level 특성의
notification 을 enable 시켜야 합니다.
==> CSC && battery notification enable 후 영상을 기타 항목에 첨부하니 참고하세요.
7-4> 아래 원문에서 순서상 한가지 빠진 부분이 있어서 추가했습니다.
< 원문>
Do a 'start auto calibration' speed and cadence control point operation
▶ Write value '02' (OpCode: BLE_SCPT_START_AUTOMATIC_CALIBRATION) to
the SC Control Point Characteristic (UUID 0x2A55).
▶ Observe that you receive one indication of the SC Control Point Characteristic indicating success (100201).
7-4-1> SC Control Point CCCD indication Enable (Play 버튼) 한 후 데이타 '02' 쓰기
7-4-2> indication data 로 "10 02 01" 값이 들어오는지 확인합니다.
10 : BLE_SCPT_RESPONSE_CODE
02 : OPCOE ( BLE_SCPT_START_AUTOMATIC_CALIBRATION)
01 : STATUS ( BLE_SCPT_SUCCESS )
7-5> Do a 'set cumulative value' speed and cadence control point operation
▶ SC Control Point 에 '01 12 34 56 78' 쓰기
01 : BLE_SCPT_SET_CUMULATIVE_VALUE
12 34 56 78 : cumulative_value (32bit)
▶ indication data 로 '10 01 01' 값이 들어오는지 확인
Observe that you receive one indication of the SC Control Point Characteristic indicating success (100101)
and that the bytes 1-4 of the next Csc Measurement nofitications match the new value
(received notification should be yyxx345678, where yy being the byte 0 containing flags,
xx being the cumulative value LSB which changes quickly, and should be bigger than 12).
7-6> Do a 'request supported sensor locations' speed and cadence control point operation
▶ Write value '04' (OpCode: BLE_SCPT_REQUEST_SUPPORTED_SENSOR_LOCATIONS) to the SC Control Point
▶ Observe that you receive one indication of the SC Control Point Characteristic indicating success
and the list of supported locations (1004010405060708090A0B0C0D).
7-7> Do an 'update sensor location' speed and cadence control point operation
▶ Write value '03 0A' (OpCode: BLE_SCPT_UPDATE_SENSOR_LOCATION Operand:
SENSOR_LOCATION_REAR_DROPOUT) to the SC Control Point Characteristic (UUID 0x2A55).
▶ Observe that you receive one indication of the SC Control Point Characteristic indicating success (100301).
▶ Read the Sensor Location Charactersitic (UUID 0x2A5D) and verify that the read value is 0x0A
8> 상세분석
8-1> 2 개의 timer 가 사용되고 각각 다음의 기능을 수행합니다.
▶ Battery level update ,
▶ Cycling Speed and Cadence Measurements.
8-2> CSC Measurement Notification enable 시 들어오는 데이타
▶ 관련코드
: timer 관련 코드 및 sd_ble_gatts_hvx(...) 함수 호출이 되는 곳을 찾으면 됩니다.
--> notification 이 1초 단위로 들어오므로 timer 관련 코드찾기
APP_TIMER_DEF(m_csc_meas_timer_id);
app_timer_create(&m_csc_meas_timer_id, APP_TIMER_MODE_REPEATED, csc_meas_timeout_handler);
#define SPEED_AND_CADENCE_MEAS_INTERVAL 1000
csc_meas_timer_ticks = APP_TIMER_TICKS(SPEED_AND_CADENCE_MEAS_INTERVAL);
app_timer_start(m_csc_meas_timer_id, csc_meas_timer_ticks, NULL);
void csc_meas_timeout_handler(void * p_context)
{
~~~~ 중략 ~~~~
ble_cscs_measurement_send(&m_cscs, &cscs_measurement);
~~~~ 중략 ~~~~
}
uint32_t ble_cscs_measurement_send(ble_cscs_t * p_cscs, ble_cscs_meas_t * p_measurement)
{
~~~~ 중략 ~~~~
csc_measurement_encode(p_cscs, p_measurement, encoded_csc_meas);
~~~~ 중략 ~~~~
hvx_params.type = BLE_GATT_HVX_NOTIFICATION;
~~~~ 중략 ~~~~
sd_ble_gatts_hvx(p_cscs->conn_handle, &hvx_params);
}
▶ 위 CSC Measurement notification 데이타를 해석해 보면
Notification data: 3 A7 00 00 00 C0 B6 37 00 F7 B4
3 A7 00 00 00 (4) C0 B6 (2) 37 00 (2) F7 B4 (2)
Flag cumulative_wheel_revs last_wheel_event_time cumulative_crank_revs last_crank_event_time
8-3> Notification data 2개 이상일 경우 구분 방법
▶ ble_gatts_hvx_params_t 구조체 인자중 handle 값을 체킹
8-4> CCCD Write 시 호출되는 ble 이벤트
▶ BLE_GATTS_EVT_WRITE
8-5> SC Control Point (0x2A55) 특성 write 시 호출되는 코드
▶ call stack
>> 초기 characteristic 추가 관련 코드
uint32_t characteristic_add(uint16_t service_handle,
ble_add_char_params_t * p_char_props,
ble_gatts_char_handles_t * p_char_handle)
{
ble_gatts_attr_t attr_char_value;
ble_gatts_attr_md_t attr_md;
~~~~ 중략 ~~~~
attr_md.wr_auth = (p_char_props->is_defered_write ? 1 : 0);
~~~~ 중략 ~~~~
attr_char_value.p_attr_md = &attr_md;
~~~~ 중략 ~~~~
return sd_ble_gatts_characteristic_add(..., &char_md, &attr_char_value, p_char_handle);
}
uint32_t ble_sc_ctrlpt_init(ble_sc_ctrlpt_t * p_sc_ctrlpt,
const ble_cs_ctrlpt_init_t * p_sc_ctrlpt_init)
{
ble_add_char_params_t add_char_params;
~~~~ 중략 ~~~~
add_char_params.uuid = BLE_UUID_SC_CTRLPT_CHAR;
~~~~ 중략 ~~~~
add_char_params.is_defered_write = true;
return characteristic_add(..., &add_char_params, &p_sc_ctrlpt->sc_ctrlpt_handles);
}
>> write 시 호출되는 코드
#define BLE_CSCS_DEF(_name) \
static ble_cscs_t _name; \
NRF_SDH_BLE_OBSERVER(_name ## _obs, BLE_CSCS_BLE_OBSERVER_PRIO, ble_cscs_on_ble_evt, &_name)
BLE_CSCS_DEF(m_cscs);
void ble_cscs_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context)
{
~~~~ 중략 ~~~~
ble_sc_ctrlpt_on_ble_evt(&(p_cscs->ctrl_pt), p_ble_evt);
~~~~ 중략 ~~~~
}
void ble_sc_ctrlpt_on_ble_evt(ble_sc_ctrlpt_t * p_sc_ctrlpt, ble_evt_t const * p_ble_evt)
{
~~~~ 중략 ~~~~
switch (p_ble_evt->header.evt_id)
{
~~~~ 중략 ~~~~
case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST:
on_rw_authorize_request(p_sc_ctrlpt, &p_ble_evt->evt.gatts_evt);break;
~~~~ 중략 ~~~~
}
}
void on_rw_authorize_request(ble_sc_ctrlpt_t * p_sc_ctrlpt, ble_gatts_evt_t const * p_gatts_evt)
{
~~~~ 중략 ~~~~
on_ctrlpt_write(p_sc_ctrlpt, &p_auth_req->request.write);
}
void on_ctrlpt_write(ble_sc_ctrlpt_t * p_sc_ctrlpt,
ble_gatts_evt_write_t const * p_evt_write)
{
~~~~ 중략 ~~~~
sd_ble_gatts_rw_authorize_reply(p_sc_ctrlpt->conn_handle, &auth_reply);
~~~~ 중략 ~~~~
}
==> 특성 write 시 값으로 들어오는 변수 심층분석 (ble_gatts_evt_write_t ==> data[] )
typedef struct
{
~~ 중략 ~~
uint8_t data[1];
} ble_gatts_evt_write_t;
typedef struct
{
uint8_t type;
union {
~~ 중략 ~~
ble_gatts_evt_write_t write;
} request;
} ble_gatts_evt_rw_authorize_request_t;
typedef struct
{
uint16_t conn_handle;
union
{
~~ 중략 ~~
ble_gatts_evt_rw_authorize_request_t authorize_request;
~~ 중략 ~~
} params;
} ble_gatts_evt_t;
typedef struct
{
ble_evt_hdr_t header; /**< Event header. */
union
{
~~ 중략 ~~
ble_gatts_evt_t gatts_evt;
~~ 중략 ~~
} evt; /**< Event union. */
} ble_evt_t;
<기타>
A> Bluetooth Low Energy 프로그램 로그 출력
15:13:45.471 Using nrf-device-lib-js version: 0.4.5
15:13:45.472 Using nrf-device-lib version: 0.11.0
15:13:45.472 Using nrfjprog DLL version: 10.15.1
15:13:45.472 Using JLink version: JLink_V7.58b
15:13:45.507 Updated list of uuids with data from https://github.com/NordicSemiconductor/bluetooth-numbers-database/tree/master/v1
15:13:50.058 Selected device with s/n 000682577309
15:13:50.885 Device setup completed
15:13:50.886 Getting information from J-Link debugger...
15:13:50.887 Found device type: nRF52832. J-Link firmware: J-Link OB-SAM3U128-V2-NordicSemi compiled Feb 2 2021 16:47:20.
15:13:51.725 Connectivity firmware version: 4.1.4. SoftDevice API version: 5.
15:13:51.730 Opening adapter connected to COM4
15:13:52.687 Successfully opened COM4. Baud rate: 1000000. Flow control: none. Parity: none.
15:13:52.694 Reset performed on adapter COM4
15:13:53.779 Adapter connected to COM4 opened
15:14:15.395 Scan started
15:15:15.408 Scanning timed out on adapter COM4
15:18:44.664 Scan started
15:18:56.530 Connecting to device
15:18:56.575 Connected to device D0:8E:FB:B9:09:43: interval: 7.5ms, timeout: 4000ms, latency: 0
15:18:56.910 Attribute value read, handle: 0x03, value (0x): 4E-6F-72-64-69-63-5F-43-53-43
15:19:52.824 Security updated, mode:1, level:2
15:19:52.854 Storing bond info for device D0:8E:FB:B9:09:43
15:52:54.335 Attribute value changed, handle: 0x0E, value (0x): 01-00
15:52:54.345 Attribute value written, handle: 0x0E, value (0x): 01-00
15:52:55.138 Attribute value changed, handle: 0x0D, value (0x): 03-66-1A-00-00-E5-EF-A3-08-C0-E9
15:52:56.143 Attribute value changed, handle: 0x0D, value (0x): 03-68-1A-00-00-EE-F3-A4-08-24-F1
15:52:57.140 Attribute value changed, handle: 0x0D, value (0x): 03-6A-1A-00-00-B6-F7-A5-08-AF-F7
15:52:58.138 Attribute value changed, handle: 0x0D, value (0x): 03-6C-1A-00-00-49-FB-A5-08-B6-F7
15:52:59.143 Attribute value changed, handle: 0x0D, value (0x): 03-6E-1A-00-00-AE-FE-A6-08-74-FD
15:52:59.385 Connection parameters updated for device D0:8E:FB:B9:09:43: interval 500ms, timeout 4000ms, latency: 0
15:53:00.392 Attribute value changed, handle: 0x0D, value (0x): 03-71-1A-00-00-85-03-A7-08-B9-02
15:53:01.392 Attribute value changed, handle: 0x0D, value (0x): 03-73-1A-00-00-91-06-A8-08-99-07
15:53:02.391 Attribute value changed, handle: 0x0D, value (0x): 03-76-1A-00-00-F3-0A-A8-08-A0-07
15:53:03.391 Attribute value changed, handle: 0x0D, value (0x): 03-79-1A-00-00-1E-0F-A9-08-24-0C
15:53:04.390 Attribute value changed, handle: 0x0D, value (0x): 03-7C-1A-00-00-19-13-AA-08-68-10
15:53:05.392 Attribute value changed, handle: 0x0E, value (0x): 00-00
15:53:05.418 Attribute value written, handle: 0x0E, value (0x): 00-00
15:56:36.906 Disconnected from device D0:8E:FB:B9:09:43, reason: BLE_HCI_LOCAL_HOST_TERMINATED_CONNECTION
15:56:41.818 Connecting to device
15:56:41.867 Connected to device D0:8E:FB:B9:09:43: interval: 7.5ms, timeout: 4000ms, latency: 0
15:56:41.919 Security updated, mode:1, level:2
15:56:42.207 Attribute value read, handle: 0x03, value (0x): 4E-6F-72-64-69-63-5F-43-53-43
15:56:57.278 Authentication failed with status BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP
16:09:19.869 Attribute value changed, handle: 0x0E, value (0x): 01-00
16:09:19.878 Attribute value written, handle: 0x0E, value (0x): 01-00
16:09:20.161 Attribute value changed, handle: 0x0D, value (0x): 03-28-27-00-00-93-53-D1-0C-10-53
16:09:21.168 Attribute value changed, handle: 0x0D, value (0x): 03-2D-27-00-00-5D-57-D3-0C-74-57
16:09:22.164 Attribute value changed, handle: 0x0D, value (0x): 03-33-27-00-00-FE-5B-D5-0C-EC-5B
16:09:23.162 Attribute value changed, handle: 0x0D, value (0x): 03-38-27-00-00-F8-5F-D6-0C-3B-5E
16:09:24.167 Attribute value changed, handle: 0x0D, value (0x): 03-3C-27-00-00-3C-63-D8-0C-EE-62
16:09:24.921 Connection parameters updated for device D0:8E:FB:B9:09:43: interval 500ms, timeout 4000ms, latency: 0
16:09:25.425 Attribute value changed, handle: 0x0D, value (0x): 03-41-27-00-00-69-67-DA-0C-CB-67
16:09:26.424 Attribute value changed, handle: 0x0D, value (0x): 03-46-27-00-00-B6-6B-DB-0C-50-6A
16:09:27.424 Attribute value changed, handle: 0x0D, value (0x): 03-4A-27-00-00-42-6F-DD-0C-7A-6F
16:09:28.424 Attribute value changed, handle: 0x0D, value (0x): 03-4F-27-00-00-D0-73-DE-0C-28-72
16:09:29.424 Attribute value changed, handle: 0x0D, value (0x): 03-53-27-00-00-95-77-E0-0C-AC-77
16:09:30.424 Attribute value changed, handle: 0x0D, value (0x): 03-57-27-00-00-78-7B-E1-0C-8D-7A
16:09:31.424 Attribute value changed, handle: 0x0D, value (0x): 03-5B-27-00-00-7B-7F-E2-0C-80-7D
16:09:32.424 Attribute value changed, handle: 0x0D, value (0x): 03-5F-27-00-00-A1-83-E4-0C-A2-83
16:09:33.425 Attribute value changed, handle: 0x0D, value (0x): 03-63-27-00-00-EF-87-E5-0C-DD-86
16:09:34.425 Attribute value changed, handle: 0x0D, value (0x): 03-66-27-00-00-4A-8B-E6-0C-32-8A
16:09:35.425 Attribute value changed, handle: 0x0D, value (0x): 03-6A-27-00-00-E9-8F-E7-0C-A5-8D
16:09:36.427 Attribute value changed, handle: 0x0D, value (0x): 03-6D-27-00-00-88-93-E8-0C-3B-91
16:09:37.427 Attribute value changed, handle: 0x0D, value (0x): 03-70-27-00-00-4A-97-E9-0C-F7-94
16:09:38.426 Attribute value changed, handle: 0x0D, value (0x): 03-73-27-00-00-33-9B-EA-0C-E1-98
16:09:39.426 Attribute value changed, handle: 0x0D, value (0x): 03-76-27-00-00-49-9F-EB-0C-00-9D
16:09:40.427 Attribute value changed, handle: 0x0D, value (0x): 03-79-27-00-00-91-A3-EC-0C-5B-A1
16:09:41.427 Attribute value changed, handle: 0x0D, value (0x): 03-7B-27-00-00-91-A6-ED-0C-00-A6
16:09:42.425 Attribute value changed, handle: 0x0D, value (0x): 03-7E-27-00-00-43-AB-EE-0C-FA-AA
16:09:43.426 Attribute value changed, handle: 0x0D, value (0x): 03-80-27-00-00-94-AE-EE-0C-E9-AA
16:09:44.427 Attribute value changed, handle: 0x0D, value (0x): 03-83-27-00-00-D4-B3-EF-0C-63-B0
16:09:45.426 Attribute value changed, handle: 0x0D, value (0x): 03-85-27-00-00-98-B7-F0-0C-6B-B6
16:09:45.929 Attribute value changed, handle: 0x0E, value (0x): 00-00
16:09:45.953 Attribute value written, handle: 0x0E, value (0x): 00-00
B > CSC && 배터리 레벨 notification Enable 후 들어오는 데이타 영상
C> CSC 광고 패킷 분석
D> Bluetooth Profile && Service
▶ Cycling Speed and Cadence Profile
▶ Cycling Speed and Cadence Service
그럼 오늘도 수고하세요.
'Nordic_nRF52' 카테고리의 다른 글
[nRF52] record_launch_app 프로젝트 분석 (0) | 2022.12.30 |
---|---|
[nRF52 ] DFU serial 에러 메시지 (0) | 2022.07.21 |
[nRF52 ] ble_app_hrs_rscs_relay 프로젝트 분석 (0) | 2022.06.17 |
[nRF52 ] ble_app_bps 프로젝트 분석 (0) | 2022.06.14 |
[nRF52 ] ble_app_alert_notification 프로젝트 분석 (0) | 2022.06.13 |