[SOLVED]For Loop in motor control

I am trying to finish a project that requires a lead screw to have a home position and a limit switch.
BHL64 was a great help in getting me sorted. I have now got all functions sorted, except the final bit of positioning.

My requirement is that once the leadscrew is positioned, I can press the 'set button' and the leadscrew will back off by a preset amount.

I have the values required outputted to the serial monitor, and the value 'pulseCount' is correct.
pulseCount is a value that takes into account the microstep setting, the leadscrew pitch and allows the user to enter the gap value in mm.

So, in the code section 'void setSet()', I have used the pulseCount value in a FOR loop. but the leadscrew just runs in reverse constantly until the carriage hits the home switch.

Could anyone help please?

[code]
// setup libraries
#include <Wire.h>
#include <Keypad.h>
#include <LiquidCrystal_I2C.h>



// Initialise LCD
LiquidCrystal_I2C lcd (0x27, 20, 4);
int lcdPowerPin = 13;
byte newChar[8] = {
  B01001,
  B01001,
  B01001,
  B01001,
  B01110,
  B01000,
  B01000,
  B10000
};


// setup Keypad
const byte numRows = 5; //number of rows on the keypad
const byte numCols = 4; //number of columns on the keypad

//keymap defines the key pressed according to the row and columns just as appears on the keypad
char keymap[numRows][numCols] =
{
  {'A', 'B', '#', '*'},
  {'1', '2', '3', 'U'},
  {'4', '5', '6', 'D'},
  {'7', '8', '9', 'C'},
  {'L', '0', 'R', 'E'}
};

int csr = 0;

byte rowPins[numRows] = {26, 28, 30, 32, 34};
byte colPins[numCols] = {42, 40, 38, 36};

//initializes an instance of the Keypad class
Keypad keypad = Keypad(makeKeymap(keymap), rowPins, colPins, numRows, numCols);


// setup Motor control parameters
String gap = "";
int gapNum = 0;
int gapFlag = 0;
int mm = 0;
int gapSteps = 0;
String steps = "";
int stepNum = 0;
int stepFlag = 0;
int pos = 0;
int posMax = 0;
int pulseCount;


// Set up Stepper Control Pins
const int enablePin = 10;
const int dirPin = 11;
const int pulsePin = 12;

#define CLOCKWISE LOW
#define COUNTERCLOCKWISE HIGH


// setup switches
const int homeButtonPin = 52;
const int fwdButtonPin = 50;
const int revButtonPin = 48;
const int setButtonPin = 46;
const int clearButtonPin = 44;

const int homeSwitchPin = 33;
const int homeSwitchNegPin = 31;
const int limitSwitchPin = 29;
const int limitSwitchNegPin = 27;


// setup LEDs
const int homeLed = 53;
const int homeLedGnd = 51;
const int forwardLed = 49;
const int forwardLedGnd = 47;
const int reverseLed = 41;
const int reverseLedGnd = 45;
const int setLed = 37;
const int setLedGnd = 43;
const int clearLed = 39;
const int clearLedGnd = 35;


// Set up Switch Registry
int homeButtonState;
int fwdButtonState;
int revButtonState;
int setButtonState;
int clearButtonState;
int homeSwitchState;
int limitSwitchState;
int homeFlag = 0;
int dly = 0;
int flagTotal = 0;
int leadScrewConstant = 50;

int dely;

