Stepper + IR Response speed

Hey All,

First post, first project! Looking for some feedback and suggestions to fine-tune the operation…

I’m working on a model building project with a remote control lift door. The door is an acrylic slab that is raised and lowered by reeling cord on and off of a spool. The spools are attached to a drive shaft to a stepper motor which is controlled with an arduino + apple remote + IR sensor.

The intent of the mechanism is such that it should work like a remote control screen (or window shades); it moves in the specified direction (up or down) when the button is depressed and stops when the button is released [as an aside - this is opposed to pressing a button and having it lift all the way, and pressing another and having it lower all the way - it’s important that it can be stopped at will over the course of travel].

I’m using the Adafruit motor shield and a 48 step stepper, an IR decoder, and an old apple remote. I’ve used the Ken Sharriff tutorial / blog (http://www.arcfn.com/2009/08/multi-protocol-infrared-remote-library.html) as a starting point for remote decoding.

The loop continually looks for a signal and if the IR signal matches a specified code, the stepper moves forward or backward in a sets of 50 steps and then resumes looking for the IR signal. Based on my observations, when any button is depressed on the remote, the first signal is unique to the pressed button and then a universal signal continues to pass indicating that the button is being held down -(this should explain the “buttonDown” variable).

Thus the problem…

Because of the continually looping code, there’s a pause between bursts of movement. Each set of steps occurs a little more often than twice a second and between the sets of steps there’s a brief pause. chug, chug, chug, chug, chug…(etc.) My ratio right now (speed of 200, sets of 50 microsteps) is attempting to minimize the pause, but it’s still pretty evident. Ideally, it’d be absolutely smooth.

Any thoughts on ways to further minimize the chugging, perhaps through the code? Anybody dealt with a similar problem?

I’ve attached the code. Thanks in advance!

#include <IRremote.h>
#include <AFMotor.h>

AF_Stepper motor(48, 2);

int RECV_PIN = 2;
int myButtonVariable = 9;
boolean buttonDown = false;

IRrecv irrecv(RECV_PIN);

decode_results results;

void setup()
{

  Serial.begin(9600);
  irrecv.enableIRIn(); // Start the receiver
  motor.setSpeed(200);  // 10 rpm   

  motor.step(20, FORWARD, MICROSTEP); 
  motor.release();
  delay(1000);

}

void loop() {
  if (irrecv.decode(&results)) {
    //Serial.println(results.value, DEC);  
    if(results.value == 2011287595){
      myButtonVariable = 0;
      buttonDown = true;
    }

    if(results.value == 2011279403){
      myButtonVariable = 1;
      buttonDown = true;
    }

    if(results.value == 4294967295){
      buttonDown = true;
    }
    if (buttonDown = true){
      switch (myButtonVariable){
      case 0:
      //  Serial.println("upward");
        motor.step(50,FORWARD,MICROSTEP);
        motor.release();
        break;
      case 1:
      //  Serial.println("downward");
        motor.step(50,BACKWARD,MICROSTEP);
        motor.release();
        break;
    //  default:
      //  Serial.println("ummm");
      }
      buttonDown = false;  
    }
    irrecv.resume(); // Receive the next value
  }

}

Ideally, it'd be absolutely smooth.

Yes that is possible but not with the stepping motor library you are using. The trick is to start the motor going on command and only when you fail to see the move command returned from the IR do you stop it. That requires the motor to be driven by an interrupt service routine in place of the library you have. You can set up a timer to generate a regular interrupt. The the interrupt routing looks at a flag and drives the motor one step or not depending on the flag. Also another flag will indicate the direction of the motor drive. These flags are then controlled from the loop() in response to the IR signals received.