NRF delay is running before it was call

Hi,

I'm trying to use a nrf delay to make a delay for a motor. The idea is to make the motor oscillated by putting it forward and then reverse via a delay. (you can find this logic at the line 124, the function "oscillate").

But when I want to run the code, I got an issue, the delay is running before the motor is going forward (line 128 with the 1st pwm active). I don't understand why...
The delay is defined via math's formula at the line 77. I tried to put it as a constant and here's the troubleshoot :

  • With the delay as 3000 ms, we clearly see the delay before the motor starts spinning forward.
  • With the delay as 100ms, we don't see it, but it's probably there but the human eye can not see it

So what I want to resolve in my code is that this angluation_delay is running before my motor starts spinning when I want first the motor to spin forward, and then the delay to active.

#define SAMPLES_IN_BUFFER               1                                       //Number of SAADC samples in RAM before returning a SAADC event. For low power SAADC set this constant to 1. Otherwise the EasyDMA will be enabled for an extended time which consumes high current.

#define MOTOR_FORWARD                   34
#define MOTOR_REVERSE                   35

#define MOTOR_MAX_RPM                   50000

static nrf_saadc_value_t m_buffer[SAMPLES_IN_BUFFER];
bool test;
uint16_t motor_angluar_max_speed = MOTOR_MAX_RPM*2*M_PI/60;
uint8_t pourcent_speed;
static nrf_drv_pwm_t m_pwm0 = NRF_DRV_PWM_INSTANCE(0);
int gLEDG = MOTOR_FORWARD;
static uint16_t const m_top  = 255;
static nrf_pwm_values_individual_t  seq_values;
static nrf_pwm_sequence_t const seq =
{
    .values.p_individual = &seq_values,
    .length              = NRF_PWM_VALUES_LENGTH(seq_values),
    .repeats             = 0,
    .end_delay           = 0
};
uint16_t speed;
uint8_t angulation = 90;
uint32_t angulation_delay;

void update_pwm(uint16_t duty_forward, uint16_t duty_reverse)
{
    seq_values.channel_0 = m_top-duty_forward;
    seq_values.channel_1 = m_top-duty_reverse;

    nrf_drv_pwm_simple_playback(&m_pwm0, &seq, 1,  NRF_DRV_PWM_FLAG_LOOP);
}

static void idle_state_handle(void)
{
    if (NRF_LOG_PROCESS() == false)
    {
        nrf_pwr_mgmt_run();
    }
}

uint32_t get_rtc_counter(void)
{
    return NRF_RTC2->COUNTER;
}

/**@brief Function for initializing the nrf log module.
 */
static void log_init(void)
{
    ret_code_t err_code = NRF_LOG_INIT(get_rtc_counter);
    APP_ERROR_CHECK(err_code);

    NRF_LOG_DEFAULT_BACKENDS_INIT();
}

void saadc_callback(nrf_drv_saadc_evt_t const * p_event)
{
    if (p_event->type == NRF_DRV_SAADC_EVT_DONE)
    {
        ret_code_t err_code;

        err_code = nrf_drv_saadc_buffer_convert(p_event->data.done.p_buffer, SAMPLES_IN_BUFFER);
        APP_ERROR_CHECK(err_code);
        
        if (p_event->data.done.p_buffer[0] <= 0){
          speed = 0;
        } else{
          speed = p_event->data.done.p_buffer[0];
        }
        //NRF_LOG_INFO("SPEED %d\r\n", speed);
        pourcent_speed = floor(speed*100/255);       
        //NRF_LOG_INFO("POURCENT %d", pourcent_speed);
        float angulation_rad = angulation * (M_PI / 180.0);
        float number = (angulation_rad/(motor_angluar_max_speed*pourcent_speed/100))*100000;
        angulation_delay = (uint32_t) floor(number);
        //NRF_LOG_INFO("DELAY %d\r\n", angulation_delay);
    }
}

void saadc_init(void)
{
    ret_code_t err_code;
    nrf_saadc_channel_config_t channel_config = NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN5);
    
    ////Configure SAADC
    nrf_drv_saadc_config_t saadc_config;                                                  
    saadc_config.resolution = NRF_SAADC_RESOLUTION_8BIT;  

    err_code = nrf_drv_saadc_init(&saadc_config, saadc_callback);
    APP_ERROR_CHECK(err_code);

    err_code = nrf_drv_saadc_channel_init(0, &channel_config);
    APP_ERROR_CHECK(err_code);

    err_code = nrf_drv_saadc_buffer_convert(m_buffer, SAMPLES_IN_BUFFER);
    APP_ERROR_CHECK(err_code);
}

static void pwm_init(void)
{
    uint32_t err_code;
    nrf_drv_pwm_config_t const config0 =
    {
        .output_pins =
        {
            MOTOR_FORWARD,            // channel 0
            MOTOR_REVERSE,            // channel 1
            NRF_DRV_PWM_PIN_NOT_USED, // channel 2
            NRF_DRV_PWM_PIN_NOT_USED  // channel 3
        },
        .irq_priority = APP_IRQ_PRIORITY_LOWEST,
        .base_clock   = NRF_PWM_CLK_16MHz,
        .count_mode   = NRF_PWM_MODE_UP,
        .top_value    = m_top,
        .load_mode    = NRF_PWM_LOAD_INDIVIDUAL,
        .step_mode    = NRF_PWM_STEP_AUTO
    };
    err_code = nrf_drv_pwm_init(&m_pwm0, &config0, NULL);
    APP_ERROR_CHECK(err_code);
}

static void oscillate(void)
{      
    if (pourcent_speed > 5)
    {
        update_pwm(speed, 0);
        nrf_delay_ms(angulation_delay);
        update_pwm(0, speed);
        nrf_delay_ms(angulation_delay);
    } else
    {
        update_pwm(0, 0);
    }
}

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

    // Initialize.
    log_init();
    saadc_init();
    pwm_init();
    NRF_LOG_INFO("START");
    
    for (;;)
    {   
        nrf_drv_saadc_sample();
        oscillate();
        idle_state_handle();
    }
}


/**
 * @}
 */

Thanks for your answers,

Chris

Parents Reply Children
Related