void setup() {


  // setup pin functions
  pinMode (lcdPowerPin, OUTPUT);
  pinMode (enablePin, OUTPUT);
  pinMode (dirPin, OUTPUT);
  pinMode (pulsePin, OUTPUT);
  pinMode (homeButtonPin, INPUT_PULLUP);
  pinMode (fwdButtonPin, INPUT_PULLUP);
  pinMode (revButtonPin, INPUT_PULLUP);
  pinMode (setButtonPin, INPUT_PULLUP);
  pinMode (clearButtonPin, INPUT_PULLUP);
  pinMode (homeSwitchPin, INPUT_PULLUP);
  pinMode (homeSwitchNegPin, OUTPUT);
  pinMode (limitSwitchPin, INPUT_PULLUP);
  pinMode (limitSwitchNegPin, OUTPUT);

  pinMode (homeLed, OUTPUT);
  pinMode (homeLedGnd, OUTPUT);
  pinMode (forwardLed, OUTPUT);
  pinMode (forwardLedGnd, OUTPUT);
  pinMode (reverseLed, OUTPUT);
  pinMode (reverseLedGnd, OUTPUT);
  pinMode (setLed, OUTPUT);
  pinMode (setLedGnd, OUTPUT);
  pinMode (clearLed, OUTPUT);
  pinMode (clearLedGnd, OUTPUT);


  // setup common grounds

  digitalWrite (dirPin, LOW);
  digitalWrite (pulsePin, LOW);
  digitalWrite (homeSwitchNegPin, LOW);
  digitalWrite (limitSwitchNegPin, LOW);

  // setup stepper initial conditions
  digitalWrite (enablePin, HIGH);
  digitalWrite (dirPin, LOW);
  digitalWrite (pulsePin, LOW);

  // setup Serial Monitor
  Serial.begin (115200);


  //setup LCD Display
  digitalWrite (lcdPowerPin, HIGH);
  lcd.init();
  lcd.backlight();
  lcd.createChar(0, newChar);

  gapFlag = 0;
  stepFlag = 0;


}

void loop() {

  lcd.setCursor (4, 0);
  lcd.print ("Project Adept");
  lcd.setCursor (0, 1);
  lcd.print ("Gap= ");
  lcd.setCursor (9, 1);
  lcd.write (0);
  lcd.print ("Steps=");
  lcd.setCursor (0, 2);
  lcd.print ("State = ");
  lcd.setCursor (0, 3);
  lcd.print ("Pos = ");
  lcd.print (pos);
  lcd.print (" / ");
  lcd.print (posMax);



  flagTotal = gapFlag + stepFlag + homeFlag;

  Serial.print ("Home Button = ");
  Serial.print (homeButtonState);
  Serial.print (" Forward Button = ");
  Serial.print (fwdButtonState);
  Serial.print (" Gap (mm) = ");
  Serial.print (gapNum);
  Serial.print (" Step Delay = ");
  Serial.print (dely);
  Serial.print (" Microsteps = ");
  Serial.print (stepNum);
  Serial.print (" mm = ");
  Serial.print (mm);
  Serial.print (" Set Pulse Count = ");
  Serial.print (pulseCount);
  Serial.print (" Flag Total = ");
  Serial.println (flagTotal);

  //Sets the number of pulses to reverse when set button pressed

  mm = leadScrewConstant * stepNum;;
  pulseCount = (gapNum * mm);

  homeButtonState = digitalRead(homeButtonPin);
  fwdButtonState = digitalRead(fwdButtonPin);

  //display values
  if (gapFlag == 0) {
    lcd.setCursor (5, 1);
    lcd.print ("F1 ");
  }
  if (gapFlag == 1) {
    lcd.setCursor (5, 1);
    lcd.print (gapNum);
  }


  if (stepFlag == 0) {
    lcd.setCursor (17, 1);
    lcd.print ("F2 ");
  }
  if (stepFlag == 1) {
    lcd.setCursor (17, 1);
    lcd.print (stepNum);
  }

  if (homeFlag != 1) {
    lcd.setCursor (8, 2);
    lcd.print ("Set Home  ");
  }

  if (homeFlag == 1) {
    lcd.setCursor (8, 2);
    lcd.print ("Ready     ");
  }

  if ((homeButtonState == LOW) && (homeFlag == 0)) {
    digitalWrite (homeLed, HIGH);
    Home();
    digitalWrite (homeLed, LOW);
  }
  if ((homeButtonState == LOW) && (homeFlag == 1)) {
    lcd.setCursor (8, 2);
    lcd.print("Home Set  ");
    delay (1500);
  }

  if (stepNum == 1) {
    dely = 475;
  }
  if (stepNum == 2) {
    dely = 300;
  }
  if (stepNum == 4) {
    dely = 100;
  }
  if (stepNum == 8) {
    dely = 50;
  }
  if (stepNum == 16) {
    dely = 25;
  }
  if (stepNum == 32) {
    dely = 7.5;
  }


  // Set Forward Motion

  fwdButtonState = digitalRead (fwdButtonPin);
  if ((fwdButtonState == LOW) && (flagTotal != 3)) {
    lcd.setCursor (8, 2);
    lcd.print ("Set Values  ");
    delay (1500);
  }

  if ((fwdButtonState == LOW) && (flagTotal == 3)) {
    digitalWrite (forwardLed, HIGH);
    forward();
    digitalWrite (forwardLed, LOW);
  }

  if ((fwdButtonState == LOW) && (limitSwitchState == HIGH)) {
    lcd.setCursor (8, 2);
    lcd.print ("FWD LIMIT    ");
  }

  //Set Reverse Motion

  revButtonState = digitalRead (revButtonPin);
  if ((revButtonState == LOW) && (flagTotal != 3)) {
    lcd.setCursor (8, 2);
    lcd.print ("Set Values  ");
    delay (1500);
  }

  if ((revButtonState == LOW) && (flagTotal == 3)) {
    digitalWrite (reverseLed, HIGH);
    reverse();
    digitalWrite (reverseLed, LOW);
  }

  if ((revButtonState == LOW) && (homeSwitchState == HIGH)) {
    lcd.setCursor (8, 2);
    lcd.print ("REV LIMIT    ");
  }

  clearButtonState = digitalRead (clearButtonPin);
  if (clearButtonState == LOW) {
    digitalWrite (clearLed, HIGH);
    gap = "";
    gapNum = 0;
    gapFlag = 0;
    steps = "";
    stepNum = 0;
    stepFlag = 0;
    homeFlag = 0;
    delay (1500);
    digitalWrite (clearLed, LOW);
  }

  //Set Clearance
  setButtonState = digitalRead (setButtonPin);
  if ((setButtonState == LOW) && (flagTotal == 3)) {
    digitalWrite (setLed, HIGH);
    setSet();
    delay (500);
    digitalWrite (setLed, LOW);
  }





  //read keypad
  char keypressed = keypad.getKey();
  if (keypressed != NO_KEY) {                           //curly bracket 1
    if ((keypressed != 'A') && (keypressed != 'B')) {
      lcd.clear();
      lcd.setCursor (3, 1);
      lcd.print ("Invalid Input");
      delay (2000);
      lcd.clear();
      loop();
    }
    switch (keypressed) {
        break;

      case 'A': //When pressing F1
        gapSet();
        break;

      case 'B': //when pressing F2
        stepSet();
        break;






    }
  }
}
[/code]

