Skip to content

Commit

Permalink
Additions for optional ABC axes
Browse files Browse the repository at this point in the history
Largely based on work by @EliteEng
If extra axes are enabled, may only work on Mega2560 due to extra pins
needed and larger code flash size
Still needs further testing and additional work on rotary axis limits
  • Loading branch information
electrokean committed Feb 8, 2015
1 parent 23c1e15 commit b3e6d6a
Show file tree
Hide file tree
Showing 12 changed files with 250 additions and 35 deletions.
13 changes: 9 additions & 4 deletions config.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@

// Default cpu mappings. Grbl officially supports the Arduino Uno only. Other processor types
// may exist from user-supplied templates or directly user-defined in cpu_map.h
#define CPU_MAP_ATMEGA328P // Arduino Uno CPU
#define CPU_MAP_ATMEGA2560 // Arduino Uno CPU

// Define realtime command special characters. These characters are 'picked-off' directly from the
// serial read data stream and are not passed to the grbl line execution parser. Select characters
Expand Down Expand Up @@ -77,8 +77,13 @@
// will not be affected by pin sharing.
// NOTE: Defaults are set for a traditional 3-axis CNC machine. Z-axis first to clear, followed by X & Y.
#define HOMING_CYCLE_0 (1<<Z_AXIS) // REQUIRED: First move Z to clear workspace.
#define HOMING_CYCLE_1 ((1<<X_AXIS)|(1<<Y_AXIS)) // OPTIONAL: Then move X,Y at the same time.
//#define HOMING_CYCLE_1 ((1<<X_AXIS)|(1<<Y_AXIS)) // OPTIONAL: Then move X,Y at the same time.
// #define HOMING_CYCLE_2 // OPTIONAL: Uncomment and add axes mask to enable
#define HOMING_CYCLE_1 (1<<Y_AXIS) // OPTIONAL: Then move Y
#define HOMING_CYCLE_2 (1<<X_AXIS) // OPTIONAL: Finally move X
//#define HOMING_CYCLE_1 (1<<B_AXIS) // OPTIONAL: Then move B (head)
//#define HOMING_CYCLE_2 (1<<Y_AXIS) // OPTIONAL: Then move Y
//#define HOMING_CYCLE_3 (1<<X_AXIS) // OPTIONAL: Finally move X

// Number of homing cycles performed after when the machine initially jogs to limit switches.
// This help in preventing overshoot and should improve repeatability. This value should be one or
Expand All @@ -88,7 +93,7 @@
// After homing, Grbl will set by default the entire machine space into negative space, as is typical
// for professional CNC machines, regardless of where the limit switches are located. Uncomment this
// define to force Grbl to always set the machine origin at the homed location despite switch orientation.
// #define HOMING_FORCE_SET_ORIGIN // Uncomment to enable.
#define HOMING_FORCE_SET_ORIGIN // Uncomment to enable.

// Number of blocks Grbl executes upon startup. These blocks are stored in EEPROM, where the size
// and addresses are defined in settings.h. With the current settings, up to 2 startup blocks may
Expand Down Expand Up @@ -176,7 +181,7 @@
// Sets the maximum step rate allowed to be written as a Grbl setting. This value is strictly limited
// by the CPU speed and will change if something other than an AVR running at 16MHz is used.
// NOTE: For now disabled, will enable if flash space permits.
// #define MAX_STEP_RATE_HZ 30000 // Hz
#define MAX_STEP_RATE_HZ 30000 // Hz

// By default, Grbl sets all input pins to normal-high operation with their internal pull-up resistors
// enabled. This simplifies the wiring for users by requiring only a switch connected to ground,
Expand Down
43 changes: 26 additions & 17 deletions cpu_map.h
Original file line number Diff line number Diff line change
Expand Up @@ -152,28 +152,34 @@
#define SERIAL_UDRE USART0_UDRE_vect

