Using a rotary handwheel and joystick to control a 48V DC Motor

I am trying to control a 48V DC motor with an encoder handwheel, similar to what you would find on a CNC, and a joystick. The goal being the handwheel makes small "steps" and the joystick moves the motor rapidly. My entire code will be to control two motors X and Y axis but for simplicity I am only showing X axis control. My problem is when I use the handwheel the motor is "stepping" but it is jerky at times depending on how quickly the wheel is spun. I have looked at various code and examples using encoders but have not found anything similar to this application. I think an option may be to put an encoder on the motor but, I don't want to go down that rabbit hole unless I have no other option.

`#include <Encoder.h>

Encoder myEncX(2,3);

//Inputs & Outputs
int XEnable=6;        //X Motor PWM 
int XDirA=4;          //X Motor direction A
int XDirB=5;          //X Motor direction B
int JoyBut=12;         //Joy Stick Button to enable Joy Stick
const int X_pin = A0; // analog pin connected to X input
const int Y_pin = A1; // analog pin connected to Y input

//Handwheel variables
long HWXoldPos = -999;
long HWXnewPos;
int JOG=125;          //Speed of PWM when using handwheel

int X_data;
int Y_data;

//Bool
bool JoyMove = false;

void setup() 
{
  pinMode(JoyBut, INPUT_PULLUP);
  pinMode(XEnable, OUTPUT);
  pinMode(XDirA, OUTPUT);
  pinMode(XDirB, OUTPUT);
  pinMode(X_pin, INPUT);
  pinMode(Y_pin, INPUT);
  Serial.begin(9600);
}

void loop() 
{
  //X axis Handwheel Operation
  long HWXnewPos = myEncX.read();
  if (HWXnewPos != HWXoldPos) 
  {
    Serial.println(HWXnewPos);
    if (HWXnewPos < HWXoldPos)
    {
      analogWrite(XEnable,JOG);
      digitalWrite(XDirA,LOW);
      digitalWrite(XDirB,HIGH);
      Serial.println("On XDirB");
      delay(1);
      digitalWrite(XDirB,LOW);      
    }
    if (HWXnewPos > HWXoldPos)
    {
      analogWrite(XEnable,JOG);
      digitalWrite(XDirA,HIGH);
      digitalWrite(XDirB,LOW);
      Serial.println("On XDirA");
      delay(1);
      digitalWrite(XDirA,LOW);      
    }
    HWXoldPos = HWXnewPos;
  }  
  
  //JoyStick Operation
  if (digitalRead(JoyBut) == LOW)  
  {
    JoyMove = true;
  }
  if (digitalRead(JoyBut) == HIGH)
  {
    JoyMove = false;
    analogWrite(XEnable,0);
    digitalWrite(XDirA,LOW);
    digitalWrite(XDirB,LOW);   
  }

  if (JoyMove == true)  //Joy stick will not opperate unless button on top is pressed/held
  {    
    Serial.println("JoyBut");
    X_data = analogRead(X_pin);
    Y_data = analogRead(Y_pin);
    
    //Backward Movement
    if(X_data <= 500)
    {
      int X_speedB = map(X_data, 500, 0, 0, 255);    
      Serial.print("X B ");
      Serial.println(X_data);
      analogWrite(XEnable,X_speedB);
      digitalWrite(XDirA,LOW);
      digitalWrite(XDirB,HIGH);
    }
    //Forward Movement
    else if(X_data >= 590)
    {
      int X_speedF = map(X_data, 550, 1024, 0, 255);
      Serial.print("X F ");
      Serial.println(X_data);
      analogWrite(XEnable,X_speedF);
      digitalWrite(XDirA,HIGH);
      digitalWrite(XDirB,LOW);
    }
    //Don't Move
    else
    {
      analogWrite(XEnable,0);
      digitalWrite(XDirA,LOW);
      digitalWrite(XDirB,LOW);
    }  
  }  
}   
`

When we see descriptions like yours, we immediately look for first, delay used in the code. I see very few, which do nothing useful. But I see lots of Serial.print() statements, which slow your code tremendously, especially when the Baud rate is set to 9600. Make you print statements all comments and see if that improves the motor response.

Thank you Paul! Commenting out the Serial.print() statements fixed the jerky response. Why did the print statements cause this? They were being used initially for debugging purposes.

The Serial.print() puts the characters into a 64 byte buffer and tells the UART code to begin sending the characters to your PC. They are sent one character at a time in the form of 10 bits per character. With a Baud rate of 9600, only 96 characters can be sent in one second. Your Arduino code runs very, very fast and will add more characters to the 64 byte buffer. So, fast that the Serial.print() code will wait for space for the message and block your program from running until space is found. That blocking is what you see as the motor starting and stopping.

Serial.print() is a wonderful way to debug a few lines of code, but should be removed when the code works as you want.

If your program needs to Serial.print() something on periodically, then wait for that period, perhaps a second, and then print the message. Give the buffer time to empty before adding to it!

A trick I use is get the baud as fast as I can then use a number or letter to keep the responses short.