Code:
//Program for reading UART output on CNCUSB Mk2/4, displaying axis positions on a 16x2 LCD display. 4 axes, no displaying of RPM.
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
//Machine variables
//Keeping the constants inside loop as few as possible
int nrAxis = 4; //Number of axes to display 1 = X, 2 = XY, 3 = XYZ, 4 = XYZA
float Xpos = 0; //Stored position of X in units
float Ypos = 0; //Stored position of Y in units
float Zpos = 0; //Stored position of Z in units
float Apos = 0; //Stored position of A in units
float Xspu = 10.00; //Steps per unit for X
float Yspu = 10.00; //Steps per unit for Y
float Zspu = 10.00; //Steps per unit for Z
float Aspu = 10.00; //Steps per unit for A
//Data transfer from CNCUSB, 6 bytes total, 8N1)
byte rxData = 0; //Data header, first byte of transmisson from CNCUSB, 31 = position, 21 = Setup data (not read)
byte recAxis = 0; //Received axis, second byte of transmission from CNCUSB, 1 = X, 2 = Y, 3 = Z, 4 = A
byte recData[4] = {0, 0, 0, 0}; //Array for receiving position data from CNCUSB, 4 bytes, byte 3-6 in transmission (6 total)
long recPos; //Received position from CNCUSB in steps, refined from recData[]
int uartDelay = 2; //Delay between reading bytes in UART transmission from CNCUSB, adjust as low as it gets without corrupting data
void setup(){
Serial.begin(9600); //Optocoupler used in serial circuit between CNCUSB and Arduino not for fast switching, can't handle more than 9600bps.
lcd.begin(16, 2); //Uses a kinda too small LCD for presenting positions
}
void loop(){
//Receiving data from CNCUSB, 6 bytes total. Header, Axis, 4x Position bytes. Position bytes 1-4 should be stored and read as 4-1 (bytes not reversed internally, just the order of bytes)
if (Serial.available() > 0 ) { //Receive byte and look for 31 header
rxData = Serial.read();
if (rxData == 31) {
delay(uartDelay); //Receive second byte, store as axis number, 1 = X, 2 = Y, 3 = Z, 4 = A
(Serial.available() > 0 ) ;
recAxis = Serial.read();
delay(uartDelay); //Receive first byte of position data, store in first position in array. LSB
(Serial.available() > 0);
recData[0] = Serial.read();
delay(uartDelay); //Receive second byte of position data, store in second position in array
(Serial.available() > 0);
recData[1] = Serial.read();
delay(uartDelay); //Receive third byte of position data, store in third position in array
(Serial.available() > 0);
recData[2] = Serial.read();
delay(uartDelay); //Receive fourth byte of position data, store in fourth position in array. MSB
(Serial.available() > 0);
recData[3] = Serial.read();
}
}
//Sorting data in recData[] array to received position
recPos = (long)recData[3]<<24 | (long)recData[2]<<16 | (long)recData[1]<<8 | (long)recData[0]; //Byte array sorted, bitshifted and OR combined into one long int
//Sorting received position according to recieved axis number and converting to units.
//Received position in steps divided with SPU = Position in units
switch(recAxis){
case 1:
Xpos = (recPos / Xspu);
break;
case 2:
Ypos = (recPos / Yspu);
break;
case 3:
Zpos = (recPos / Zspu);
break;
case 4:
Apos = (recPos / Aspu);
break;
default:
//Just in case no data recieved
break;
}
//Presenting axis positions on LCD. Doesn't show more axes than nrAxis is set at.
if (nrAxis > 0){
lcd.setCursor(0, 0);
lcd.print("X");
lcd.setCursor(1,0);
lcd.print(Xpos);}
if (nrAxis > 1){
lcd.setCursor(0, 1);
lcd.print("Y");
lcd.setCursor(1,1);
lcd.print(Ypos);}
if (nrAxis > 2){
lcd.setCursor(9, 0);
lcd.print("Z");
lcd.setCursor(10,0);
lcd.print(Zpos);}
if (nrAxis > 3){
lcd.setCursor(9, 1);
lcd.print("A");
lcd.setCursor(10,1);
lcd.print(Apos);}
}