My project uses the rotary encoder having pin A, B and Common with nrf52832. I connected them to pin 9 and 10 and GND.
I modified Qdec example to but it does not print the value of position. Please advice. I want to have a low power design too but I am not sure if it is right way.
I am using nRF5_SDK_17.1.0_ddde560 and SES v4.3. Thanks!
qdec3.zipThanks.
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#include <stdio.h>
#include "nrf.h"
#include "bsp.h"
#include "nrf_delay.h"
#include "nrf_drv_qdec.h"
#include "nrf_error.h"
#include "app_error.h"
#include "nordic_common.h"
#include "nrf_log.h"
#include "nrf_log_ctrl.h"
#include "nrf_log_default_backends.h"
static volatile bool m_report_ready_flag = false;
static volatile uint32_t m_accdblread;
static volatile int32_t m_accread;
static int32_t m_total_position = 0;
static nrf_drv_qdec_config_t m_qdec_config = {
.reportper = 0x00, // Adjust as needed (e.g., 10 samples per report)
.sampleper = 0x06, // e.g., 8192 us (adjust as needed; 0x00=128us to 0x06=16384us)
.psela = 9, // Change to your rotary encoder A pin
.pselb = 10, // Change to your rotary encoder B pin
.pselled = NRF_QDEC_LED_NOT_CONNECTED, // No LED for mechanical encoder
.ledpre = 0, // No LED pre-time
.ledpol = NRF_QDEC_LEPOL_ACTIVE_HIGH,
.dbfen = true, // Enable debouncing filter for mechanical encoder
.sample_inten = false, // Use report interrupts, not sample
.interrupt_priority = 6
};
//
//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. */
//} nrfx_qdec_config_t;
static void qdec_event_handler(nrf_drv_qdec_event_t event)
{
if (event.type == NRF_QDEC_EVENT_REPORTRDY)
{
m_accdblread = event.data.report.accdbl;
m_accread = event.data.report.acc;
m_report_ready_flag = true;
nrf_drv_qdec_disable(); // Do not disable QDEC for continuous operation
}
}
int main(void)
{
uint32_t err_code;
err_code = NRF_LOG_INIT(NULL);
APP_ERROR_CHECK(err_code);
NRF_LOG_DEFAULT_BACKENDS_INIT();
// Initialize hardware with custom config for real encoder
err_code = nrf_drv_qdec_init(&m_qdec_config, qdec_event_handler);
APP_ERROR_CHECK(err_code);
// Configure pull-ups AFTER init (important for mechanical encoders without external pull-ups)
nrf_gpio_cfg_input(9, NRF_GPIO_PIN_PULLUP);
nrf_gpio_cfg_input(10, NRF_GPIO_PIN_PULLUP);
nrf_drv_qdec_enable();
NRF_LOG_INFO("pin A: %d", m_qdec_config.psela);
NRF_LOG_FLUSH();
NRF_LOG_INFO("pin B: %d", m_qdec_config.pselb);
NRF_LOG_FLUSH();
NRF_LOG_INFO("Sampling period: %d", m_qdec_config.sampleper);
NRF_LOG_FLUSH();
NRF_LOG_INFO("Report period: %d", m_qdec_config.reportper);
NRF_LOG_FLUSH();
NRF_LOG_INFO("QDEC with real rotary encoder started. Turn the encoder to see position updates.");
NRF_LOG_FLUSH();
while (true)
{
// Wait for a report
while (! m_report_ready_flag)
{
__WFE();
}
// Check for double accumulation (should be 0 unless double resolution enabled)
if (m_accdblread != 0)
{
NRF_LOG_WARNING("Double accumulation detected: %u", m_accdblread);
}
// Accumulate position
m_total_position += m_accread;
NRF_LOG_INFO("Report ready. Delta: %d, Total position: %d", (int)m_accread, (int)m_total_position);
NRF_LOG_FLUSH();
m_report_ready_flag = false;
}
}