Skip to main content
Tweeted twitter.com/StackArduino/status/1332112011455553543
deleted 847 characters in body
Source Link
Jay
  • 61
  • 6
 const int uSensor = 12;
const int proxSensor = 10;

const int labViewHomePin = 9;
const int labViewInputPin = 8;

const int labViewOutFeedback = 7;
const int labViewInFeedback = 6;

const int StepperStepPin = 2;
const int StepperDirectionPin = 3;
const int ENPin = 13;

enum {IdleState, ForwardState, BackwardState} State;            // this switch case is used to call the correct function that turns the motor in the desired direction

boolean rampDone = false;
boolean pusherIn = false;
boolean pusherOut = false;
boolean homingDone = false;

boolean updateGiven = false;

int motorSpeed = 300;
int rampStartSpeed = 500;
int rampStepCountNo = 800;

boolean boolInitialMove = true;
unsigned long timeInitialMove = 6000;
unsigned long startTime;
unsigned long endTime;


void setup() {
  Serial.begin(9600);
  pinMode(uSensor, INPUT);
  pinMode(proxSensor, INPUT);
  pinMode(labViewHomePin, INPUT);                                  // initialising input pins                                     
  pinMode(labViewInputPin, INPUT);                                  // initialising input pins

  pinMode(StepperDirectionPin, OUTPUT);                             //Direction
  pinMode(StepperStepPin, OUTPUT);                                  // Step
  pinMode(ENPin, OUTPUT);                                           // Enable
  
  Serial.println();
  Serial.println("Setup phase called");
  Serial.println();
  
  pinMode(labViewInFeedback, OUTPUT);                             // initialising output pins to let LabVIEW know the pusher is operating correctly
  pinMode(labViewOutFeedback, OUTPUT);  

  State = IdleState;                                                // initial switch case is the 'Idle State' - the motor sits idle, waiting for a digital signal from LabVIEW
  digitalWrite(ENPin,HIGH);                                         // Disable the drive by default
                                    
  
  homingDone = false;
}

void loop() {
  if ((digitalRead(labViewHomePin) == HIGH) && (homingDone == false)) {
    Serial.println("Homing Pin High Detected");
    homingRoutine();
    homingDone = true;  
    Serial.print("Homing Done = ");
    Serial.println(homingDone);
    State = IdleState;

    if(digitalRead(proxSensor) == HIGH) {
      digitalWrite(labViewInFeedback,HIGH);
      digitalWrite(labViewOutFeedback,LOW);
    }
    else if(digitalRead(uSensor) == HIGH)  {
      digitalWrite(labViewInFeedback,LOW);
      digitalWrite(labViewOutFeedback,HIGH);
    }
    else {
      digitalWrite(labViewInFeedback,LOW);
      digitalWrite(labViewOutFeedback,LOW);
    }
  
  }
  
  switch (State) {
    case IdleState:
    boolInitialMove = true;
    digitalWrite(ENPin,HIGH);

      if(updateGiven == false) {
        Serial.println("I am in IdleState");
        Serial.print("Pusher Out Boolean = ");
        Serial.println(pusherOut);
        Serial.print("Pusher In Boolean = ");
        Serial.println(pusherIn);
        Serial.print("Prox Sensor status: ");
        Serial.println(digitalRead(proxSensor));
        Serial.print("U-Sensor status: ");
        Serial.println(digitalRead(uSensor));
        updateGiven = true;
      }

        
      if ((digitalRead(labViewInputPin) == HIGH) && (pusherOut == false) && (homingDone == true)) {
        digitalWrite(ENPin,LOW);                                    // Enable drive
        State = ForwardState;                                       // if the digital pin is sent high, the state switches to ForwardState. see the ForwardState case to see what happens here
        Serial.println("LabVIEW High detected. Case switched to ForwardState");
        Serial.println("");
        updateGiven = false;
      }
      else if ((digitalRead(labViewInputPin) == LOW) && (pusherIn == false) && (homingDone == true)) {
        digitalWrite(ENPin,LOW);                                    // Enable drive
        State = BackwardState;                                       // if the digital pin is sent high, the state switches to ForwardState. see the ForwardState case to see what happens here        
        Serial.println("LabVIEW Low detected. Case switched to BackwardState");
        Serial.println("");
        updateGiven = false;
      }
      else {
        //do nothing
      }
      
      if(digitalRead(uSensor) == HIGH) {
        pusherOut = true;
        pusherIn = false; 
      }
      else if(digitalRead(proxSensor) == HIGH) {
        pusherOut = false;
        pusherIn = true;
      }
      else {
        //do nothing
      }
      
      break;
      

    case ForwardState:

    if(updateGiven == false) {
        Serial.println("I am in ForwardState");
        Serial.print("LabVIEW Actuate Pin = ");
        Serial.println(digitalRead(labViewHomePin));
        updateGiven = true;
      }
      
    if(boolInitialMove == true) {
        digitalWrite(StepperDirectionPin, LOW);
        rampUpCosineWave(rampStartSpeed, rampStepCountNo, motorSpeed);
        startTime = millis();
        endTime = startTime;
        boolInitialMove = false;
      }
      
      endTime = millis();
      rotateForward(motorSpeed);                                            // this calls the function ForwardState which starts pushing out the pusher
      
      if (digitalRead(uSensor) == HIGH) {
        digitalWrite(labViewInFeedback,LOW);                   
        digitalWrite(labViewOutFeedback,HIGH);
        Serial.println("U-Sensor High detected. Case switched to Idlestate");
        Serial.println("");
        updateGiven = false;
        
        pusherOut = true;
        pusherIn = false;
        State = IdleState;                                    // the motor stays rotating until the uSensor gives a low input signal (u-sensor beam broken). The state switches to the backwardstate
      }
      else if((endTime-startTime) > timeInitialMove) {
        digitalWrite(ENPin,HIGH);
        digitalWrite(StepperStepPin, LOW);
        digitalWrite(StepperDirectionPin, LOW);
        digitalWrite(labViewOutFeedback,HIGH);
        digitalWrite(labViewInFeedback,HIGH);

        
        Serial.println("");
        Serial.println("**TIMEOUT DETECTED**");
        Serial.println("");
        
        State = IdleState; 
      }
      break;
      

    case BackwardState:

    if(updateGiven == false) {
        Serial.println("I am in BackwardState");
        Serial.print("LabVIEW Actuate Pin = ");
        Serial.println(digitalRead(labViewHomePin));
        updateGiven = true;
      }
      
    if(boolInitialMove == true) {
        digitalWrite(StepperDirectionPin, HIGH);
        rampUpCosineWave(rampStartSpeed, rampStepCountNo, motorSpeed);
        startTime = millis();
        endTime = startTime;
        boolInitialMove = false;
      }
      
      endTime = millis();
      rotateBackward(motorSpeed);                                          // the motor rotates backwards, pulling in the pusher until the poximity sensor gives a hgih input signal, confirming the pusher is home
      
      if (digitalRead(proxSensor) == HIGH) {
        digitalWrite(labViewInFeedback,HIGH);                   
        digitalWrite(labViewOutFeedback,LOW);                                // Disable drive
        Serial.println("Prox Sensor High detected. Case switched to Idlestate");
        Serial.println("");
        updateGiven = false;
        
        pusherOut = false;
        pusherIn = true;
        State = IdleState;                                      // the motor is set idle again, awaiting a digital input signal from LabVIEW to restart the whole process
      }
      else if((endTime-startTime) > timeInitialMove) {
        digitalWrite(ENPin,HIGH);
        digitalWrite(StepperStepPin, LOW);
        digitalWrite(StepperDirectionPin, LOW);
        digitalWrite(labViewOutFeedback,HIGH);
        digitalWrite(labViewInFeedback,HIGH);

        Serial.println("");
        Serial.println("**TIMEOUT DETECTED**");
        Serial.println("");
        
        State = IdleState; 
      }
      break;
 
  } // end switch
}

