Page 1 of 1
[TODO] QEI driver
Posted: Tue Oct 16, 2012 5:32 pm
by tinito
Hi,
I've wrote a new driver for Quadrature Encoders, it actually is really simple as there are no interrupt & callbacks: if you enable the update/overflow interrupt and your motor vibrates around that value, you can get many interrupts, and actually I did not find any application which needs QEI callbacks (any suggestions?).
I started from the ICU driver files, the QEI driver simply:
- configures the given timer as QEI
- enables it with qeiEnable()
- returns the current value with qeiGetCount()
The configuration parameters are the one I saw on both STM32 and NXP17xx reference manuals: encoder mode (quadrature or direction+clock), precision (count on edges from only one channel or from both channels) and direction (invert or not the counting direction).
As attachment there are the high & low level drivers, while an updated ChibiOS source tree with everything added is here:
https://github.com/openrobots-dev/ChibiOSA demo which uses the driver (quadrature mode, both edges) with an HEDS-5540 encoder is here:
https://github.com/openrobots-dev/R2P_DCM_moduleWith that configuration, it seems to work

Re: QEI driver
Posted: Wed Oct 17, 2012 7:53 pm
by Giovanni
Hi,
I will give it a try soon (tm), right now I am very busy with that mysterious project.
Giovanni
Re: [TODO] QEI driver
Posted: Wed Jul 03, 2013 1:41 pm
by tinito
I've updated the QEI driver, adding the qeiUpdate() function which returns the delta from last reading.
You can find the current code as attachment.
Re: [TODO] QEI driver
Posted: Wed Jul 03, 2013 2:51 pm
by utzig
tinito,
Wouldn't it make sense to extend the ICU model to support quadrature encoding. Usually the same pins used for input capture are also used for quadrature encoding. Apart from the fact the input capture uses one pin and quadrature uses two, it seems logically very similar, at least to me. Btw, I'll download your suggestions and give it a look.
Fabio Utzig
Re: [TODO] QEI driver
Posted: Wed Jul 03, 2013 5:00 pm
by tinito
ICU generally means measuring the time between two events (e.g., two edges of the input signal), so the timer is clocked by the microcontroller and the timestamp of the two events is taken (generally a direct measure of speed).
QEI works in a different way: the timer acts as a counter clocked by the external signal (two square waves in quadrature), and you read the counter value (which represent, generally, a position). If you differentiate two consecutive reads, given the time between them, you get the speed-
They are often used for the same purpose (measuring a position or a speed), and generally they use the same hardware (a timer), but the way they work isn't the same, so I'm not sure a merge between the two drivers would be the right approach.
Re: [TODO] QEI driver
Posted: Tue Oct 01, 2013 12:49 am
by bvanheu
Just a suggestion regarding qeiUpdate(), wouldn't it make more sense to return a signed type?
The problem is that when you turn the encoder the other side, you will get a delta of the order of 65xxx.
Re: [TODO] QEI driver
Posted: Tue Oct 01, 2013 11:45 am
by tinito
Oh yes that's a typo. I did define the qeidelta_t type and used it inside the function but the return value was wrong.
Patched.
Thanks for noticing it!
Re: [TODO] QEI driver
Posted: Mon Jan 26, 2015 5:43 pm
by blei
Thanks a lot for this driver. I'm using it for 2 motor and 2 odometry encoders connected to TIM2-5 pins in a robot.
It's very simple to set up, but of course you mustn't forget to configure the pins in Alternate Function (AF) mode.

A solution to obtain precise timestamps when you read out the counters would be nice.
Re: [TODO] QEI driver
Posted: Mon Jan 26, 2015 5:57 pm
by tinito
Hi, I use this driver for the same application in most cases (robot odometry), and what I do to get a precise timestamp of the readings is simply to read both encoders inside a locked zone:
Code: Select all
chSysLock();
timestamp = ...
delta_left = qeiUpdateI(&QEID3);
delta_left = qeiUpdateI(&QEID4);
chSysUnlock();
each update just calls a macro and makes a sum and an assignment, so I think putting them inside a lock is OK, and the delay between the two calls is constant if you care.
For the timestamp I use a dedicated timer as I still use ChibiOS 2.6, but with 3.0 you should be OK with chTimeNow(), you can get up to ~20uS resolution if I remember right the results posted by Giovanni.
Re: [TODO] QEI driver
Posted: Tue Feb 03, 2015 2:45 pm
by SpaceCoaster
Worked well for handling the A/B phases on one of
these cheapo laser printer motors with attached 448 line encoders.
Any ideas about handling more than 16 bits of offset? The encoders can generate around 250,000 transitions per second.
A few tweaks were needed for 3.0, mostly to do with debug.
Thanks