// Increase Buffers to make use of extra SRAM
//#define RX_BUFFER_SIZE 256
//#define TX_BUFFER_SIZE 128
//#define BLOCK_BUFFER_SIZE 36
//#define LINE_BUFFER_SIZE 100
#define RX_BUFFER_SIZE 256
#define TX_BUFFER_SIZE 128
#define BLOCK_BUFFER_SIZE 36
#define LINE_BUFFER_SIZE 100

// Define step pulse output pins. NOTE: All step bit pins must be on the same port.
#define STEP_DDR DDRA
#define STEP_PORT PORTA
#define STEP_PIN PINA
#define X_STEP_BIT 2 // MEGA2560 Digital Pin 24
#define Y_STEP_BIT 3 // MEGA2560 Digital Pin 25
#define Z_STEP_BIT 4 // MEGA2560 Digital Pin 26
#define STEP_MASK ((1<<X_STEP_BIT)|(1<<Y_STEP_BIT)|(1<<Z_STEP_BIT)) // All step bits
#define X_STEP_BIT 0 // MEGA2560 Digital Pin 22
#define Y_STEP_BIT 1 // MEGA2560 Digital Pin 23
#define Z_STEP_BIT 2 // MEGA2560 Digital Pin 24
#define A_STEP_BIT 3 // MEGA2560 Digital Pin 25
#define B_STEP_BIT 4 // MEGA2560 Digital Pin 26
#define C_STEP_BIT 5 // MEGA2560 Digital Pin 27
#define STEP_MASK ((1<<X_STEP_BIT)|(1<<Y_STEP_BIT)|(1<<Z_STEP_BIT)|(1<<A_STEP_BIT)|(1<<B_STEP_BIT)|(1<<C_STEP_BIT)) // All step bits

// Define step direction output pins. NOTE: All direction pins must be on the same port.
#define DIRECTION_DDR DDRC
#define DIRECTION_PORT PORTC
#define DIRECTION_PIN PINC
#define X_DIRECTION_BIT 7 // MEGA2560 Digital Pin 30
#define Y_DIRECTION_BIT 6 // MEGA2560 Digital Pin 31
#define Z_DIRECTION_BIT 5 // MEGA2560 Digital Pin 32
#define DIRECTION_MASK ((1<<X_DIRECTION_BIT)|(1<<Y_DIRECTION_BIT)|(1<<Z_DIRECTION_BIT)) // All direction bits
#define X_DIRECTION_BIT 0 // MEGA2560 Digital Pin 37
#define Y_DIRECTION_BIT 1 // MEGA2560 Digital Pin 36
#define Z_DIRECTION_BIT 2 // MEGA2560 Digital Pin 35
#define A_DIRECTION_BIT 3 // MEGA2560 Digital Pin 34
#define B_DIRECTION_BIT 4 // MEGA2560 Digital Pin 33
#define C_DIRECTION_BIT 5 // MEGA2560 Digital Pin 32
#define DIRECTION_MASK ((1<<X_DIRECTION_BIT)|(1<<Y_DIRECTION_BIT)|(1<<Z_DIRECTION_BIT)|(1<<A_DIRECTION_BIT)|(1<<B_DIRECTION_BIT)|(1<<C_DIRECTION_BIT)) // All direction bits

