Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 3 of 3

Thread: Rotary Encoder Debugging on SAMD11

  1. #1

    Rotary Encoder Debugging on SAMD11

    Not sure if this is a technical support question or just a general request for project help.

    I'm working on a project called Makernet where I am designing lots of little devices that are all accessible on an I2C-like bus. This is a OSH project. This project aims to use a Teensy as one of the main MCU controllers (which thanks to some other help on this forum I've gotten to work...!) Anyway, one of the sub-devices I'm designing is a rotary encoder and I am working on the firmware, and this is where I've run into trouble.

    After discovering that Paul did not have ATSAMD11 support for Encoder.h, I decided to start working on adding it in. However, my early attempts did not yield nearly the same stability that this library has on a Teensy 3.2. Notably, the encoder rattles around more, and often skips steps. In other cases, it gets "wedged" and alternates between single steps without moving up or down.

    I'm using the Sparkfun RGB decoder without any hardware debouncing. On the Teensy this device seems to read quite well, but as a cheapo encoder, my guess is that its pretty noisy.

    Anyway, the software problem led to a large-scale investigation to isolate the issue and I ended up creating simpler and simpler test cases and moving the key algorithm out of the Encoder library entirely. Now I'm a bit stuck. I have learned that ArduinoCore for the SAMD seems to not really support attachInterrupt, although loading the code over JTAG without any USB libraries seems to let that route work. I suspect that the interrupt is firing too many times. Also I am aware that my code is probably not reading the two ports atomically.

    I was hoping that someone with some in-depth experience could explain what are the key factors that make Encoder reading stable, and help me figure out what to try next. If not already obvious, I'm a weekend hobby guy, not EE trained. Some hypotheses:

    1) The SAMD11 pullups are weaker than the Teensy
    2) The 48Mhrz is too slow to read the encoder properly (...?)
    3) The Teensy may have a bit of a schmitt trigger on its pins, and the SAMD11 doesn't?
    4) I'm actually polling the encoder too fast, and the tiny bit of time between reading the two pin creates instability
    5) Something else entirely

    ZIP files of my target firmware
    Hardware.zip

    Test Sketch:
    jg20170604_makerneti2c_encoderlibrary_test.ino

    Library code:
    MakernetEncoderReader.cpp
    MakernetEncoderReader.h

  2. #2
    I think I found a dead ringer for the type of problem I had. This time I caught it on a logic probe.

    In the trace below, I move the rotary encoder up 2 detents slowly.

    The first movement read out 0-4. GOOD.

    The next one oscillated between 5,6 and then landed at 4 rather than 8.

    5
    4
    5
    6
    5
    3
    4

    An example of the glitch. Note: The notify pin is brought HIGH during the ISR as a visual on what the code is doing.

    As you can see, the "A" line fell but bounced around quite a bit in the process. This was during a period where the B was low. As soon as it fell the first time, the code reports an increase from 5->6. But in the process of the noise and the 20-30 interrupts that fired, the 6 fell back to a 5. This probably garbled the state machine.

    Click image for larger version. 

Name:	Screen Shot 2017-06-04 at 9.37.04 PM.jpg 
Views:	39 
Size:	75.3 KB 
ID:	10734

    I'm guessing someone who has looked at a lot of these types of traces and built a rotary decoder before probably knows exactly what's going on, but I'm mystified.

  3. #3
    jgilbert, Some thoughts:
    Its much easier to get some code working all in one sketch before trying to do the library stuff.
    Try to avoid calling noInterrupts() from within an interrupt.
    Do the minimum possible within an interrupt, just set some global volatile variable.

    Don't throw away useful information, in this case using one function for both pins looses some info.

    Following the above you end up with something like I posted here. No initial conditions req'd, debounce not required, quick - tested to 30k rpm. Never misses.
    https://forum.pjrc.com/threads/34949...l=1#post106888
    It could still be improved. As shown it does no hardware error checking.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •