I have an EC11 rotary encoder wired to my nRF52840 and I am trying to get readings from it using the sensor API. However, I'm having issues with (seemingly) garbage data. When I rotate one "click" I get a variety of readings. Sometimes no readings whatsoever, sometimes multiple readings. I referenced the nrf_desktop wheel implementation for my configuration.
I should note that I am relying on software pullups for my configuration, hence the specific gpio definition for the encoder pins.
It is important to me that I do not poll the encoder in order to save power. Am I missing something obvious?
Here's my overlay file:
/ {
aliases {
sw0 = &button0;
sw1 = &button1;
sw2 = &button2;
qdec0 = &qdec0;
qenca = &encoder_a;
qencb = &encoder_b;
};
encoder_a: encoder_a_pin {
gpios = <&gpio1 13 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>;
label = "Rotary interrupt A";
};
encoder_b: encoder_b_pin {
gpios = <&gpio1 15 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>;
label = "Rotary interrupt B";
};
};
&pinctrl {
qdec_pinctrl: qdec_pinctrl {
group1 {
psels = <NRF_PSEL(QDEC_A, 1, 13)>,
<NRF_PSEL(QDEC_B, 1, 15)>;
};
};
};
&qdec0 {
status = "okay";
pinctrl-0 = <&qdec_pinctrl>;
pinctrl-names = "default";
steps = <80>;
led-pre = <0>;
};
My interface code:
const struct device *const encoder_device = DEVICE_DT_GET(DT_NODELABEL(qdec0));
static void sample_encoder()
{
struct sensor_value val;
int rc;
rc = sensor_sample_fetch(encoder_device);
if (rc != 0)
{
LOG_INF("Failed to fetch sample (%d)\n", rc);
return 0;
}
rc = sensor_channel_get(encoder_device, SENSOR_CHAN_ROTATION, &val);
if (rc != 0)
{
LOG_INF("Failed to get data (%d)\n", rc);
return 0;
}
if (val.val1 != position)
{
position = val.val1;
LOG_INF("Position = %d degrees\n", position);
}
}
void init_encoder(){
if (!device_is_ready(encoder_device))
{
LOG_ERR("Cannot get QDEC device");
return -ENXIO;
}
static const struct sensor_trigger qdec_trig = {
.type = SENSOR_TRIG_DATA_READY,
.chan = SENSOR_CHAN_ROTATION,
};
err = sensor_trigger_set(encoder_device, (struct sensor_trigger *)&qdec_trig,
sample_encoder);
}
Here is an example log of one "click" clockwise:
[00:11:40.740,112] <inf> main_logging: Position = 4 degrees [00:11:40.822,021] <inf> main_logging: Position = 13 degrees
And here is the logs from three "clicks" counterclockwise:
[00:12:14.900,543] <inf> main_logging: Position = -9 degrees [00:12:17.931,579] <inf> main_logging: Position = -18 degrees [00:12:19.979,553] <inf> main_logging: Position = -4 degrees [00:12:20.061,492] <inf> main_logging: Position = -13 degrees


