encoder to stepper

Hello everyone,

I'm definitely new to the Arduino but am having a great time working out projects with it. I'm hoping someone can at least point me in the right direction.

So far I've been able to accomplish control of stepper speed through pots, and other more advanced things from computer control. I've been reading countless articles on encoders but am having a hard time developing a way to control a stepper motor from an encoder.

I'd like to accomplish the fairly simple task of: each encoder step converted into x number of motor steps (with direction defined by the direction of the turns on the encoder). This seems to be a common thing and was hoping to find someone elses sketch to learn from...no luck though.

If anyone can help with any source of information, it'd be greatly appreciated!

Take care,

Marc

I'd like to accomplish the fairly simple task of: each encoder step converted into x number of motor steps

Does this mean that you want to use the encoder just like you used the pot?
What do you get out of the encoder code you have at the moment?

No. Currently the the pot is used as a speed control (the further I turn it, the faster the motor turns). I've also tried it as an absolute position control. Unfortunately, neither of which are my goals for the encoder.

I would like to use the encoder as a "step incrementer". I literally want to convert encoder steps into a certain number of motor steps. Such as +1 on the encoder becomes +1 on the motor (and vis versa where -1 becomes -1). This would also allow software gearing and still fine control over the motor.

At this stage my encoder arduino code knowledge only goes so far as to being able to serialprint values :stuck_out_tongue:

Thanks for responding.

You must not think there is something like an "encoder" - there are many... We generally assume you have the cheapest sort, but even among them are differences.
Check this as a beginning:
http://www.arduino.cc/playground/Main/RotaryEncoders
Then this
http://www.neufeld.newton.ks.us/electronics/?p=248

Thanks for the reply daSilva.

That article definitely has been one of the most helpful I've found too at getting me started. I've read it quite a few times and am still working on it :wink:

Hi,

To read the encoder, the function below does the trick for me. Call it from loop as frequently as possible, so it doesn't skip transitions.

Hopefully its self explanatory. If you need more context you can download the whole sketch from http://www.arduinoevilgenius.com

Its in the sketch for project 11.

int getEncoderTurn()
{
// return -1, 0, or +1
static int oldA = LOW;
static int oldB = LOW;
int result = 0;
int newA = digitalRead(aPin);
int newB = digitalRead(bPin);
if (newA != oldA || newB != oldB)
{
// something has changed
if (oldA == LOW && newA == HIGH)
{
result = -(oldB * 2 - 1);
}
}
oldA = newA;
oldB = newB;
return result;
}

Here's a sketch that should work to give you the current value of the encoder:

long encoderCount = 0;

void setup() {
  
  Serial.begin (9600);
  
  pinMode(2, INPUT);                       // encoder A input, pin 2
  pinMode(4, INPUT);                       // encoder B input, pin 4
  
  attachInterrupt(0, quadEncoder, CHANGE);     // encoder trips interrupt on change at pin 2
  
}

void quadEncoder() {
  
  if ( digitalRead(2) == digitalRead(4) ) {
    encoderCount += 1;
  }
  
  else {
    encoderCount -= 1;
  }
}

void loop() {

  long lastEncoder = 0;
  
  if ( lastEncoder != encoderCount ) {
    Serial.println( encoderCount );
    lastEncoder = encoderCount;
  }
}

You can do anything you like in the loop. I think the easiest way to increment the stepper once per encoder count would be to put it in the loop along with the Serial.println function. You could just as easily put it in the interrupt service routine (the quadEncoder() function,) but you may find that having it in the loop() makes it easier to manipulate the numbers.

For things like this, you may need to make each encoder step one or two or one-half a step, and this is where having a loop that just watches the current step value is nice. You don't need to sit there and bang on the loop watching the counters, since the interrupt pin will make sure that you catch every encoder change. You can do pretty much whatever you like in the loop unless the encoder goes REALLY fast. You could trim the fat from the interrupt service routine further by replacing the relatively slow digitalRead() with direct port I/O. I can post a slightly more optimized sketch if that's what you're into.

I use this type of routine to count encoders in dry gas meters for measuring volume of a gas sampling system, and I can't afford to be more than 1cc off in my volume :slight_smile:

Have fun!

Thanks guys! These solutions are a lot simpler than the implementation I managed to cobble together from another project. Managed to get it working in a rough manner, but still have a lot of value "bouncing" happening. I'm going to try with some of the ideas that were presented here though and try to smooth the value situation.

Thanks again.

int newA = digitalRead(aPin);
 int newB = digitalRead(bPin);

What is going to happen when encoder turns in between two digitalRead() commands?

Well what do you think?
Obviously there will be an error.

int newA=0;
int newAs=1;
int newB=1;
while(newA != newAs){
newA = digitalRead(aPin);
newB = digitalRead(bPin);
newAs = digitalRead(aPin);
}

Would fix it if you are worried.

This is another way to read encoder -> http://www.circuitsathome.com/mcu/programming/reading-rotary-encoder-on-arduino