void rotateForward(int mtrSpeed) {                                          
  digitalWrite(StepperDirectionPin, LOW);
  digitalWrite(StepperStepPin, HIGH);
  delayMicroseconds(mtrSpeed);
  digitalWrite(StepperStepPin, LOW);
}

void rotateBackward(int mtrSpeed) {
  digitalWrite(StepperDirectionPin, HIGH);
  digitalWrite(StepperStepPin, LOW);
  delayMicroseconds(mtrSpeed);
  digitalWrite(StepperStepPin, HIGH);
}

void homingRoutine() {
  digitalWrite(ENPin,LOW);
  Serial.println("Homing Routine called");
  bool firstCycle = false;
  bool secondCycle = false;
  bool thirdCycle = false;
  bool fourthCycle = false;
   
  while(digitalRead(uSensor) != HIGH) {
    rotateForward(rampStartSpeed);
  }
  delay(500);
  Serial.println("First home movement completed");
  while(digitalRead(proxSensor) != HIGH) {
    rotateBackward(rampStartSpeed);
  }
  delay(500);
  Serial.println("Second home movement completed");
  while(digitalRead(uSensor) != HIGH) {
    rotateForward(rampStartSpeed);
  }
  delay(500);
  Serial.println("Third home movement completed");
  while(digitalRead(proxSensor) != HIGH) {
    rotateBackward(rampStartSpeed);
  }

  delay(500);

  
  homingDone = true;
  pusherIn = true;
  pusherOut = false;

}
  
  int rampUpCosineWave(int startSpeed, int rampUpSteps, int maximumSpeed) {
  int countedSteps = 0;
  float amp = ((startSpeed-maximumSpeed)/2);
  for(int currentSpeed = startSpeed; currentSpeed > maximumSpeed; currentSpeed = (int)((amp + maximumSpeed)+(amp*(cos((PI/rampUpSteps)*countedSteps))))) {
    digitalWrite(StepperStepPin, LOW);
    delayMicroseconds(currentSpeed);
    digitalWrite(StepperStepPin, HIGH);
    countedSteps++;
  }

  return countedSteps;
}
 const int uSensor = 12;
const int proxSensor = 10;

const int labViewHomePin = 9;
const int labViewInputPin = 8;

