CNC mill controller questions/issues coding

Okay, first off, as you can tell, I’m a n00b to this. I’ve picked up what I know so far by decompiling sketches and ramming what I’ve gleaned from that together to form sketches. Now, prior to getting into microcontrolling via Arduino, I have had no prior programming experience. Keep it simple at first; I gain ground and can hold my own fast. I’ve gotten through this design!

I’ll give y’all a rundown of what I want to do, then I’ll get to the code and the errors I’m encountering.

I’m designing a CNC mill. Now, the driver area of it I’ve pretty much gotten down-pat, but I wanted to design a controller for it. That is, this CNC mill takes the brute-force approach of having to have every dimension, every movement converted into steps, dimensions, and delays and hard-coded into the software itself. That’s fine and dandy…if I’m trying to mill a square or rectangle. But for complex designs increasing the scope of the mill requires increasing the coding by exactly that much.

So I’ve gone about designing a controller. That is, a second Arduino which would have a keypad entry and 3 4-digit 7-segment displays for displaying entered values in the X, Y, and Z axes, and 5 push-buttons. Each button would essentially trigger “on” an axis - for data to be written to the X-axis screen and placed into memory as a value, the X-button has to be depressed. It’s the brute-force way of doing this, but with this mill I won’t be in any hurry to do the coding nor do I want to make the coding more complex than it has to be. Revamping it is for when I have a working device in the first place. The other two buttons are a reset button, for resetting the controller for the next command, and another button (in the code called masterButton) that triggers an analogWrite series of commands writing the X, Y, and Z axis values to pins.

Not that it’s specifically relevant, but the prevailing notion being the driver Arduino receives said values at its analog inputs and does the appropriate math to convert from inches to steps via appropriate step ratios - another reason for designing this controller is to allow me to put inputs in inches, in tangible units, not to have to back-convert every measurement via that ratio and take twice as long in the coding process. I want to use this device to generate very precision creations, and the 4-digit displays would ideally have the decimal mapped as to allow a maximum of 0 to 9.999" - that is, one integer position and three decimal positions. As the Arduino’s analog outputting capabilities are limited to 1,024 possible values, I planned on dividing that result by a factor of 10 in the output coding. It reduces accuracy but the only field I’d need thousandth-inch accuracy is mil-spec weapons manufacture, of which I think is safe to say even unspoken is out of my reach.

Without further ado:

#include <Keypad.h>
#include <SevenSegment.h>

#define CLOCK 1
#define CLOCK 4
#define CLOCK 7
#define DATA 2
#define DATA 5
#define DATA 8
#define LOAD 3
#define LOAD 6
#define LOAD 9

const byte ROWS = 4; 
const byte COLS = 3; 
char keys[ROWS][COLS] = {
  {'1','2','3'},
  {'4','5','6'},
  {'7','8','9'},
  {'*','0','#'}
};
byte rowPins[ROWS] = {16, 17, 18, 19}; 
byte colPins[COLS] = {20, 21, 22}; 

Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

SevenSegment scrnX(1,2,3);
SevenSegment scrnY(4,5,6);
SevenSegment scrnZ(7,8,9);
int ButtonX = 10;
int ButtonY = 11;
int ButtonZ = 12;
int masterButton = 13;
int resetButton = 23;
int coordX = 14;
int coordY = 15;
int coordZ = 16;
int xmitled = 24;
int ButtonXState = 0;
int ButtonYState = 0;
int ButtonZState = 0;
int masterButtonState = 0;
int resetButtonState = 0;
int valX = 0;
int valY = 0;
int valZ = 0;

void setup()
{
  scrnX.begin("M5450","8888");
  scrnY.begin("M5450","8888");
  scrnZ.begin("M5450","8888");
  pinMode(coordX, OUTPUT);
  pinMode(coordY, OUTPUT);
  pinMode(coordZ, OUTPUT);
  pinMode(xmitled, OUTPUT);
}  