void forward() {
  digitalWrite (enablePin, LOW);
  digitalWrite (dirPin, COUNTERCLOCKWISE);
  limitSwitchState = digitalRead (limitSwitchPin);
  fwdButtonState = digitalRead (fwdButtonPin);

  while (( limitSwitchState == LOW) && (fwdButtonState == LOW)) {
    limitSwitchState = digitalRead (limitSwitchPin);
    fwdButtonState = digitalRead (fwdButtonPin);
    digitalWrite (pulsePin, LOW);
    delayMicroseconds (dely);
    digitalWrite (pulsePin, HIGH);
    delayMicroseconds (dely);
    pos ++;
  }
  lcd.setCursor (0, 3);
  lcd.print ("                   ");
}
[code]
void gapSet() {
  gapFlag = 0;
  gapNum = 0;
  gap = "";
  csr = 0;
  lcd.clear();
  lcd.setCursor (1, 0);
  lcd.print ("Set Gap Distance");
  lcd.setCursor (1, 1);
  lcd.print ("mm");
  lcd.setCursor (9, 1);
  lcd.print ("(100mm Max)");

  do {
    char gapKey = keypad.getKey();

    if (gapKey) {
      lcd.setCursor ((csr) + 1, 3); //move cursor on LCD
      lcd.print (gapKey);           //display character pressed on keypad

      if  (gapKey >= '0' && gapKey <= '9') {     // only act on numeric keys
        gap += gapKey;               // append new character to input string
        csr++; //increase cursor count to move on lcd

      } else if (gapKey == 'E') {
        if ((gap.length() > 0) && (gap.length() <= 3)) {
          gapNum = gap.toInt(); // YOU GOT AN INTEGER NUMBER
          if (gapNum < 1) {
            lcd.clear();
            lcd.setCursor (3, 1);
            lcd.print ("Invalid Input");
            delay (2000);
            lcd.clear();
            gap = "";
            gapNum = 0;
            gapFlag = 0;
            break;
          }
          if (gapNum > 100) {
            lcd.clear();
            lcd.setCursor (3, 1);
            lcd.print ("Invalid Input");
            delay (2000);
            lcd.clear();
            gap = "";
            gapNum = 0;
            gapFlag = 0;

            break;
          }
          gapFlag = 1;            // DO YOUR WORK HERE
          gap = "";               // clear input
        }
      } else if (gapKey == 'C') {
        gapFlag = 0;
        gapNum = 0;
        gap = "";              // clear input
        lcd.clear();
        break;
      }
    }
  } while (gapFlag != 1);
  lcd.clear();

}
[/code]