const int labViewOutFeedback = 7;
const int labViewInFeedback = 6;

const int StepperStepPin = 2;
const int StepperDirectionPin = 3;
const int ENPin = 13;

enum {IdleState, ForwardState, BackwardState} State;            // this switch case is used to call the correct function that turns the motor in the desired direction

boolean rampDone = false;
boolean pusherIn = false;
boolean pusherOut = false;
boolean homingDone = false;

boolean updateGiven = false;

int motorSpeed = 300;
int rampStartSpeed = 500;
int rampStepCountNo = 800;

boolean boolInitialMove = true;
unsigned long timeInitialMove = 6000;
unsigned long startTime;
unsigned long endTime;


void setup() {
  Serial.begin(9600);
  pinMode(uSensor, INPUT);
  pinMode(proxSensor, INPUT);
  pinMode(labViewHomePin, INPUT);                                  // initialising input pins                                     
  pinMode(labViewInputPin, INPUT);                                  // initialising input pins

  pinMode(StepperDirectionPin, OUTPUT);                             //Direction
  pinMode(StepperStepPin, OUTPUT);                                  // Step
  pinMode(ENPin, OUTPUT);                                           // Enable
  
  Serial.println();
  Serial.println("Setup phase called");
  Serial.println();
  
  pinMode(labViewInFeedback, OUTPUT);                             // initialising output pins to let LabVIEW know the pusher is operating correctly
  pinMode(labViewOutFeedback, OUTPUT);  

  State = IdleState;                                                // initial switch case is the 'Idle State' - the motor sits idle, waiting for a digital signal from LabVIEW
  digitalWrite(ENPin,HIGH);                                         // Disable the drive by default
                                    
  
  homingDone = false;
}

void loop() {
  if ((digitalRead(labViewHomePin) == HIGH) && (homingDone == false)) {
    Serial.println("Homing Pin High Detected");
    homingRoutine();
    homingDone = true;  
    Serial.print("Homing Done = ");
    Serial.println(homingDone);
    State = IdleState;

    if(digitalRead(proxSensor) == HIGH) {
      digitalWrite(labViewInFeedback,HIGH);
      digitalWrite(labViewOutFeedback,LOW);
    }
    else if(digitalRead(uSensor) == HIGH)  {
      digitalWrite(labViewInFeedback,LOW);
      digitalWrite(labViewOutFeedback,HIGH);
    }
    else {
      digitalWrite(labViewInFeedback,LOW);
      digitalWrite(labViewOutFeedback,LOW);
    }
  
  }
  
  switch (State) {
    case IdleState:
    boolInitialMove = true;
    digitalWrite(ENPin,HIGH);

      if(updateGiven == false) {
        Serial.println("I am in IdleState");
        Serial.print("Pusher Out Boolean = ");
        Serial.println(pusherOut);
        Serial.print("Pusher In Boolean = ");
        Serial.println(pusherIn);
        Serial.print("Prox Sensor status: ");
        Serial.println(digitalRead(proxSensor));
        Serial.print("U-Sensor status: ");
        Serial.println(digitalRead(uSensor));
        updateGiven = true;
      }

        
      if ((digitalRead(labViewInputPin) == HIGH) && (pusherOut == false) && (homingDone == true)) {
        digitalWrite(ENPin,LOW);                                    // Enable drive
        State = ForwardState;                                       // if the digital pin is sent high, the state switches to ForwardState. see the ForwardState case to see what happens here
        Serial.println("LabVIEW High detected. Case switched to ForwardState");
        Serial.println("");
        updateGiven = false;
      }
      else if ((digitalRead(labViewInputPin) == LOW) && (pusherIn == false) && (homingDone == true)) {
        digitalWrite(ENPin,LOW);                                    // Enable drive
        State = BackwardState;                                       // if the digital pin is sent high, the state switches to ForwardState. see the ForwardState case to see what happens here        
        Serial.println("LabVIEW Low detected. Case switched to BackwardState");
        Serial.println("");
        updateGiven = false;
      }
      else {
        //do nothing
      }
      
      if(digitalRead(uSensor) == HIGH) {
        pusherOut = true;
        pusherIn = false; 
      }
      else if(digitalRead(proxSensor) == HIGH) {
        pusherOut = false;
        pusherIn = true;
      }
      else {
        //do nothing
      }
      
      break;
      

    case ForwardState:

    if(updateGiven == false) {
        Serial.println("I am in ForwardState");
        Serial.print("LabVIEW Actuate Pin = ");
        Serial.println(digitalRead(labViewHomePin));
        updateGiven = true;
      }
      
    if(boolInitialMove == true) {
        digitalWrite(StepperDirectionPin, LOW);
        rampUpCosineWave(rampStartSpeed, rampStepCountNo, motorSpeed);
        startTime = millis();
        endTime = startTime;
        boolInitialMove = false;
      }
      
      endTime = millis();
      rotateForward(motorSpeed);                                            // this calls the function ForwardState which starts pushing out the pusher
      
      if (digitalRead(uSensor) == HIGH) {
        digitalWrite(labViewInFeedback,LOW);                   
        digitalWrite(labViewOutFeedback,HIGH);
        Serial.println("U-Sensor High detected. Case switched to Idlestate");
        Serial.println("");
        updateGiven = false;
        
        pusherOut = true;
        pusherIn = false;
        State = IdleState;                                    // the motor stays rotating until the uSensor gives a low input signal (u-sensor beam broken). The state switches to the backwardstate
      }
      else if((endTime-startTime) > timeInitialMove) {
        digitalWrite(ENPin,HIGH);
        digitalWrite(StepperStepPin, LOW);
        digitalWrite(StepperDirectionPin, LOW);
        digitalWrite(labViewOutFeedback,HIGH);
        digitalWrite(labViewInFeedback,HIGH);

        
        Serial.println("");
        Serial.println("**TIMEOUT DETECTED**");
        Serial.println("");
        
        State = IdleState; 
      }
      break;
      

    case BackwardState:

    if(updateGiven == false) {
        Serial.println("I am in BackwardState");
        Serial.print("LabVIEW Actuate Pin = ");
        Serial.println(digitalRead(labViewHomePin));
        updateGiven = true;
      }
      
    if(boolInitialMove == true) {
        digitalWrite(StepperDirectionPin, HIGH);
        rampUpCosineWave(rampStartSpeed, rampStepCountNo, motorSpeed);
        startTime = millis();
        endTime = startTime;
        boolInitialMove = false;
      }
      
      endTime = millis();
      rotateBackward(motorSpeed);                                          // the motor rotates backwards, pulling in the pusher until the poximity sensor gives a hgih input signal, confirming the pusher is home
      
      if (digitalRead(proxSensor) == HIGH) {
        digitalWrite(labViewInFeedback,HIGH);                   
        digitalWrite(labViewOutFeedback,LOW);                                // Disable drive
        Serial.println("Prox Sensor High detected. Case switched to Idlestate");
        Serial.println("");
        updateGiven = false;
        
        pusherOut = false;
        pusherIn = true;
        State = IdleState;                                      // the motor is set idle again, awaiting a digital input signal from LabVIEW to restart the whole process
      }
      else if((endTime-startTime) > timeInitialMove) {
        digitalWrite(ENPin,HIGH);
        digitalWrite(StepperStepPin, LOW);
        digitalWrite(StepperDirectionPin, LOW);
        digitalWrite(labViewOutFeedback,HIGH);
        digitalWrite(labViewInFeedback,HIGH);

        Serial.println("");
        Serial.println("**TIMEOUT DETECTED**");
        Serial.println("");
        
        State = IdleState; 
      }
      break;
 
  } // end switch
}

void rotateForward(int mtrSpeed) {                                          
  digitalWrite(StepperDirectionPin, LOW);
  digitalWrite(StepperStepPin, HIGH);
  delayMicroseconds(mtrSpeed);
  digitalWrite(StepperStepPin, LOW);
}

void rotateBackward(int mtrSpeed) {
  digitalWrite(StepperDirectionPin, HIGH);
  digitalWrite(StepperStepPin, LOW);
  delayMicroseconds(mtrSpeed);
  digitalWrite(StepperStepPin, HIGH);
}

void homingRoutine() {
  digitalWrite(ENPin,LOW);
  Serial.println("Homing Routine called");
  bool firstCycle = false;
  bool secondCycle = false;
  bool thirdCycle = false;
  bool fourthCycle = false;
   
  while(digitalRead(uSensor) != HIGH) {
    rotateForward(rampStartSpeed);
  }
  delay(500);
  Serial.println("First home movement completed");
  while(digitalRead(proxSensor) != HIGH) {
    rotateBackward(rampStartSpeed);
  }
  delay(500);
  Serial.println("Second home movement completed");
  while(digitalRead(uSensor) != HIGH) {
    rotateForward(rampStartSpeed);
  }
  delay(500);
  Serial.println("Third home movement completed");
  while(digitalRead(proxSensor) != HIGH) {
    rotateBackward(rampStartSpeed);
  }

  delay(500);

  
  homingDone = true;
  pusherIn = true;
  pusherOut = false;

}
  
  int rampUpCosineWave(int startSpeed, int rampUpSteps, int maximumSpeed) {
  int countedSteps = 0;
  float amp = ((startSpeed-maximumSpeed)/2);
  for(int currentSpeed = startSpeed; currentSpeed > maximumSpeed; currentSpeed = (int)((amp + maximumSpeed)+(amp*(cos((PI/rampUpSteps)*countedSteps))))) {
    digitalWrite(StepperStepPin, LOW);
    delayMicroseconds(currentSpeed);
    digitalWrite(StepperStepPin, HIGH);
    countedSteps++;
  }

  return countedSteps;
}
 const int uSensor = 12;
const int proxSensor = 10;

const int labViewHomePin = 9;
const int labViewInputPin = 8;

const int labViewOutFeedback = 7;
const int labViewInFeedback = 6;

const int StepperStepPin = 2;
const int StepperDirectionPin = 3;
const int ENPin = 13;

enum {IdleState, ForwardState, BackwardState} State;            // this switch case is used to call the correct function that turns the motor in the desired direction

boolean rampDone = false;
boolean pusherIn = false;
boolean pusherOut = false;
boolean homingDone = false;

boolean updateGiven = false;

int motorSpeed = 300;
int rampStartSpeed = 500;
int rampStepCountNo = 800;

boolean boolInitialMove = true;
unsigned long timeInitialMove = 6000;
unsigned long startTime;
unsigned long endTime;


void setup() {
  Serial.begin(9600);
  pinMode(uSensor, INPUT);
  pinMode(proxSensor, INPUT);
  pinMode(labViewHomePin, INPUT);                                  // initialising input pins                                     
  pinMode(labViewInputPin, INPUT);                                  // initialising input pins

  pinMode(StepperDirectionPin, OUTPUT);                             //Direction
  pinMode(StepperStepPin, OUTPUT);                                  // Step
  pinMode(ENPin, OUTPUT);                                           // Enable
  
  Serial.println();
  Serial.println("Setup phase called");
  Serial.println();
  
  pinMode(labViewInFeedback, OUTPUT);                             
  pinMode(labViewOutFeedback, OUTPUT);  

  State = IdleState;                                                
  digitalWrite(ENPin,HIGH);                                         // Disable the drive by default
                                    
  
  homingDone = false;
}

void loop() {
  if ((digitalRead(labViewHomePin) == HIGH) && (homingDone == false)) {
    Serial.println("Homing Pin High Detected");
    homingRoutine();
    homingDone = true;  
    Serial.print("Homing Done = ");
    Serial.println(homingDone);
    State = IdleState;

    if(digitalRead(proxSensor) == HIGH) {
      digitalWrite(labViewInFeedback,HIGH);
      digitalWrite(labViewOutFeedback,LOW);
    }
    else if(digitalRead(uSensor) == HIGH)  {
      digitalWrite(labViewInFeedback,LOW);
      digitalWrite(labViewOutFeedback,HIGH);
    }
    else {
      digitalWrite(labViewInFeedback,LOW);
      digitalWrite(labViewOutFeedback,LOW);
    }
  
  }
  
  switch (State) {
    case IdleState:
    boolInitialMove = true;
    digitalWrite(ENPin,HIGH);

      if(updateGiven == false) {
        Serial.println("I am in IdleState");
        Serial.print("Pusher Out Boolean = ");
        Serial.println(pusherOut);
        Serial.print("Pusher In Boolean = ");
        Serial.println(pusherIn);
        Serial.print("Prox Sensor status: ");
        Serial.println(digitalRead(proxSensor));
        Serial.print("U-Sensor status: ");
        Serial.println(digitalRead(uSensor));
        updateGiven = true;
      }

        
      if ((digitalRead(labViewInputPin) == HIGH) && (pusherOut == false) && (homingDone == true)) {
        digitalWrite(ENPin,LOW);                                    // Enable drive
        State = ForwardState;        
        Serial.println("LabVIEW High detected. Case switched to ForwardState");
        Serial.println("");
        updateGiven = false;
      }
      else if ((digitalRead(labViewInputPin) == LOW) && (pusherIn == false) && (homingDone == true)) {
        digitalWrite(ENPin,LOW);                                    // Enable drive
        State = BackwardState;                                       
        Serial.println("LabVIEW Low detected. Case switched to BackwardState");
        Serial.println("");
        updateGiven = false;
      }
      else {
        //do nothing
      }
      
      if(digitalRead(uSensor) == HIGH) {
        pusherOut = true;
        pusherIn = false; 
      }
      else if(digitalRead(proxSensor) == HIGH) {
        pusherOut = false;
        pusherIn = true;
      }
      else {
        //do nothing
      }
      
      break;
      

    case ForwardState:

    if(updateGiven == false) {
        Serial.println("I am in ForwardState");
        Serial.print("LabVIEW Actuate Pin = ");
        Serial.println(digitalRead(labViewHomePin));
        updateGiven = true;
      }
      
    if(boolInitialMove == true) {
        digitalWrite(StepperDirectionPin, LOW);
        rampUpCosineWave(rampStartSpeed, rampStepCountNo, motorSpeed);
        startTime = millis();
        endTime = startTime;
        boolInitialMove = false;
      }
      
      endTime = millis();
      rotateForward(motorSpeed);                                            // this calls the function ForwardState which starts pushing out the pusher
      
      if (digitalRead(uSensor) == HIGH) {
        digitalWrite(labViewInFeedback,LOW);                   
        digitalWrite(labViewOutFeedback,HIGH);
        Serial.println("U-Sensor High detected. Case switched to Idlestate");
        Serial.println("");
        updateGiven = false;
        
        pusherOut = true;
        pusherIn = false;
        State = IdleState;                                   
      }
      else if((endTime-startTime) > timeInitialMove) {
        digitalWrite(ENPin,HIGH);
        digitalWrite(StepperStepPin, LOW);
        digitalWrite(StepperDirectionPin, LOW);
        digitalWrite(labViewOutFeedback,HIGH);
        digitalWrite(labViewInFeedback,HIGH);

        
        Serial.println("");
        Serial.println("**TIMEOUT DETECTED**");
        Serial.println("");
        
        State = IdleState; 
      }
      break;
      

    case BackwardState:

    if(updateGiven == false) {
        Serial.println("I am in BackwardState");
        Serial.print("LabVIEW Actuate Pin = ");
        Serial.println(digitalRead(labViewHomePin));
        updateGiven = true;
      }
      
    if(boolInitialMove == true) {
        digitalWrite(StepperDirectionPin, HIGH);
        rampUpCosineWave(rampStartSpeed, rampStepCountNo, motorSpeed);
        startTime = millis();
        endTime = startTime;
        boolInitialMove = false;
      }
      
      endTime = millis();
      rotateBackward(motorSpeed);                                          
      
      if (digitalRead(proxSensor) == HIGH) {
        digitalWrite(labViewInFeedback,HIGH);                   
        digitalWrite(labViewOutFeedback,LOW);                                // Disable drive
        Serial.println("Prox Sensor High detected. Case switched to Idlestate");
        Serial.println("");
        updateGiven = false;
        
        pusherOut = false;
        pusherIn = true;
        State = IdleState;                                      
      }
      else if((endTime-startTime) > timeInitialMove) {
        digitalWrite(ENPin,HIGH);
        digitalWrite(StepperStepPin, LOW);
        digitalWrite(StepperDirectionPin, LOW);
        digitalWrite(labViewOutFeedback,HIGH);
        digitalWrite(labViewInFeedback,HIGH);

        Serial.println("");
        Serial.println("**TIMEOUT DETECTED**");
        Serial.println("");
        
        State = IdleState; 
      }
      break;
 
  } // end switch
}