void loop()
{
  ButtonXState = digitalRead(ButtonX);
  ButtonYState = digitalRead(ButtonY);
  ButtonZState = digitalRead(ButtonZ);
  masterButtonState = digitalRead(masterButton);
  resetButtonState = digitalRead(resetButton);
  char key = keypad.getKey();
  if ((key != NO_KEY) && (ButtonXState = HIGH))
  {
    scrnX.print(key);
    valX = char key;
  } 
  if ((key != NO_KEY) && (ButtonYState = HIGH))
  {
    scrnY.print(key);
    valY = char key;
  }
  if ((key != NO_KEY) && (ButtonZState = HIGH))
  {
    scrnZ.print(key);
    valZ = char key;
  }
if (masterButtonState = HIGH)
  {
    analogWrite(coordX, valX / 10);
    analogWrite(coordY, valY / 10);
    analogWrite(coordZ, valZ / 10);
    digitalWrite(xmitled, HIGH);
  }

}

Error messages I’ve received are next. I’ve resolved the ones regarding values not being defined being a lapse in the first place, but I cannot resolve the char command errors.

sketch_may21a.ino: In function 'void loop()':
sketch_may21a:69: error: invalid conversion from 'char' to 'char*'
sketch_may21a:69: error: initializing argument 1 of 'void SevenSegment::print(char*)'
sketch_may21a:74: error: invalid conversion from 'char' to 'char*'
sketch_may21a:74: error: initializing argument 1 of 'void SevenSegment::print(char*)'
sketch_may21a:75: error: expected primary-expression before 'char'
sketch_may21a:75: error: expected `;' before 'char'
sketch_may21a:79: error: invalid conversion from 'char' to 'char*'
sketch_may21a:79: error: initializing argument 1 of 'void SevenSegment::print(char*)'
sketch_may21a:80: error: expected primary-expression before 'char'
sketch_may21a:80: error: expected `;' before 'char'

Any ideas on how to correct this?

Also, if any of you had any constructive criticism or ideas for the design conceptually, I’d be glad to hear them.

Thanks,
Eli Fedele
(djkolumbian)

    valX = char key;

What do YOU think this is doing? It's wrong.

sketch_may21a:69: error: initializing argument 1 of 'void SevenSegment::print(char*)'

This is saying that the print() method of the SevenSegment class expects a string (a NULL terminated array of chars) as an argument, not a single char.

    scrnX.print(key);

This is trying to call it with a single char.

djkolumbian:
[... snip ...]

Also, if any of you had any constructive criticism or ideas for the design conceptually, I'd be glad to hear them.

Looks like you are doing one step at a time nicely. (Get the driver working, then do a controller to feed live data to the driver.) I'd suggest once you get this working to extend the controller to either take live data from the keypad, or read a file off a SD card (that you had previously written a file to on a computer), so you can playback recordings.

Good luck with your project, it seems like a fun experience.

I'm sure it is possible to use an Arduino as a data entry and conversion front-end for another Arduino that controls your mill. But wouldn't it be a thousand times simpler to use a PC for the front end?

...R

Robin2:
I'm sure it is possible to use an Arduino as a data entry and conversion front-end for another Arduino that controls your mill. But wouldn't it be a thousand times simpler to use a PC for the front end?

...R

Probably would be. I assumed (yes, I know what assuming does...) that option was obvious to the OP and he elected to use a second Arduino for either or both:

  • Learn more about programming an Arduino and using it to control the world.
  • Having a stand-alone, non computer connected CNC mill. (Which is why I suggested as a follow up to reading the mill "program" from a SD card...)

If I was wrong, no harm to me though. :wink:

djkolumbian:
... that triggers an analogWrite series of commands writing the X, Y, and Z axis values to pins.

...Not that it's specifically relevant, but the prevailing notion being the driver Arduino receives said values at its analog inputs and does the appropriate math to convert from inches to steps via appropriate step ratios...

  • another reason for designing this controller is to allow me to put inputs in inches, in tangible units, not to have to back-convert every measurement ...