void Home() {
  lcd.setCursor (8, 2);
  lcd.print ("Homing   ");

  // Drive the motor CLOCKWISE until home switch is detected
  digitalWrite (dirPin, CLOCKWISE);
  digitalWrite (enablePin, LOW);

  while (digitalRead (homeSwitchPin) == LOW) {
    digitalWrite (pulsePin, LOW);
    delayMicroseconds (dely);
    digitalWrite (pulsePin, HIGH);
    delayMicroseconds (dely);
  }

  // at HOME position so call this zero
  pos = 0;
  digitalWrite (enablePin, HIGH);

  // drive the motor in reverse until limit switch is detected
  digitalWrite (dirPin, COUNTERCLOCKWISE);
  digitalWrite (enablePin, LOW);

  while (digitalRead (limitSwitchPin) == LOW) {
    digitalWrite (pulsePin, LOW);
    delayMicroseconds (dely);
    digitalWrite (pulsePin, HIGH);
    delayMicroseconds (dely);
    pos ++;
  }

  // at LIMIT postiion
  digitalWrite (enablePin, HIGH);
  posMax = (pos);

  // Drive the motor back home
  digitalWrite (dirPin, CLOCKWISE);
  digitalWrite (enablePin, LOW);

  while (pos > 0) {

    digitalWrite (pulsePin, LOW);
    delayMicroseconds (dely);
    digitalWrite (pulsePin, HIGH);
    delayMicroseconds (dely);

    pos --;
  }
  lcd.setCursor (6, 3);
  lcd.print (pos);
  lcd.print (" ");  // need to blank out last postion when transitioning from 10000 to 9999, 1000 to 999, etc.

  // all done
  homeFlag = 1;
  digitalWrite (enablePin, HIGH);


}
[code]
void reverse() {
  digitalWrite (enablePin, LOW);
  digitalWrite (dirPin, CLOCKWISE);
  homeSwitchState = digitalRead (homeSwitchPin);
  revButtonState = digitalRead (revButtonPin);

  while (( homeSwitchState == LOW) && (revButtonState == LOW)) {
    homeSwitchState = digitalRead (homeSwitchPin);
    revButtonState = digitalRead (revButtonPin);
    digitalWrite (pulsePin, LOW);
    delayMicroseconds (dely);
    digitalWrite (pulsePin, HIGH);
    delayMicroseconds (dely);
    pos --;
  }
  lcd.setCursor (0, 3);
  lcd.print ("                   ");
}
[/code]

