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.

  • Smit

    below is the code that I am using to measure the output of a Hall effect sensor. Their is a pulse width of 30 - 200us.

    typedef struct
    {
    uint32_t pulseWidth; //!< pulse width in us
    uint32_t period; //!< period in us
    } sensorDataStruct;
    sensorDataStruct sensorData[SENSOR_BUFFER_SIZE];
    iuint16_t sensorDataIn;
    uint16_t sensorDataOut;
    uint16_t sensorDataCount;
    nt32_t inputPulseWidth;
    int32_t inputPeriod;
    void hallSensorCallback(struct device *dev, struct gpio_callback *cb, uint32_t pins);
    void configurePins();

    main()

    {

    ...

    ...

    sensorDataIn = 0;
    sensorDataOut = 0;
    sensorDataCount = 0;
    timer_init();
    configurePins();

    NRF_TIMER1->TASKS_START = 1;
    ...

    ...

    }

    void timer_init()
    {
    NRF_TIMER1->TASKS_STOP = 1;
    NRF_TIMER1->MODE = TIMER_MODE_MODE_Timer;
    NRF_TIMER1->PRESCALER = 4; // Fhck / 2^4 = 1us
    // NRF_TIMER1->CC[0] = 62500; // 62500 - 1s

    NRF_TIMER1->BITMODE = (TIMER_BITMODE_BITMODE_32Bit << TIMER_BITMODE_BITMODE_Pos);

    NRF_TIMER1->TASKS_CLEAR = 1;
    // NRF_TIMER1->INTENSET = (TIMER_INTENSET_COMPARE0_Enabled << TIMER_INTENSET_COMPARE0_Pos);

    NRF_TIMER1->EVENTS_COMPARE[0] = 0;
    }


    void hallSensorCallback(struct device *dev, struct gpio_callback *cb, uint32_t pins)
    {
    int pin;

    pin = gpio_pin_get(dev, HALL_SENSOR_PIN);
    gpio_pin_set(dev,LED3_PIN,pin);
    if(pin == 0)
    {
    NRF_TIMER1->TASKS_CAPTURE[0] = 1;
    inputPeriod = NRF_TIMER1->CC[0];
    NRF_TIMER1->TASKS_CLEAR = 1;
    if(sensorDataCount == 0) /* check if first pulse width measured */
    return;
    if( sensorDataIn == 0 )
    sensorData[SENSOR_BUFFER_SIZE - 1].period = inputPeriod;
    else
    sensorData[sensorDataIn - 1].period = inputPeriod;
    }
    else
    {
    NRF_TIMER1->TASKS_CAPTURE[0] = 1;
    inputPulseWidth = NRF_TIMER1->CC[0];
    if(inputPulseWidth >= 1000) /* check if valid pulse width */
    return;
    if(sensorDataCount < SENSOR_BUFFER_SIZE)
    {
    sensorData[sensorDataIn++].pulseWidth = inputPulseWidth;
    sensorData[sensorDataIn - 1].period = 0;
    if(sensorDataIn == SENSOR_BUFFER_SIZE) /* is it wrap around */
    sensorDataIn = 0;
    sensorDataCount++;
    }
    }
    }

    void configurePins()
    {
    /* configure output pins */
    // gpio_pin_configure(gpioPtr, LED3_PIN,GPIO_OUTPUT | GPIO_ACTIVE_HIGH | GPIO_PULL_UP);
    gpio_pin_configure(gpioPtr, LED3_PIN,GPIO_OUTPUT );

    /* configure input pins */
    gpio_pin_configure(gpioPtr, HALL_SENSOR_PIN,GPIO_INPUT | GPIO_ACTIVE_LOW );

    /* configure interrupt callbacks */
    gpio_init_callback(&gpio_hall_sensor_cb, (gpio_callback_handler_t)hallSensorCallback, BIT(HALL_SENSOR_PIN));
    gpio_add_callback(gpioPtr, &gpio_hall_sensor_cb);
    }

Related