void rotateForward(int mtrSpeed) {                                          
  digitalWrite(StepperDirectionPin, LOW);
  digitalWrite(StepperStepPin, HIGH);
  delayMicroseconds(mtrSpeed);
  digitalWrite(StepperStepPin, LOW);
}

void rotateBackward(int mtrSpeed) {
  digitalWrite(StepperDirectionPin, HIGH);
  digitalWrite(StepperStepPin, LOW);
  delayMicroseconds(mtrSpeed);
  digitalWrite(StepperStepPin, HIGH);
}

void homingRoutine() {
  digitalWrite(ENPin,LOW);
  Serial.println("Homing Routine called");
  bool firstCycle = false;
  bool secondCycle = false;
  bool thirdCycle = false;
  bool fourthCycle = false;
   
  while(digitalRead(uSensor) != HIGH) {
    rotateForward(rampStartSpeed);
  }
  delay(500);
  Serial.println("First home movement completed");
  while(digitalRead(proxSensor) != HIGH) {
    rotateBackward(rampStartSpeed);
  }
  delay(500);
  Serial.println("Second home movement completed");
  while(digitalRead(uSensor) != HIGH) {
    rotateForward(rampStartSpeed);
  }
  delay(500);
  Serial.println("Third home movement completed");
  while(digitalRead(proxSensor) != HIGH) {
    rotateBackward(rampStartSpeed);
  }

  delay(500);

  
  homingDone = true;
  pusherIn = true;
  pusherOut = false;

}
  
  int rampUpCosineWave(int startSpeed, int rampUpSteps, int maximumSpeed) {
  int countedSteps = 0;
  float amp = ((startSpeed-maximumSpeed)/2);
  for(int currentSpeed = startSpeed; currentSpeed > maximumSpeed; currentSpeed = (int)((amp + maximumSpeed)+(amp*(cos((PI/rampUpSteps)*countedSteps))))) {
    digitalWrite(StepperStepPin, LOW);
    delayMicroseconds(currentSpeed);
    digitalWrite(StepperStepPin, HIGH);
    countedSteps++;
  }

  return countedSteps;
}
Source Link
Jay
  • 61
  • 6

Arduino Nano randomly resetting

I am currently struggling with an intermittent problem with an Arduino project.

Background

I am using a LabVIEW program to control a few pieces of hardware. One of them is a NEMA 17 stepper motor that drives a rack and pinion actuator. I am using a genuine Arduino Nano with an (official) EasyDriver motor driver to drive the NEMA 17. The Arduino listens for the state of a DI pin, and if it is pulled high it moves out the rack until a U-shaped sensor sends a high input signal at the outermost position, it then listens for that DI pin to be pulled low and retracts the rack until a proximity sensor sends a high input signal.

The Problem

I noticed that my actuator was either becoming unresponsive to the input signals from the LabVIEW DAQ, or that it was getting stuck mid actuation (motor has plenty of torque for this application). After changing up the code to print updates to the serial port, I realized that after a few cycles the Arduino resets and re-enters the Setup() function.

I changed out the Nano and it made no difference. I am using a timeout feature for the first time and I was wondering if the memory usage of this feature could be causing problems - however I commented out this part of the code and the Arduino still reset. The code is below - would really love to hear any thoughts on whether this is likely to be a hardware or software issue. I am powering the Arduino with a 7V line from a Power Supply into the Vin port. The prox sensor operates at 24V but I divide the output signal's voltage so that the input voltage is ~4.8V (I have measured this). I am using the same U-shaped sensor with a few other Arduinos and I am not seeing this issue. I have powered Arduinos with the same 7V line in the past and have also never seen them reset like this.

Let me know what you think, thank you!

 const int uSensor = 12;
const int proxSensor = 10;

const int labViewHomePin = 9;
const int labViewInputPin = 8;

const int labViewOutFeedback = 7;
const int labViewInFeedback = 6;

const int StepperStepPin = 2;
const int StepperDirectionPin = 3;
const int ENPin = 13;

enum {IdleState, ForwardState, BackwardState} State;            // this switch case is used to call the correct function that turns the motor in the desired direction

boolean rampDone = false;
boolean pusherIn = false;
boolean pusherOut = false;
boolean homingDone = false;

boolean updateGiven = false;

int motorSpeed = 300;
int rampStartSpeed = 500;
int rampStepCountNo = 800;

boolean boolInitialMove = true;
unsigned long timeInitialMove = 6000;
unsigned long startTime;
unsigned long endTime;


void setup() {
  Serial.begin(9600);
  pinMode(uSensor, INPUT);
  pinMode(proxSensor, INPUT);
  pinMode(labViewHomePin, INPUT);                                  // initialising input pins                                     
  pinMode(labViewInputPin, INPUT);                                  // initialising input pins

  pinMode(StepperDirectionPin, OUTPUT);                             //Direction
  pinMode(StepperStepPin, OUTPUT);                                  // Step
  pinMode(ENPin, OUTPUT);                                           // Enable
  
  Serial.println();
  Serial.println("Setup phase called");
  Serial.println();
  
  pinMode(labViewInFeedback, OUTPUT);                             // initialising output pins to let LabVIEW know the pusher is operating correctly
  pinMode(labViewOutFeedback, OUTPUT);  

  State = IdleState;                                                // initial switch case is the 'Idle State' - the motor sits idle, waiting for a digital signal from LabVIEW
  digitalWrite(ENPin,HIGH);                                         // Disable the drive by default
                                    
  
  homingDone = false;
}