It reduces accuracy but the only field I'd need thousandth-inch accuracy is mil-spec weapons manufacture, of which I think is safe to say even unspoken is out of my reach.

...
Also, if any of you had any constructive criticism or ideas for the design conceptually, I'd be glad to hear them.

If you don't mind some constructive criticism, I (personally) wouldn't chose to use an analog interface between the user interface and the mill controller - it's highly improbable that you'd achieve the accuracy / repeatability that you'd be probably looking for - mil-spec or otherwise. Far better to have a digital encoded link between the two controllers to avoid any issue with noise on the signalling - particularly if you're using a PWM output from the interface arduino.

PaulS:

    valX = char key;

What do YOU think this is doing? It's wrong.

sketch_may21a:69: error: initializing argument 1 of 'void SevenSegment::print(char*)'

This is saying that the print() method of the SevenSegment class expects a string (a NULL terminated array of chars) as an argument, not a single char.

    scrnX.print(key);

This is trying to call it with a single char.

If you haven't read the top header of the post that put it into context, I've been working on programming for about a week. Everything I've put into this I've had to strip out of examples & tuts and cross-reference with library definitions with a lot of frustrated head-bashing in between. I do not have intrinsic understanding of syntax yet in the least. I thought that a), I was mapping a X-axis value to the key result provided the correct axis button was pressed for selectivity.

Secondly, I only knew how the syntax for the keypad and print command looked. There is a point where the tutorials & examples will not deconstruct past, and I thought what I was doing was correct to the extent of my knowledge.

Robin2:
I'm sure it is possible to use an Arduino as a data entry and conversion front-end for another Arduino that controls your mill. But wouldn't it be a thousand times simpler to use a PC for the front end?

...R

Yes, and I know I could rig a few drivers mechanically and wire to the good ol' fashioned parallel port, tell a G-code interpreter the mapping at the port pinout, and be off crazy. This doesn't provide much advantage in the way of efficiency, but for someone who's trying to learn (& struggling at it!) programming, this provides a way.

It also debunks CNC for me. If I were to use a PC program to control the driver stage or motors, I wouldn't see what is going on under the hood. I wouldn't feel in control of what it does (even though that is not necessary). With this manner of doing things I can learn the magic of milling, which for what I would like to do later in life is something I will have to deal with. Sure, this will be a brute-force method that will only execute what I am sitting there telling it at the point of operation.

But for me, seeing the action and having that sense of achievement is the whole goal!

Doddy:

djkolumbian:
... that triggers an analogWrite series of commands writing the X, Y, and Z axis values to pins.

...Not that it's specifically relevant, but the prevailing notion being the driver Arduino receives said values at its analog inputs and does the appropriate math to convert from inches to steps via appropriate step ratios...

  • another reason for designing this controller is to allow me to put inputs in inches, in tangible units, not to have to back-convert every measurement ...

It reduces accuracy but the only field I'd need thousandth-inch accuracy is mil-spec weapons manufacture, of which I think is safe to say even unspoken is out of my reach.

...
Also, if any of you had any constructive criticism or ideas for the design conceptually, I'd be glad to hear them.

If you don't mind some constructive criticism, I (personally) wouldn't chose to use an analog interface between the user interface and the mill controller - it's highly improbable that you'd achieve the accuracy / repeatability that you'd be probably looking for - mil-spec or otherwise. Far better to have a digital encoded link between the two controllers to avoid any issue with noise on the signalling - particularly if you're using a PWM output from the interface arduino.

Does that fall into the realm of I2C communication? (not that I understand anything about it as of yet)

I've considered this, although the only consideration being the use of larger-gauge wire and shielded cable. I took that route because being new, there were four commands I understood intrinsically by noticing the main two used in examples: digitalRead, digitalWrite, analogRead, and analogWrite.

I figured it would be easiest at first to not worry about digital communication and encoding/decoding between the two and spit out an output per axis that is not only intuitively obvious but that would take minimal work on the driver end to understand.

djkolumbian:
[... snip ...]

