Last active
January 4, 2023 03:18
-
-
Save jmcgill/0e94826c0ee0ed38971d6d2df80b825c to your computer and use it in GitHub Desktop.
Code for Arduino based CNC Controller
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <Keyboard.h> | |
#include <EEPROM.h> | |
#include <Encoder.h> | |
int CENTER = 0; | |
int UP = 1; | |
int DOWN = 2; | |
int LEFT = 3; | |
int RIGHT = 4; | |
char buffer[50]; | |
char *dirs[] = { "CENTER", "UP", "DOWN", "LEFT", "RIGHT" }; | |
char *modes[] = { "CORNER", "CENTER", "???", "SLOW JOG", "MEDIUM JOG", "FAST JOG" }; | |
char dirKeys[] = {'C', 'U', 'D', 'L', 'R'}; | |
char jogKeys[] = {'C', KEY_UP_ARROW, KEY_DOWN_ARROW, KEY_LEFT_ARROW, KEY_RIGHT_ARROW}; | |
char modeKeys[] = {'1', '2', '3', '4', '5', '6'}; | |
unsigned long lastDirectionSent = 0; | |
int direction = CENTER; | |
int lastDirection = CENTER; | |
int buttonValues[10]; | |
int lastMode = -1; | |
int mode = -1; | |
unsigned long buttonTimers[12]; | |
// Pins 0 and 1 are used for the Z-Axis encoder | |
Encoder knob(0, 1); | |
long encoderPosition = -999; | |
// long lastSentPosition = -999; | |
int encoderDirection = CENTER; | |
int lastEncoderDirection = CENTER; | |
unsigned long encoderTimer = 0; | |
void sendCode(char code) { | |
sprintf(buffer, "Sending code %c\n", code); | |
Serial.print(buffer); | |
Keyboard.press(KEY_LEFT_CTRL); | |
Keyboard.press(code); | |
delay(100); | |
Keyboard.releaseAll(); | |
} | |
void setup() { | |
// Pins 2 through 7 are used for the rotary selector switch | |
pinMode(2, INPUT_PULLUP); | |
pinMode(3, INPUT_PULLUP); | |
pinMode(4, INPUT_PULLUP); | |
pinMode(5, INPUT_PULLUP); | |
pinMode(6, INPUT_PULLUP); | |
pinMode(7, INPUT_PULLUP); | |
// Pins 8 and 9 are used for Start / Stop | |
pinMode(8, INPUT_PULLUP); | |
pinMode(9, INPUT_PULLUP); | |
// Home No Z | |
pinMode(14, INPUT_PULLUP); | |
// Ref All Home No Z Button | |
pinMode(15, INPUT_PULLUP); | |
// Auto Tool Zero | |
pinMode(16, INPUT_PULLUP); | |
// Ref All Home Button | |
pinMode(18, INPUT_PULLUP); | |
pinMode(19, INPUT_PULLUP); | |
// Spindle Toggle | |
pinMode(10, INPUT_PULLUP); | |
// Read mode | |
// mode = EEPROM.read(0); | |
} | |
int getMode() { | |
for (int i = 2; i < 8; ++i) { | |
int val = digitalRead(i); | |
if (val == 0) { | |
return i - 2; | |
} | |
} | |
} | |
int pinMappings[] = { | |
14, | |
15, | |
16, | |
19, | |
10, | |
8, | |
9, | |
}; | |
int risingEdgeWithDebounce(int index) { | |
int value = digitalRead(pinMappings[index]); | |
if ((millis() - buttonTimers[index]) > 200) { | |
if (value == 0) { | |
if (buttonValues[index] == 1) { | |
buttonTimers[index] = millis(); | |
buttonValues[index] = 0; | |
return 1; | |
} | |
} | |
if (value == 1) { | |
if (buttonValues[index] == 0) { | |
buttonTimers[index] = millis(); | |
buttonValues[index] = 1; | |
} | |
} | |
} | |
return 0; | |
} | |
void sendSpecialCommand(int i) { | |
if (i == 0) { | |
// Go to CNC zero | |
Serial.print("Moving X,Y to CNC Zero\n"); | |
sendCode('7'); | |
} else if (i == 1) { | |
// Set current X,Y = 0 | |
Serial.print("Zero X & Y\n"); | |
sendCode('Q'); | |
sendCode('E'); | |
} else if (i == 2) { | |
// Home No Z | |
Serial.print("Home No Z\n"); | |
sendCode('8'); | |
} else if (i == 3) { | |
// Auto Tool Zero | |
Serial.print("Auto Tool 0\n"); | |
sendCode('0'); | |
} else if (i == 4) { | |
// Spindle Toggle | |
Serial.print("Toggle Spindle\n"); | |
sendCode('S'); | |
} else if (i == 5) { | |
// Start | |
Serial.print("Starting"); | |
Keyboard.press(KEY_LEFT_ALT); | |
Keyboard.press('r'); | |
delay(100); | |
Keyboard.releaseAll(); | |
} else if (i == 6) { | |
// Stop / Pause | |
Serial.print("Pausing"); | |
Keyboard.print(' '); | |
} | |
} | |
void loop() { | |
// Buttons | |
for (int i = 0; i < 7; ++i) { | |
if (risingEdgeWithDebounce(i)) { | |
sendSpecialCommand(i); | |
} | |
} | |
// Check rotary encoder | |
long newEncoderPosition; | |
newEncoderPosition = knob.read(); | |
if (newEncoderPosition != encoderPosition) { | |
Serial.print(newEncoderPosition); | |
Serial.print(' '); | |
if (newEncoderPosition > encoderPosition) { | |
encoderDirection = UP; | |
} else { | |
encoderDirection = DOWN; | |
} | |
if (encoderDirection != lastEncoderDirection) { | |
Keyboard.releaseAll(); | |
sendCode(modeKeys[3]); | |
if (encoderDirection == UP) { | |
Serial.print("Z UP"); | |
Keyboard.press(KEY_PAGE_UP); | |
} else { | |
Serial.print("Z DOWN"); | |
Keyboard.press(KEY_PAGE_DOWN); | |
} | |
lastEncoderDirection = encoderDirection; | |
} | |
encoderTimer = millis(); | |
encoderPosition = newEncoderPosition; | |
} | |
// If we haven't seen any action in 100 mS then pause | |
if (millis() - encoderTimer > 250 && lastEncoderDirection != CENTER) { | |
Serial.print("Releasing Z\n"); | |
Keyboard.releaseAll(); | |
lastEncoderDirection = CENTER; | |
} | |
// Read the value of the rotary selector | |
mode = getMode(); | |
if (mode != lastMode) { | |
Serial.print("Setting mode to: "); | |
Serial.print(modes[mode]); | |
Serial.print("\n"); | |
// EEPROM.write(0, mode); | |
sendCode(modeKeys[mode]); | |
lastMode = mode; | |
} | |
// Read the value of the joystick, with maximum of one command | |
// sent per second. | |
int y = analogRead(A2); | |
int x = analogRead(A3); | |
if (x > 1000) { | |
direction = RIGHT; | |
} else if (x < 10) { | |
direction = LEFT; | |
} else if (y > 1000) { | |
direction = DOWN; | |
} else if (y < 10) { | |
direction = UP; | |
} else { | |
direction = CENTER; | |
} | |
if (mode < 3) { | |
if (direction != lastDirection || (millis() - lastDirectionSent) > 1000) { | |
lastDirectionSent = millis(); | |
lastDirection = direction; | |
// Don't send center keycodes | |
if (direction != CENTER) { | |
//if (mode < 3) { | |
// We send the mode before every direction keypress to ensure | |
// that the mode in Mach3 always matches the mode on the control box. | |
sendCode(modeKeys[mode]); | |
sendCode(dirKeys[direction]); | |
//} else { | |
// sendCode(jogKeys[direction]); | |
//} | |
} | |
} | |
} else { | |
if (direction != lastDirection) { | |
sprintf(buffer, "Releasing arrow keys\n"); | |
Serial.print(buffer); | |
Keyboard.releaseAll(); | |
if (direction != CENTER ) { | |
sprintf(buffer, "Sending direction key %s\n", dirs[direction]); | |
Serial.print(buffer); | |
sendCode(modeKeys[mode]); | |
Keyboard.press(jogKeys[direction]); | |
} | |
} | |
lastDirection = direction; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment