Encoder Acceleration help

Status
Not open for further replies.

mtiger

Well-known member
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/RotaryEncoderAcceleration), 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
 
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_timing_elaspedMillis.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/language/functions/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.
 
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

}
 
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?
 
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.
 
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?
 
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
 
Status
Not open for further replies.
Back
Top