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.

Parents
  • You need to use timer for this purpose. You shall use GPIO pin which can create an interrupt. Create an interrupt when the pulse changes high low and start the counter. Stop the counter when the pulse goes  low. This will give you the pulse width

    Similarly to measure period, start the counter when the pusle goes from high to low and stop it in the next hight to low

    This is standard procedure for any  micro 

  • 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();

    ...

    ...

    }

    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);
    }

Reply
  • 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();

    ...

    ...

    }

    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);
    }

Children
No Data
Related