Skip to content

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

Closed
wants to merge 7 commits into from

Conversation

robert-hh
Copy link
Contributor

@robert-hh robert-hh commented Oct 19, 2021

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.

@robert-hh
Copy link
Contributor Author

Another goodie for the mimxrt port, now at the merge front. Updated and rebased. The documentation for it is in PR #7494.

@robert-hh robert-hh force-pushed the mimxrt_qecnt branch 3 times, most recently from a4c3252 to 84dcd9e Compare December 2, 2021 11:22
@robert-hh
Copy link
Contributor Author

robert-hh commented Dec 5, 2021

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
encoder-compare

encoder-compare.ods

@peterhinch
Copy link
Contributor

@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.

@robert-hh robert-hh force-pushed the mimxrt_qecnt branch 11 times, most recently from 23d151c to ac560bc Compare December 15, 2021 18:54
@robert-hh robert-hh force-pushed the mimxrt_qecnt branch 3 times, most recently from c01b536 to 4f30bea Compare December 25, 2021 16:23
@robert-hh robert-hh force-pushed the mimxrt_qecnt branch 2 times, most recently from 7bce2bc to 4b85f4e Compare December 29, 2021 13:49
@androiddrew
Copy link

I just encountered an issue when using my build from this branch. The machine.UART doesn't appear to have an irq method. I have a Bluetooth serial UART (ZS040) that I was going to fire a handler whenever data was received :( Is this a problem with this branch or does the Teensy UART not have support for an irq?

>>> UART.
any             read            readinto        readline
write           __bases__       __dict__        INV_RX
INV_TX          init            sendbreak
>>> UART.

@robert-hh
Copy link
Contributor Author

robert-hh commented Jul 16, 2022

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.
UART.irq() exists at the moment only for the WiPy (CC3200) port, which is more or less legacy.

Just a question: Why do you use this branch for building the firmware? Do you need the Encoder?

@robert-hh
Copy link
Contributor Author

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().

@robert-hh
Copy link
Contributor Author

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.
But before that, one have to agree over the API. Using the existing API seems to be an overhead. It has many options with a single possible choice.

@robert-hh robert-hh force-pushed the mimxrt_qecnt branch 2 times, most recently from f8977c8 to 1ee0f71 Compare September 19, 2022 14:31
@IhorNehrutsa
Copy link
Contributor

Hi, Robert.
May you please update the comparison table with latest PR
Proposal: Esp32 machine.PCNT through Encoder.py and Counter.py #8253
ESP32: Add Quadrature Encoder and Pulse Counter classes. #8766
esp32/esp32_pcnt: Add PCNT class and Counter/Encoder shims in machine #7582
Thanks.

@robert-hh
Copy link
Contributor Author

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.

@IhorNehrutsa
Copy link
Contributor

@robert-hh
Unfortunately, the ESP32 port is not a priority for @dpgeorge and @jimmo.
Only minor updates are applied during year.
This is very disappointing and hurts the project.
:(
Thank you.

@robert-hh robert-hh marked this pull request as draft November 17, 2022 07:13
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.
@robert-hh robert-hh marked this pull request as ready for review November 18, 2022 08:20
tannewt added a commit to tannewt/circuitpython that referenced this pull request Apr 29, 2023
@robert-hh
Copy link
Contributor Author

Reducing the PR-essure by an epsilon.

@robert-hh robert-hh closed this May 3, 2023
@androiddrew
Copy link

Sorry haven't been following this. Does this mean no encoder support for the teensy 4.x?

@robert-hh
Copy link
Contributor Author

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.

@robert-hh
Copy link
Contributor Author

Re-submitted as #12347

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants