This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts
This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

How do I control servo simultaneosly in the interrupt_hadler?

FormerMember
FormerMember

Hi,

I'm using SD110, SDK 10.0.0, nRF51822

In my own application, I control 4 servo by pwm with Timer1 and Timer2,

and I have 2 buttons, each button is a flag for moving servo1,2 and servo3,4.

When button1 occur button_interrupt, a flag which I declared refer move_servo1_or_servo2.

This is example code :

button_handler()
{
  switch(pin)
  {
    case button1:
     flag = move_servo1_or_servo2;
     break;
    case button2:
     flag = move_servo3_or_servo4;
     break;
  }
}

int main()
{
  while()
  {
    if(flag != null)
    {
      move_servo(flag);
    }
  }
}

Until now, This is not a problem, but I need to control servo within interrupt.

For example :

button_handler()
{
  switch(pin)
  {
    case button1:
      move_servo1();
      break;
    case button2:
      move_servo2();
      break;
  }
}

Like above,

The problem is when I deal with controling servo in interrupt, application is stopped every activity, or something unpredictable result.

How do I solve it?

Thaks,

  • What do move_servo1() and move_servo2() do? After the pwm value is updated with app_pwm_channel_duty_set(..) it will be busy until it receives a timer interrupt. This interrupt is run at APP_IRQ_PRIORITY_LOW. If you are waiting for the pwm to be ready in another interrupt you will wait forever since the pwm will stay busy forever (timer interrupt will never happen).

    For example, don't do this in the button interrupt:

    while (app_pwm_channel_duty_set(&PWM1, 0, value) == NRF_ERROR_BUSY);
    
  • FormerMember
    0 FormerMember

    Okay, let me explain you another example.

    I have two servo motors and two buttons, and each servo's pwm is matched with timer1 and timer2.

    And I can active servo1 by button1, servo2 by button2.

    When I push button1 and button2 in the same time, I wanna active two servo motors in the same time.

    For now, I've programmed it like below(I tried, but failed, It wasn't actived in the same time) :

    void button_handler()
    {
      switch(pin)
      {
        case button1:
          active_servo(1);
          break;
        case button2:
          active_servo(2);
          break;
      }
    }
    
    inline void active_servo(i)
    {
      app_pwm_channel_duty_set(pwm[i], 0, value1);
      nrf_delay_ms(550);
      app_pwm_channel_duty_set(pwm[i], 0, value2);
      nrf_delay_ms(450);
    }
    

    How do I program it?

  • Again you are doing the update inside an interrupt (button_handler). The first app_pwm_channel_duty_set(..) will probably work, but the next will not because it will not be ready before the timer interrupt has happen, which will at earliest happen after the button_handler is finished. If you check the return value of the second call to app_pwm_channel_duty_set(..) it should be NRF_ERROR_BUSY. Use app scheduler to run the function in main context instead.

  • FormerMember
    0 FormerMember

    Thanks, I apply app_scheduler and though it wouldn't be actived simultaneously, but it is up to me. Eventually, now I contorl servo motors in main context, so I can do that soon.

Related