Using the QDEC driver with a incremental encoder.

Hello!

I have an incremental encoder such as this one: https://www.digikey.no/en/products/detail/cui-devices/AMT103-2048-N4000-S/10468125

I have to make this work with the nRF52832.

After some research I see that the nRF connect sdk has a QDEC driver, which I assume is for dealing with these kinds of encoders. Looking through the documentation and exaples I am not sure how to set this up properly.

First of all: when creating the example code from zephyr, the nRF52 is not listed as compatible, is this right? I can't find an exaple using nrfx or for nordic boards.

Second: there are three pins coming from the encoder, channel A, B and index. The documentation only uses channels a and b, then one input for LED. I don't understand what this LED input is for.

Thanks for the assistance!

Filip

  • Hi Filip,

    First of all: when creating the example code from zephyr, the nRF52 is not listed as compatible, is this right? I can't find an exaple using nrfx or for nordic boards.

    You can refer to the Wheel module in nRF Desktop to see an example of using the Zephyr QDEC driver, and see how it is used in the nRF Desktop reference design. The QDEC peripheral is essentially the same on all nRF52 devices. Another option could be to use the low-level nrfx driver directly.

    Second: there are three pins coming from the encoder, channel A, B and index. The documentation only uses channels a and b, then one input for LED. I don't understand what this LED input is for.

    The LED is an output, not input (to control the LED that shins through holes or similar in the rotating encoder). Some encoders has an index that gives you a fixed reference point, so that you can know the exact position of the wheel. That is not supported by the nRF QDEC peripheral, though (which target use case is something like a mouse wheel).

  • Hello!

    The LED is an output, not input (to control the LED that shins through holes or similar in the rotating encoder).

    Okay, I see. So in my case I would probably just disable this input then.

    I am currently trying to use the QDEC driver in the nrfx library: https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/nrfx/drivers/qdec/driver.html

    But I can't seem to get it to work. And there are no example codes for this either. Could you help me with a simple stup for an incremental encoder with channel A and B?

    Thank you.

    Filip

  • Hi Filip,

    I don't have a nRF Connect SDK QDEC example at hand but as you are using nrfx_qdec I suggest you take a look at the QDEC Example from the nRF5 SDK. This uses the nrf_drv_qdec driver which is a wrapper over nrfx_qdec. With a few minor differences, this is exactly the same just with different names. So this also shows you how to use nrfx_qdec.

  • Okay. Is there a github page for the nRF5 sdk? I don't have it installed, so it would be nice to be able to check it out without having to download it.

    Also:

    I am trying to initialize the QDEC. Looking through the header of nrfx_qdec I see that this is the struct for configurating:

    typedef struct
    {
        nrf_qdec_reportper_t reportper;          ///< Report period in samples.
        nrf_qdec_sampleper_t sampleper;          ///< Sampling period in microseconds.
        uint32_t             psela;              ///< Pin number for A input.
        uint32_t             pselb;              ///< Pin number for B input.
        uint32_t             pselled;            ///< Pin number for LED output.
        uint32_t             ledpre;             ///< Time (in microseconds) how long LED is switched on before sampling.
        nrf_qdec_ledpol_t    ledpol;             ///< Active LED polarity.
        bool                 dbfen;              ///< State of debouncing filter.
        bool                 sample_inten;       ///< Enabling sample ready interrupt.
        uint8_t              interrupt_priority; ///< QDEC interrupt priority.
        bool                 skip_gpio_cfg;      ///< Skip GPIO configuration of pins.
                                                 /**< When set to true, the driver does not modify
                                                  *   any GPIO parameters of the used pins. Those
                                                  *   parameters are supposed to be configured
                                                  *   externally before the driver is initialized. */
        bool                 skip_psel_cfg;      ///< Skip pin selection configuration.
                                                 /**< When set to true, the driver does not modify
                                                  *   pin select registers in the peripheral.
                                                  *   Those registers are supposed to be set up
                                                  *   externally before the driver is initialized.
                                                  *   @note When both GPIO configuration and pin
                                                  *   selection are to be skipped, the structure
                                                  *   fields that specify pins can be omitted,
                                                  *   as they are ignored anyway. */
    } nrfx_qdec_config_t;

    Also this is the macro for default configuration:

    #define NRFX_QDEC_DEFAULT_CONFIG(_pin_a, _pin_b, _pin_led)           \
        {                                                                \
            .reportper          = NRF_QDEC_REPORTPER_10,                 \
            .sampleper          = NRF_QDEC_SAMPLEPER_16384us,            \
            .psela              = _pin_a,                                \
            .pselb              = _pin_b,                                \
            .pselled            = _pin_led,                              \
            .ledpre             = 500,                                   \
            .ledpol             = NRF_QDEC_LEPOL_ACTIVE_HIGH,            \
            .dbfen              = NRF_QDEC_DBFEN_DISABLE,                \
            .sample_inten       = false,                                 \
            .interrupt_priority = NRFX_QDEC_DEFAULT_CONFIG_IRQ_PRIORITY  \
        }

    But when I try to define a struct in my program I get an error, is this how you would define it?

    	//Initialize encoder 1
    	struct nrfx_qdec_config_t encoder_def_conf = NRFX_QDEC_DEFAULT_CONFIG(3, 4, 16);

    And with the handler that goes into the qdec_init function, how would you define that handler to get meaningful data out of it?

    Thank you

    Filip

  • Hi Filip,

    The nRF5 SDK is distributed as a zip, you can download it from here: https://www.nordicsemi.com/Products/Development-software/nRF5-SDK/Download?lang=en#infotabs.

    Faws said:
    But when I try to define a struct in my program I get an error, is this how you would define it?

    This looks sensible. Which error do you get?

    Faws said:
    how would you define that handler to get meaningful data out of it?

    The handler should have a prototype like this:

    void your_qdec_handler(nrfx_qdec_event_t event);

    and the events are on this form:

    /** @brief QDEC event handler structure. */
    typedef struct
    {
        nrf_qdec_event_t  type; /**< Event type. */
        union
        {
            nrfx_qdec_sample_data_evt_t sample; /**< Sample event data. */
            nrfx_qdec_report_data_evt_t report; /**< Report event data. */
        } data;                                 /**< Union to store event data. */
    } nrfx_qdec_event_t;

Related