Hi guys, I'm building an IR remote-controlled camera slider with 3 stepper motors controlling individual things on the slider.
- Stepper 1 = LATERAL Movement (side to side)
- Stepper 2 = ROTARY Movement (spins camera around)
- Stepper 3 = FOCUS PULL Movement (rigged to clamp on lens that changes focus)
Here is a photo of the full circuit as of right now:
The main problem:
I'm using an old TV remote control to send IR signals to an IR receiver hooked into pin 12 on an UNO. The remote keypresses work PERFECTLY and do exactly what I want them to very reliably.
Pressing LEFT moves the motors clockwise, RIGHT moves the motors CCW, and MUTE stops all the motors based on "motor states" in the code. Everytime I press a remote button, it works every time as its intended.
Now the issue is adding a HOME endstop (and later adding multiple endstops) to trigger a "state" for the motors to STOP ALL MOVEMENT and home one of the steppers (in this case the LATERAL side-to-side stepper). See full code below to see the "motor states". Here is an example of the states for the LATERAL stepper:
CW ROTATION STATE (Lateral Stepper)
LeftTurnUp = 1
RightTurnDown = 0
CCW ROTATION STATE (Lateral Stepper)
LeftTurnUp = 0
RightTurnDown = 1
STOP ALL ROTATION (Lateral Stepper)
LeftTurnUp = 0
RightTurnDown = 0
For example when the MUTE button on the remote is pressed, the STOP ALL ROTATION state is activated and the motors stop. Works great. When LEFT or RIGHT buttons are pressed after that, the states change and work as expected.
I've added in a mechanical endstop to pin 10 to ALSO change the state to the STOP ALL ROTATION.
- The switch's C lead is connected to 5V+ from Arduino
- The switch's NO lead is connected to GND through a pull down 47ohm resistor
- The NC lead is not connected.
- The signal pin is connected to PIN 10 on the UNO
- When the switch is off, measured 0.0v through and when pressed a reliable ~4.5v to signal pin
The endstop works intermittently at best and is nowhere near reliable enough to act as an endstop. Here is the code for the HOME endstop:
IN INT:
int homeButton = 10; // "home" endstop
IN SETUP:
pinMode(homeButton, INPUT);
IN LOOP:
if (digitalRead(homeButton) == HIGH){
RightTurnDown = 0;
LeftTurnUp = 0;
delay(50);
}
At first I thought it was a DEBOUNCING issue so tried some debouncing code (some simple, some complex) from a few sources and none of them worked, still had the intermittent switch problem.
I even tried using a SN7400 logic gate chip to mechanically debounce the switch signal and still had the same problem intermittent function.
I've tried everything I can to make the switch work and coming here is a last resort. All my attempts lead me to believe this might be a programming issue and not a problem with the circuit which is why I didn't post this in the motor forum. Another switch of the same make had the same problem so I don't think its a faulty switch.
I think I might be going about this the wrong way (I'm not a very good programmer)?
Maybe the loop is too long and the button isn't getting read in the loop fast enough and the program is "hiccuping"?
Again, the IR remote signal changes states perfectly, quickly and reliably. Is there maybe a way to 'simulate' a command from the remote by pressing the switch?
Here are the project specs in a nutshell:
- 3 Stepper Motors all the same (200 steps/r, 2 phase, 1.2a/phase, 2.5ohm)
- 3 A4988 Stepstick drivers (set to 1/16th mode with jumpers)
- Power Supply is a 12V 2000ma wall wart to a 100uf capacitor
- Keyes IR Receiver breakout
- Using ACCELSTEPPER Library to control steppers
- In this particular program, motors are set to different speeds as proof of concept
Here is another close up photo of the breadboard:
Here is the full code of the program:
This particular program is not really based on the relative position of the motors - the idea is that when a direction is pressed on the remote, the motor keeps moving indefinitely until an endstop is triggered at either end (or remote key pressed) and the endstop switch resets the position.
#include <IRremote.h>
#include <IRremoteInt.h>
#include <AccelStepper.h>
//INT
int receiver = 12; // IR receiver pin
IRrecv irrecv(receiver); // create a new instance of IR receiver
decode_results results;
int LeftTurnUp = 0; // initial state set to 0
int RightTurnDown = 0; // initial state set to 0
int incomingByte = 0; // for incoming serial data
int homeButton = 10; // "home" endstop
//STEPPER MOTORS
AccelStepper lateral(1, 3, 6); // LATERAL Stepper: pin 3 = step, pin 6 = direction
AccelStepper rotary(1, 4, 7); // ROTARY Stepper: pin 4 = step, pin 7 = direction
AccelStepper focuspull(1, 5, 8); // FOCUS PULL Stepper: pin 5 = step, pin 8 = direction
byte hBval;
void setup() {
Serial.begin(9600);
//STEPPER MOTORS
lateral.setMaxSpeed(50); // slowest speed
lateral.setAcceleration(3000);
rotary.setMaxSpeed(100); // medium speed
rotary.setAcceleration(3000);
focuspull.setMaxSpeed(500); // fastest speed
focuspull.setAcceleration(3000);
//IR RECEIVER
irrecv.enableIRIn(); // Start the IR Receiver.
delay(100);
//ENDSTOP
pinMode(homeButton, INPUT);
}
void loop() {
if (irrecv.decode(&results)) { // we have received an IR signal
Serial.println (results.value, DEC); // display decimal value of signal code
irrecv.resume(); // receive the next value
delay(10);
}
switch(results.value){
case 2003594874: // Left Button: Rotates CW
LeftTurnUp = 1;
RightTurnDown = 0;
break;
case 584651451: // Right Button: Rotates CCW
RightTurnDown = 1;
LeftTurnUp = 0;
break;
case 2464142367: // Mute Button: STOPS all motors
RightTurnDown = 0;
LeftTurnUp = 0;
break;
}
//END STOPS - ONLY WORKS INTERMITTENTLY!!!
if (digitalRead(homeButton) == HIGH){
RightTurnDown = 0;
LeftTurnUp = 0;
delay(50);
}
//STEPPER MOTOR STATES
if (LeftTurnUp == 1) //MOTORS TURN CLOCKWISE
{
lateral.moveTo(1000000); //Keep moving CW until stopped.
rotary.moveTo(1000000); //Keep moving CW until stopped.
focuspull.moveTo(1000000); //Keep moving CW until stopped.
}
if (RightTurnDown == 1) //MOTORS TURN COUNTER CLOCKWISE
{
lateral.moveTo(-1000000); //Keep moving CCW until stopped.
rotary.moveTo(-1000000); //Keep moving CCW until stopped.
focuspull.moveTo(-1000000); //Keep moving CCW until stopped.
}
if (RightTurnDown == 0 && LeftTurnUp == 0) //STOP ALL MOTOR MOVEMENT
{
lateral.stop();
rotary.stop();
focuspull.stop();
}
lateral.run();
rotary.run();
focuspull.run();
}
/*
IR REMOTE CONTROL BUTTON CODES
MUTE BUTTON = 2464142367 (Stops movement of motors.)
LEFT BUTTON = 2003594874 (Rotates motors CW.)
RIGHT = 584651451 (Rotates motors CCW.)
*/
Any help or suggestions is hugely appreciated. I realize I might have to rethink how the entire program is run. Thanks all in advance.

