16

Stepper motors are often pricey for a large motor. However, with a powerful, standard DC motor and a rotary encoder, you can "simulate" a stepper motor. How accurate are rotary encoders with Arduino just with a basic loop and not much other code? Is it going to "miss a pulse" and not record enough rotation often? How can I handle this with much more code? Is there a better way to do this? Would interrupts help? Is there some sort of circuit that would help with this problem?

Note: It will probably not exceed 4 rotations a second... (That may be a lot but if you're doing a lead screw type mechanism that would only be 24 inches a minute if there is 10 rotations per inch of linear motion.)

1
  • I've used rotary encoders that refused to work properly when spinned fast. I guess it varies with price.
    – jippie
    Mar 4, 2014 at 6:10

2 Answers 2

11

Interrupts are what you would use in this situation.

The rates that you have mentioned are slow enough where you probably would be able to count it inside of a loop, however this is not recommended, as a typical loop will take many clock cycles to complete, and depending on the number of instuctiuons per loop, you may miss some counts.

Interrupts are made for this purpose, as they can be triggered at any time, regardless of the state of the loop.

There is a function named attachInterrupt() which will take three arguments.

  1. Interrupt Pin
  2. Interrupt Service Routine
  3. Mode

Below is an example for counting an interrupt

volatile int myCounter = 0;

void setup(){
    attachInterrupt(0, count, RISING);
}

void count(){
    myCounter++;
}

The Modes are as follows:

LOW, CHANGE, RISING, FALLING

More information about using interrupts can be found here.

Depending on the encoder you use, you will need to tailor the code your needs, and do some more calculations to determine your position, but this should be a good starting point.

Edit Here is some example code from Arduino Sandbox for using a rotary encoder.

6
  • 1
    An interrupt driven edge detector on a Duemilanove easily handles 100 edges per second (6500rpm on a motor). Mar 4, 2014 at 23:31
  • @WayfaringStranger So then there's no problem on an Uno, then. Thanks! Mar 5, 2014 at 2:02
  • 1
    @AnnonomusPerson - How much work are you willing to put in? If you go naked (ISR_NAKED()), you can skip the automatic C context saving, and pull off 100-500 Khz interrupt rates without issue, but you're basically writing assembly in C at that point. Mar 5, 2014 at 9:01
  • 1
    If you want a completely banannas document about optimizing the absolute crap out of interrupt response, look here. Placing code directly in the interrupt table to further reduce interrupt latency! Mar 5, 2014 at 9:07
  • 1
    Also, note that if you're going for low-latency interrupts, the arduino attachInterrupt function injects a whole additional function-call overhead versus using the interrupt ISR() directly. Apr 10, 2014 at 2:13
3

Adding some references to already-written libraries and examples, to enable comparison between different approaches, and experiences with speed versus susceptibility to missing steps.

Reading rotary encoders: http://playground.arduino.cc/Main/RotaryEncoders

Quadrature Encoder too Fast for Arduino (with Solution): http://www.hessmer.org/blog/2011/01/30/quadrature-encoder-too-fast-for-arduino/

Teensy Encoder library: https://www.pjrc.com/teensy/td_libs_Encoder.html

Reading rotary encoder on Arduino: http://www.circuitsathome.com/mcu/reading-rotary-encoder-on-arduino/

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.