// Define stepper driver enable/disable output pin.
#define STEPPERS_DISABLE_DDR DDRB
Expand All @@ -185,13 +191,16 @@
#define LIMIT_DDR DDRB
#define LIMIT_PORT PORTB
#define LIMIT_PIN PINB
#define X_LIMIT_BIT 4 // MEGA2560 Digital Pin 10
#define Y_LIMIT_BIT 5 // MEGA2560 Digital Pin 11
#define Z_LIMIT_BIT 6 // MEGA2560 Digital Pin 12
#define X_LIMIT_BIT 0 // MEGA2560 Digital Pin 53
#define Y_LIMIT_BIT 1 // MEGA2560 Digital Pin 52
#define Z_LIMIT_BIT 2 // MEGA2560 Digital Pin 51
#define A_LIMIT_BIT 3 // MEGA2560 Digital Pin 50
#define B_LIMIT_BIT 4 // MEGA2560 Digital Pin 10
#define C_LIMIT_BIT 5 // MEGA2560 Digital Pin 11
#define LIMIT_INT PCIE0 // Pin change interrupt enable pin
#define LIMIT_INT_vect PCINT0_vect
#define LIMIT_PCMSK PCMSK0 // Pin change interrupt register
#define LIMIT_MASK ((1<<X_LIMIT_BIT)|(1<<Y_LIMIT_BIT)|(1<<Z_LIMIT_BIT)) // All limit bits
#define LIMIT_MASK ((1<<X_LIMIT_BIT)|(1<<Y_LIMIT_BIT)|(1<<Z_LIMIT_BIT)|(1<<A_LIMIT_BIT)|(1<<B_LIMIT_BIT)|(1<<C_LIMIT_BIT)) // All limit bits

// Define spindle enable and spindle direction output pins.
#define SPINDLE_ENABLE_DDR DDRH
Expand Down Expand Up @@ -250,7 +259,7 @@

#define SPINDLE_PWM_DDR DDRH
#define SPINDLE_PWM_PORT PORTH
#define SPINDLE_PWM_BIT 4 // MEGA2560 Digital Pin 97
#define SPINDLE_PWM_BIT 4 // MEGA2560 Digital Pin 7
#endif // End of VARIABLE_SPINDLE

#endif
Expand Down
16 changes: 16 additions & 0 deletions defaults.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,22 @@
#define DEFAULT_X_MAX_TRAVEL 200.0 // mm
#define DEFAULT_Y_MAX_TRAVEL 200.0 // mm
#define DEFAULT_Z_MAX_TRAVEL 200.0 // mm

#define DEFAULT_A_STEPS_PER_MM 250.0
#define DEFAULT_A_MAX_RATE 500.0 // mm/min
#define DEFAULT_A_ACCELERATION (10.0*60*60) // 10*60*60 mm/min^2 = 10 mm/sec^2
#define DEFAULT_A_MAX_TRAVEL 200.0 // mm

#define DEFAULT_B_STEPS_PER_MM 250.0
#define DEFAULT_B_MAX_RATE 500.0 // mm/min
#define DEFAULT_B_ACCELERATION (10.0*60*60) // 10*60*60 mm/min^2 = 10 mm/sec^2
#define DEFAULT_B_MAX_TRAVEL 200.0 // mm

#define DEFAULT_C_STEPS_PER_MM 250.0
#define DEFAULT_C_MAX_RATE 500.0 // mm/min
#define DEFAULT_C_ACCELERATION (10.0*60*60) // 10*60*60 mm/min^2 = 10 mm/sec^2
#define DEFAULT_C_MAX_TRAVEL 200.0 // mm

