Control Stepper Motor with Nextion HMI

Hi all ! I'm trying to control stepper motor for a lab automation project. The motor will invert the test tube 180 degree per second for 60 seconds. The homing, start, stop instruction are triggered from a Nextion HMI.
I have made the basic function working with the code below. I need to stop the motor during the test tube inversion cycle whenever the STOP button being pressed. What I did currently is to check whether STOP button pressed after every pulse. Could you please suggest a correct or better way to achieve this? Thanks in advance!

#define Pulse 9
#define dir_pin 8
#define home_switch 3
const int STEPS_PER_REV = 200;

void setup() {
  pinMode(Pulse,OUTPUT);
  pinMode(dir_pin,OUTPUT);
  pinMode(home_switch, INPUT_PULLUP);
  Serial.begin(9600);
  Serial.println("Started !");
}


void loop() {
  
  if (Serial.available()) {
    String data_from_display = "";
    delay(30);
    while(Serial.available()) {
      data_from_display += char(Serial.read());
    }
    sendData(data_from_display);
  }
}

void Start() {
  Serial.println("START invert");
  for (int x = 1; x<=30 ; x++)
  {
  // Set motor direction clockwise
    digitalWrite(dir_pin,LOW); 
    
    // Spin motor one rotation slowly
    for(int i = 0; i < (STEPS_PER_REV/2); i++) {
      digitalWrite(Pulse,HIGH); 
      delayMicroseconds(5000); 
      digitalWrite(Pulse,LOW); 
      delayMicroseconds(5000); 
    }
    
    // Set motor direction counterclockwise
    digitalWrite(dir_pin,HIGH);
    
    // Spin motor two rotations quickly
    for(int i = 0; i < (STEPS_PER_REV/2); i++) {
      digitalWrite(Pulse,HIGH);
      delayMicroseconds(5000);
      digitalWrite(Pulse,LOW);
      delayMicroseconds(5000);
    }
    Serial.println(x);
    if (Serial.available()) {
      String data_from_display = "";
      //delay(30);
      while(Serial.available()) {
        data_from_display += char(Serial.read());
      }
      if (data_from_display=="S")
        return;
    }
  }
    
}
void Homing() {
  while (digitalRead(home_switch))
    {  // Do this until the switch is activated   
     digitalWrite(dir_pin, HIGH);  // (HIGH = anti-clockwise / LOW = clockwise)
     digitalWrite(Pulse,HIGH); 
     delayMicroseconds(5000); 
     digitalWrite(Pulse,LOW); 
     delayMicroseconds(5000);   
   }
  while (!digitalRead(home_switch)) 
  { // Do this until the switch is not activated
     for (int i =0; i<5; i++)
     {
      digitalWrite(dir_pin, LOW);  // (HIGH = anti-clockwise / LOW = clockwise)
      digitalWrite(Pulse,HIGH); 
      delayMicroseconds(5000); 
      digitalWrite(Pulse,LOW); 
      delayMicroseconds(5000);
      }
   }  
}

void sendData(String data_from_display) {
  if (data_from_display == "START") {
    Start();
  }
  if (data_from_display == "HOMING") {
    Homing();
  }
}

Good job on the code tags with your first post.

Your issue is not really Nextion related, but rather, you have a very common problem of reading serial input to control a stepper in code with blocking stepper commands.

If you need the input to be more responsive than the two seconds taken for the stepper moves in the for loops you will can recraft the code to take one step and check Serial. Individual steps can also be made non blocking with timer interrupts or millis( ) timers instead of the delayMicroseconds( ). The Serial reading can also be made non blocking by reading a single character if available and knowing the message is complete with an end character.

What you do from here depends on if what you presently have is functioning adequately for your application or if you want to begin a coding journey into non blocking code. How much time to you want to spend as a lab chemist and how much time as a programmer?

Thank you very much for your advice. I think non-blocking code is something I need to look into further.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.