void loop() {
  if ((digitalRead(labViewHomePin) == HIGH) && (homingDone == false)) {
    Serial.println("Homing Pin High Detected");
    homingRoutine();
    homingDone = true;  
    Serial.print("Homing Done = ");
    Serial.println(homingDone);
    State = IdleState;

    if(digitalRead(proxSensor) == HIGH) {
      digitalWrite(labViewInFeedback,HIGH);
      digitalWrite(labViewOutFeedback,LOW);
    }
    else if(digitalRead(uSensor) == HIGH)  {
      digitalWrite(labViewInFeedback,LOW);
      digitalWrite(labViewOutFeedback,HIGH);
    }
    else {
      digitalWrite(labViewInFeedback,LOW);
      digitalWrite(labViewOutFeedback,LOW);
    }
  
  }
  
  switch (State) {
    case IdleState:
    boolInitialMove = true;
    digitalWrite(ENPin,HIGH);

      if(updateGiven == false) {
        Serial.println("I am in IdleState");
        Serial.print("Pusher Out Boolean = ");
        Serial.println(pusherOut);
        Serial.print("Pusher In Boolean = ");
        Serial.println(pusherIn);
        Serial.print("Prox Sensor status: ");
        Serial.println(digitalRead(proxSensor));
        Serial.print("U-Sensor status: ");
        Serial.println(digitalRead(uSensor));
        updateGiven = true;
      }

        
      if ((digitalRead(labViewInputPin) == HIGH) && (pusherOut == false) && (homingDone == true)) {
        digitalWrite(ENPin,LOW);                                    // Enable drive
        State = ForwardState;                                       // if the digital pin is sent high, the state switches to ForwardState. see the ForwardState case to see what happens here
        Serial.println("LabVIEW High detected. Case switched to ForwardState");
        Serial.println("");
        updateGiven = false;
      }
      else if ((digitalRead(labViewInputPin) == LOW) && (pusherIn == false) && (homingDone == true)) {
        digitalWrite(ENPin,LOW);                                    // Enable drive
        State = BackwardState;                                       // if the digital pin is sent high, the state switches to ForwardState. see the ForwardState case to see what happens here        
        Serial.println("LabVIEW Low detected. Case switched to BackwardState");
        Serial.println("");
        updateGiven = false;
      }
      else {
        //do nothing
      }
      
      if(digitalRead(uSensor) == HIGH) {
        pusherOut = true;
        pusherIn = false; 
      }
      else if(digitalRead(proxSensor) == HIGH) {
        pusherOut = false;
        pusherIn = true;
      }
      else {
        //do nothing
      }
      
      break;
      

    case ForwardState:

    if(updateGiven == false) {
        Serial.println("I am in ForwardState");
        Serial.print("LabVIEW Actuate Pin = ");
        Serial.println(digitalRead(labViewHomePin));
        updateGiven = true;
      }
      
    if(boolInitialMove == true) {
        digitalWrite(StepperDirectionPin, LOW);
        rampUpCosineWave(rampStartSpeed, rampStepCountNo, motorSpeed);
        startTime = millis();
        endTime = startTime;
        boolInitialMove = false;
      }
      
      endTime = millis();
      rotateForward(motorSpeed);                                            // this calls the function ForwardState which starts pushing out the pusher
      
      if (digitalRead(uSensor) == HIGH) {
        digitalWrite(labViewInFeedback,LOW);                   
        digitalWrite(labViewOutFeedback,HIGH);
        Serial.println("U-Sensor High detected. Case switched to Idlestate");
        Serial.println("");
        updateGiven = false;
        
        pusherOut = true;
        pusherIn = false;
        State = IdleState;                                    // the motor stays rotating until the uSensor gives a low input signal (u-sensor beam broken). The state switches to the backwardstate
      }
      else if((endTime-startTime) > timeInitialMove) {
        digitalWrite(ENPin,HIGH);
        digitalWrite(StepperStepPin, LOW);
        digitalWrite(StepperDirectionPin, LOW);
        digitalWrite(labViewOutFeedback,HIGH);
        digitalWrite(labViewInFeedback,HIGH);

        
        Serial.println("");
        Serial.println("**TIMEOUT DETECTED**");
        Serial.println("");
        
        State = IdleState; 
      }
      break;
      

    case BackwardState:

    if(updateGiven == false) {
        Serial.println("I am in BackwardState");
        Serial.print("LabVIEW Actuate Pin = ");
        Serial.println(digitalRead(labViewHomePin));
        updateGiven = true;
      }
      
    if(boolInitialMove == true) {
        digitalWrite(StepperDirectionPin, HIGH);
        rampUpCosineWave(rampStartSpeed, rampStepCountNo, motorSpeed);
        startTime = millis();
        endTime = startTime;
        boolInitialMove = false;
      }
      
      endTime = millis();
      rotateBackward(motorSpeed);                                          // the motor rotates backwards, pulling in the pusher until the poximity sensor gives a hgih input signal, confirming the pusher is home
      
      if (digitalRead(proxSensor) == HIGH) {
        digitalWrite(labViewInFeedback,HIGH);                   
        digitalWrite(labViewOutFeedback,LOW);                                // Disable drive
        Serial.println("Prox Sensor High detected. Case switched to Idlestate");
        Serial.println("");
        updateGiven = false;
        
        pusherOut = false;
        pusherIn = true;
        State = IdleState;                                      // the motor is set idle again, awaiting a digital input signal from LabVIEW to restart the whole process
      }
      else if((endTime-startTime) > timeInitialMove) {
        digitalWrite(ENPin,HIGH);
        digitalWrite(StepperStepPin, LOW);
        digitalWrite(StepperDirectionPin, LOW);
        digitalWrite(labViewOutFeedback,HIGH);
        digitalWrite(labViewInFeedback,HIGH);

        Serial.println("");
        Serial.println("**TIMEOUT DETECTED**");
        Serial.println("");
        
        State = IdleState; 
      }
      break;
 
  } // end switch
}

void rotateForward(int mtrSpeed) {                                          
  digitalWrite(StepperDirectionPin, LOW);
  digitalWrite(StepperStepPin, HIGH);
  delayMicroseconds(mtrSpeed);
  digitalWrite(StepperStepPin, LOW);
}

void rotateBackward(int mtrSpeed) {
  digitalWrite(StepperDirectionPin, HIGH);
  digitalWrite(StepperStepPin, LOW);
  delayMicroseconds(mtrSpeed);
  digitalWrite(StepperStepPin, HIGH);
}

void homingRoutine() {
  digitalWrite(ENPin,LOW);
  Serial.println("Homing Routine called");
  bool firstCycle = false;
  bool secondCycle = false;
  bool thirdCycle = false;
  bool fourthCycle = false;
   
  while(digitalRead(uSensor) != HIGH) {
    rotateForward(rampStartSpeed);
  }
  delay(500);
  Serial.println("First home movement completed");
  while(digitalRead(proxSensor) != HIGH) {
    rotateBackward(rampStartSpeed);
  }
  delay(500);
  Serial.println("Second home movement completed");
  while(digitalRead(uSensor) != HIGH) {
    rotateForward(rampStartSpeed);
  }
  delay(500);
  Serial.println("Third home movement completed");
  while(digitalRead(proxSensor) != HIGH) {
    rotateBackward(rampStartSpeed);
  }

  delay(500);

  
  homingDone = true;
  pusherIn = true;
  pusherOut = false;

}
  
  int rampUpCosineWave(int startSpeed, int rampUpSteps, int maximumSpeed) {
  int countedSteps = 0;
  float amp = ((startSpeed-maximumSpeed)/2);
  for(int currentSpeed = startSpeed; currentSpeed > maximumSpeed; currentSpeed = (int)((amp + maximumSpeed)+(amp*(cos((PI/rampUpSteps)*countedSteps))))) {
    digitalWrite(StepperStepPin, LOW);
    delayMicroseconds(currentSpeed);
    digitalWrite(StepperStepPin, HIGH);
    countedSteps++;
  }

  return countedSteps;
}