#define DEFAULT_STEP_PULSE_MICROSECONDS 10
#define DEFAULT_STEPPING_INVERT_MASK 0
#define DEFAULT_DIRECTION_INVERT_MASK 0
Expand Down
14 changes: 10 additions & 4 deletions gcode.c
Original file line number Diff line number Diff line change
Expand Up @@ -324,9 +324,15 @@ uint8_t gc_execute_line(char *line)
legal g-code words and stores their value. Error-checking is performed later since some
words (I,J,K,L,P,R) have multiple connotations and/or depend on the issued commands. */
switch(letter){
// case 'A': // Not supported
// case 'B': // Not supported
// case 'C': // Not supported
#ifdef A_AXIS
case 'A': word_bit = WORD_A; gc_block.values.xyz[A_AXIS] = value; axis_words |= (1<<A_AXIS); break;
#endif
#ifdef B_AXIS
case 'B': word_bit = WORD_B; gc_block.values.xyz[B_AXIS] = value; axis_words |= (1<<B_AXIS); break;
#endif
#ifdef C_AXIS
case 'C': word_bit = WORD_C; gc_block.values.xyz[C_AXIS] = value; axis_words |= (1<<C_AXIS); break;
#endif
// case 'D': // Not supported
case 'F': word_bit = WORD_F; gc_block.values.f = value; break;
// case 'H': // Not supported
Expand Down Expand Up @@ -822,7 +828,7 @@ uint8_t gc_execute_line(char *line)
// [0. Non-specific error-checks]: Complete unused value words check, i.e. IJK used when in arc
// radius mode, or axis words that aren't used in the block.
bit_false(value_words,(bit(WORD_N)|bit(WORD_F)|bit(WORD_S)|bit(WORD_T))); // Remove single-meaning value words.
if (axis_command) { bit_false(value_words,(bit(WORD_X)|bit(WORD_Y)|bit(WORD_Z))); } // Remove axis words.
if (axis_command) { bit_false(value_words,(bit(WORD_X)|bit(WORD_Y)|bit(WORD_Z)|bit(WORD_A)|bit(WORD_B)|bit(WORD_C))); } // Remove axis words.
if (value_words) { FAIL(STATUS_GCODE_UNUSED_WORDS); } // [Unused words]


Expand Down
5 changes: 4 additions & 1 deletion gcode.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,9 @@
#define WORD_Y 11
#define WORD_Z 12

#define WORD_A 13
#define WORD_B 14
#define WORD_C 15



Expand Down Expand Up @@ -162,7 +165,7 @@ typedef struct {
float r; // Arc radius
float s; // Spindle speed
uint8_t t; // Tool selection
float xyz[3]; // X,Y,Z Translational axes
float xyz[N_AXIS]; // X,Y,Z Translational axes
} gc_values_t;


Expand Down
3 changes: 3 additions & 0 deletions motion_control.c
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,9 @@ void mc_homing_cycle()
#ifdef HOMING_CYCLE_2
limits_go_home(HOMING_CYCLE_2); // Homing cycle 2
#endif
#ifdef HOMING_CYCLE_3
limits_go_home(HOMING_CYCLE_3); // Homing cycle 3
#endif

protocol_execute_realtime(); // Check for reset and set system abort.
if (sys.abort) { return; } // Did not complete. Alarm state set by mc_alarm.
Expand Down
6 changes: 4 additions & 2 deletions nuts_bolts.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,13 @@
#define true 1

// Axis array index values. Must start with 0 and be continuous.
#define N_AXIS 3 // Number of axes
#define N_AXIS 5 // Number of axes
#define X_AXIS 0 // Axis indexing value.
#define Y_AXIS 1
#define Z_AXIS 2
// #define A_AXIS 3
#define A_AXIS 3
#define B_AXIS 4
//#define C_AXIS 5

// CoreXY motor assignments. DO NOT ALTER.
// NOTE: If the A and B motor axis bindings are changed, this effects the CoreXY equations.
Expand Down
29 changes: 27 additions & 2 deletions report.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,10 @@ void report_status_message(uint8_t status_code)
printPgmString(PSTR("Homing not enabled")); break;
case STATUS_OVERFLOW:
printPgmString(PSTR("Line overflow")); break;
// case STATUS_MAX_STEP_RATE_EXCEEDED:
// printPgmString(PSTR("Step rate > 30kHz")); break;
#ifdef MAX_STEP_RATE_HZ
case STATUS_MAX_STEP_RATE_EXCEEDED:
printPgmString(PSTR("Step rate > 30kHz")); break;
#endif

// Common g-code parser errors.
case STATUS_GCODE_MODAL_GROUP_VIOLATION:
Expand Down Expand Up @@ -211,13 +213,36 @@ void report_grbl_settings() {
case X_AXIS: printPgmString(PSTR("x")); break;
case Y_AXIS: printPgmString(PSTR("y")); break;
case Z_AXIS: printPgmString(PSTR("z")); break;
#ifdef A_AXIS
case A_AXIS: printPgmString(PSTR("a")); break;
#endif
#ifdef B_AXIS
case B_AXIS: printPgmString(PSTR("b")); break;
#endif
#ifdef C_AXIS
case C_AXIS: printPgmString(PSTR("c")); break;
#endif
}
#ifdef A_AXIS
if (idx >= A_AXIS ) {
switch (set_idx) {
case 0: printPgmString(PSTR(", step/deg")); break;
case 1: printPgmString(PSTR(" max rate, deg/min")); break;
case 2: printPgmString(PSTR(" accel, deg/sec^2")); break;
case 3: printPgmString(PSTR(" max travel, deg")); break;
}
} else {
#endif
switch (set_idx) {
case 0: printPgmString(PSTR(", step/mm")); break;
case 1: printPgmString(PSTR(" max rate, mm/min")); break;
case 2: printPgmString(PSTR(" accel, mm/sec^2")); break;
case 3: printPgmString(PSTR(" max travel, mm")); break;
}
#ifdef A_AXIS
}
#endif

printPgmString(PSTR(")\r\n"));
}
val += AXIS_SETTINGS_INCREMENT;
Expand Down
2 changes: 1 addition & 1 deletion report.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
#define STATUS_ALARM_LOCK 9
#define STATUS_SOFT_LIMIT_ERROR 10
#define STATUS_OVERFLOW 11
// #define STATUS_MAX_STEP_RATE_EXCEEDED 12
#define STATUS_MAX_STEP_RATE_EXCEEDED 12

