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

Thread: Encoder Acceleration help

  1. #1

    Encoder Acceleration help

    Hi guys,

    Trying to understand a way to implement Encoder acceleration with this library I'm using (https://github.com/mathertel/RotaryEncoder) and simply can't wrap my head around it.

    I've had a search and found this (https://playground.arduino.cc/Main/R...erAcceleration), however can't seem to understand how I would integrate something like this into the library I'm using considering the implementation of the additional libraries.

    Does anyone have experience or suggestions?

    Cheers,
    M

  2. #2
    Anyone....?

  3. #3
    Senior Member
    Join Date
    Apr 2013
    Posts
    1,789
    You would be tracking how fast the encoder is rotating and increasing the move rate if so.

    Basic idea is to seperatly track encoder value, and your controlled value and then each time your encoder detects motion look at how long it has been since the last move, using millis or ellapsed millis
    https://www.pjrc.com/teensy/td_timin...pedMillis.html
    If time is low, then increment/decrement your controlled value by more than one, possibly as simply by using an if statment for time <100ms = move in steps of five or 10.

    More elegant is to run averaging of five or so times and then use a power calculation (https://www.arduino.cc/reference/en/...ions/math/pow/) to provide a smooth curve ramping the move rate up but that would need some thought about the math to get right, where one or more if's will be much easier to get right.

  4. #4
    Thanks Gremlin, I'll give that a go and report back

  5. #5
    Junior Member
    Join Date
    Nov 2017
    Posts
    9
    Any progress with it mtiger? I rolled my own acceleration using the line slope equation. works fine on an arduino, but need it working on a teensy 2.0

    #include "Rotary.h"

    int c = 4; //height
    float a = 0.3; //slope
    //y=ax+c line
    int rev = 0;

    unsigned long lastTransition;
    unsigned long revolutionTime = 0;
    unsigned long now = 0;

    int b = 0;
    int z = 0;
    Rotary rotary = Rotary(5, 2);

    void setup() {

    }

    void loop() {

    unsigned char result = rotary.process();

    if (result == DIR_CW) {
    z = -1;
    }
    if (result == DIR_CCW) {
    z = 1;
    }

    if (z != 0) {
    now = millis();
    revolutionTime = now - lastTransition;

    if (revolutionTime < 27) {
    rev = 27 - revolutionTime ;
    b = (int)a * rev + c;
    z = z * b;
    }
    lastTransition = now;
    }

    //use the z encoder value
    z = 0; //reset encoder value

    }

  6. #6
    Hey gipetto, I haven’t had the time to focus on this recently, however I will look into it further and report back!

    Wondering if you have had any success with the Teensy? Would assume your code should work on either platform. If not, why wouldn’t it?

  7. #7
    Junior Member
    Join Date
    Nov 2017
    Posts
    9
    It should, but the teensy 2.0 I am testing on is another mans software project. He has it set up with a makefile so I can't seem to get any millis(); to work, don't know how to add libraries either. If you were using a teensy 3.6 with the ide I see no reason why it should not work. those ints are all memory hogs too, many need to be replaced with uint8_t. I actually like the feel of using it though, acceleration is not too sharp as many similar software uses a curve, this is linear and easy to control.

  8. #8
    Hi gipetto, sorry for the long delayed response. Been away and haven't had time to figure this out.

    Could you please explain your code?

  9. #9
    Junior Member
    Join Date
    Nov 2017
    Posts
    9
    Ok, I can't seem to find where i downloaded the rotary library but from examing my own files this seems to be a clone https://github.com/fiendie/Rotary
    Look at that link to see how to implement a rotary encoder.
    all the acceleration happens in the main loop.

    if (z != 0) { // if there is any encoder movement in either direction
    now = millis(); // set a variable to a millisecond count of time elapsed since the arduino powered on
    revolutionTime = now - lastTransition; // revolution stores the time between successive rotated encoder states,
    // by subtracting the previous conditional loop elapsed time from the current.
    if (revolutionTime < 27) { // trigger acceleration only when encoder speed is sufficiently high.
    rev = 27 - revolutionTime ; // start counting from one with increasing speed to make a usable variable for acceleration
    b = (int)a * rev + c; // slope of a line equation to provide acceleration.
    z = z * b; // create encoder movements using acceleration as a multiplier
    }
    lastTransition = now;
    }

    //use the z encoder value
    z = 0; //reset encoder value

  10. #10
    Great, thanks for your explanation.

Posting Permissions

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