HELP! - Arduino based stepper motor display turntable

Hi! I'm fairly new to Arduino and programming in general (this is my first project) and even though I'm pretty proud of myself so far, I need some help!

I'm trying to create a dynamic video mapping installation. Dynamic in the sense, that the object which I'm gonna project on is rotating. To achieve this rotation I build a little display turntable using a Nema 17 stepper motor, an Arduino mega 2560 and an Easy Driver stepper motor driver by Cylewet hooked up to a 9V power source.

The setup generally works, meaning with a simple code I can make the turntable turn at different velocities and both clockwise and anti-clockwise.

Right now I'm trying to write a code, which would make the Arduino wait for a serial input (in this case the Key '1'), once triggered would make the motor turn for 1 rotation using 50 seconds and then stop and wait for the next trigger.

This is what I have got so far:

// X = delay to make 1 rotation last 50 secs.
#define X1 7812
#define X2 7813

long rotationCount = 0;





void setup() {
  
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(13, OUTPUT);


  digitalWrite(2, HIGH);
  digitalWrite(3, HIGH);
  digitalWrite(4, LOW); //LOW = Enabled, HIGH = Disabled
  digitalWrite(8, HIGH);
  digitalWrite(13, LOW);

  Serial.begin(9600);
}





void loop() {

  while (Serial.available() == 0);
  int val = (Serial.read() - '0');

  if (val == 1 && rotationCount < 50000000)  { // 50'000'000 = 1 Rotation in 50 secs
  
    Serial.println("Rotation Mode: ON");
    digitalWrite(13, HIGH);

    rotation();
  }

  if (rotationCount >= 50000000)  {

  rotationCount = 0;
  Serial.println("Rotation Mode: OFF");
    digitalWrite(13, LOW);
  }
}





void rotation() {
  digitalWrite(9, HIGH);
  delayMicroseconds(X1);
  digitalWrite(9, LOW);
  delayMicroseconds(X2);

  rotationCount = rotationCount + 15625; // X1 + X2

  
}

When I run this code and I send the trigger to the Arduino, I get the correct Message in my console (Rotation Mode: ON), however, the stepper motor isn't turning. When I slightly modify the code just to eliminate the serial trigger and the if statement, the motor turns fine and at (what seems to be) the correct speed.

Modified code:

// X = delay to make 1 rotation last 50 secs.
#define X1 7812
#define X2 7813

long rotationCount = 0;





void setup() {
  
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(13, OUTPUT);


  digitalWrite(2, HIGH);
  digitalWrite(3, HIGH);
  digitalWrite(4, LOW); //LOW = Enabled, HIGH = Disabled
  digitalWrite(8, HIGH);
  digitalWrite(13, LOW);

  Serial.begin(9600);
}





void loop() {

  //while (Serial.available() == 0);
  //int val = (Serial.read() - '0');
  //if (val == 1 && rotationCount < 50000000)  { // 50'000'000 = 1 Rotation in 50 secs

  if (rotationCount < 50000000) {  
    
    //Serial.println("Rotation Mode: ON");
    //digitalWrite(13, HIGH);

    rotation();
  }

  if (rotationCount >= 50000000)  {

  rotationCount = 0;
  //Serial.println("Rotation Mode: OFF");
    //digitalWrite(13, LOW);
  }
}





void rotation() {
  digitalWrite(9, HIGH);
  delayMicroseconds(X1);
  digitalWrite(9, LOW);
  delayMicroseconds(X2);

  rotationCount = rotationCount + 15625; // X1 + X2

  
}

Since both actions (serial communication & rotation) seem to be working on there own, I suspect they must be interfering with each other, but I don't know where or how I could fix it...

I hope someone has a better approach to this than me...

Thank you in advance for the help!

  while (Serial.available() == 0);

This says "wait here if there are no characters in the input buffer." Your "rotation()" function only does one step pulse. That means you can only move one step each time a '1' arrives. That is going to be VERY slow and does not appear to be what you wanted to do.

Typically you would use the input to set a flag:

const int StepsPerRevolution = 200;
boolean RotationMode = false;
void loop()
{
  static int stepCount = 0;
  if (Serial.available() > 0)
  {
    char inputCharacter = Serial.read();
    if (inputCharacter == '1')
      RotationMode = true;
  }

  if (RotationMode)
  {
    rotation();  // Take one step
    stepCount++;
    if (stepCount >= StepsPerRevolution)
    {
      RotationMode = false;
      stepCount = 0;
    }
  }
}
void rotation() {
  digitalWrite(9, HIGH);
  delayMicroseconds(X1);
  digitalWrite(9, LOW);
  delayMicroseconds(X2);

  rotationCount = rotationCount + 15625; // X1 + X2 
}

The rotation code you wrote is blocking in nature and so is the Serial receive code

while (Serial.available() == 0);

Regarding the stepper motor code there is no shame in that, in fact the stepper.h library is made out of blocking code, you may get away with doing

while (Serial.available() == 0) rotation();

but a serial event will cause some jitter, (all of a sudden there is code to be executed and that takes time) In the long runyou may be better off using a timer to drive the stepper motor (as long as you keep interrupts turned on) have a look at TimerOne For creating a non-blocking Serial communication check out Robin's Serial Input Basics

Have a look at the examples in Serial Input Basics - simple reliable non-blocking ways to receive data.

And have a look at the second example in this Simple Stepper Code for an example of non-blocking code.

Have a look at Using millis() for timing. A beginners guide if you need more explanation.

...R
Stepper Motor Basics