#define STATUS_GCODE_UNSUPPORTED_COMMAND 20
#define STATUS_GCODE_MODAL_GROUP_VIOLATION 21
Expand Down
65 changes: 63 additions & 2 deletions settings.c
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,24 @@ void settings_restore_global_settings() {
settings.max_travel[X_AXIS] = (-DEFAULT_X_MAX_TRAVEL);
settings.max_travel[Y_AXIS] = (-DEFAULT_Y_MAX_TRAVEL);
settings.max_travel[Z_AXIS] = (-DEFAULT_Z_MAX_TRAVEL);
#ifdef A_AXIS
settings.steps_per_mm[A_AXIS] = DEFAULT_A_STEPS_PER_MM;
settings.max_rate[A_AXIS] = DEFAULT_A_MAX_RATE;
settings.acceleration[A_AXIS] = DEFAULT_A_ACCELERATION;
settings.max_travel[A_AXIS] = (-DEFAULT_A_MAX_TRAVEL);
#endif
#ifdef B_AXIS
settings.steps_per_mm[B_AXIS] = DEFAULT_B_STEPS_PER_MM;
settings.max_rate[B_AXIS] = DEFAULT_B_MAX_RATE;
settings.acceleration[B_AXIS] = DEFAULT_B_ACCELERATION;
settings.max_travel[B_AXIS] = (-DEFAULT_B_MAX_TRAVEL);
#endif
#ifdef C_AXIS
settings.steps_per_mm[C_AXIS] = DEFAULT_C_STEPS_PER_MM;
settings.acceleration[C_AXIS] = DEFAULT_C_ACCELERATION;
settings.max_rate[C_AXIS] = DEFAULT_C_MAX_RATE;
settings.max_travel[C_AXIS] = (-DEFAULT_C_MAX_TRAVEL);
#endif

write_global_settings();
}
Expand Down Expand Up @@ -201,11 +219,15 @@ uint8_t settings_store_global_setting(uint8_t parameter, float value) {
// Valid axis setting found.
switch (set_idx) {
case 0:
// if (value*settings.max_rate[parameter] > (MAX_STEP_RATE_HZ*60.0)) { return(STATUS_MAX_STEP_RATE_EXCEEDED); }
#ifdef MAX_STEP_RATE_HZ
if (value*settings.max_rate[parameter] > (MAX_STEP_RATE_HZ*60.0)) { return(STATUS_MAX_STEP_RATE_EXCEEDED); }
#endif
settings.steps_per_mm[parameter] = value;
break;
case 1:
// if (value*settings.steps_per_mm[parameter] > (MAX_STEP_RATE_HZ*60.0)) { return(STATUS_MAX_STEP_RATE_EXCEEDED); }
#ifdef MAX_STEP_RATE_HZ
if (value*settings.steps_per_mm[parameter] > (MAX_STEP_RATE_HZ*60.0)) { return(STATUS_MAX_STEP_RATE_EXCEEDED); }
#endif
settings.max_rate[parameter] = value;
break;
case 2: settings.acceleration[parameter] = value*60*60; break; // Convert to mm/min^2 for grbl internal use.
Expand Down Expand Up @@ -323,7 +345,20 @@ uint8_t get_step_pin_mask(uint8_t axis_idx)
{
if ( axis_idx == X_AXIS ) { return((1<<X_STEP_BIT)); }
if ( axis_idx == Y_AXIS ) { return((1<<Y_STEP_BIT)); }
#if defined(A_AXIS) || defined(B_AXIS) || defined(C_AXIS)
if ( axis_idx == Z_AXIS ) { return((1<<Z_STEP_BIT)); }
#endif
#ifdef A_AXIS
if ( axis_idx == A_AXIS ) { return((1<<A_STEP_BIT)); }
#endif
#ifdef B_AXIS
if ( axis_idx == B_AXIS ) { return((1<<B_STEP_BIT)); }
#endif
#ifdef C_AXIS
return((1<<C_STEP_BIT));
#else
return((1<<Z_STEP_BIT));
#endif
}


Expand All @@ -332,7 +367,20 @@ uint8_t get_direction_pin_mask(uint8_t axis_idx)
{
if ( axis_idx == X_AXIS ) { return((1<<X_DIRECTION_BIT)); }
if ( axis_idx == Y_AXIS ) { return((1<<Y_DIRECTION_BIT)); }
#if defined(A_AXIS) || defined(B_AXIS) || defined(C_AXIS)
if ( axis_idx == Z_AXIS ) { return((1<<Z_DIRECTION_BIT)); }
#endif
#ifdef A_AXIS
if ( axis_idx == A_AXIS ) { return((1<<A_DIRECTION_BIT)); }
#endif
#ifdef B_AXIS
if ( axis_idx == B_AXIS ) { return((1<<B_DIRECTION_BIT)); }
#endif
#ifdef C_AXIS
return((1<<C_DIRECTION_BIT));
#else
return((1<<Z_DIRECTION_BIT));
#endif
}


Expand All @@ -341,5 +389,18 @@ uint8_t get_limit_pin_mask(uint8_t axis_idx)
{
if ( axis_idx == X_AXIS ) { return((1<<X_LIMIT_BIT)); }
if ( axis_idx == Y_AXIS ) { return((1<<Y_LIMIT_BIT)); }
#if defined(A_AXIS) || defined(B_AXIS) || defined(C_AXIS)
if ( axis_idx == Z_AXIS ) { return((1<<Z_LIMIT_BIT)); }
#endif
#ifdef A_AXIS
if ( axis_idx == A_AXIS ) { return((1<<A_LIMIT_BIT)); }
#endif
#ifdef B_AXIS
if ( axis_idx == B_AXIS ) { return((1<<B_LIMIT_BIT)); }
#endif
#ifdef C_AXIS
return((1<<C_LIMIT_BIT));
#else
return((1<<Z_LIMIT_BIT));
#endif
}
2 changes: 1 addition & 1 deletion settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
#define settings_h


#define GRBL_VERSION "0.9h"
#define GRBL_VERSION "0.9h 6-AXIS"
#define GRBL_VERSION_BUILD "20150204"

// Version of the EEPROM data. Will be used to migrate existing data from older versions of Grbl
Expand Down
Loading

0 comments on commit b3e6d6a

Please sign in to comment.