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

using PWM to measure input period and pulse width

I have an input signal of unknown period and pulse width on a GPIO. I want to use the PWM capture capabilities to  retrieve those parameters.

I see in the documentation there is

pwm_pin_configure_capture, pwm_pin_enable_capture, pwm_pin_disable_capture, pwm_pin_capture_usec, pwm_capture_callback_handler

I did not see an example how to use these. could you show me a simple example of what I need to do to  get the period and pulse width from an input signal using a PWM. The functions seem to be exactly what I need but the implementation is not clear in the documentation and I am getting a lot of compile errors. I am sure it is something simple I am missing. I appreciate any help you can give.

  • As I can understand, Seggar studio may the most complicated IDE in the world.  What I can do in few lines in Arduino or in CCS Compilers, this  Seggar takes few pages of codes.  

    Simplicity of programming is not in nRF world. However, the support engineers are good to support. 

  • vkadal

    I have a frequency coming into a GPIO. I trigger an interrupt on each edge. I can use the TIMER1 to measure *** width and period but I cannot get it measure below ~10ms for pulse width or period accurately. anything above ~10ms all works fine. I am setting an LED in the interrupt routine so I can see what I am measuring. There is milliseconds delay before the led toggles so I do not start the timer exactly when the interrupt occurs. the frequency I need to measure is ~12KHz and the pulse widths I need to measure are 30-150us. is there any way to accurately measure these. The TIMER does not have external start/stop capabilities. It must relay on interrupts and code to stop/start it.

    sample code below to measure the period. the code to measure pulse width was removed to simplify to see what the shortest period I could measure. This code saves the timer count (period) on every negative edge and clears the timer count.. This works well until you get < 10ms. any ideas how I measure us. the TIMER can measure us but I can not stop/start it fast enough. I removed the LED commands and the result was the same. It is not the LED commands causing the delay.

    if (evt.type == UI_EVT_BUTTON_ACTIVE)
    {
    dk_set_led(LED2,0x01);  /* positive edge */
    }
    else
    {
    dk_set_led(LED2,0x00);   /*negative edge */
    NRF_TIMER1->TASKS_CAPTURE[0] = 1;
    inputPeriod = NRF_TIMER1->CC[0];
    NRF_TIMER1->TASKS_CLEAR = 1;

    }

  • I am not very conversant with Segger.  Could  you abe to increase the ticks here? 

    SYS_CLOCK_TICKS_PER_SEC (32768) 

  • Vkadal

    no that will not work. that messes up the system timing. that is used by software timers. the TIMER1 are hardware timers counting at 16 MHz or 1MHZ. the problem is they have no hardware control. the control is all software which does not help get to microsecond measurements.

  • Let me assume the  hardware time has 16 Mhz clock input. Then the time elapsed  for  one tick is 1/16 uS.  That is roughly 60 Nano second. This is the level of  accuracy , you can achieve for pulse width or period measurement. 

    If it is 1 MHz, then you need to  live with 1 us accuracy / resolution

Related