본문 바로가기
Embedded/nRF52 BLE 개발 안내서

nRF52 BLE 개발하기 - led_softblink

by 큐찡 2021. 1. 2.
728x90
반응형

시작하기

저번 글에서 LED를 켜고 끄는 방법에 대해서 알아보았다.

이번에는 예제 이름에서 알 수 있듯이 LED를 좀 더 부드럽게 켜고 끄는 방법에 대해서 알아보겠다.

어째서 LED를 부드럽게 켜고 꺼야 하는지 궁금하겠지만 이런 기능을 요구하는 사람들도 있기 마련이다.

그럼 바로 led_softblink\pca10040\blank\ses 폴더로 가서 프로젝트 파일을 실행시켜보자.

/**
 * @brief Function for starting lfclk needed by APP_TIMER.
 */
static void lfclk_init(void)
{
    uint32_t err_code;
    err_code = nrf_drv_clock_init();
    APP_ERROR_CHECK(err_code);

    nrf_drv_clock_lfclk_request(NULL);
}

/**
 * @brief Function for application main entry.
 */
int main(void)
{
    ret_code_t err_code;

    lfclk_init();

    // Start APP_TIMER to generate timeouts.
    err_code = app_timer_init();
    APP_ERROR_CHECK(err_code);

    const led_sb_init_params_t led_sb_init_param = LED_SB_INIT_DEFAULT_PARAMS(LEDS_MASK);

    err_code = led_softblink_init(&led_sb_init_param);
    APP_ERROR_CHECK(err_code);

    err_code = led_softblink_start(LEDS_MASK);
    APP_ERROR_CHECK(err_code);

    while (true)
    {
        __WFE();
    }
}

blinky 예제와는 다르게 소스코드가 이제 좀 복잡해 보인다. 하지만 한 줄 한 줄 들여다보면 답이 보이는 법이다.

저번에는 함수 위치에서 콘텍스트 메뉴를 통해 함수가 정의된 위치를 찾아 분석했지만 이번에는 다른 방법으로 분석해보겠다.

노르딕에서는 예제에 대한 설명을 사이트를 통해 제공해주는데 이곳에서 함수를 검색하고 기능을 대략적으로 알 수 있다.

링크를 통해 노르딕 인포센터 사이트에 접속해보자.

사이트 첫 화면을 보면 좌측에는 카테고리별로 분류되어 있고 우측에는 해당되는 내용이 표시되는 구성이다.

여기서 led_softblink 예제에 대한 설명을 찾으려면 다음과 같이 카테고리를 찾으면 된다.

Software Development Kit - nRF5 SDK v17.0.2 - Examples - Hardware peripheral examples - LED Softblink Example

The LED Softblink Example demonstrates how to use the LED softblink library. It shows how to light up the LEDs with a gradual changing intensity that depends on the parameters that are specified during initialization.

You can find the source code and the project file of the example in the following folder: <InstallFolder>\examples\peripheral\led_softblink

Testing
Test the LED Softblink Example application by performing the following steps:

Compile and program the application.
Observe that the LED light intensity changes. The LEDs stay turned off for 2 seconds between every cycle.

설명을 대략적으로 살펴보면 LED softblink library를 사용해서 예제를 구현하고 있다고 한다.

그렇다면 LED softblink library가 뭔지 한 번 알아보자.

The LED softblink library provides functions to generate and configure a changing pulse-width modulated output signal that can be used to smoothly blink LEDs.

The library uses the Low-power PWM library to generate the signal.

Key features include:
 ⊙ Configurable intensity, pauses, and changing speed.
 ⊙ Any number of output channels.
 ⊙ Configurable polarity.
 ⊙ Power efficient because of the use of the Low-power PWM library.

Only one instance of LED softblink can be used at a time. If you require more instances, use the Low-power PWM library directly.

This library uses an application timer and is therefore not very accurate. It can be used to control LEDs, but for peripherals that need a high accuracy, you should use the PWM library instead.

Starting LED softblink

Complete the following steps to start LED softblink on the default LEDs:
 1. Start Application Timer.
 2. Create a led_sb_init_params_t structure that holds the initialization parameters. If you want to use the default configuration, call the   LED_SB_INIT_DEFAULT_PARAMS macro with the LED mask to fill the init structure.
 The following parameters must be specified:
  ⊙ active_high: Polarity.
  ⊙ duty_cycle_max: Maximum pulse width (in ticks, with the period set to 255 ticks).
  ⊙ duty_cycle_min: Minimum pulse width (in ticks, with the period set to 255 ticks).
  ⊙ duty_cycle_step: Duty cycle change step. This value denotes the delta in ticks between the current duty cycle and the next.
  ⊙ off_time_ms: Time to stay in minimum duty cycle.
  ⊙ on_time_ms: Time to stay in maximum duty cycle.
  ⊙ leds_pin_bm: Mask of used LEDs.
 3.Call led_softblink_init with the init structure to initialize LED softblink.
 4.Use the led_softblink_start function to start LED softblink. Specify the same pin mask that you used in led_sb_init_params_t or a subset of it.

The following code example shows how to initialize LED softblink with the default configuration and start blinking the LEDs:

led_sb_init_params_t led_sb_init_params = LED_SB_INIT_DEFAULT_PARAMS(LEDS_MASK); 
// create structure and fill with default configuration using given LEDS_MASK
ret_code_t ret = led_softblink_init(&led_sb_init_params);
// handle ret - if (ret==NRF_SUCCESS):
ret = led_softblink_start(LEDS_MASK);

