Hello!
I have to decode signals from two quadrature encoders. I know nordic has a driver for this, QDEC, however. there are a couple problems:
1. I need to control two encoders, and this driver only works with one at a time. I would have to un-init and re-init encoders for every time I use a different one (?).
2. I can't get it to show the correct values.
Therefore, I am planning to make a library from scratch that handles the input from encoders and decodes into accumulated pulses. I plan on doing this with interrupts. With the code I have now, I increment a counter by one every time interrupt from channel a on one encoder is triggered. I am expecting to get something like 2048 pulses, because that is the resolution of the encoder. But I am getting completely random values that don't make sense. I assume it is because I print out the values into the terminal every time it is triggered, and maybe it can't keep up.
void enc1_a_trigger(const struct device *dev, struct gpio_callback *cb, uint32_t pins)
{
enc_1_counter++;
printk("Position %i\n", enc_1_counter);
}
But! If I remove the printing for every interrupt, like below, the counter goes wild. And if I even slightly touch the encoder, it jumps up several thousand at a time. I am guessing maybe it is because the clock is running so quickly.
void enc1_a_trigger(const struct device *dev, struct gpio_callback *cb, uint32_t pins)
{
enc_1_counter++;
}
How do I solve these problems and get a reliable and repeatable output from the encoder?
This is the code in the encoder.c file:
#include "encoder.h"
int enc_1_counter = 0;
int enc_2_counter = 0;
void enc1_a_trigger(const struct device *dev, struct gpio_callback *cb, uint32_t pins)
{
enc_1_counter++;
}
void enc1_b_trigger(const struct device *dev, struct gpio_callback *cb, uint32_t pins)
{
}
static struct gpio_callback button1_cb_data;
static struct gpio_callback button2_cb_data;
void encoder_init(encoder *enc_1, encoder *enc_2)
{
const struct device *dev;
int ret;
dev = device_get_binding("GPIO_0");
if (dev == NULL)
{
printk("Encoder init failed.\n");
}
ret = gpio_pin_interrupt_configure(dev, enc_1->ch_a, GPIO_INT_EDGE_BOTH);
ret = gpio_pin_interrupt_configure(dev, enc_1->ch_b, GPIO_INT_EDGE_BOTH);
gpio_init_callback(&button1_cb_data, enc1_a_trigger, BIT(enc_1->ch_a));
gpio_init_callback(&button2_cb_data, enc1_b_trigger, BIT(enc_1->ch_b));
gpio_add_callback(dev, &button1_cb_data);
gpio_add_callback(dev, &button2_cb_data);
}
void encoder_get_value(encoder *enc_n)
{
if (enc_n->enc_n == 0)
{
printk("Encoder 1 count: %i\n", enc_1_counter);
}
if (enc_n->enc_n == 1)
{
printk("Encoder 2 count: %i\n", enc_2_counter);
}
}
It should take an input of a struct with some values with pins and etc and then put that into a function that sets up an encoder with interrupts on specified pins in the struct.
Thank you!