This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

nrf52832 cannot control a PWM(servo motor) via Bluetooth

I am using the Hackable kit which has nrf52832 to control a servo motor and read accelerometer(AXL335) readings through a iOS app. I am a novice when comes to embedded. I got the ios app ready to send an integer value to the kit. Right now i am using the ble_blinky example from SDK 15 to turn on/off some external LED's and a piezo buzzer. But when i try to run the PWM_Library integrated(basically copy pasted with the pin numbers changed) in the same project the servo motor doesn't run and the program crashes at run time. Can anyone help me to accomplish my goal?

The code i use for BLE is as below.

APP_PWM_INSTANCE(PWM1,1);                   // Create the instance "PWM1" using TIMER1.(For Servo Motor)

static volatile bool ready_flag;            // A flag indicating PWM status.(For Servo Motor)

void pwm_ready_callback(uint32_t pwm_id)    // PWM callback function. (For Servo Motor)
{
    ready_flag = true;
}

void servo_config()
{
    ret_code_t err_code;
   app_pwm_config_t pwm1_cfg = APP_PWM_DEFAULT_CONFIG_2CH(5000L, 2, 3);

    /* Switch the polarity of the second channel. */
    pwm1_cfg.pin_polarity[1] = APP_PWM_POLARITY_ACTIVE_HIGH;

    /* Initialize and enable PWM. */
    err_code = app_pwm_init(&PWM1, &pwm1_cfg, pwm_ready_callback);
    APP_ERROR_CHECK(err_code);
    app_pwm_enable(&PWM1);
    nrf_gpio_cfg_output(2);
    nrf_gpio_cfg_output(3);
}

void servo_start()
{

    uint32_t value = 0;
    int a = 0;
    while (true) {
      
      for (uint8_t i = 0; i < 40; ++i) {
        value = (i < 20) ? (i * 5) : (100 - (i - 20) * 5);

        ready_flag = false;
        /* Set the duty cycle - keep trying until PWM is ready... */
        while (app_pwm_channel_duty_set(&PWM1, 0, value) == NRF_ERROR_BUSY)
          ;

        /* ... or wait for callback. */
        while (!ready_flag)
          ;
        APP_ERROR_CHECK(app_pwm_channel_duty_set(&PWM1, 1, value));
        nrf_delay_ms(25);
      }
      a = a + 1;
      if (a == 20) {
        break;
      }
  }
}

void servo_stop()
{
    app_pwm_disable(&PWM1);
    nrf_gpio_pin_clear(2);
    nrf_gpio_pin_clear(3);
} 

/**@brief Function for handling write events to the LED characteristic.
 *
 * @param[in] p_lbs     Instance of LED Button Service to which the write applies.
 * @param[in] led_state Written/desired state of the LED.
 */
static void led_write_handler(uint16_t conn_handle, ble_lbs_t *p_lbs, uint8_t led_state) {
 
  switch (led_state) {
  case 0:
    //bsp_board_led_off(LEDBUTTON_LED);
    NRF_LOG_INFO("Received LED OFF!");
    for (int i = 25; i < 28; i++) {
      nrf_gpio_pin_clear(i);
    }
    break;
  case 1:
    //bsp_board_led_on(LEDBUTTON_LED);
    NRF_LOG_INFO("Received LED ON!");
    for (int i = 25; i < 28; i++) {
      nrf_gpio_pin_set(i);
    }
    break;
  case 2:
    //Buzzer On
    nrf_gpio_pin_set(4);
    break;
  case 3:
    //Buzzer Off
    nrf_gpio_pin_clear(4);
    break;
  case 4:
    //Servo Motor ON
    servo_start();
    break;
  case 5:
    //Servo Off
    servo_stop();
    break;
  default:
    break;
  }
}

int main(void)
{
    // Initialize.
    log_init();
    leds_init();
    timers_init();

    buttons_init();
    power_management_init();
    ble_stack_init();
    gap_params_init();
    gatt_init();
    services_init();
    advertising_init();
    conn_params_init();
    
    //servo_start();
    // Start execution.
    NRF_LOG_INFO("Blinky example started.");
    advertising_start();
    servo_config();
    
//    // Enter main loop.
    for (;;)
    {
        idle_state_handle();
    }
}
it is same as the ble Blinky with this function added. Also there were some sdk_config changes that were made to compile this code like Enabling NRFX_TIMER = 1.

I am using SEGGER to program and compile the code, and push it to the device using ARM GCC GDB. 

Related