Doddy:
[... snip ...]
If you don't mind some constructive criticism, I (personally) wouldn't chose to use an analog interface between the user interface and the mill controller - it's highly improbable that you'd achieve the accuracy / repeatability that you'd be probably looking for - mil-spec or otherwise. Far better to have a digital encoded link between the two controllers to avoid any issue with noise on the signalling - particularly if you're using a PWM output from the interface arduino.

Does that fall into the realm of I2C communication? (not that I understand anything about it as of yet)

I've considered this, although the only consideration being the use of larger-gauge wire and shielded cable. I took that route because being new, there were four commands I understood intrinsically by noticing the main two used in examples: digitalRead, digitalWrite, analogRead, and analogWrite.

I figured it would be easiest at first to not worry about digital communication and encoding/decoding between the two and spit out an output per axis that is not only intuitively obvious but that would take minimal work on the driver end to understand.

Doddy has a point. Even if you were able to output true analog from the control Arduino (hint, there are some that can...), you will still have resistive losses over the lines that would scale the intended value down as well as analog noise that could give bad values. But since you are planning on using the fake analog trick of PWM, things get worse. Digital communication is probably better.

But, it doesn't need to be as complicated as I2C (which includes addressing as well as other protocol muck). Because there are only two devices here, simple point-to-point serial communication would work. Transmit from one via serial the value instead of using that value to set the PWM.
Here are a few hints to help get you started:

  • Hint1: Use Serial.write() to send a value instead of Serial.print() to send the ASCII description of the value. You should probably have a start identifier byte (or character) to give axis. And either an end identifier byte (use a value that would never be sent as a movement value) or always send the same number of bytes of movement data from the controller so you know when you have the full movement data for that axis on the driver end.
  • Hint2: Have a character or byte that the driver sends back to the controller to essentially state that it is ready for the next command. This can be expanded to also have characters for feedback and/or error conditions.
  • Hint3: Use SoftwareSerial.h instead of the hardware Serial to leave the hardware serial available to send debugging information back to your Serial Monitor when developing the code.
  • Hint4: Write a few practice sketches doing nothing but sending data back and forth between two Arduinos to get the hang of the techniques before messing with your CNC mill code.
  • Hint5: Write a few more practice sketches expanding on Hint4 to have both Arduinos doing other cyclical things (move servos around, blink lights, etc) and be able to communicate between each other simultaneously. Learning the techniques of periodically polling things and using milli() and micro() counters will certainly help you not only with this project, but in most projects in the future. Knowing how to leverage non-blocking code is essential for non-multitasking environments like the Arduino.

Sembazuru:
Doddy has a point. Even if you were able to output true analog from the control Arduino (hint, there are some that can...), you will still have resistive losses over the lines that would scale the intended value down as well as analog noise that could give bad values. But since you are planning on using the fake analog trick of PWM, things get worse. Digital communication is probably better.

But, it doesn't need to be as complicated as I2C (which includes addressing as well as other protocol muck). Because there are only two devices here, simple point-to-point serial communication would work. Transmit from one via serial the value instead of using that value to set the PWM.
Here are a few hints to help get you started:

  • Hint1: Use Serial.write() to send a value instead of Serial.print() to send the ASCII description of the value. You should probably have a start identifier byte (or character) to give axis. And either an end identifier byte (use a value that would never be sent as a movement value) or always send the same number of bytes of movement data from the controller so you know when you have the full movement data for that axis on the driver end.
  • Hint2: Have a character or byte that the driver sends back to the controller to essentially state that it is ready for the next command. This can be expanded to also have characters for feedback and/or error conditions.
  • Hint3: Use SoftwareSerial.h instead of the hardware Serial to leave the hardware serial available to send debugging information back to your Serial Monitor when developing the code.
  • Hint4: Write a few practice sketches doing nothing but sending data back and forth between two Arduinos to get the hang of the techniques before messing with your CNC mill code.
  • Hint5: Write a few more practice sketches expanding on Hint4 to have both Arduinos doing other cyclical things (move servos around, blink lights, etc) and be able to communicate between each other simultaneously. Learning the techniques of periodically polling things and using milli() and micro() counters will certainly help you not only with this project, but in most projects in the future. Knowing how to leverage non-blocking code is essential for non-multitasking environments like the Arduino.

