/* IR Controlled Linear Motion Machine
Created by TaeganTheZombie on 6-16-2019
Using bits from the following sources:
Motor Homing code using AccelStepper and the Serial Monitor
https://www.brainy-bits.com/setting-stepper-motors-home-position-using-accelstepper/
And bits from his IR Receiver code
https://www.brainy-bits.com/ir-remote-arduino/
Both created by Yvan / https://Brainy-Bits.com
*/
#include "IRremote.h"
#include "AccelStepper.h"
/*-----( Constants )-----*/
#define dir_pin 2 // NANO Pin connected to DIR pin of Driver
#define step_pin 3 // NANO Pin connected to STEP pin of Driver
#define receiver 4 // Signal Pin of IR receiver to Arduino Digital Pin
#define home_switch 5 // Pin connected to Home Switch (MicroSwitch)
#define beep_pin 10 // Digital Pin used for different Beep Tones
const int stepsPerMM = 200; // Steps per MM of linear travel, [(Steps per rotation)/(Leadscrew Lead in MM)]
const int maxLength = 400; // Maximum linear movement in MM, Software endstop
const int speedLimit = 2000; // Top limit for speed
const float incriment = 10.0; // Number of incriments to use for the IR Remote controlled speed and length
/*-----( Variables )-----*/
float maxSteps = (maxLength*stepsPerMM); // Max Length in steps, taken from constants
int program = 0; // Program number to run
int remoteLength = 1; // Used to store the length setting, set by IR Remote, from 0-10
float currentLength = ((float)maxSteps/incriment)*remoteLength; // Set current stroke length, in steps, using remoteLength as a scale
int remoteSpeed = 1; // Used to store the speed setting, set by IR Remote, from 0-10
float currentSpeed = ((float)speedLimit/incriment)*remoteSpeed; // Set current speed, using remoteSpeed as a scale
float currentAccel = currentSpeed*0.75; // Acceleration to use, currently 3/4 of speed
long initial_homing = -1; // Used to Home Stepper at startup
/*-----( Declare objects )-----*/
IRrecv irrecv(receiver); // create instance of 'irrecv'
decode_results results; // create instance of 'decode_results'
AccelStepper stepperX(1, step_pin, dir_pin); // 1 = Driver interface
// NANO Pin 3 connected to STEP pin of Driver
// NANO Pin 2 connected to DIR pin of Driver
void setup(){ /*----( SETUP: RUNS ONCE )----*/
Serial.begin(9600); // Start the Serial monitor with speed of 9600 Bauds
//pinMode(home_switch, INPUT_PULLUP); // Set Home switch pin
delay(5); // Wait for Driver wake up
irrecv.enableIRIn(); // Start the IR receiver
homeAxis(); // Home and set acceletation and speed
}/*--(end setup )---*/
void loop(){ /*----( LOOP: RUNS CONSTANTLY )----*/
if (!digitalRead(home_switch)) {
homeAxis();
}
else{ // While home switch is not pressed, do these things:
// IR Section
if (irrecv.decode(&results)) // have we received an IR signal?
{
translateIR();
irrecv.resume(); // receive the next value
}
// Stepper Section
runProgram(); // Runs whatever program is selected
}
stepperX.run(); // Move Stepper
}/* --(end main loop )-- */
/*-----( Functions )-----*/
void runProgram() { // Call to run program, selected by IR Remote
switch (program){
case 0: stepperX.moveTo(0); break; // Program 0, does nothing
case 1: // Program 1
if (stepperX.targetPosition() != currentLength && stepperX.isRunning() == false){
stepperX.moveTo(currentLength);
}
else if (stepperX.targetPosition() != 0 && stepperX.isRunning() == false) {
stepperX.moveTo(0);
}
break; // End Program 1
case 2: break; // Program 2
case 3: break; // Program 3
case 4: break; // Program 4
case 5: break; // Program 5
case 6: break; // Program 6
case 7: break; // Program 7
case 8: break; // Program 8
case 9: break; // Program 9
case 10: break; // Program 10
}
}
void homeAxis() { // Homes and sets zero, then sets speed and acceleration
stepperX.setMaxSpeed(600.0); // Set Max Speed of Stepper homing stage 1
stepperX.setAcceleration(500.0); // Set Acceleration of Stepper
while (digitalRead(home_switch)) { // Make the Stepper move CCW until the switch is activated
stepperX.moveTo(initial_homing); // Set the position to move to
initial_homing--; // Decrease by 1 for next move if needed
stepperX.run(); // Start moving the stepper
}
delay(5);
stepperX.setCurrentPosition(0); // Set the current position as zero for now
stepperX.setMaxSpeed(300.0); // Set Max Speed of Stepper homing stage 2
stepperX.setAcceleration(200.0); // Set Acceleration of Stepper
initial_homing=1;
while (!digitalRead(home_switch)) { // Make the Stepper move CW until the switch is deactivated
stepperX.moveTo(initial_homing);
stepperX.run();
initial_homing++;
}
stepperX.setCurrentPosition(0);
stepperX.setMaxSpeed(currentSpeed); // Set Max Speed of Stepper (Faster for regular movements)
stepperX.setAcceleration(currentAccel); // Set Acceleration of Stepper
}
void singleBeep(){
tone(beep_pin, 880, 200);
}
void longBeep(){
tone(beep_pin, 880, 200);
tone(beep_pin, 440, 200);
}
void button_up(){
if (remoteSpeed >= 10){ // Check if speed is already at 10 (or above)
remoteSpeed = 10; // Set to 10, incase above 10
longBeep(); // Long beep because setting is at max
stepperX.setMaxSpeed(currentSpeed); // Set Max Speed of Stepper
stepperX.setAcceleration(currentAccel); // Set Acceleration of Stepper
}
else{ // If speed is less than 10
remoteSpeed++; // Increase speed by 1
singleBeep(); // Beep for feedback response
stepperX.setMaxSpeed(currentSpeed); // Set Max Speed of Stepper
stepperX.setAcceleration(currentAccel); // Set Acceleration of Stepper
}
}
void button_down(){
if (remoteSpeed <= 0){ // Check if speed is already at 0 (or below)
remoteSpeed = 0; // Set to 0, incase below 0
longBeep(); // Long beep because setting is at min
stepperX.setMaxSpeed(currentSpeed); // Set Max Speed of Stepper
stepperX.setAcceleration(currentAccel); // Set Acceleration of Stepper
}
else{ // If speed is more than 0
remoteSpeed--; // Decrease speed by 1
singleBeep(); // Beep for feedback response
stepperX.setMaxSpeed(currentSpeed); // Set Max Speed of Stepper
stepperX.setAcceleration(currentAccel); // Set Acceleration of Stepper
}
}
void button_right(){
if (remoteLength >= 10){ // Check if length is already at 10 (or above)
remoteLength = 10; // Set to 10, incase above 10
longBeep(); // Long beep because setting is at max
}
else{ // If length is less than 10
remoteLength++; // Increase length by 1
singleBeep(); // Beep for feedback response
}
}
void button_left(){
if (remoteLength <= 0){ // Check if length is already at 0 (or below)
remoteLength = 0; // Set to 0, incase below 0
longBeep(); // Long beep because setting is at min
}
else{ // If length is more than 0
remoteLength--; // Decrease length by 1
singleBeep(); // Beep for feedback response
}
}
void translateIR(){ // Takes action based on IR code received
switch(results.value){
case 0x3D9AE3F7: button_up(); break; // Up
case 0x8C22657B: button_left(); break; // Left
case 0x488F3CBB: program = 10; singleBeep(); break; // OK button, program 10
case 0x449E79F: button_right(); break; // Right
case 0x1BC0157B: button_down(); break; // Down
case 0xE318261B: program = 1; singleBeep(); break; // 1
case 0x511DBB: program = 2; singleBeep(); break; // 2
case 0xEE886D7F: program = 3; singleBeep(); break; // 3
case 0x52A3D41F: program = 4; singleBeep(); break; // 4
case 0xD7E84B1B: program = 5; singleBeep(); break; // 5
case 0x20FE4DBB: program = 6; singleBeep(); break; // 6
case 0xF076C13B: program = 7; singleBeep(); break; // 7
case 0xA3C8EDDB: program = 8; singleBeep(); break; // 8
case 0xE5CFBD7F: program = 9; singleBeep(); break; // 9
case 0xC101E57B: longBeep(); homeAxis(); break; // * button homes axis
case 0x97483BFB: program = 0; singleBeep(); break; // 0
case 0xF0C41643: longBeep(); homeAxis(); break; // # button also homes
}
}