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

low power PWM library channel control

Hi,

So I am using nRF51822 chip to develop our products. We have two motors attacked to our PCB and we want to control the pulse with low power PWM. We want to control one motor at a time AND both motors at the same time. Is that possible? How do I need to take in the parameters to the functions? 

Thanks!

Parents
  • Hello,

    I suggest that you check out the SDK12.3.0\examples\peripheral\pwm_library example for this. (NB: the pwm_library, not pwm_driver).

    What you need to do is to find out what pwm frequency and duty cycle your pwm motors require.

    APP_PWM_DEFAULT_CONFIG_2CH() the first parameter is the pwm period in µs. The two last inputs are the pins for the two pwm channels.

    Then you can either use app_pwm_channel_duty_set(instance, channel, value), where channel is 0 or 1, and "value" is the duty cycle in percentage (0-100).

    If you don't want to use the percentage (It may be that it has too low resolution), you can use the app_pwm_channel_duty_ticks_set() to set the number of ticks on the timer directly.

    Best regards,

    Edvin

Reply
  • Hello,

    I suggest that you check out the SDK12.3.0\examples\peripheral\pwm_library example for this. (NB: the pwm_library, not pwm_driver).

    What you need to do is to find out what pwm frequency and duty cycle your pwm motors require.

    APP_PWM_DEFAULT_CONFIG_2CH() the first parameter is the pwm period in µs. The two last inputs are the pins for the two pwm channels.

    Then you can either use app_pwm_channel_duty_set(instance, channel, value), where channel is 0 or 1, and "value" is the duty cycle in percentage (0-100).

    If you don't want to use the percentage (It may be that it has too low resolution), you can use the app_pwm_channel_duty_ticks_set() to set the number of ticks on the timer directly.

    Best regards,

    Edvin

Children
  • We found out PWM drains a lot of power, so we decided to use LOW POWER PWM instead. Could you tell me how to call the functions so that I can control one motor at a time and control both motors at the same time? Thanks!

  • To control one or both motors:

    void control_motor1(void)
    {
        ...
        // the things you need to control motor 1
    }
    
    void control_motor2(void)
    {
        ...
        // the things you need to control motor 2
    }
    
    void control_both_motors(void)
    {
        control_motor1();
        control_motor2();
    }

    But I am not sure I would recommend to use the low_power_pwm. At least not if you intend to use the softdevice (If you want to do any Bluetooth low energy things in your application). Is that the plan?

    Yes. The pwm_library draws a bit more current, but it is not dependent on CPU activity to toggle the PWM pins, which the low_power_pwm example is. This means that when you have some softdevice interrupts, which is running on a higher priority than the PWM, you will get some pulses that are longer (or shorter) than intended, which might not be so fortunate when you use the PWM to control motors.

  • Sorry for not being clear to explain my problem. When I said controlling both motors, I mean that letting them vibrate at the same time. 

    And yes, we are using BLE as part of our application. Does that mean low power PWM is not recommended in this situation? I tried to use low power PWM and I cannot detect my device over BLE anymore. 

    So if you don't recommend using low power PWM while using softdevice, could you give some advice about how to reduce the current drawn? I saw some posts saying to call app_pwm_disable() function, but it didn't quite work (although the way I tested it is not enabling PWM after initializing it). Thanks!

  • The current drawn from using the pwm_library example is due to the timer running. As you say, it uses a bit more current than the low_power_pwm example, but does it really matter if you are also running 2 x PWM motors? I would imagine that they draw a lot more current. Isn't that the case?

    You may consider changing the TIMER to use one of the free RTCs, but then you can't use the app_timer module. The nRF51 only has two RTCs, and one is used by the softdevice, leaving you with one for the application. If it is used by the app_timer, you can't use it for this purpose. 

     

    moroboshidan said:
    I tried to use low power PWM and I cannot detect my device over BLE anymore. 

     Have you tried to debug this? Does the application stop? Does it advertise? 

    My guess is that you are caught in the error handler. One of the calls to APP_ERROR_CHECK(err_code); receives an err_code != 0 (NRF_SUCCESS).

    Define DEBUG in your preprocessor defines, and set a breakpoint on line 76 in app_error.c:

    app_error_fault_handler(NRF_FAULT_ID_SDK_ERROR, 0, (uint32_t)(&error_info));

    Does it stop there?

    However, I suggest you check how much current your motors drag.

    If they use several mA, then a couple of houndred µA used by the timer (including the HFXTAL) may be neglectable?

    As mentioned, if you don't need to use the app_timer for anything, then I believe it is possible to change the pwm_library example to use the RTC1 instead of a TIMER1. 

  • I asked in another post, and the engineer told me to use segger embedded studio to debug. But since we are using our own PCB instead of development kit, is it still possible to use that debugger? 

Related