First of all, thanks for helping me with this.

A few questions then we'll get to code concept.

First of all, how would I store the sequence of key presses as a value into the code? That would bypass my original errors. Also, I intend to use the Arduino Mega (2560), so I would have access to 4 possible serial ports. If possible, I'd like to configure each one to be each axis, as reflected in the code I'm posting. That way, I avoid having to use byte descriptors prior to main controller transmission to confer axis.

I'm leaving Serial0 free for debugging as you suggested, but using hardware serial ports to prevent it from tying up other pins (which as you can see from the above code, the controller will be very pin-heavy). As per the reference for SoftwareSerial.h the Mega only has a certain number of pins which can be used properly.

As for where you suggested I have a feedback mechanism in place - for now I don't plan on having any reception on the controller end. This is because I haven't implemented into the driver any method of detecting when the code has been completely executed. I can design that in, but you can't ice a cupcake if you don't have a cupcake to begin with. First things first.

I would use serial.write() instead of serial.print(), but if I were to implement serial.write(varX) would the controller know to convert to byte information? This is where not being versed very well in programming is coming back to bite me.

void setup()
{
  Serial1.begin(9600); //X-axis 
  Serial2.begin(9600); //Y-axis
  Serial3.begin(9600); //Z-axis
}

void loop()
{
  Serial1.print(varX);
  Serial2.print(varY);
  Serial3.print(varZ);
}

Does this jive?

Yes, and I know I could rig a few drivers mechanically and wire to the good ol' fashioned parallel port,

Just to clarify ... I was not suggesting that you drive the mill directly with the PC. As I understand your original post you already have successfully made an Arduino that controls the mill in a limited way and you are looking for a solution that will more easily create the advanced instructions that are needed by the existing Arduino to make the mill follow complex shapes.

All I am suggesting is that, instead of writing a program for a second Arduino to generate the advanced instructions it would be much easier to do that on a PC - which would then send the data to your existing Arduino.

...R

Robin2:

Yes, and I know I could rig a few drivers mechanically and wire to the good ol’ fashioned parallel port,

Just to clarify … I was not suggesting that you drive the mill directly with the PC. As I understand your original post you already have successfully made an Arduino that controls the mill in a limited way and you are looking for a solution that will more easily create the advanced instructions that are needed by the existing Arduino to make the mill follow complex shapes.

All I am suggesting is that, instead of writing a program for a second Arduino to generate the advanced instructions it would be much easier to do that on a PC - which would then send the data to your existing Arduino.

…R

Ah, okay. Misunderstood you - this will actually probably be my next step. It would not be hard for me to have a serial communication interface on the computer that sends values. I could also have it read from a register, a text file perhaps, and mill everything automated without necessitating proportionally larger code for larger projects.

Just redid the code I originally posted; it checks out with the compiler this time.

#include <SevenSegment.h>
#include <Keypad.h>

SevenSegment screenX(2,3,4);
SevenSegment screenY(5,6,7);
SevenSegment screenZ(8,9,10);

const byte ROWS = 4; 
const byte COLS = 3; 
char keys[ROWS][COLS] = {
  {'1','2','3'},
  {'4','5','6'},
  {'7','8','9'},
  {'*','0','#'}
};
byte rowPins[ROWS] = {16, 17, 18, 19}; //Assigns keypad row pins
byte colPins[COLS] = {20, 21, 22};  //Assigns keypad column pins

Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
int v1;       int varX1;
int v2;       int varY1;
int v3;       int varZ1; 
int v4;       int var0; 
int varX;     int bX = 24;
int varY;     int bY = 25;
int varZ;     int bZ = 26;
int bR = 23;  int bM = 27;
int bR0;      int bY0;
int bM0;      int bZ0;
int bX0;      