void setSet() {

  // causes the lead screw to retract a preset number of pulses

  digitalWrite (enablePin, LOW);
  digitalWrite (dirPin, CLOCKWISE);
  for (int i = 0; i < pulseCount; i++) { // uses for loop to create a set number of pulses
    while (homeSwitchState == LOW) {
      homeSwitchState = digitalRead (homeSwitchPin); //prevents running into end stock
      digitalWrite (pulsePin, HIGH);
      delayMicroseconds (dely);
      digitalWrite (pulsePin, LOW);
      delayMicroseconds (dely);
      pos = pos - 1;

    }
  }
}
void stepSet() {
  stepFlag = 0;
  stepNum = 0;
  steps = "";
  csr = 0;
  lcd.clear();
  lcd.setCursor (1, 0);
  lcd.print ("MicroSteps");
  lcd.setCursor (1, 1);
  lcd.print ("");
  lcd.setCursor (9, 1);
  lcd.print ("(32 Max)");

  do {
    char stepKey = keypad.getKey();

    if (stepKey) {
      lcd.setCursor ((csr) + 1, 3); //move cursor on LCD
      lcd.print (stepKey);           //display character pressed on keypad

      if  (stepKey >= '0' && stepKey <= '9') {     // only act on numeric keys
        steps += stepKey;               // append new character to input string
        csr++; //increase cursor count to move on lcd

      } else if (stepKey == 'E') {
        if ((steps.length() > 0) && (steps.length() <= 2)) {
          stepNum = steps.toInt(); // YOU GOT AN INTEGER NUMBER
          if (stepNum < 1) {
            lcd.clear();
            lcd.setCursor (3, 1);
            lcd.print ("Invalid Input");
            delay (2000);
            lcd.clear();
            steps = "";
            stepNum = 0;
            stepFlag = 0;
            break;
          }
          if ((stepNum != 1) && (stepNum != 2) && (stepNum != 4) && (stepNum != 8) && (stepNum != 16) && (stepNum != 32)) {
            lcd.clear();
            lcd.setCursor (3, 1);
            lcd.print ("Invalid Input");
            delay (2000);
            lcd.clear();
            steps = "";
            stepNum = 0;
            stepFlag = 0;

            break;
          }
          stepFlag = 1;            // DO YOUR WORK HERE
          steps = "";               // clear input
        }
      } else if (stepKey == 'C') {
        stepFlag = 0;
        stepNum = 0;
        steps = "";              // clear input
        lcd.clear();
        break;
      }
    }
  } while (stepFlag != 1);
  lcd.clear();

}

Do we have to scroll through 7 separate pieces of code or copy-paste 7 times to a editor to get the code together ? Can you put the complete sketch between code tags as a single block ?

The code that you posted does not have a setSet() function in it

I am using the tab function in the arduino ide, and I am not sure how I get all the code in one go.... sorry....

here is the missing bit of code... sorry

[code]
void setSet() {

  // causes the lead screw to retract a preset number of pulses

  digitalWrite (enablePin, LOW);
  digitalWrite (dirPin, CLOCKWISE);
  for (int i = 0; i < pulseCount; i++) { // uses for loop to create a set number of pulses
    while (homeSwitchState == LOW) {
      homeSwitchState = digitalRead (homeSwitchPin); //prevents running into end stock
      digitalWrite (pulsePin, HIGH);
      delayMicroseconds (dely);
      digitalWrite (pulsePin, LOW);
      delayMicroseconds (dely);
      pos = pos - 1;

    }
  }
}
[/code]

GOT IT!!!!
i am a blithering idiot. I used a 'while' when I should have used an 'IF'

sorry to be a pain.....

That is okay, we all have made such mistakes. I'm glad you found the problem :smiley:

Tips:

  1. The B01001 is made up by Arduino. The 'C' language uses 0b00001001. You don't have to change that, but you could already get used to the real thing :wink:
  2. The 'lcdPowerPin' and the 'newChar' and the 'keymap' are also constants, you could add there a 'const'.
  3. What is the 'lcdPowerPin' doing ? Do you have a transistor to power the LCD backlight ? A digital output might not give enough current for the backlight. If you don't use it, then power the LCD with 5V.
  4. Search what the "F macro" does. Do you have a basic Arduino board such as the Uno or Mega, then the 'F()' will help to reduce SRAM memory. Use it for the Serial messages and the text to the LCD display.
  5. Someday, you have to use millis() to do multiple things at once or a multitasking OS. I think this sketch has gone to big. Start with something simple and make a millis-timer. This is the starting page: https://www.arduino.cc/en/Tutorial/BuiltInExamples/BlinkWithoutDelay