LED softblink library는 Low-power PWM library를 사용해서 LED를 부드럽게 깜박이게 하는 기능을 구현한다고 한다.

application timer를 사용하므로 LED를 제어하는 데에는 문제없지만 높은 정확도를 필요로 한다면 적합하지 않은 것 같다.

LED를 부드럽게 깜박이기 위한 순서는 다음과 같다.

1. application timer를 시작한다.

2. led_sb_init_params_t led_sb_init_params = LED_SB_INIT_DEFAULT_PARAMS(LEDS_MASK) 이런 식으로 초기화를 시켜준다.

led_sb_init_params_t 구조체에는 softblink를 위한 초기화 값을 지정해줄 수 있으며 LED_SB_INIT_DEFAULT_PARAMS의 값으로 설정한다.

3. led_softblink_init 함수를 호출하여 LED softblink를 초기화한다.

4. led_softblink_start 함수를 호출하여 LED softblink를 사용한다.

/**
 * @brief Structure holding the initialization parameters.
 */
typedef struct
{
    bool            active_high;     /**< Activate negative polarity. */
    uint8_t         duty_cycle_max;  /**< Maximum impulse width. */
    uint8_t         duty_cycle_min;  /**< Minimum impulse width. */
    uint8_t         duty_cycle_step; /**< Cycle step. */
    uint32_t        off_time_ticks;  /**< Ticks to stay in low impulse state. */
    uint32_t        on_time_ticks;   /**< Ticks to stay in high impulse state. */
    uint32_t        leds_pin_bm;     /**< Mask of used LEDs. */
    NRF_GPIO_Type * p_leds_port;     /**< Port of used LEDs mask. */
}led_sb_init_params_t;

/**
 * @name Default settings
 * @brief Default settings for LED softblink.
 * @{
 */
#define LED_SB_INIT_PARAMS_ACTIVE_HIGH            false
#define LED_SB_INIT_PARAMS_DUTY_CYCLE_MAX         220
#define LED_SB_INIT_PARAMS_DUTY_CYCLE_MIN         0
#define LED_SB_INIT_PARAMS_DUTY_CYCLE_STEP        5
#define LED_SB_INIT_PARAMS_OFF_TIME_TICKS         65536
#define LED_SB_INIT_PARAMS_ON_TIME_TICKS          0
#define LED_SB_INIT_PARAMS_LEDS_PIN_BM(mask)      (mask)
#define LED_SB_INIT_PARAMS_LEDS_PORT              NRF_GPIO
/** @} */

/**
 * @brief LED softblink default configuration.
 */
#define LED_SB_INIT_DEFAULT_PARAMS(mask)                            \
{                                                                   \
    .active_high        = LED_SB_INIT_PARAMS_ACTIVE_HIGH,           \
    .duty_cycle_max     = LED_SB_INIT_PARAMS_DUTY_CYCLE_MAX,        \
    .duty_cycle_min     = LED_SB_INIT_PARAMS_DUTY_CYCLE_MIN,        \
    .duty_cycle_step    = LED_SB_INIT_PARAMS_DUTY_CYCLE_STEP,       \
    .off_time_ticks     = LED_SB_INIT_PARAMS_OFF_TIME_TICKS,        \
    .on_time_ticks      = LED_SB_INIT_PARAMS_ON_TIME_TICKS,         \
    .leds_pin_bm        = LED_SB_INIT_PARAMS_LEDS_PIN_BM(mask),     \
    .p_leds_port        = LED_SB_INIT_PARAMS_LEDS_PORT              \
}

#define LEDS_MASK      (BSP_LED_0_MASK | BSP_LED_1_MASK | \
                        BSP_LED_2_MASK | BSP_LED_3_MASK | \
                        BSP_LED_4_MASK | BSP_LED_5_MASK | \
                        BSP_LED_6_MASK | BSP_LED_7_MASK)

복잡해 보이지만 여기서 알아야 하는 부분은 그렇게 많지 않다.

softblink를 사용하기 위해 단 4줄의 코드를 작성하면 바로 기능을 사용할 수 있다.

물론 led_sb_init_params_t 구조체의 초기화 값을 변경하려면 매개변수에 대해 알아야 하지만 그 부분도 그렇게 어렵지 않다.

active_high : false (LED 회로의 극성으로 active low이므로 false)
duty_cycle_max : 220 (최대 펄스폭)
duty_cycle_min : 0 (최소 펄스폭)
duty_cycle_step : 5 (펄스 스텝)
off_time_ms : 65536 (최소 듀티 사이클을 유지하는 시간)
on_time_ms : 0 (최대 듀티 사이클을 유지하는 시간)
leds_pin_bm : LEDS_MASK (사용하려는 LED의 마스크)
p_leds_port : NRF_GPIO (사용하려는 LED의 포트)

LED 구동 회로가 active low 또는 high인가, 듀티 사이클 폭과 주기, 듀티 사이클 시간, LED 마스크만 설정해주면 된다.

이 부분은 nRF52 DK를 사용해서 값을 변경해보면 알 수 있을 것이다.

duty_cycle_step = 5 (좌), duty_cycle_step = 2(우)

앞으로

LED softblink library를 사용해서 LED를 부드럽게 깜박이게 하는 방법에 대해서 알아보았다.

지금까지 GPIO 출력에 관한 예제들이었다면 다음에는 GPIO 입력에 대한 예제를 통해 버튼 사용 방법에 대해 알아보도록 하자.

728x90
반응형

댓글