void setup()
{
  pinMode(bR, INPUT);
  pinMode(bM, INPUT);
  pinMode(bX, INPUT);
  pinMode(bY, INPUT);
  pinMode(bZ, INPUT);
  Serial1.begin(9600);
  Serial2.begin(9600);
  Serial3.begin(9600);
  screenX.begin("M5450","8888");
  screenY.begin("M5450","8888");
  screenZ.begin("M5450","8888");
}

void loop()
{
  v1 = GetNumber();
  v2 = GetNumber();
  v3 = GetNumber();
  v4 = GetNumber();
  var0 = ((1.0 * v1) + (0.1 * v2) + (0.01 * v3) + (0.001 * v4));
  bR0 = digitalRead(bR);
  bM0 = digitalRead(bM);
  bX0 = digitalRead(bX);
  bY0 = digitalRead(bY);
  bZ0 = digitalRead(bZ);
  if (bR0 == HIGH)
  {
    screenX.clear();
    screenY.clear();
    screenZ.clear();
  }
  if (bX0 == HIGH)
  {
    varX = var0;
    screenX.printNumber(varX); 
  }
  if (bY0 == HIGH)
  {
    varY = var0;
    screenY.printNumber(varY);
  }
  if (bZ0 == HIGH)
  {
    varZ = var0;
    screenZ.printNumber(varZ);
  }
  if (bM0 == HIGH) 
  {
    Serial1.print(varX);
    delay(50);
    Serial2.print(varY);
    delay(50);
    Serial3.print(varZ);
    delay(50);
  }  
} 

int GetNumber()
{
   int num = 0;
   char key = keypad.getKey();
   while(key != '#')
   {
      switch (key)
      {
         case NO_KEY:
            break;
         case '0': case '1': case '2': case '3': case '4':
         case '5': case '6': case '7': case '8': case '9':
            break;
         case '*':
            num = 0;

            break;
      }
      key = keypad.getKey();
   }
   return num;
}

djkolumbian:

Sembazuru:
Doddy has a point. Even if you were able to output true analog from the control Arduino (hint, there are some that can...), you will still have resistive losses over the lines that would scale the intended value down as well as analog noise that could give bad values. But since you are planning on using the fake analog trick of PWM, things get worse. Digital communication is probably better.

But, it doesn't need to be as complicated as I2C (which includes addressing as well as other protocol muck). Because there are only two devices here, simple point-to-point serial communication would work. Transmit from one via serial the value instead of using that value to set the PWM.
Here are a few hints to help get you started:

  • Hint1: Use Serial.write() to send a value instead of Serial.print() to send the ASCII description of the value. You should probably have a start identifier byte (or character) to give axis. And either an end identifier byte (use a value that would never be sent as a movement value) or always send the same number of bytes of movement data from the controller so you know when you have the full movement data for that axis on the driver end.
  • Hint2: Have a character or byte that the driver sends back to the controller to essentially state that it is ready for the next command. This can be expanded to also have characters for feedback and/or error conditions.
  • Hint3: Use SoftwareSerial.h instead of the hardware Serial to leave the hardware serial available to send debugging information back to your Serial Monitor when developing the code.
  • Hint4: Write a few practice sketches doing nothing but sending data back and forth between two Arduinos to get the hang of the techniques before messing with your CNC mill code.
  • Hint5: Write a few more practice sketches expanding on Hint4 to have both Arduinos doing other cyclical things (move servos around, blink lights, etc) and be able to communicate between each other simultaneously. Learning the techniques of periodically polling things and using milli() and micro() counters will certainly help you not only with this project, but in most projects in the future. Knowing how to leverage non-blocking code is essential for non-multitasking environments like the Arduino.

First of all, thanks for helping me with this.

A few questions then we'll get to code concept.

First of all, how would I store the sequence of key presses as a value into the code? That would bypass my original errors. Also, I intend to use the Arduino Mega (2560), so I would have access to 4 possible serial ports. If possible, I'd like to configure each one to be each axis, as reflected in the code I'm posting. That way, I avoid having to use byte descriptors prior to main controller transmission to confer axis.

