-
-
Notifications
You must be signed in to change notification settings - Fork 8.2k
mimxrt: Add Quadrature Encoder and Pulse Counter classes. #7911
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
3c58d9a
to
a8f789a
Compare
a8f789a
to
1d86dde
Compare
1d86dde
to
f2a6554
Compare
Another goodie for the mimxrt port, now at the merge front. Updated and rebased. The documentation for it is in PR #7494. |
a4c3252
to
84dcd9e
Compare
84dcd9e
to
c63c342
Compare
Since there are now four Quadrature Encoder/Counter classes around, two for ESP32, one for Mimxrt and the generic Python one of @pythoncoder as a Python example, I made a small comparison table so show similarities and differences. It should be the aim to have at least a common subset of functions and methods. I added the ods file as well for corrections/extension |
@robert-hh There is also Dave Hylands' offering. This is an STM specific hardware based solution. From looking at the hardware I think it may be capable of bit-perfect results but I haven't tested this. |
23d151c
to
ac560bc
Compare
c01b536
to
4f30bea
Compare
7bce2bc
to
4b85f4e
Compare
4b85f4e
to
5a806d7
Compare
I just encountered an issue when using my build from this branch. The
|
UART is interrupt based at the MIMXRT port. In the RX interrupt handler the receive buffer is filled. It is obviously possible to call a handler after the input queue has been drained. Maybe just with a handler=xxx keyword option. Just a question: Why do you use this branch for building the firmware? Do you need the Encoder? |
The Teensy is pretty fast. So as a workaround you can set up a timer callback like every few ms and check for new data with uart.any(). |
I looked into the code, and at least for MIMXRT it would require to rework the receive section. The codes uses a ringbuffer, but this buffer is part of the support library. It has a callback there, but that assumes that the target buffer for data is static. That is not the case for MicroPython. The other option would be to have the ringbuffer in the MP code part, like it's done for instance in the rpi 2040 port. Then full control over the behavior is possible. |
f8977c8
to
1ee0f71
Compare
1ee0f71
to
1bc7211
Compare
Hi @IhorNehrutsa I noticed the discussion about the various ESP32 Encoder PRs, but I did not look into the PRs except your's. And until no one of @dpgeorge or @jimmo shows and active feedback to the Encoder/Counter classes, this topic is on halt. I keep my PR mergeable, but that's it. The SAMD controller have Encoder/Counter hardware too, but without a general approach there is no sense in supporting it. |
@robert-hh |
These classes are base on the Quadrature Encoder blocks of the i.MXRT MCUs. The i.MXRT 102x has two encoders, the other ones four. The i.MXRT 101x does not support this function. It is implemented as two classes, Encoder and Counter. The number of pins that can be uses as inputs is limited by the MCU architecture and the board schematics. The Encoder class supports: - Defining the module - Defining the input pins. - Defining a pin for an index signal. - Defining a pin for a Home signal. - Defining an output pin showing the compare match signal. - Setting the number of cycles per revolution. - Setting the initial value for the position. - Setting the counting direction. - Setting a glitch filter. - Setting the value counter as signed or unsigned integers. - Defining callbacks for getting to a specific position, overrun and underrun (starting the next revolution). These callbacks can be hard interrupts to ensure short latency. The encoder counts all phases of a cycle. The span for the position is 2**32, for the revolution is 2**16. The highest input frequency is CPU-Clock/24. The Counter mode counts single pulses on input A of the Encoder. The configuration support: - Defining the module - Defining the input pin. - Defining the counting direction, either fixed or controlled by the level of an input pin. - Defining a pin for an index signal. - Defining an ouput pin showing th compare match signal. - Setting the counter value. - Setting the glitch filter. - Returing the value counter as signed or unsigned integer. - Defining a callback which is called at a certain value. The counting range is 0 - 2**32-1 and a 16 bit overrun counter. The highest input frequency is CPU-Clock/12.
The MIMXRT1015 MCU has only one encoder/counter unit.
This is the MIMXRT specific version, compliant to the documentation of PR micropython#8072 in the basic methods.
Thanks to @androiddrew for testing the code and finding the inconsitencies to the documentation.
1bc7211
to
4f2d497
Compare
Reducing the PR-essure by an epsilon. |
Sorry haven't been following this. Does this mean no encoder support for the teensy 4.x? |
The topic of Encoder has been discussed a lot, but besides that there is no progress. So I close it for now. I can always reopen or re-submit it. The branch with the encoder still exists at https://github.com/robert-hh/micropython/tree/mimxrt_qecnt and I will maintain it. Besides that you can always use the python implementations for encoders, as discussed in the PR message. At Teensy the work well up to a pulse rate of several kHz. |
Re-submitted as #12347 |
This PR adds Quadrature Encoder and Pulse Counter classes based on the Encoder hardware of the mimxrt MCUs. The base methods are as simple as possible, with options to make use of the hardware features supporting fast encoder sensors, like index pulses.
Tested with a slow manual encoder and a simulation of fast encoder/counter signals up to a input frequency of 25 MHz.