That makes sense. I hope you are planning (for simplicity) to use a Mega for both the driver and controller. (Handling more than 1 serial port with SoftwareSerial.h can be done, but it has limitations. It only has 1 buffer shared for all its instances so any data received on the first instance when listening to the second instance is completely lost so manual handshaking is pretty much a must, and I think its transmit is blocking.)

I'm leaving Serial0 free for debugging as you suggested, but using hardware serial ports to prevent it from tying up other pins (which as you can see from the above code, the controller will be very pin-heavy). As per the reference for SoftwareSerial.h the Mega only has a certain number of pins which can be used properly.

As for where you suggested I have a feedback mechanism in place - for now I don't plan on having any reception on the controller end. This is because I haven't implemented into the driver any method of detecting when the code has been completely executed. I can design that in, but you can't ice a cupcake if you don't have a cupcake to begin with. First things first.

LOL, yeah baby steps first.

I would use serial.write() instead of serial.print(), but if I were to implement serial.write(varX) would the controller know to convert to byte information? This is where not being versed very well in programming is coming back to bite me.

void setup()

{
  Serial1.begin(9600); //X-axis
  Serial2.begin(9600); //Y-axis
  Serial3.begin(9600); //Z-axis
}

void loop()
{
  Serial1.print(varX);
  Serial2.print(varY);
  Serial3.print(varZ);
}




Does this jive?

Not quite. I'm hoping that varX through varZ are all byte datatypes based on your original idea of sending PWM data (and AnalogWrite() only accepts a byte for the value) from the controller. Lets say the value in varX is 45. Serial1.print(varX); will send the two ASCII characters "4" and "5", but Serial1.write(varX); would send a single byte of value 45 (0b00101101 or 0x2D). On the receiving end you have a variable of datatype byte (lets call coordX for clarity with this example) that you read with Serial1.read(coordX); and because the argument is of type byte it will be handled as the value 45, not the ASCII character "-".

If the intent is to send an int of data (2 bytes) because the driver is expecting to read the value with AnalogRead() (actually will only be a 10-bit result, but the variable container holding that result needs to be greater than 8-bits long) then there is a bit more playing to do. I remember seeing techniques treating an int as an array of 2 bytes. Will need a second variable to act as a pointer. Unfortunately, I'm at work and don't have an Arduino to do some quick tests. But it might be valuable for you to try something like this (drop this code into the setup function of a blank sketch framework):

  Serial.begin(115200); // change this to whatever your like running your Serial Monitor at.

  unsigned int integerValue = 0xD5AA; // Both bytes have MSb == 1 to trap accidental sign issues.

  Serial.print(F("0x")); // using the F() macro is just a habit I've gotten into to not waste valuable SRAM with diagnostic character strings...
  Serial.print(integerValue,HEX); // the HEX keyword converts to the ASCII representation of the hex value
  Serial.println(F(" == the starting integer value in Hex."));

  byte* integerPointer; // Setup the pointer variable
  integerPointer = (byte*)&integerValue; // make the value of the pointer the address of the first byte of our integer

  Serial.print(F("0x"));
  Serial.print(integerPointer[0],HEX);
  Serial.println(F(" == the first byte of the integer value in Hex."));

  Serial.print(F("0x"));
  Serial.print(integerPointer[1],HEX);
  Serial.println(F(" == the second byte of the integer value in Hex."));
  
  Serial.println();
  Serial.println(F("Lets change the integer value to 0x4546 using the pointers."));
  
  integerPointer[0] = 0x45;
  integerPointer[1] = 0x46;

  Serial.print(F("0x"));
  Serial.print(integerValue,HEX);
  Serial.println(F(" == the final integer value in Hex."));

I've compiled the above w/o error, but I'm not sure if it actually does what I think it will. If the byte values are backwards, I may have the endian wrong. If this does work, play around with it a bit using signed datatypes, and even try larger datatypes like long.