New startup script setting. New dry run, check gcode switches. New system state variable. Lots of reorganizing.
(All v0.8 features installed. Still likely buggy, but now thourough testing will need to start to squash them all. As soon as we're done, this will be pushed to master and v0.9 development will be started. Please report ANY issues to us so we can get this rolled out ASAP.) - User startup script! A user can now save one (up to 5 as compile-time option) block of g-code in EEPROM memory. This will be run everytime Grbl resets. Mainly to be used as a way to set your preferences, like G21, G54, etc. - New dry run and check g-code switches. Dry run moves ALL motions at rapids rate ignoring spindle, coolant, and dwell commands. For rapid physical proofing of your code. The check g-code switch ignores all motion and provides the user a way to check if there are any errors in their program that Grbl may not like. - Program restart! (sort of). Program restart is typically an advanced feature that allows users to restart a program mid-stream. The check g-code switch can perform this feature by enabling the switch at the start of the program, and disabling it at the desired point with some minimal changes. - New system state variable. This state variable tracks all of the different state processes that Grbl performs, i.e. cycle start, feed hold, homing, etc. This is mainly for making managing of these task easier and more clear. - Position lost state variable. Only when homing is enabled, Grbl will refuse to move until homing is completed and position is known. This is mainly for safety. Otherwise, it will let users fend for themselves. - Moved the default settings defines into config.h. The plan is to eventually create a set of config.h's for particular as-built machines to help users from doing it themselves. - Moved around misc defines into .h files. And lots of other little things.
This commit is contained in:
parent
303cf59f52
commit
4c711a4af7
59
config.h
59
config.h
@ -69,6 +69,33 @@
|
|||||||
#define COOLANT_MIST_BIT 1 // Uno Analog Pin 1
|
#define COOLANT_MIST_BIT 1 // Uno Analog Pin 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Default settings (used when resetting eeprom-settings)
|
||||||
|
// TODO: Begin to fill these out for various as-built machines, i.e. config_sherline5400.h
|
||||||
|
#define MICROSTEPS 4
|
||||||
|
#define DEFAULT_X_STEPS_PER_MM (94.488188976378*MICROSTEPS)
|
||||||
|
#define DEFAULT_Y_STEPS_PER_MM (94.488188976378*MICROSTEPS)
|
||||||
|
#define DEFAULT_Z_STEPS_PER_MM (94.488188976378*MICROSTEPS)
|
||||||
|
#define DEFAULT_STEP_PULSE_MICROSECONDS 10
|
||||||
|
#define DEFAULT_MM_PER_ARC_SEGMENT 0.1
|
||||||
|
#define DEFAULT_RAPID_FEEDRATE 500.0 // mm/min
|
||||||
|
#define DEFAULT_FEEDRATE 250.0
|
||||||
|
#define DEFAULT_ACCELERATION (DEFAULT_FEEDRATE*60*60/10.0) // mm/min^2
|
||||||
|
#define DEFAULT_JUNCTION_DEVIATION 0.05 // mm
|
||||||
|
#define DEFAULT_STEPPING_INVERT_MASK ((1<<X_STEP_BIT)|(1<<Y_STEP_BIT)|(1<<Z_STEP_BIT))
|
||||||
|
#define DEFAULT_REPORT_INCHES 0 // false
|
||||||
|
#define DEFAULT_AUTO_START 1 // true
|
||||||
|
#define DEFAULT_INVERT_ST_ENABLE 0 // false
|
||||||
|
#define DEFAULT_HARD_LIMIT_ENABLE 0 // false
|
||||||
|
#define DEFAULT_HOMING_ENABLE 0 // false
|
||||||
|
#define DEFAULT_HOMING_DIR_MASK 0 // move positive dir
|
||||||
|
#define DEFAULT_HOMING_RAPID_FEEDRATE 250.0 // mm/min
|
||||||
|
#define DEFAULT_HOMING_FEEDRATE 50 // mm/min
|
||||||
|
#define DEFAULT_HOMING_DEBOUNCE_DELAY 100 // msec (0-65k)
|
||||||
|
#define DEFAULT_HOMING_PULLOFF 1 // mm
|
||||||
|
#define DEFAULT_STEPPER_IDLE_LOCK_TIME 25 // msec (0-255)
|
||||||
|
#define DEFAULT_DECIMAL_PLACES 3
|
||||||
|
#define DEFAULT_N_ARC_CORRECTION 25
|
||||||
|
|
||||||
// Define runtime command special characters. These characters are 'picked-off' directly from the
|
// Define runtime 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
|
// serial read data stream and are not passed to the grbl line execution parser. Select characters
|
||||||
// that do not and must not exist in the streamed g-code program. ASCII control characters may be
|
// that do not and must not exist in the streamed g-code program. ASCII control characters may be
|
||||||
@ -114,6 +141,12 @@
|
|||||||
// greater.
|
// greater.
|
||||||
#define N_HOMING_CYCLE 2 // Integer (1-128)
|
#define N_HOMING_CYCLE 2 // Integer (1-128)
|
||||||
|
|
||||||
|
// 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 5 startup blocks may
|
||||||
|
// be stored and executed in order. These startup blocks would typically be used to set the g-code
|
||||||
|
// parser state depending on user preferences.
|
||||||
|
#define N_STARTUP_LINE 1 // Integer (1-5)
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------------
|
||||||
// FOR ADVANCED USERS ONLY:
|
// FOR ADVANCED USERS ONLY:
|
||||||
|
|
||||||
@ -146,32 +179,6 @@
|
|||||||
|
|
||||||
// ---------------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------------
|
||||||
|
|
||||||
// TODO: The following options are set as compile-time options for now, until the next EEPROM
|
|
||||||
// settings version has solidified. This is to prevent having to support dozens of different
|
|
||||||
// incremental settings versions.
|
|
||||||
// -> NOW CODED INTO SETTINGS #define BLOCK_DELETE_ENABLE 0 // Block delete enable/disable flag during g-code parsing
|
|
||||||
|
|
||||||
// This parameter sets the delay time before disabling the steppers after the final block of movement.
|
|
||||||
// A short delay ensures the steppers come to a complete stop and the residual inertial force in the
|
|
||||||
// CNC axes don't cause the axes to drift off position. This is particularly important when manually
|
|
||||||
// entering g-code into grbl, i.e. locating part zero or simple manual machining. If the axes drift,
|
|
||||||
// grbl has no way to know this has happened, since stepper motors are open-loop control. Depending
|
|
||||||
// on the machine, this parameter may need to be larger or smaller than the default time.
|
|
||||||
// NOTE: If set to zero, no lock will occur. If set to max 255, the lock will never release, in other
|
|
||||||
// words, the steppers never disable for users that require this.
|
|
||||||
// -> NOW INSTALLED IN SETTINGS #define STEPPER_IDLE_LOCK_TIME 25 // (milliseconds) - Integer > 0
|
|
||||||
|
|
||||||
// Number of arc generation iterations by small angle approximation before exact arc trajectory
|
|
||||||
// correction. This parameter maybe decreased if there are issues with the accuracy of the arc
|
|
||||||
// generations. In general, the default value is more than enough for the intended CNC applications
|
|
||||||
// of grbl, and should be on the order or greater than the size of the buffer to help with the
|
|
||||||
// computational efficiency of generating arcs.
|
|
||||||
// -> NOW INSTALLED IN SETTINGS #define N_ARC_CORRECTION 25 // Integer (1-255)
|
|
||||||
|
|
||||||
// Specifies the number of work coordinate systems grbl will support (G54 - G59).
|
|
||||||
// This parameter must be one or greater, currently supporting up to a value of 6.
|
|
||||||
// -> NOW CODED INTO SETTINGS.C #define N_COORDINATE_SYSTEM 6
|
|
||||||
|
|
||||||
// TODO: Install compile-time option to send numeric status codes rather than strings.
|
// TODO: Install compile-time option to send numeric status codes rather than strings.
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
14
gcode.c
14
gcode.c
@ -177,7 +177,7 @@ uint8_t gc_execute_line(char *line)
|
|||||||
switch(int_value) {
|
switch(int_value) {
|
||||||
case 0: gc.program_flow = PROGRAM_FLOW_PAUSED; break; // Program pause
|
case 0: gc.program_flow = PROGRAM_FLOW_PAUSED; break; // Program pause
|
||||||
case 1: // Program pause with optional stop on, otherwise do nothing.
|
case 1: // Program pause with optional stop on, otherwise do nothing.
|
||||||
if (bit_istrue(sys.switches,BITFLAG_OPT_STOP)) {
|
if (bit_istrue(gc.switches,BITFLAG_OPT_STOP)) {
|
||||||
gc.program_flow = PROGRAM_FLOW_PAUSED;
|
gc.program_flow = PROGRAM_FLOW_PAUSED;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -253,13 +253,20 @@ uint8_t gc_execute_line(char *line)
|
|||||||
NOTE: Independent non-motion/settings parameters are set out of this order for code efficiency
|
NOTE: Independent non-motion/settings parameters are set out of this order for code efficiency
|
||||||
and simplicity purposes, but this should not affect proper g-code execution. */
|
and simplicity purposes, but this should not affect proper g-code execution. */
|
||||||
|
|
||||||
|
// ([F]: Set feed rate. Already performed, but enforce rapids for dry runs.)
|
||||||
|
if (bit_istrue(gc.switches,BITFLAG_DRY_RUN)) { gc.feed_rate = settings.default_seek_rate; }
|
||||||
|
|
||||||
// ([M6]: Tool change should be executed here.)
|
// ([M6]: Tool change should be executed here.)
|
||||||
|
|
||||||
// [M3,M4,M5]: Update spindle state
|
// [M3,M4,M5]: Update spindle state
|
||||||
|
if (!(gc.switches & (BITFLAG_DRY_RUN | BITFLAG_CHECK_GCODE))) {
|
||||||
spindle_run(gc.spindle_direction); //, gc.spindle_speed);
|
spindle_run(gc.spindle_direction); //, gc.spindle_speed);
|
||||||
|
}
|
||||||
|
|
||||||
// [*M7,M8,M9]: Update coolant state
|
// [*M7,M8,M9]: Update coolant state
|
||||||
|
if (!(gc.switches & (BITFLAG_DRY_RUN | BITFLAG_CHECK_GCODE))) {
|
||||||
coolant_run(gc.coolant_mode);
|
coolant_run(gc.coolant_mode);
|
||||||
|
}
|
||||||
|
|
||||||
// [G54,G55,...,G59]: Coordinate system selection
|
// [G54,G55,...,G59]: Coordinate system selection
|
||||||
if ( bit_istrue(modal_group_words,bit(MODAL_GROUP_12)) ) { // Check if called in block
|
if ( bit_istrue(modal_group_words,bit(MODAL_GROUP_12)) ) { // Check if called in block
|
||||||
@ -276,8 +283,11 @@ uint8_t gc_execute_line(char *line)
|
|||||||
if (p < 0) { // Time cannot be negative.
|
if (p < 0) { // Time cannot be negative.
|
||||||
FAIL(STATUS_INVALID_STATEMENT);
|
FAIL(STATUS_INVALID_STATEMENT);
|
||||||
} else {
|
} else {
|
||||||
|
// Ignore dwell in dry run and check gcode modes
|
||||||
|
if (!(gc.switches & (BITFLAG_DRY_RUN | BITFLAG_CHECK_GCODE))) {
|
||||||
mc_dwell(p);
|
mc_dwell(p);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case NON_MODAL_SET_COORDINATE_DATA:
|
case NON_MODAL_SET_COORDINATE_DATA:
|
||||||
int_value = trunc(p); // Convert p value to int.
|
int_value = trunc(p); // Convert p value to int.
|
||||||
@ -537,7 +547,7 @@ uint8_t gc_execute_line(char *line)
|
|||||||
|
|
||||||
// M0,M1,M2,M30: Perform non-running program flow actions. During a program pause, the buffer may
|
// M0,M1,M2,M30: Perform non-running program flow actions. During a program pause, the buffer may
|
||||||
// refill and can only be resumed by the cycle start run-time command.
|
// refill and can only be resumed by the cycle start run-time command.
|
||||||
if (gc.program_flow || bit_istrue(sys.switches,BITFLAG_SINGLE_BLOCK)) {
|
if (gc.program_flow || bit_istrue(gc.switches,BITFLAG_SINGLE_BLOCK)) {
|
||||||
plan_synchronize(); // Finish all remaining buffered motions. Program paused when complete.
|
plan_synchronize(); // Finish all remaining buffered motions. Program paused when complete.
|
||||||
sys.auto_start = false; // Disable auto cycle start. Forces pause until cycle start issued.
|
sys.auto_start = false; // Disable auto cycle start. Forces pause until cycle start issued.
|
||||||
|
|
||||||
|
11
gcode.h
11
gcode.h
@ -62,8 +62,19 @@
|
|||||||
#define NON_MODAL_SET_COORDINATE_OFFSET 7 // G92
|
#define NON_MODAL_SET_COORDINATE_OFFSET 7 // G92
|
||||||
#define NON_MODAL_RESET_COORDINATE_OFFSET 8 //G92.1
|
#define NON_MODAL_RESET_COORDINATE_OFFSET 8 //G92.1
|
||||||
|
|
||||||
|
// Define bit flag masks for gc.switches. (8 flag limit)
|
||||||
|
#define BITFLAG_CHECK_GCODE bit(0)
|
||||||
|
#define BITFLAG_DRY_RUN bit(1)
|
||||||
|
#define BITFLAG_BLOCK_DELETE bit(2)
|
||||||
|
#define BITFLAG_SINGLE_BLOCK bit(3)
|
||||||
|
#define BITFLAG_OPT_STOP bit(4)
|
||||||
|
// #define bit(5)
|
||||||
|
// #define bit(6)
|
||||||
|
// #define bit(7)
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t status_code; // Parser status for current block
|
uint8_t status_code; // Parser status for current block
|
||||||
|
uint8_t switches; // Handles non-gcode switches modes. Set externally by protocol. Default off
|
||||||
uint8_t motion_mode; // {G0, G1, G2, G3, G80}
|
uint8_t motion_mode; // {G0, G1, G2, G3, G80}
|
||||||
uint8_t inverse_feed_rate_mode; // {G93, G94}
|
uint8_t inverse_feed_rate_mode; // {G93, G94}
|
||||||
uint8_t inches_mode; // 0 = millimeter mode, 1 = inches mode {G20, G21}
|
uint8_t inches_mode; // 0 = millimeter mode, 1 = inches mode {G20, G21}
|
||||||
|
3
limits.c
3
limits.c
@ -33,7 +33,6 @@
|
|||||||
#include "limits.h"
|
#include "limits.h"
|
||||||
#include "report.h"
|
#include "report.h"
|
||||||
|
|
||||||
#define MICROSECONDS_PER_ACCELERATION_TICK (1000000/ACCELERATION_TICKS_PER_SECOND)
|
|
||||||
|
|
||||||
void limits_init()
|
void limits_init()
|
||||||
{
|
{
|
||||||
@ -63,7 +62,7 @@ ISR(LIMIT_INT_vect)
|
|||||||
// Kill all processes upon hard limit event.
|
// Kill all processes upon hard limit event.
|
||||||
if ((LIMIT_PIN & LIMIT_MASK) ^ LIMIT_MASK) {
|
if ((LIMIT_PIN & LIMIT_MASK) ^ LIMIT_MASK) {
|
||||||
mc_alarm(); // Initiate system kill.
|
mc_alarm(); // Initiate system kill.
|
||||||
report_status_message(STATUS_HARD_LIMIT); // Print ok in interrupt since system killed.
|
sys.state = STATE_LIMIT; // Set system state to indicate event.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
1
limits.h
1
limits.h
@ -22,6 +22,7 @@
|
|||||||
#define limits_h
|
#define limits_h
|
||||||
|
|
||||||
#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)) // All limit bits
|
||||||
|
#define MICROSECONDS_PER_ACCELERATION_TICK (1000000/ACCELERATION_TICKS_PER_SECOND)
|
||||||
|
|
||||||
// initialize the limits module
|
// initialize the limits module
|
||||||
void limits_init();
|
void limits_init();
|
||||||
|
48
main.c
48
main.c
@ -51,8 +51,7 @@ int main(void)
|
|||||||
|
|
||||||
memset(&sys, 0, sizeof(sys)); // Clear all system variables
|
memset(&sys, 0, sizeof(sys)); // Clear all system variables
|
||||||
sys.abort = true; // Set abort to complete initialization
|
sys.abort = true; // Set abort to complete initialization
|
||||||
|
sys.state = STATE_LOST; // Set state to indicate unknown initial position
|
||||||
// TODO: When Grbl system status is installed, need to set position lost state upon startup.
|
|
||||||
|
|
||||||
for(;;) {
|
for(;;) {
|
||||||
|
|
||||||
@ -60,44 +59,41 @@ int main(void)
|
|||||||
// Once here, it is safe to re-initialize the system. At startup, the system will automatically
|
// Once here, it is safe to re-initialize the system. At startup, the system will automatically
|
||||||
// reset to finish the initialization process.
|
// reset to finish the initialization process.
|
||||||
if (sys.abort) {
|
if (sys.abort) {
|
||||||
|
// If a critical event has occurred, set the position lost system state. For example, a
|
||||||
// Retain last known machine position and work coordinate offset(s). If the system abort
|
// hard limit event can cause the stepper to lose steps and position due to an immediate
|
||||||
// occurred while in motion, machine position is not guaranteed, since a hard stop can cause
|
// stop, not with a controlled deceleration. Or, if an abort was issued while a cycle
|
||||||
// the steppers to lose steps. Always perform a feedhold before an abort, if maintaining
|
// was active, the immediate stop can also cause lost steps.
|
||||||
// accurate machine position is required.
|
if (sys.state == STATE_ALARM) { sys.state = STATE_LOST; }
|
||||||
// TODO: Report last position and coordinate offset to users to help relocate origins. Future
|
|
||||||
// releases will auto-reset the machine position back to [0,0,0] if an abort is used while
|
|
||||||
// grbl is moving the machine.
|
|
||||||
int32_t last_position[3];
|
|
||||||
memcpy(last_position, sys.position, sizeof(sys.position)); // last_position[] = sys.position[]
|
|
||||||
// TODO: Last coordinate system method.
|
|
||||||
|
|
||||||
// Reset system.
|
// Reset system.
|
||||||
memset(&sys, 0, sizeof(sys)); // Clear all system variables
|
|
||||||
serial_reset_read_buffer(); // Clear serial read buffer
|
serial_reset_read_buffer(); // Clear serial read buffer
|
||||||
settings_init(); // Load grbl settings from EEPROM
|
settings_init(); // Load grbl settings from EEPROM
|
||||||
protocol_init(); // Clear incoming line data
|
|
||||||
plan_init(); // Clear block buffer and planner variables
|
plan_init(); // Clear block buffer and planner variables
|
||||||
gc_init(); // Set g-code parser to default state
|
gc_init(); // Set g-code parser to default state
|
||||||
|
protocol_init(); // Clear incoming line data and execute startup lines
|
||||||
spindle_init();
|
spindle_init();
|
||||||
coolant_init();
|
coolant_init();
|
||||||
limits_init();
|
limits_init();
|
||||||
st_reset(); // Clear stepper subsystem variables.
|
st_reset(); // Clear stepper subsystem variables.
|
||||||
|
|
||||||
// Reload last known machine position and work systems. G92 coordinate offsets are reset.
|
// Set cleared gcode and planner positions to current system position, which is only
|
||||||
memcpy(sys.position, last_position, sizeof(last_position)); // sys.position[] = last_position[]
|
// cleared upon startup, not a reset/abort. If Grbl does not know or ensure its position,
|
||||||
gc_set_current_position(last_position[X_AXIS],last_position[Y_AXIS],last_position[Z_AXIS]);
|
// a feedback message will be sent back to the user to let them know.
|
||||||
plan_set_current_position(last_position[X_AXIS],last_position[Y_AXIS],last_position[Z_AXIS]);
|
gc_set_current_position(sys.position[X_AXIS],sys.position[Y_AXIS],sys.position[Z_AXIS]);
|
||||||
|
plan_set_current_position(sys.position[X_AXIS],sys.position[Y_AXIS],sys.position[Z_AXIS]);
|
||||||
|
|
||||||
// Set system runtime defaults
|
// Reset system variables
|
||||||
// TODO: Eventual move to EEPROM from config.h when all of the new settings are worked out.
|
sys.abort = false;
|
||||||
// Mainly to avoid having to maintain several different versions.
|
sys.execute = 0;
|
||||||
if (bit_istrue(settings.flags,BITFLAG_AUTO_START)) {
|
if (sys.state == STATE_LOST && bit_istrue(settings.flags,BITFLAG_HOMING_ENABLE)) {
|
||||||
sys.auto_start = true;
|
report_feedback_message(MESSAGE_POSITION_LOST);
|
||||||
|
} else {
|
||||||
|
sys.state = STATE_IDLE;
|
||||||
}
|
}
|
||||||
// TODO: Install G20/G21 unit default into settings and load appropriate settings.
|
if (bit_istrue(settings.flags,BITFLAG_AUTO_START)) { sys.auto_start = true; }
|
||||||
|
|
||||||
report_init_message();
|
// Execute user startup script
|
||||||
|
protocol_execute_startup();
|
||||||
}
|
}
|
||||||
|
|
||||||
protocol_execute_runtime();
|
protocol_execute_runtime();
|
||||||
|
@ -21,15 +21,15 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <avr/io.h>
|
#include <avr/io.h>
|
||||||
|
#include <util/delay.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "gcode.h"
|
#include "gcode.h"
|
||||||
#include "motion_control.h"
|
#include "motion_control.h"
|
||||||
#include "spindle_control.h"
|
#include "spindle_control.h"
|
||||||
#include "coolant_control.h"
|
#include "coolant_control.h"
|
||||||
#include <util/delay.h>
|
|
||||||
#include <math.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include "nuts_bolts.h"
|
#include "nuts_bolts.h"
|
||||||
#include "stepper.h"
|
#include "stepper.h"
|
||||||
#include "planner.h"
|
#include "planner.h"
|
||||||
@ -62,8 +62,17 @@ void mc_line(float x, float y, float z, float feed_rate, uint8_t invert_feed_rat
|
|||||||
protocol_execute_runtime(); // Check for any run-time commands
|
protocol_execute_runtime(); // Check for any run-time commands
|
||||||
if (sys.abort) { return; } // Bail, if system abort.
|
if (sys.abort) { return; } // Bail, if system abort.
|
||||||
} while ( plan_check_full_buffer() );
|
} while ( plan_check_full_buffer() );
|
||||||
|
|
||||||
|
// If in check gcode mode, prevent motion by blocking planner.
|
||||||
|
if (bit_isfalse(gc.switches,BITFLAG_CHECK_GCODE)) {
|
||||||
plan_buffer_line(x, y, z, feed_rate, invert_feed_rate);
|
plan_buffer_line(x, y, z, feed_rate, invert_feed_rate);
|
||||||
|
|
||||||
|
// Indicate to the system there is now a planned block in the buffer ready to cycle start.
|
||||||
|
// NOTE: If homing cycles are enabled, a position lost state will lock out all motions,
|
||||||
|
// until a homing cycle has been completed. This is a safety feature to help prevent
|
||||||
|
// the machine from crashing.
|
||||||
|
if (!sys.state) { sys.state = STATE_QUEUED; }
|
||||||
|
|
||||||
// Auto-cycle start immediately after planner finishes. Enabled/disabled by grbl settings. During
|
// Auto-cycle start immediately after planner finishes. Enabled/disabled by grbl settings. During
|
||||||
// a feed hold, auto-start is disabled momentarily until the cycle is resumed by the cycle-start
|
// a feed hold, auto-start is disabled momentarily until the cycle is resumed by the cycle-start
|
||||||
// runtime command.
|
// runtime command.
|
||||||
@ -74,6 +83,7 @@ void mc_line(float x, float y, float z, float feed_rate, uint8_t invert_feed_rat
|
|||||||
// helps make sure it minimizes any dwelling/motion hiccups and keeps the cycle going.
|
// helps make sure it minimizes any dwelling/motion hiccups and keeps the cycle going.
|
||||||
if (sys.auto_start) { st_cycle_start(); }
|
if (sys.auto_start) { st_cycle_start(); }
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Execute an arc in offset mode format. position == current xyz, target == target xyz,
|
// Execute an arc in offset mode format. position == current xyz, target == target xyz,
|
||||||
@ -195,14 +205,19 @@ void mc_dwell(float seconds)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Execute homing cycle to locate and set machine zero.
|
// Perform homing cycle to locate and set machine zero. Only '$H' executes this command.
|
||||||
|
// NOTE: There should be no motions in the buffer and Grbl must be in an idle state before
|
||||||
|
// executing the homing cycle. This prevents incorrect buffered plans after homing.
|
||||||
void mc_go_home()
|
void mc_go_home()
|
||||||
{
|
{
|
||||||
plan_synchronize(); // Empty all motions in buffer before homing.
|
sys.state = STATE_HOMING; // Set system state variable
|
||||||
PCICR &= ~(1 << LIMIT_INT); // Disable hard limits pin change interrupt
|
PCICR &= ~(1 << LIMIT_INT); // Disable hard limits pin change interrupt
|
||||||
plan_clear_position();
|
|
||||||
|
|
||||||
limits_go_home(); // Perform homing routine.
|
limits_go_home(); // Perform homing routine.
|
||||||
|
if (sys.abort) {
|
||||||
|
sys.state = STATE_LOST; // Homing routine did not complete.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// The machine should now be homed and machine zero has been located. Upon completion,
|
// The machine should now be homed and machine zero has been located. Upon completion,
|
||||||
// reset planner and system internal position vectors, but not gcode parser position yet.
|
// reset planner and system internal position vectors, but not gcode parser position yet.
|
||||||
@ -227,6 +242,7 @@ void mc_go_home()
|
|||||||
|
|
||||||
// If hard limits feature enabled, re-enable hard limits interrupt after homing cycle.
|
// If hard limits feature enabled, re-enable hard limits interrupt after homing cycle.
|
||||||
if (bit_istrue(settings.flags,BITFLAG_HARD_LIMIT_ENABLE)) { PCICR |= (1 << LIMIT_INT); }
|
if (bit_istrue(settings.flags,BITFLAG_HARD_LIMIT_ENABLE)) { PCICR |= (1 << LIMIT_INT); }
|
||||||
|
sys.state = STATE_IDLE; // Finished!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@ void mc_arc(float *position, float *target, float *offset, uint8_t axis_0, uint8
|
|||||||
// Dwell for a specific number of seconds
|
// Dwell for a specific number of seconds
|
||||||
void mc_dwell(float seconds);
|
void mc_dwell(float seconds);
|
||||||
|
|
||||||
// Send the tool home (not implemented)
|
// Perform homing cycle to locate machine zero. Requires limit switches.
|
||||||
void mc_go_home();
|
void mc_go_home();
|
||||||
|
|
||||||
// Kills all motion and sets system alarm
|
// Kills all motion and sets system alarm
|
||||||
|
@ -20,8 +20,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "nuts_bolts.h"
|
#include "nuts_bolts.h"
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <util/delay.h>
|
#include <util/delay.h>
|
||||||
|
|
||||||
#define MAX_INT_DIGITS 8 // Maximum number of digits in int32 (and float)
|
#define MAX_INT_DIGITS 8 // Maximum number of digits in int32 (and float)
|
||||||
|
39
nuts_bolts.h
39
nuts_bolts.h
@ -66,36 +66,29 @@
|
|||||||
// #define bit(6) // bitmask 01000000
|
// #define bit(6) // bitmask 01000000
|
||||||
// #define bit(7) // bitmask 10000000
|
// #define bit(7) // bitmask 10000000
|
||||||
|
|
||||||
// Define bit flag masks for sys.switches. (8 flag limit)
|
// Define system state bit map. The state variable primarily tracks the individual functions
|
||||||
#define BITFLAG_BLOCK_DELETE bit(0)
|
// of Grbl to manage each without overlapping. It is also used as a messaging flag for
|
||||||
#define BITFLAG_SINGLE_BLOCK bit(1)
|
// critical events.
|
||||||
#define BITFLAG_OPT_STOP bit(2)
|
#define STATE_IDLE 0 // Must be zero.
|
||||||
// #define bit(3)
|
#define STATE_QUEUED 1 // Indicates buffered blocks, awaiting cycle start.
|
||||||
// #define bit(4)
|
#define STATE_CYCLE 2 // Cycle is running
|
||||||
// #define bit(5)
|
#define STATE_HOLD 3 // Executing feed hold
|
||||||
// #define bit(6)
|
#define STATE_HOMING 4 // Performing homing cycle
|
||||||
// #define bit(7)
|
#define STATE_JOG 5 // Jogging mode is unique like homing.
|
||||||
|
#define STATE_ALARM 6 // In alarm state. Locks out all but reset
|
||||||
// Define Grbl system states for sys.state
|
#define STATE_LOST 7 // Used to message position may be lost upon startup or event
|
||||||
|
#define STATE_LIMIT 8 // Used to message hard limit triggered.
|
||||||
// Define position lost in states?
|
|
||||||
|
|
||||||
|
|
||||||
// Define global system variables
|
// Define global system variables
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t abort; // System abort flag. Forces exit back to main loop for reset.
|
uint8_t abort; // System abort flag. Forces exit back to main loop for reset.
|
||||||
uint8_t feed_hold; // Feed hold flag. Held true during feed hold. Released when ready to resume.
|
uint8_t state; // Tracks the current state of Grbl.
|
||||||
uint8_t auto_start; // Planner auto-start flag. Toggled off during feed hold. Defaulted by settings.
|
|
||||||
uint8_t switches; // Switches state bitflag variable. For features not governed by g-code.
|
|
||||||
|
|
||||||
// uint8_t state; // Tracks the current state of Grbl.
|
|
||||||
// TODO: This may replace the functionality of the feed_hold and cycle_start variables. Need to
|
|
||||||
// make sure that overall processes don't change.
|
|
||||||
|
|
||||||
volatile uint8_t cycle_start; // Cycle start flag. Set by stepper subsystem or main program.
|
|
||||||
volatile uint8_t execute; // Global system runtime executor bitflag variable. See EXEC bitmasks.
|
volatile uint8_t execute; // Global system runtime executor bitflag variable. See EXEC bitmasks.
|
||||||
int32_t position[3]; // Real-time machine (aka home) position vector in steps.
|
int32_t position[3]; // Real-time machine (aka home) position vector in steps.
|
||||||
// NOTE: This may need to be a volatile variable, if problems arise.
|
// NOTE: This may need to be a volatile variable, if problems arise.
|
||||||
|
uint8_t auto_start; // Planner auto-start flag. Toggled off during feed hold. Defaulted by settings.
|
||||||
|
// uint8_t feed_hold; // Feed hold flag. Held true during feed hold. Released when ready to resume.
|
||||||
|
// volatile uint8_t cycle_start; // Cycle start flag. Set by stepper subsystem or main program.
|
||||||
} system_t;
|
} system_t;
|
||||||
extern system_t sys;
|
extern system_t sys;
|
||||||
|
|
||||||
|
@ -23,9 +23,7 @@
|
|||||||
/* The ring buffer implementation gleaned from the wiring_serial library by David A. Mellis. */
|
/* The ring buffer implementation gleaned from the wiring_serial library by David A. Mellis. */
|
||||||
|
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <math.h>
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "planner.h"
|
#include "planner.h"
|
||||||
#include "nuts_bolts.h"
|
#include "nuts_bolts.h"
|
||||||
#include "stepper.h"
|
#include "stepper.h"
|
||||||
@ -33,9 +31,6 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "protocol.h"
|
#include "protocol.h"
|
||||||
|
|
||||||
// The number of linear motions that can be in the plan at any give time
|
|
||||||
#define BLOCK_BUFFER_SIZE 18
|
|
||||||
|
|
||||||
static block_t block_buffer[BLOCK_BUFFER_SIZE]; // A ring buffer for motion instructions
|
static block_t block_buffer[BLOCK_BUFFER_SIZE]; // A ring buffer for motion instructions
|
||||||
static volatile uint8_t block_buffer_head; // Index of the next block to be pushed
|
static volatile uint8_t block_buffer_head; // Index of the next block to be pushed
|
||||||
static volatile uint8_t block_buffer_tail; // Index of the block to process now
|
static volatile uint8_t block_buffer_tail; // Index of the block to process now
|
||||||
@ -335,7 +330,7 @@ uint8_t plan_check_full_buffer()
|
|||||||
// Block until all buffered steps are executed.
|
// Block until all buffered steps are executed.
|
||||||
void plan_synchronize()
|
void plan_synchronize()
|
||||||
{
|
{
|
||||||
while (plan_get_current_block() || sys.cycle_start) {
|
while (plan_get_current_block()) {
|
||||||
protocol_execute_runtime(); // Check and execute run-time commands
|
protocol_execute_runtime(); // Check and execute run-time commands
|
||||||
if (sys.abort) { return; } // Check for system abort
|
if (sys.abort) { return; } // Check for system abort
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,8 @@
|
|||||||
#ifndef planner_h
|
#ifndef planner_h
|
||||||
#define planner_h
|
#define planner_h
|
||||||
|
|
||||||
#include <inttypes.h>
|
// The number of linear motions that can be in the plan at any give time
|
||||||
|
#define BLOCK_BUFFER_SIZE 18
|
||||||
|
|
||||||
// This struct is used when buffering the setup for each linear movement "nominal" values are as specified in
|
// This struct is used when buffering the setup for each linear movement "nominal" values are as specified in
|
||||||
// the source g-code and may never actually be reached if acceleration management is active.
|
// the source g-code and may never actually be reached if acceleration management is active.
|
||||||
|
3
print.c
3
print.c
@ -23,7 +23,6 @@
|
|||||||
used to be a part of the Arduino project. */
|
used to be a part of the Arduino project. */
|
||||||
|
|
||||||
|
|
||||||
#include <math.h>
|
|
||||||
#include <avr/pgmspace.h>
|
#include <avr/pgmspace.h>
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "serial.h"
|
#include "serial.h"
|
||||||
@ -109,6 +108,8 @@ void printInteger(long n)
|
|||||||
// Convert float to string by immediately converting to a long integer, which contains
|
// Convert float to string by immediately converting to a long integer, which contains
|
||||||
// more digits than a float. Number of decimal places, which are tracked by a counter,
|
// more digits than a float. Number of decimal places, which are tracked by a counter,
|
||||||
// may be set by the user. The integer is then efficiently converted to a string.
|
// may be set by the user. The integer is then efficiently converted to a string.
|
||||||
|
// NOTE: AVR '%' and '/' integer operations are very efficient. Bitshifting speed-up
|
||||||
|
// techniques are actually just slightly slower. Found this out the hard way.
|
||||||
void printFloat(float n)
|
void printFloat(float n)
|
||||||
{
|
{
|
||||||
if (n < 0) {
|
if (n < 0) {
|
||||||
|
123
protocol.c
123
protocol.c
@ -26,11 +26,8 @@
|
|||||||
#include "print.h"
|
#include "print.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include <math.h>
|
|
||||||
#include "nuts_bolts.h"
|
#include "nuts_bolts.h"
|
||||||
#include <avr/pgmspace.h>
|
|
||||||
#include "stepper.h"
|
#include "stepper.h"
|
||||||
#include "planner.h"
|
|
||||||
#include "report.h"
|
#include "report.h"
|
||||||
#include "motion_control.h"
|
#include "motion_control.h"
|
||||||
|
|
||||||
@ -43,8 +40,24 @@ void protocol_init()
|
|||||||
{
|
{
|
||||||
char_counter = 0; // Reset line input
|
char_counter = 0; // Reset line input
|
||||||
iscomment = false;
|
iscomment = false;
|
||||||
|
report_init_message(); // Welcome message
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Executes user startup script, if stored.
|
||||||
|
void protocol_execute_startup()
|
||||||
|
{
|
||||||
|
uint8_t n;
|
||||||
|
for (n=0; n < N_STARTUP_LINE; n++) {
|
||||||
|
if (!(settings_read_startup_line(n, line))) {
|
||||||
|
report_status_message(STATUS_SETTING_READ_FAIL);
|
||||||
|
} else {
|
||||||
|
if (line[0] != 0) {
|
||||||
|
printString(line); // Echo startup line to indicate execution.
|
||||||
|
report_status_message(gc_execute_line(line));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Executes run-time commands, when required. This is called from various check points in the main
|
// Executes run-time commands, when required. This is called from various check points in the main
|
||||||
// program, primarily where there may be a while loop waiting for a buffer to clear space or any
|
// program, primarily where there may be a while loop waiting for a buffer to clear space or any
|
||||||
@ -65,7 +78,16 @@ void protocol_execute_runtime()
|
|||||||
// System alarm. Something has gone wrong. Disable everything by entering an infinite
|
// System alarm. Something has gone wrong. Disable everything by entering an infinite
|
||||||
// loop until system reset/abort.
|
// loop until system reset/abort.
|
||||||
if (rt_exec & EXEC_ALARM) {
|
if (rt_exec & EXEC_ALARM) {
|
||||||
if (bit_isfalse(rt_exec,EXEC_RESET)) { // Ignore loop if reset is already issued
|
// Report the cause of the alarm here in the main program.
|
||||||
|
if (sys.state == STATE_LIMIT) { report_status_message(STATUS_HARD_LIMIT); }
|
||||||
|
if (sys.state == STATE_CYCLE) { // Pick up abort during active cycle.
|
||||||
|
report_status_message(STATUS_ABORT_CYCLE);
|
||||||
|
sys.state = STATE_LOST;
|
||||||
|
}
|
||||||
|
// Ignore loop if reset is already issued. In other words, a normal system abort/reset
|
||||||
|
// will not enter this loop, only a critical event not controlled by the user will.
|
||||||
|
if (bit_isfalse(rt_exec,EXEC_RESET)) {
|
||||||
|
sys.state = STATE_ALARM;
|
||||||
report_feedback_message(MESSAGE_SYSTEM_ALARM);
|
report_feedback_message(MESSAGE_SYSTEM_ALARM);
|
||||||
while (bit_isfalse(sys.execute,EXEC_RESET)) { sleep_mode(); }
|
while (bit_isfalse(sys.execute,EXEC_RESET)) { sleep_mode(); }
|
||||||
}
|
}
|
||||||
@ -75,14 +97,6 @@ void protocol_execute_runtime()
|
|||||||
// System abort. Steppers have already been force stopped.
|
// System abort. Steppers have already been force stopped.
|
||||||
if (rt_exec & EXEC_RESET) {
|
if (rt_exec & EXEC_RESET) {
|
||||||
sys.abort = true;
|
sys.abort = true;
|
||||||
|
|
||||||
// If the cycle is active before killing the motion, the event will likely caused a loss
|
|
||||||
// of position since there is no controlled deceleration(feed hold) to a stop.
|
|
||||||
// TODO: Add force home option upon position lost. Need to verify that cycle start isn't
|
|
||||||
// set false by anything but the stepper module. Also, need to look at a better place for
|
|
||||||
// this. Main.c?
|
|
||||||
// if (sys.cycle_start) { protocol_feedback_message(MESSAGE_POSITION_LOST); }
|
|
||||||
|
|
||||||
return; // Nothing else to do but exit.
|
return; // Nothing else to do but exit.
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -98,7 +112,7 @@ void protocol_execute_runtime()
|
|||||||
bit_false(sys.execute,EXEC_FEED_HOLD);
|
bit_false(sys.execute,EXEC_FEED_HOLD);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reinitializes the stepper module running flags and re-plans the buffer after a feed hold.
|
// Reinitializes the stepper module running state and, if a feed hold, re-plans the buffer.
|
||||||
// NOTE: EXEC_CYCLE_STOP is set by the stepper subsystem when a cycle or feed hold completes.
|
// NOTE: EXEC_CYCLE_STOP is set by the stepper subsystem when a cycle or feed hold completes.
|
||||||
if (rt_exec & EXEC_CYCLE_STOP) {
|
if (rt_exec & EXEC_CYCLE_STOP) {
|
||||||
st_cycle_reinitialize();
|
st_cycle_reinitialize();
|
||||||
@ -133,6 +147,7 @@ uint8_t protocol_execute_line(char *line)
|
|||||||
if(line[0] == '$') {
|
if(line[0] == '$') {
|
||||||
|
|
||||||
uint8_t char_counter = 1;
|
uint8_t char_counter = 1;
|
||||||
|
uint8_t helper_var = 0; // Helper variable
|
||||||
float parameter, value;
|
float parameter, value;
|
||||||
switch( line[char_counter] ) {
|
switch( line[char_counter] ) {
|
||||||
case 0 : report_grbl_help(); break;
|
case 0 : report_grbl_help(); break;
|
||||||
@ -149,8 +164,11 @@ uint8_t protocol_execute_line(char *line)
|
|||||||
else { report_gcode_modes(); }
|
else { report_gcode_modes(); }
|
||||||
break;
|
break;
|
||||||
case 'H' : // Perform homing cycle
|
case 'H' : // Perform homing cycle
|
||||||
if (bit_istrue(settings.flags,BITFLAG_HOMING_ENABLE)) { mc_go_home(); }
|
if (bit_istrue(settings.flags,BITFLAG_HOMING_ENABLE)) {
|
||||||
else { return(STATUS_SETTING_DISABLED); }
|
// Only perform homing if Grbl is idle or lost.
|
||||||
|
if ( sys.state==STATE_IDLE || sys.state==STATE_LOST ) { mc_go_home(); }
|
||||||
|
else { return(STATUS_HOMING_ERROR); }
|
||||||
|
} else { return(STATUS_SETTING_DISABLED); }
|
||||||
break;
|
break;
|
||||||
// case 'J' : break; // Jogging methods
|
// case 'J' : break; // Jogging methods
|
||||||
// TODO: Here jogging can be placed for execution as a seperate subprogram. It does not need to be
|
// TODO: Here jogging can be placed for execution as a seperate subprogram. It does not need to be
|
||||||
@ -164,42 +182,63 @@ uint8_t protocol_execute_line(char *line)
|
|||||||
// handled by the planner. It would be possible for the jog subprogram to insert blocks into the
|
// handled by the planner. It would be possible for the jog subprogram to insert blocks into the
|
||||||
// block buffer without having the planner plan them. It would need to manage de/ac-celerations
|
// block buffer without having the planner plan them. It would need to manage de/ac-celerations
|
||||||
// on its own carefully. This approach could be effective and possibly size/memory efficient.
|
// on its own carefully. This approach could be effective and possibly size/memory efficient.
|
||||||
// case 'N' : // Start up blocks
|
case 'S' : // Switch modes
|
||||||
// if(!read_float(line, &char_counter, ¶meter)) { return(STATUS_BAD_NUMBER_FORMAT); }
|
// Set helper_var as switch bitmask or clearing flag
|
||||||
// if(line[char_counter++] != '=') { return(STATUS_UNSUPPORTED_STATEMENT); }
|
switch (line[++char_counter]) {
|
||||||
// // Extract startup block, execute, and store.
|
case 0 : helper_var = 0; break;
|
||||||
// for (char_counter = 0; char_counter < LINE_BUFFER_SIZE-3; char_counter++) {
|
case '0' : helper_var = BITFLAG_CHECK_GCODE; break;
|
||||||
// line[char_counter] = line[char_counter+3];
|
case '1' : helper_var = BITFLAG_DRY_RUN; break;
|
||||||
// }
|
case '2' : helper_var = BITFLAG_BLOCK_DELETE; break;
|
||||||
// uint8_t status = gc_execute_line(line);
|
case '3' : helper_var = BITFLAG_SINGLE_BLOCK; break;
|
||||||
// if (status) { return(status); }
|
case '4' : helper_var = BITFLAG_OPT_STOP; break;
|
||||||
// else { settings_store_startup_block(line); }
|
default : return(STATUS_INVALID_STATEMENT);
|
||||||
// break;
|
}
|
||||||
case 'B' : // Toggle block delete
|
if (helper_var) {
|
||||||
if ( line[++char_counter] != 0 ) { return(STATUS_UNSUPPORTED_STATEMENT); }
|
if ( line[++char_counter] != 0 ) { return(STATUS_UNSUPPORTED_STATEMENT); }
|
||||||
sys.switches ^= BITFLAG_BLOCK_DELETE;
|
gc.switches ^= helper_var;
|
||||||
if (bit_istrue(sys.switches,BITFLAG_BLOCK_DELETE)) { report_feedback_message(MESSAGE_SWITCH_ON); }
|
if (bit_istrue(gc.switches,helper_var)) { report_feedback_message(MESSAGE_SWITCH_ON); }
|
||||||
else { report_feedback_message(MESSAGE_SWITCH_OFF); }
|
else { report_feedback_message(MESSAGE_SWITCH_OFF); }
|
||||||
|
} else {
|
||||||
|
gc.switches = helper_var; // Clear all switches
|
||||||
|
report_feedback_message(MESSAGE_SWITCHES_CLEARED);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 'S' : // Toggle single block mode
|
case 'N' : // Startup lines.
|
||||||
if ( line[++char_counter] != 0 ) { return(STATUS_UNSUPPORTED_STATEMENT); }
|
if ( line[++char_counter] == 0 ) { // Print startup lines
|
||||||
sys.switches ^= BITFLAG_SINGLE_BLOCK;
|
for (helper_var=0; helper_var < N_STARTUP_LINE; helper_var++) {
|
||||||
if (bit_istrue(sys.switches,BITFLAG_SINGLE_BLOCK)) { report_feedback_message(MESSAGE_SWITCH_ON); }
|
if (!(settings_read_startup_line(helper_var, line))) {
|
||||||
else { report_feedback_message(MESSAGE_SWITCH_OFF); }
|
report_status_message(STATUS_SETTING_READ_FAIL);
|
||||||
|
} else {
|
||||||
|
report_startup_line(helper_var,line);
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 'O' : // Toggle optional stop
|
} else { // Store startup line
|
||||||
if ( line[++char_counter] != 0 ) { return(STATUS_UNSUPPORTED_STATEMENT); }
|
helper_var = true; // Set helper_var to flag storing method.
|
||||||
sys.switches ^= BITFLAG_OPT_STOP;
|
// No break. Continues into default: to read remaining command characters.
|
||||||
if (bit_istrue(sys.switches,BITFLAG_OPT_STOP)) { report_feedback_message(MESSAGE_SWITCH_ON); }
|
}
|
||||||
else { report_feedback_message(MESSAGE_SWITCH_OFF); }
|
default : // Storing setting methods
|
||||||
break;
|
|
||||||
default : // Store global setting
|
|
||||||
if(!read_float(line, &char_counter, ¶meter)) { return(STATUS_BAD_NUMBER_FORMAT); }
|
if(!read_float(line, &char_counter, ¶meter)) { return(STATUS_BAD_NUMBER_FORMAT); }
|
||||||
if(line[char_counter++] != '=') { return(STATUS_UNSUPPORTED_STATEMENT); }
|
if(line[char_counter++] != '=') { return(STATUS_UNSUPPORTED_STATEMENT); }
|
||||||
|
if (helper_var) { // Store startup line
|
||||||
|
// Prepare sending gcode block to gcode parser by shifting all characters
|
||||||
|
helper_var = char_counter; // Set helper variable as counter to start of gcode block
|
||||||
|
do {
|
||||||
|
line[char_counter-helper_var] = line[char_counter];
|
||||||
|
} while (line[char_counter++] != 0);
|
||||||
|
// Execute gcode block to ensure block is valid.
|
||||||
|
helper_var = gc_execute_line(line); // Set helper_var to returned status code.
|
||||||
|
if (helper_var) { return(helper_var); }
|
||||||
|
else {
|
||||||
|
helper_var = trunc(parameter); // Set helper_var to int value of parameter
|
||||||
|
settings_store_startup_line(helper_var,line);
|
||||||
|
}
|
||||||
|
} else { // Store global setting.
|
||||||
if(!read_float(line, &char_counter, &value)) { return(STATUS_BAD_NUMBER_FORMAT); }
|
if(!read_float(line, &char_counter, &value)) { return(STATUS_BAD_NUMBER_FORMAT); }
|
||||||
if(line[char_counter] != 0) { return(STATUS_UNSUPPORTED_STATEMENT); }
|
if(line[char_counter] != 0) { return(STATUS_UNSUPPORTED_STATEMENT); }
|
||||||
return(settings_store_global_setting(parameter, value));
|
return(settings_store_global_setting(parameter, value));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return(STATUS_OK); // If '$' command makes it to here, then everything's ok.
|
return(STATUS_OK); // If '$' command makes it to here, then everything's ok.
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@ -249,7 +288,7 @@ void protocol_process()
|
|||||||
// Throw away whitepace and control characters
|
// Throw away whitepace and control characters
|
||||||
} else if (c == '/') {
|
} else if (c == '/') {
|
||||||
// Disable block delete and throw away characters. Will ignore until EOL.
|
// Disable block delete and throw away characters. Will ignore until EOL.
|
||||||
if (bit_istrue(sys.switches,BITFLAG_BLOCK_DELETE)) {
|
if (bit_istrue(gc.switches,BITFLAG_BLOCK_DELETE)) {
|
||||||
iscomment = true;
|
iscomment = true;
|
||||||
}
|
}
|
||||||
} else if (c == '(') {
|
} else if (c == '(') {
|
||||||
|
@ -21,6 +21,8 @@
|
|||||||
#ifndef protocol_h
|
#ifndef protocol_h
|
||||||
#define protocol_h
|
#define protocol_h
|
||||||
|
|
||||||
|
#include <avr/sleep.h>
|
||||||
|
|
||||||
// Line buffer size from the serial input stream to be executed.
|
// Line buffer size from the serial input stream to be executed.
|
||||||
// NOTE: Not a problem except for extreme cases, but the line buffer size can be too small
|
// NOTE: Not a problem except for extreme cases, but the line buffer size can be too small
|
||||||
// and g-code blocks can get truncated. Officially, the g-code standards support up to 256
|
// and g-code blocks can get truncated. Officially, the g-code standards support up to 256
|
||||||
@ -42,4 +44,7 @@ uint8_t protocol_execute_line(char *line);
|
|||||||
// Checks and executes a runtime command at various stop points in main program
|
// Checks and executes a runtime command at various stop points in main program
|
||||||
void protocol_execute_runtime();
|
void protocol_execute_runtime();
|
||||||
|
|
||||||
|
// Execute the startup script lines stored in EEPROM upon initialization
|
||||||
|
void protocol_execute_startup();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -9,25 +9,26 @@ It accepts standards-compliant G-code and has been tested with the output of sev
|
|||||||
Grbl includes full acceleration management with look ahead. That means the controller will look up to 18 motions into the future and plan its velocities ahead to deliver smooth acceleration and jerk-free cornering.
|
Grbl includes full acceleration management with look ahead. That means the controller will look up to 18 motions into the future and plan its velocities ahead to deliver smooth acceleration and jerk-free cornering.
|
||||||
|
|
||||||
*Changelog for v0.8 from v0.7:*
|
*Changelog for v0.8 from v0.7:*
|
||||||
- *BETA status: _Under development. Code state may significantly change with each push as new features are integrated._*
|
- *BETA status: _Under development but nearing completion. Code state may change with each push as new features are integrated or when bugs are squashed._*
|
||||||
- Major structural overhaul to allow for multi-tasking events and new feature sets
|
- Major structural overhaul to allow for multi-tasking events and new feature sets.
|
||||||
- New run-time command control: Feed hold (pause), Cycle start (resume), Reset (abort), Status reporting
|
- Run-time command control: Feed hold (pause), Cycle start (resume), Reset (abort), Status reporting
|
||||||
- Controlled feed hold with deceleration to ensure no skipped steps and loss of location.
|
- Controlled feed hold with deceleration to ensure no skipped steps and loss of location.
|
||||||
- After feed hold, cycle accelerations are re-planned and may be resumed.
|
- After feed hold, cycle accelerations are re-planned and may be resumed.
|
||||||
- Advanced homing cycle with direction and speed configuration options. (Requires limit switches.)
|
- Advanced homing cycle with direction and speed configuration options. (Requires limit switches.) When enabled, homing is required before use to ensure safety.
|
||||||
- Limit pins are held normal high with an internal pull-up resister. Wiring only requires a normally-open switch connected to ground. (For both ends of an axis, simply wire two in parallel into the same pin.)
|
- Limit pins are held normal high with internal pull-up resistors. Wiring only requires a normally-open switch connected to ground. (For both ends of an axis, simply wire two in parallel into the same pin.)
|
||||||
- Hard limits option and plays nice with homing cycle, so switches can be used for both homing and hard limits.
|
- Hard limits option and plays nice with homing cycle, so switches can be used for both homing and hard limits.
|
||||||
|
- New switch commands: Dry-run, block delete, single block mode, optional stop. A check g-code switch has also been added to allow users to error check their programs. This feature can also be used as a "program restart" by enabling the check g-code switch, begin streaming, and disable the check g-code switch at the desired point with minimal additional g-code.
|
||||||
- Re-factored g-code parser with robust error-checking.
|
- Re-factored g-code parser with robust error-checking.
|
||||||
- 6 work coordinate systems (G54-G59), offsets(G92), and machine coordinate system support. Work systems are stored in EEPROM and persistent.
|
- 6 work coordinate systems (G54-G59), offsets(G92), and machine coordinate system support. Work coordinate systems are stored in EEPROM and persistent.
|
||||||
- G10 L2 and L20 work coordinate settings support. L2 sets one or more axes values. L20 sets the current machine position to the specified work origin.
|
- G10 L2 and L20 work coordinate settings support. L2 sets one or more axes values. L20 sets the current machine position to the specified work origin.
|
||||||
- Program stop(M0,M1*,M2,M30) initial support. Optional stop to do.
|
- Program stop(M0,M1,M2,M30) initial support.
|
||||||
- Coolant control(M7*,M8,M9) support. (M7 is a compile-time option).
|
- Coolant control(M7*,M8,M9) support. (M7 is a compile-time option).
|
||||||
- System reset re-initializes grbl without resetting the Arduino and retains machine/home position and work coordinates.
|
- System reset re-initializes grbl without resetting the Arduino and retains machine/home position and work coordinates.
|
||||||
- Restructured planner and stepper modules to become independent and ready for future features.
|
- Settings overhauled and dozens of new settings and internal commands are now available, when most were compile-time only.
|
||||||
- Settings re-factoring to allow configuration without compiling of most features. (Still in progress).
|
- New startup line setting. Allows users to store a custom g-code block into Grbl's startup routine. Executes immediately upon startup or reset. May be used to set g-code defaults like G20.
|
||||||
- Misc bug fixes and removed deprecated acceleration enabled code.
|
- Misc bug fixes and removed deprecated acceleration enabled code.
|
||||||
- Planned features: Axis acceleration and max speed individual settings, full-featured status reporting, runtime settings such as toggling block delete.
|
- Planned features: Axis acceleration and max speed individual settings, full-featured status reporting.
|
||||||
- Advanced compile-time options: Up to 6 work coordinate systems(G54-G59), XON/XOFF flow control (limited support), direction and step pulse time delay.
|
- Advanced compile-time options: XON/XOFF flow control (limited support), direction and step pulse time delay, and up to 5 startup lines.
|
||||||
|
|
||||||
|
|
||||||
*Important note for Atmega 168 users:* Going forward, support for Atmega 168 will be dropped due to its limited memory and speed. However, legacy Grbl v0.51 "in the branch called 'v0_51' is still available for use.
|
*Important note for Atmega 168 users:* Going forward, support for Atmega 168 will be dropped due to its limited memory and speed. However, legacy Grbl v0.51 "in the branch called 'v0_51' is still available for use.
|
||||||
|
119
report.c
119
report.c
@ -26,14 +26,11 @@
|
|||||||
methods to accomodate their needs.
|
methods to accomodate their needs.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <avr/io.h>
|
|
||||||
#include "print.h"
|
|
||||||
#include "settings.h"
|
|
||||||
#include <math.h>
|
|
||||||
#include "nuts_bolts.h"
|
|
||||||
#include <avr/pgmspace.h>
|
#include <avr/pgmspace.h>
|
||||||
#include "report.h"
|
#include "report.h"
|
||||||
#include "protocol.h"
|
#include "print.h"
|
||||||
|
#include "settings.h"
|
||||||
|
#include "nuts_bolts.h"
|
||||||
#include "gcode.h"
|
#include "gcode.h"
|
||||||
#include "coolant_control.h"
|
#include "coolant_control.h"
|
||||||
|
|
||||||
@ -75,6 +72,10 @@ void report_status_message(uint8_t status_code)
|
|||||||
printPgmString(PSTR("Step pulse must be >= 3 microseconds")); break;
|
printPgmString(PSTR("Step pulse must be >= 3 microseconds")); break;
|
||||||
case STATUS_SETTING_READ_FAIL:
|
case STATUS_SETTING_READ_FAIL:
|
||||||
printPgmString(PSTR("Failed to read EEPROM settings. Using defaults")); break;
|
printPgmString(PSTR("Failed to read EEPROM settings. Using defaults")); break;
|
||||||
|
case STATUS_HOMING_ERROR:
|
||||||
|
printPgmString(PSTR("Grbl must be idle to home")); break;
|
||||||
|
case STATUS_ABORT_CYCLE:
|
||||||
|
printPgmString(PSTR("Abort during cycle")); break;
|
||||||
}
|
}
|
||||||
printPgmString(PSTR("\r\n"));
|
printPgmString(PSTR("\r\n"));
|
||||||
}
|
}
|
||||||
@ -84,49 +85,60 @@ void report_status_message(uint8_t status_code)
|
|||||||
// Prints feedback messages. This serves as a centralized method to provide additional
|
// Prints feedback messages. This serves as a centralized method to provide additional
|
||||||
// user feedback for things that are not of the status message response protocol. These
|
// user feedback for things that are not of the status message response protocol. These
|
||||||
// are messages such as setup warnings and how to exit alarms.
|
// are messages such as setup warnings and how to exit alarms.
|
||||||
// NOTE: For interfaces, messages are always placed within chevrons. And if silent mode
|
// NOTE: For interfaces, messages are always placed within brackets. And if silent mode
|
||||||
// is installed, the message number codes are less than zero.
|
// is installed, the message number codes are less than zero.
|
||||||
// TODO: Install silence feedback messages option in settings
|
// TODO: Install silence feedback messages option in settings
|
||||||
void report_feedback_message(int8_t message_code)
|
void report_feedback_message(int8_t message_code)
|
||||||
{
|
{
|
||||||
printPgmString(PSTR("<"));
|
printPgmString(PSTR("["));
|
||||||
switch(message_code) {
|
switch(message_code) {
|
||||||
case MESSAGE_SYSTEM_ALARM:
|
case MESSAGE_SYSTEM_ALARM:
|
||||||
printPgmString(PSTR("ALARM: Check and reset Grbl")); break;
|
printPgmString(PSTR("ALARM: Check and reset Grbl")); break;
|
||||||
case MESSAGE_POSITION_LOST:
|
case MESSAGE_POSITION_LOST:
|
||||||
printPgmString(PSTR("warning: Position may be lost")); break;
|
printPgmString(PSTR("Position unknown. '$H' to home")); break;
|
||||||
case MESSAGE_HOMING_ENABLE:
|
case MESSAGE_HOMING_ENABLE:
|
||||||
printPgmString(PSTR("'$H' to home. Ensure all limit switches are installed")); break;
|
printPgmString(PSTR("WARNING: All limit switches must be installed before homing")); break;
|
||||||
case MESSAGE_SWITCH_ON:
|
case MESSAGE_SWITCH_ON:
|
||||||
printPgmString(PSTR("Switch enabled")); break;
|
printPgmString(PSTR("Switch enabled")); break;
|
||||||
case MESSAGE_SWITCH_OFF:
|
case MESSAGE_SWITCH_OFF:
|
||||||
printPgmString(PSTR("Switch disabled")); break;
|
printPgmString(PSTR("Switch disabled")); break;
|
||||||
|
case MESSAGE_SWITCHES_CLEARED:
|
||||||
|
printPgmString(PSTR("Switches cleared")); break;
|
||||||
}
|
}
|
||||||
printPgmString(PSTR(">\r\n"));
|
printPgmString(PSTR("]\r\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Welcome message
|
// Welcome message
|
||||||
void report_init_message()
|
void report_init_message()
|
||||||
{
|
{
|
||||||
printPgmString(PSTR("\r\nGrbl " GRBL_VERSION " ['$' for help]\r\n"));
|
printPgmString(PSTR("\r\nGrbl " GRBL_VERSION " ['$' for help]\r\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Grbl help message
|
||||||
void report_grbl_help() {
|
void report_grbl_help() {
|
||||||
// char st_line[LINE_BUFFER_SIZE];
|
printPgmString(PSTR("$ (help)\r\n"
|
||||||
// printPgmString(PSTR("\r\n\r\n Startup\r\n$100 = ")); printString(settings_read_startup(st_line,0));
|
"$$ (print Grbl settings)\r\n"
|
||||||
// printPgmString(PSTR("\r\n$101 = ")); printString(settings_read_startup(st_line,1));
|
"$# (print gcode parameters)\r\n"
|
||||||
|
"$G (print gcode parser state)\r\n"
|
||||||
// char buf[4];
|
"$N (print startup blocks)\r\n"
|
||||||
// settings_startup_string((char *)buf);
|
"$x=value (store Grbl setting)\r\n"
|
||||||
// printPgmString(PSTR("\r\n Startup: ")); printString(buf);
|
"$Nx=line (store startup block)\r\n"
|
||||||
|
"$H (perform homing cycle)\r\n"
|
||||||
printPgmString(PSTR("$ (help)\r\n$$ (print Grbl settings)\r\n$# (print gcode parameters)\r\n$G (print gcode parser state)"));
|
"$S (clear all switches)\r\n"
|
||||||
printPgmString(PSTR("\r\n$x=value (store Grbl setting)\r\n$Nx=line (store startup block)\r\n$H (run homing cycle, if enabled)"));
|
"$S0 (toggle check gcode)\r\n"
|
||||||
printPgmString(PSTR("\r\n$B (toggle block delete)\r\n$S (toggle single block mode)\r\n$O (toggle opt stop)"));
|
"$S1 (toggle dry run)\r\n"
|
||||||
printPgmString(PSTR("\r\n~ (cycle start)\r\n! (feed hold)\r\n? (current position)\r\n^x (reset Grbl)\r\n"));
|
"$S2 (toggle block delete)\r\n"
|
||||||
|
"$S3 (toggle single block)\r\n"
|
||||||
|
"$S4 (toggle optional stop)\r\n"
|
||||||
|
"~ (cycle start)\r\n"
|
||||||
|
"! (feed hold)\r\n"
|
||||||
|
"? (current position)\r\n"
|
||||||
|
"^x (reset Grbl)\r\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Grbl global settings print out.
|
||||||
|
// NOTE: The numbering scheme here must correlate to storing in settings.c
|
||||||
void report_grbl_settings() {
|
void report_grbl_settings() {
|
||||||
printPgmString(PSTR("$0=")); printFloat(settings.steps_per_mm[X_AXIS]);
|
printPgmString(PSTR("$0=")); printFloat(settings.steps_per_mm[X_AXIS]);
|
||||||
printPgmString(PSTR(" (x axis, steps/mm)\r\n$1=")); printFloat(settings.steps_per_mm[Y_AXIS]);
|
printPgmString(PSTR(" (x axis, steps/mm)\r\n$1=")); printFloat(settings.steps_per_mm[Y_AXIS]);
|
||||||
@ -140,12 +152,12 @@ void report_grbl_settings() {
|
|||||||
printPgmString(PSTR(")\r\n$8=")); printFloat(settings.acceleration/(60*60)); // Convert from mm/min^2 for human readability
|
printPgmString(PSTR(")\r\n$8=")); printFloat(settings.acceleration/(60*60)); // Convert from mm/min^2 for human readability
|
||||||
printPgmString(PSTR(" (acceleration, mm/sec^2)\r\n$9=")); printFloat(settings.junction_deviation);
|
printPgmString(PSTR(" (acceleration, mm/sec^2)\r\n$9=")); printFloat(settings.junction_deviation);
|
||||||
printPgmString(PSTR(" (cornering junction deviation, mm)\r\n$10=")); printInteger(bit_istrue(settings.flags,BITFLAG_REPORT_INCHES));
|
printPgmString(PSTR(" (cornering junction deviation, mm)\r\n$10=")); printInteger(bit_istrue(settings.flags,BITFLAG_REPORT_INCHES));
|
||||||
printPgmString(PSTR(" (status report inches, bool)\r\n$11 = ")); printInteger(bit_istrue(settings.flags,BITFLAG_AUTO_START));
|
printPgmString(PSTR(" (report inches, bool)\r\n$11=")); printInteger(bit_istrue(settings.flags,BITFLAG_AUTO_START));
|
||||||
printPgmString(PSTR(" (auto start enable, bool)\r\n$12=")); printInteger(bit_istrue(settings.flags,BITFLAG_INVERT_ST_ENABLE));
|
printPgmString(PSTR(" (auto start enable, bool)\r\n$12=")); printInteger(bit_istrue(settings.flags,BITFLAG_INVERT_ST_ENABLE));
|
||||||
printPgmString(PSTR(" (invert stepper enable, bool)\r\n$13=")); printInteger(bit_istrue(settings.flags,BITFLAG_HARD_LIMIT_ENABLE));
|
printPgmString(PSTR(" (invert stepper enable, bool)\r\n$13=")); printInteger(bit_istrue(settings.flags,BITFLAG_HARD_LIMIT_ENABLE));
|
||||||
printPgmString(PSTR(" (hard limit enable, bool)\r\n$14=")); printInteger(bit_istrue(settings.flags,BITFLAG_HOMING_ENABLE));
|
printPgmString(PSTR(" (hard limit enable, bool)\r\n$14=")); printInteger(bit_istrue(settings.flags,BITFLAG_HOMING_ENABLE));
|
||||||
printPgmString(PSTR(" (homing enable, bool)\r\n$15=")); printInteger(settings.homing_dir_mask);
|
printPgmString(PSTR(" (homing enable, bool)\r\n$15=")); printInteger(settings.homing_dir_mask);
|
||||||
printPgmString(PSTR(" (homing direction mask, int:binary = ")); print_uint8_base2(settings.homing_dir_mask);
|
printPgmString(PSTR(" (homing dir invert mask, int:binary=")); print_uint8_base2(settings.homing_dir_mask);
|
||||||
printPgmString(PSTR(")\r\n$16=")); printFloat(settings.homing_feed_rate);
|
printPgmString(PSTR(")\r\n$16=")); printFloat(settings.homing_feed_rate);
|
||||||
printPgmString(PSTR(" (homing feed rate, mm/min)\r\n$17=")); printFloat(settings.homing_seek_rate);
|
printPgmString(PSTR(" (homing feed rate, mm/min)\r\n$17=")); printFloat(settings.homing_seek_rate);
|
||||||
printPgmString(PSTR(" (homing seek rate, mm/min)\r\n$18=")); printInteger(settings.homing_debounce_delay);
|
printPgmString(PSTR(" (homing seek rate, mm/min)\r\n$18=")); printInteger(settings.homing_debounce_delay);
|
||||||
@ -156,6 +168,8 @@ void report_grbl_settings() {
|
|||||||
printPgmString(PSTR(" (n arc correction, int)\r\n"));
|
printPgmString(PSTR(" (n arc correction, int)\r\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Prints gcode coordinate offset parameters
|
||||||
void report_gcode_parameters()
|
void report_gcode_parameters()
|
||||||
{
|
{
|
||||||
float coord_data[N_AXIS];
|
float coord_data[N_AXIS];
|
||||||
@ -174,7 +188,7 @@ void report_gcode_parameters()
|
|||||||
case 5: printPgmString(PSTR("G59")); break;
|
case 5: printPgmString(PSTR("G59")); break;
|
||||||
case 6: printPgmString(PSTR("G28")); break;
|
case 6: printPgmString(PSTR("G28")); break;
|
||||||
case 7: printPgmString(PSTR("G30")); break;
|
case 7: printPgmString(PSTR("G30")); break;
|
||||||
// case 8: printPgmString(PSTR("G92")); break; // G92.2, G92.3 currently not supported.
|
// case 8: printPgmString(PSTR("G92")); break; // G92.2, G92.3 not supported. Hence not stored.
|
||||||
}
|
}
|
||||||
printPgmString(PSTR(":["));
|
printPgmString(PSTR(":["));
|
||||||
for (i=0; i<N_AXIS; i++) {
|
for (i=0; i<N_AXIS; i++) {
|
||||||
@ -193,6 +207,8 @@ void report_gcode_parameters()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Print current gcode parser mode state and active switches
|
||||||
void report_gcode_modes()
|
void report_gcode_modes()
|
||||||
{
|
{
|
||||||
switch (gc.motion_mode) {
|
switch (gc.motion_mode) {
|
||||||
@ -220,8 +236,6 @@ void report_gcode_modes()
|
|||||||
if (gc.inverse_feed_rate_mode) { printPgmString(PSTR(" G93")); }
|
if (gc.inverse_feed_rate_mode) { printPgmString(PSTR(" G93")); }
|
||||||
else { printPgmString(PSTR(" G94")); }
|
else { printPgmString(PSTR(" G94")); }
|
||||||
|
|
||||||
// TODO: Check if G92 needs to be here. If so, how to track it.
|
|
||||||
|
|
||||||
switch (gc.program_flow) {
|
switch (gc.program_flow) {
|
||||||
case PROGRAM_FLOW_RUNNING : printPgmString(PSTR(" M0")); break;
|
case PROGRAM_FLOW_RUNNING : printPgmString(PSTR(" M0")); break;
|
||||||
case PROGRAM_FLOW_PAUSED : printPgmString(PSTR(" M1")); break;
|
case PROGRAM_FLOW_PAUSED : printPgmString(PSTR(" M1")); break;
|
||||||
@ -237,7 +251,9 @@ void report_gcode_modes()
|
|||||||
switch (gc.coolant_mode) {
|
switch (gc.coolant_mode) {
|
||||||
case COOLANT_DISABLE : printPgmString(PSTR(" M9")); break;
|
case COOLANT_DISABLE : printPgmString(PSTR(" M9")); break;
|
||||||
case COOLANT_FLOOD_ENABLE : printPgmString(PSTR(" M8")); break;
|
case COOLANT_FLOOD_ENABLE : printPgmString(PSTR(" M8")); break;
|
||||||
// case COOLANT_MIST_ENABLE : printPgmString(PSTR(" M7")); break;
|
#ifdef ENABLE_M7
|
||||||
|
case COOLANT_MIST_ENABLE : printPgmString(PSTR(" M7")); break;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
printPgmString(PSTR(" T"));
|
printPgmString(PSTR(" T"));
|
||||||
@ -247,36 +263,37 @@ void report_gcode_modes()
|
|||||||
if (gc.inches_mode) { printFloat(gc.feed_rate*INCH_PER_MM); }
|
if (gc.inches_mode) { printFloat(gc.feed_rate*INCH_PER_MM); }
|
||||||
else { printFloat(gc.feed_rate); }
|
else { printFloat(gc.feed_rate); }
|
||||||
|
|
||||||
if (sys.switches) {
|
// Print active switches
|
||||||
if (bit_istrue(sys.switches,BITFLAG_BLOCK_DELETE)) { printPgmString(PSTR(" $B")); }
|
if (gc.switches) {
|
||||||
if (bit_istrue(sys.switches,BITFLAG_SINGLE_BLOCK)) { printPgmString(PSTR(" $S")); }
|
if (bit_istrue(gc.switches,BITFLAG_CHECK_GCODE)) { printPgmString(PSTR(" $S0")); }
|
||||||
if (bit_istrue(sys.switches,BITFLAG_OPT_STOP)) { printPgmString(PSTR(" $O")); }
|
if (bit_istrue(gc.switches,BITFLAG_DRY_RUN)) { printPgmString(PSTR(" $S1")); }
|
||||||
|
if (bit_istrue(gc.switches,BITFLAG_BLOCK_DELETE)) { printPgmString(PSTR(" $S2")); }
|
||||||
|
if (bit_istrue(gc.switches,BITFLAG_SINGLE_BLOCK)) { printPgmString(PSTR(" $S3")); }
|
||||||
|
if (bit_istrue(gc.switches,BITFLAG_OPT_STOP)) { printPgmString(PSTR(" $S4")); }
|
||||||
}
|
}
|
||||||
|
|
||||||
printPgmString(PSTR("\r\n"));
|
printPgmString(PSTR("\r\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Prints specified startup line
|
||||||
|
void report_startup_line(uint8_t n, char *line)
|
||||||
|
{
|
||||||
|
printPgmString(PSTR("N")); printInteger(n);
|
||||||
|
printPgmString(PSTR("=")); printString(line);
|
||||||
|
printPgmString(PSTR("\r\n"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prints real-time data. This function grabs a real-time snapshot of the stepper subprogram
|
||||||
|
// and the actual location of the CNC machine. Users may change the following function to their
|
||||||
|
// specific needs, but the desired real-time data report must be as short as possible. This is
|
||||||
|
// requires as it minimizes the computational overhead and allows grbl to keep running smoothly,
|
||||||
|
// especially during g-code programs with fast, short line segments and high frequency reports (5-20Hz).
|
||||||
void report_realtime_status()
|
void report_realtime_status()
|
||||||
{
|
{
|
||||||
// TODO: Status report data is written to the user here. This function should be able to grab a
|
|
||||||
// real-time snapshot of the stepper subprogram and the actual location of the CNC machine. At a
|
|
||||||
// minimum, status report should return real-time location information. Other important information
|
|
||||||
// may be distance to go on block, processed block id, and feed rate. A secondary, non-critical
|
|
||||||
// status report may include g-code state, i.e. inch mode, plane mode, absolute mode, etc.
|
|
||||||
// The report generated must be as short as possible, yet still provide the user easily readable
|
|
||||||
// information, i.e. '[0.23,120.4,2.4]'. This is necessary as it minimizes the computational
|
|
||||||
// overhead and allows grbl to keep running smoothly, especially with g-code programs with fast,
|
|
||||||
// short line segments and interface setups that require real-time status reports (5-20Hz).
|
|
||||||
|
|
||||||
// **Under construction** Bare-bones status report. Provides real-time machine position relative to
|
// **Under construction** Bare-bones status report. Provides real-time machine position relative to
|
||||||
// the system power on location (0,0,0) and work coordinate position (G54 and G92 applied).
|
// the system power on location (0,0,0) and work coordinate position (G54 and G92 applied). Eventually
|
||||||
// The following are still needed: user setting of output units (mm|inch), compressed (non-human
|
// to be added are distance to go on block, processed block id, and feed rate. Also a settings bitmask
|
||||||
// readable) data for interfaces?, save last known position in EEPROM?, code optimizations, solidify
|
// for a user to select the desired real-time data.
|
||||||
// the reporting schemes, move to a separate .c file for easy user accessibility, and setting the
|
|
||||||
// home position by the user (likely through '$' setting interface).
|
|
||||||
// Successfully tested at a query rate of 10-20Hz while running a gauntlet of programs at various
|
|
||||||
// speeds.
|
|
||||||
uint8_t i;
|
uint8_t i;
|
||||||
int32_t current_position[3]; // Copy current state of the system position variable
|
int32_t current_position[3]; // Copy current state of the system position variable
|
||||||
memcpy(current_position,sys.position,sizeof(sys.position));
|
memcpy(current_position,sys.position,sizeof(sys.position));
|
||||||
|
8
report.h
8
report.h
@ -34,6 +34,8 @@
|
|||||||
#define STATUS_SETTING_VALUE_NEG 9
|
#define STATUS_SETTING_VALUE_NEG 9
|
||||||
#define STATUS_SETTING_STEP_PULSE_MIN 10
|
#define STATUS_SETTING_STEP_PULSE_MIN 10
|
||||||
#define STATUS_SETTING_READ_FAIL 11
|
#define STATUS_SETTING_READ_FAIL 11
|
||||||
|
#define STATUS_HOMING_ERROR 12
|
||||||
|
#define STATUS_ABORT_CYCLE 13
|
||||||
|
|
||||||
// Define Grbl feedback message codes. Less than zero to distinguish message from error.
|
// Define Grbl feedback message codes. Less than zero to distinguish message from error.
|
||||||
#define MESSAGE_SYSTEM_ALARM -1
|
#define MESSAGE_SYSTEM_ALARM -1
|
||||||
@ -41,6 +43,7 @@
|
|||||||
#define MESSAGE_HOMING_ENABLE -3
|
#define MESSAGE_HOMING_ENABLE -3
|
||||||
#define MESSAGE_SWITCH_ON -4
|
#define MESSAGE_SWITCH_ON -4
|
||||||
#define MESSAGE_SWITCH_OFF -5
|
#define MESSAGE_SWITCH_OFF -5
|
||||||
|
#define MESSAGE_SWITCHES_CLEARED -6
|
||||||
|
|
||||||
// Prints system status messages.
|
// Prints system status messages.
|
||||||
void report_status_message(uint8_t status_code);
|
void report_status_message(uint8_t status_code);
|
||||||
@ -54,6 +57,7 @@ void report_init_message();
|
|||||||
// Prints Grbl help and current global settings
|
// Prints Grbl help and current global settings
|
||||||
void report_grbl_help();
|
void report_grbl_help();
|
||||||
|
|
||||||
|
// Prints Grbl global settings
|
||||||
void report_grbl_settings();
|
void report_grbl_settings();
|
||||||
|
|
||||||
// Prints realtime status report
|
// Prints realtime status report
|
||||||
@ -62,6 +66,10 @@ void report_realtime_status();
|
|||||||
// Prints Grbl persistent coordinate parameters
|
// Prints Grbl persistent coordinate parameters
|
||||||
void report_gcode_parameters();
|
void report_gcode_parameters();
|
||||||
|
|
||||||
|
// Prints current g-code parser mode state and active switches
|
||||||
void report_gcode_modes();
|
void report_gcode_modes();
|
||||||
|
|
||||||
|
// Prints startup line
|
||||||
|
void report_startup_line(uint8_t n, char *line);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
13
serial.c
13
serial.c
@ -23,16 +23,11 @@
|
|||||||
used to be a part of the Arduino project. */
|
used to be a part of the Arduino project. */
|
||||||
|
|
||||||
#include <avr/interrupt.h>
|
#include <avr/interrupt.h>
|
||||||
#include <avr/sleep.h>
|
|
||||||
#include "serial.h"
|
#include "serial.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "motion_control.h"
|
#include "motion_control.h"
|
||||||
#include "nuts_bolts.h"
|
|
||||||
#include "protocol.h"
|
#include "protocol.h"
|
||||||
|
|
||||||
#define RX_BUFFER_SIZE 128
|
|
||||||
#define TX_BUFFER_SIZE 64
|
|
||||||
|
|
||||||
uint8_t rx_buffer[RX_BUFFER_SIZE];
|
uint8_t rx_buffer[RX_BUFFER_SIZE];
|
||||||
uint8_t rx_buffer_head = 0;
|
uint8_t rx_buffer_head = 0;
|
||||||
uint8_t rx_buffer_tail = 0;
|
uint8_t rx_buffer_tail = 0;
|
||||||
@ -42,14 +37,6 @@ uint8_t tx_buffer_head = 0;
|
|||||||
volatile uint8_t tx_buffer_tail = 0;
|
volatile uint8_t tx_buffer_tail = 0;
|
||||||
|
|
||||||
#ifdef ENABLE_XONXOFF
|
#ifdef ENABLE_XONXOFF
|
||||||
#define RX_BUFFER_FULL 96 // XOFF high watermark
|
|
||||||
#define RX_BUFFER_LOW 64 // XON low watermark
|
|
||||||
#define SEND_XOFF 1
|
|
||||||
#define SEND_XON 2
|
|
||||||
#define XOFF_SENT 3
|
|
||||||
#define XON_SENT 4
|
|
||||||
#define XOFF_CHAR 0x13
|
|
||||||
#define XON_CHAR 0x11
|
|
||||||
volatile uint8_t flow_ctrl = XON_SENT; // Flow control state variable
|
volatile uint8_t flow_ctrl = XON_SENT; // Flow control state variable
|
||||||
|
|
||||||
// Returns the number of bytes in the RX buffer. This replaces a typical byte counter to prevent
|
// Returns the number of bytes in the RX buffer. This replaces a typical byte counter to prevent
|
||||||
|
15
serial.h
15
serial.h
@ -25,8 +25,23 @@
|
|||||||
#ifndef serial_h
|
#ifndef serial_h
|
||||||
#define serial_h
|
#define serial_h
|
||||||
|
|
||||||
|
#include "nuts_bolts.h"
|
||||||
|
|
||||||
|
#define RX_BUFFER_SIZE 128
|
||||||
|
#define TX_BUFFER_SIZE 64
|
||||||
#define SERIAL_NO_DATA 0xff
|
#define SERIAL_NO_DATA 0xff
|
||||||
|
|
||||||
|
#ifdef ENABLE_XONXOFF
|
||||||
|
#define RX_BUFFER_FULL 96 // XOFF high watermark
|
||||||
|
#define RX_BUFFER_LOW 64 // XON low watermark
|
||||||
|
#define SEND_XOFF 1
|
||||||
|
#define SEND_XON 2
|
||||||
|
#define XOFF_SENT 3
|
||||||
|
#define XON_SENT 4
|
||||||
|
#define XOFF_CHAR 0x13
|
||||||
|
#define XON_CHAR 0x11
|
||||||
|
#endif
|
||||||
|
|
||||||
void serial_init(long baud);
|
void serial_init(long baud);
|
||||||
|
|
||||||
void serial_write(uint8_t data);
|
void serial_write(uint8_t data);
|
||||||
|
113
settings.c
113
settings.c
@ -20,15 +20,12 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <avr/io.h>
|
#include <avr/io.h>
|
||||||
#include <math.h>
|
#include "protocol.h"
|
||||||
|
#include "report.h"
|
||||||
|
#include "stepper.h"
|
||||||
#include "nuts_bolts.h"
|
#include "nuts_bolts.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
#include "eeprom.h"
|
#include "eeprom.h"
|
||||||
#include "print.h"
|
|
||||||
#include <avr/pgmspace.h>
|
|
||||||
#include "protocol.h"
|
|
||||||
#include "config.h"
|
|
||||||
#include "report.h"
|
|
||||||
|
|
||||||
settings_t settings;
|
settings_t settings;
|
||||||
|
|
||||||
@ -45,49 +42,29 @@ typedef struct {
|
|||||||
float junction_deviation;
|
float junction_deviation;
|
||||||
} settings_v4_t;
|
} settings_v4_t;
|
||||||
|
|
||||||
// Default settings (used when resetting eeprom-settings)
|
|
||||||
#define MICROSTEPS 8
|
|
||||||
#define DEFAULT_X_STEPS_PER_MM (94.488188976378*MICROSTEPS)
|
|
||||||
#define DEFAULT_Y_STEPS_PER_MM (94.488188976378*MICROSTEPS)
|
|
||||||
#define DEFAULT_Z_STEPS_PER_MM (94.488188976378*MICROSTEPS)
|
|
||||||
#define DEFAULT_STEP_PULSE_MICROSECONDS 30
|
|
||||||
#define DEFAULT_MM_PER_ARC_SEGMENT 0.1
|
|
||||||
#define DEFAULT_RAPID_FEEDRATE 500.0 // mm/min
|
|
||||||
#define DEFAULT_FEEDRATE 500.0
|
|
||||||
#define DEFAULT_ACCELERATION (DEFAULT_FEEDRATE*60*60/10.0) // mm/min^2
|
|
||||||
#define DEFAULT_JUNCTION_DEVIATION 0.05 // mm
|
|
||||||
#define DEFAULT_STEPPING_INVERT_MASK ((1<<X_STEP_BIT)|(1<<Y_STEP_BIT)|(1<<Z_STEP_BIT))
|
|
||||||
|
|
||||||
// Developmental default settings
|
|
||||||
#define DEFAULT_REPORT_INCHES 0 // false
|
|
||||||
#define DEFAULT_AUTO_START 1 // true
|
|
||||||
#define DEFAULT_INVERT_ST_ENABLE 0 // false
|
|
||||||
#define DEFAULT_HARD_LIMIT_ENABLE 0 // false
|
|
||||||
#define DEFAULT_HOMING_ENABLE 0 // false
|
|
||||||
#define DEFAULT_HOMING_DIR_MASK 0 // move positive dir
|
|
||||||
#define DEFAULT_HOMING_RAPID_FEEDRATE 250.0 // mm/min
|
|
||||||
#define DEFAULT_HOMING_FEEDRATE 50 // mm/min
|
|
||||||
#define DEFAULT_HOMING_DEBOUNCE_DELAY 100 // msec (0-65k)
|
|
||||||
#define DEFAULT_HOMING_PULLOFF 1 // mm
|
|
||||||
#define DEFAULT_STEPPER_IDLE_LOCK_TIME 25 // msec (0-255)
|
|
||||||
#define DEFAULT_DECIMAL_PLACES 3
|
|
||||||
#define DEFAULT_N_ARC_CORRECTION 25
|
|
||||||
|
|
||||||
|
// Method to store startup lines into EEPROM
|
||||||
|
void settings_store_startup_line(uint8_t n, char *line)
|
||||||
|
{
|
||||||
|
uint16_t addr = n*(LINE_BUFFER_SIZE+1)+EEPROM_ADDR_STARTUP_BLOCK;
|
||||||
|
memcpy_to_eeprom_with_checksum(addr,(char*)line, LINE_BUFFER_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Method to store coord data parameters into EEPROM
|
||||||
void settings_write_coord_data(uint8_t coord_select, float *coord_data)
|
void settings_write_coord_data(uint8_t coord_select, float *coord_data)
|
||||||
{
|
{
|
||||||
uint16_t addr = coord_select*(sizeof(float)*N_AXIS+1) + EEPROM_ADDR_PARAMETERS;
|
uint16_t addr = coord_select*(sizeof(float)*N_AXIS+1) + EEPROM_ADDR_PARAMETERS;
|
||||||
memcpy_to_eeprom_with_checksum(addr,(char*)coord_data, sizeof(float)*N_AXIS);
|
memcpy_to_eeprom_with_checksum(addr,(char*)coord_data, sizeof(float)*N_AXIS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Method to store Grbl global settings struct and version number into EEPROM
|
||||||
void write_global_settings()
|
void write_global_settings()
|
||||||
{
|
{
|
||||||
eeprom_put_char(0, SETTINGS_VERSION);
|
eeprom_put_char(0, SETTINGS_VERSION);
|
||||||
memcpy_to_eeprom_with_checksum(EEPROM_ADDR_GLOBAL, (char*)&settings, sizeof(settings_t));
|
memcpy_to_eeprom_with_checksum(EEPROM_ADDR_GLOBAL, (char*)&settings, sizeof(settings_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Method to reset Grbl global settings back to defaults.
|
||||||
void settings_reset(bool reset_all) {
|
void settings_reset(bool reset_all) {
|
||||||
// Reset all settings or only the migration settings to the new version.
|
// Reset all settings or only the migration settings to the new version.
|
||||||
if (reset_all) {
|
if (reset_all) {
|
||||||
@ -118,13 +95,20 @@ void settings_reset(bool reset_all) {
|
|||||||
settings.decimal_places = DEFAULT_DECIMAL_PLACES;
|
settings.decimal_places = DEFAULT_DECIMAL_PLACES;
|
||||||
settings.n_arc_correction = DEFAULT_N_ARC_CORRECTION;
|
settings.n_arc_correction = DEFAULT_N_ARC_CORRECTION;
|
||||||
write_global_settings();
|
write_global_settings();
|
||||||
|
}
|
||||||
|
|
||||||
// Zero all coordinate parameter data.
|
// Reads startup line from EEPROM. Updated pointed line string data.
|
||||||
float coord_data[N_AXIS];
|
uint8_t settings_read_startup_line(uint8_t n, char *line)
|
||||||
clear_vector_float(coord_data);
|
{
|
||||||
uint8_t i = 0;
|
uint16_t addr = n*(LINE_BUFFER_SIZE+1)+EEPROM_ADDR_STARTUP_BLOCK;
|
||||||
for (i=0; i<=SETTING_INDEX_NCOORD; i++) {
|
if (!(memcpy_from_eeprom_with_checksum((char*)line, addr, LINE_BUFFER_SIZE))) {
|
||||||
settings_write_coord_data(i,coord_data);
|
// Reset line with default value
|
||||||
|
// TODO: Need to come up with a method to do this.
|
||||||
|
line[0] = 0;
|
||||||
|
settings_store_startup_line(n, line);
|
||||||
|
return(false);
|
||||||
|
} else {
|
||||||
|
return(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -132,8 +116,9 @@ void settings_reset(bool reset_all) {
|
|||||||
uint8_t settings_read_coord_data(uint8_t coord_select, float *coord_data)
|
uint8_t settings_read_coord_data(uint8_t coord_select, float *coord_data)
|
||||||
{
|
{
|
||||||
uint16_t addr = coord_select*(sizeof(float)*N_AXIS+1) + EEPROM_ADDR_PARAMETERS;
|
uint16_t addr = coord_select*(sizeof(float)*N_AXIS+1) + EEPROM_ADDR_PARAMETERS;
|
||||||
if ((!memcpy_from_eeprom_with_checksum((char*)coord_data, addr, sizeof(float)*N_AXIS))) {
|
if (!(memcpy_from_eeprom_with_checksum((char*)coord_data, addr, sizeof(float)*N_AXIS))) {
|
||||||
clear_vector_float(coord_data); // Default zero vector
|
// Reset with default zero vector
|
||||||
|
clear_vector_float(coord_data);
|
||||||
settings_write_coord_data(coord_select,coord_data);
|
settings_write_coord_data(coord_select,coord_data);
|
||||||
return(false);
|
return(false);
|
||||||
} else {
|
} else {
|
||||||
@ -141,7 +126,7 @@ uint8_t settings_read_coord_data(uint8_t coord_select, float *coord_data)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Reads Grbl global settings struct from EEPROM.
|
||||||
uint8_t read_global_settings() {
|
uint8_t read_global_settings() {
|
||||||
// Check version-byte of eeprom
|
// Check version-byte of eeprom
|
||||||
uint8_t version = eeprom_get_char(0);
|
uint8_t version = eeprom_get_char(0);
|
||||||
@ -164,7 +149,7 @@ uint8_t read_global_settings() {
|
|||||||
// should be re-written to the default value, if the developmental version number changed.
|
// should be re-written to the default value, if the developmental version number changed.
|
||||||
|
|
||||||
// Grab settings regardless of error.
|
// Grab settings regardless of error.
|
||||||
memcpy_from_eeprom_with_checksum((char*)&settings, 1, sizeof(settings_t));
|
memcpy_from_eeprom_with_checksum((char*)&settings, EEPROM_ADDR_GLOBAL, sizeof(settings_t));
|
||||||
settings_reset(false);
|
settings_reset(false);
|
||||||
} else {
|
} else {
|
||||||
return(false);
|
return(false);
|
||||||
@ -195,9 +180,14 @@ uint8_t settings_store_global_setting(int parameter, float value) {
|
|||||||
} else { settings.flags &= ~BITFLAG_REPORT_INCHES; }
|
} else { settings.flags &= ~BITFLAG_REPORT_INCHES; }
|
||||||
break;
|
break;
|
||||||
case 11:
|
case 11:
|
||||||
|
// Immediately apply auto_start to sys struct.
|
||||||
if (value) {
|
if (value) {
|
||||||
settings.flags |= BITFLAG_AUTO_START;
|
settings.flags |= BITFLAG_AUTO_START;
|
||||||
} else { settings.flags &= ~BITFLAG_AUTO_START; }
|
sys.auto_start = true;
|
||||||
|
} else {
|
||||||
|
settings.flags &= ~BITFLAG_AUTO_START;
|
||||||
|
sys.auto_start = false;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 12:
|
case 12:
|
||||||
if (value) {
|
if (value) {
|
||||||
@ -212,6 +202,8 @@ uint8_t settings_store_global_setting(int parameter, float value) {
|
|||||||
case 14:
|
case 14:
|
||||||
if (value) {
|
if (value) {
|
||||||
settings.flags |= BITFLAG_HOMING_ENABLE;
|
settings.flags |= BITFLAG_HOMING_ENABLE;
|
||||||
|
sys.state = STATE_LOST;
|
||||||
|
report_feedback_message(MESSAGE_POSITION_LOST);
|
||||||
report_feedback_message(MESSAGE_HOMING_ENABLE);
|
report_feedback_message(MESSAGE_HOMING_ENABLE);
|
||||||
} else { settings.flags &= ~BITFLAG_HOMING_ENABLE; }
|
} else { settings.flags &= ~BITFLAG_HOMING_ENABLE; }
|
||||||
break;
|
break;
|
||||||
@ -224,7 +216,12 @@ uint8_t settings_store_global_setting(int parameter, float value) {
|
|||||||
settings.homing_pulloff = value; break;
|
settings.homing_pulloff = value; break;
|
||||||
case 20:
|
case 20:
|
||||||
settings.stepper_idle_lock_time = round(value);
|
settings.stepper_idle_lock_time = round(value);
|
||||||
// TODO: Immediately check and toggle steppers from always enable or disable?
|
// Immediately toggle stepper enable/disable functions to ensure change from always
|
||||||
|
// enable or disable. Will not start or stop a cycle.
|
||||||
|
if (!sys.state) { // Only if idle.
|
||||||
|
st_wake_up();
|
||||||
|
st_go_idle();
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 21: settings.decimal_places = round(value); break;
|
case 21: settings.decimal_places = round(value); break;
|
||||||
case 22: settings.n_arc_correction = round(value); break;
|
case 22: settings.n_arc_correction = round(value); break;
|
||||||
@ -240,17 +237,15 @@ void settings_init() {
|
|||||||
if(!read_global_settings()) {
|
if(!read_global_settings()) {
|
||||||
report_status_message(STATUS_SETTING_READ_FAIL);
|
report_status_message(STATUS_SETTING_READ_FAIL);
|
||||||
settings_reset(true);
|
settings_reset(true);
|
||||||
report_grbl_help();
|
report_grbl_settings();
|
||||||
|
}
|
||||||
|
// Read all parameter data into a dummy variable. If error, reset to zero, otherwise do nothing.
|
||||||
|
float coord_data[N_AXIS];
|
||||||
|
uint8_t i;
|
||||||
|
for (i=0; i<=SETTING_INDEX_NCOORD; i++) {
|
||||||
|
if (!settings_read_coord_data(i, coord_data)) {
|
||||||
|
report_status_message(STATUS_SETTING_READ_FAIL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// NOTE: Startup lines are handled and called by protocol_init().
|
||||||
// int8_t settings_execute_startup() {
|
}
|
||||||
//
|
|
||||||
// char buf[4];
|
|
||||||
// settings_startup_string((char *)buf);
|
|
||||||
// uint8_t i = 0;
|
|
||||||
// while (i < 4) {
|
|
||||||
// serial_write(buf[i++]);
|
|
||||||
// }
|
|
||||||
// return(gc_execute_line(buf));
|
|
||||||
// }
|
|
||||||
|
11
settings.h
11
settings.h
@ -23,7 +23,6 @@
|
|||||||
#define settings_h
|
#define settings_h
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <inttypes.h>
|
|
||||||
#include "nuts_bolts.h"
|
#include "nuts_bolts.h"
|
||||||
|
|
||||||
#define GRBL_VERSION "0.8c"
|
#define GRBL_VERSION "0.8c"
|
||||||
@ -45,7 +44,7 @@
|
|||||||
// developments.
|
// developments.
|
||||||
#define EEPROM_ADDR_GLOBAL 1
|
#define EEPROM_ADDR_GLOBAL 1
|
||||||
#define EEPROM_ADDR_PARAMETERS 512
|
#define EEPROM_ADDR_PARAMETERS 512
|
||||||
#define EEPROM_ADDR_STARTUP_SCRIPT 768
|
#define EEPROM_ADDR_STARTUP_BLOCK 768
|
||||||
|
|
||||||
// Define EEPROM address indexing for coordinate parameters
|
// Define EEPROM address indexing for coordinate parameters
|
||||||
#define N_COORDINATE_SYSTEM 6 // Number of supported work coordinate systems (from index 1)
|
#define N_COORDINATE_SYSTEM 6 // Number of supported work coordinate systems (from index 1)
|
||||||
@ -85,12 +84,16 @@ void settings_init();
|
|||||||
// A helper method to set new settings from command line
|
// A helper method to set new settings from command line
|
||||||
uint8_t settings_store_global_setting(int parameter, float value);
|
uint8_t settings_store_global_setting(int parameter, float value);
|
||||||
|
|
||||||
|
// Stores the protocol line variable as a startup line in EEPROM
|
||||||
|
void settings_store_startup_line(uint8_t n, char *line);
|
||||||
|
|
||||||
|
// Reads an EEPROM startup line to the protocol line variable
|
||||||
|
uint8_t settings_read_startup_line(uint8_t n, char *line);
|
||||||
|
|
||||||
// Writes selected coordinate data to EEPROM
|
// Writes selected coordinate data to EEPROM
|
||||||
void settings_write_coord_data(uint8_t coord_select, float *coord_data);
|
void settings_write_coord_data(uint8_t coord_select, float *coord_data);
|
||||||
|
|
||||||
// Reads selected coordinate data from EEPROM
|
// Reads selected coordinate data from EEPROM
|
||||||
uint8_t settings_read_coord_data(uint8_t coord_select, float *coord_data);
|
uint8_t settings_read_coord_data(uint8_t coord_select, float *coord_data);
|
||||||
|
|
||||||
// int8_t settings_execute_startup();
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -19,14 +19,9 @@
|
|||||||
along with Grbl. If not, see <http://www.gnu.org/licenses/>.
|
along with Grbl. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "spindle_control.h"
|
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
#include "motion_control.h"
|
#include "spindle_control.h"
|
||||||
#include "config.h"
|
|
||||||
#include "planner.h"
|
#include "planner.h"
|
||||||
#include "stepper.h"
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
static uint8_t current_direction;
|
static uint8_t current_direction;
|
||||||
|
|
||||||
|
35
stepper.c
35
stepper.c
@ -22,19 +22,12 @@
|
|||||||
/* The timer calculations of this module informed by the 'RepRap cartesian firmware' by Zack Smith
|
/* The timer calculations of this module informed by the 'RepRap cartesian firmware' by Zack Smith
|
||||||
and Philipp Tiefenbacher. */
|
and Philipp Tiefenbacher. */
|
||||||
|
|
||||||
|
#include <avr/interrupt.h>
|
||||||
#include "stepper.h"
|
#include "stepper.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
#include <math.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <util/delay.h>
|
|
||||||
#include "nuts_bolts.h"
|
|
||||||
#include <avr/interrupt.h>
|
|
||||||
#include "planner.h"
|
#include "planner.h"
|
||||||
|
|
||||||
// Some useful constants
|
|
||||||
#define TICKS_PER_MICROSECOND (F_CPU/1000000)
|
|
||||||
#define CYCLES_PER_ACCELERATION_TICK ((TICKS_PER_MICROSECOND*1000000)/ACCELERATION_TICKS_PER_SECOND)
|
|
||||||
|
|
||||||
// Stepper state variable. Contains running data and trapezoid variables.
|
// Stepper state variable. Contains running data and trapezoid variables.
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -94,7 +87,7 @@ void st_wake_up()
|
|||||||
} else {
|
} else {
|
||||||
STEPPERS_DISABLE_PORT &= ~(1<<STEPPERS_DISABLE_BIT);
|
STEPPERS_DISABLE_PORT &= ~(1<<STEPPERS_DISABLE_BIT);
|
||||||
}
|
}
|
||||||
if (sys.cycle_start) {
|
if (sys.state == STATE_CYCLE) {
|
||||||
// Initialize stepper output bits
|
// Initialize stepper output bits
|
||||||
out_bits = (0) ^ (settings.invert_mask);
|
out_bits = (0) ^ (settings.invert_mask);
|
||||||
// Initialize step pulse timing from settings. Here to ensure updating after re-writing.
|
// Initialize step pulse timing from settings. Here to ensure updating after re-writing.
|
||||||
@ -176,7 +169,7 @@ ISR(TIMER1_COMPA_vect)
|
|||||||
// Anything in the buffer? If so, initialize next motion.
|
// Anything in the buffer? If so, initialize next motion.
|
||||||
current_block = plan_get_current_block();
|
current_block = plan_get_current_block();
|
||||||
if (current_block != NULL) {
|
if (current_block != NULL) {
|
||||||
if (!sys.feed_hold) {
|
if (sys.state == STATE_CYCLE) {
|
||||||
// During feed hold, do not update rate and trap counter. Keep decelerating.
|
// During feed hold, do not update rate and trap counter. Keep decelerating.
|
||||||
st.trapezoid_adjusted_rate = current_block->initial_rate;
|
st.trapezoid_adjusted_rate = current_block->initial_rate;
|
||||||
set_step_events_per_minute(st.trapezoid_adjusted_rate); // Initialize cycles_per_step_event
|
set_step_events_per_minute(st.trapezoid_adjusted_rate); // Initialize cycles_per_step_event
|
||||||
@ -190,7 +183,6 @@ ISR(TIMER1_COMPA_vect)
|
|||||||
st.step_events_completed = 0;
|
st.step_events_completed = 0;
|
||||||
} else {
|
} else {
|
||||||
st_go_idle();
|
st_go_idle();
|
||||||
sys.cycle_start = false;
|
|
||||||
bit_true(sys.execute,EXEC_CYCLE_STOP); // Flag main program for cycle end
|
bit_true(sys.execute,EXEC_CYCLE_STOP); // Flag main program for cycle end
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -224,7 +216,7 @@ ISR(TIMER1_COMPA_vect)
|
|||||||
|
|
||||||
// While in block steps, check for de/ac-celeration events and execute them accordingly.
|
// While in block steps, check for de/ac-celeration events and execute them accordingly.
|
||||||
if (st.step_events_completed < current_block->step_event_count) {
|
if (st.step_events_completed < current_block->step_event_count) {
|
||||||
if (sys.feed_hold) {
|
if (sys.state == STATE_HOLD) {
|
||||||
// Check for and execute feed hold by enforcing a steady deceleration from the moment of
|
// Check for and execute feed hold by enforcing a steady deceleration from the moment of
|
||||||
// execution. The rate of deceleration is limited by rate_delta and will never decelerate
|
// execution. The rate of deceleration is limited by rate_delta and will never decelerate
|
||||||
// faster or slower than in normal operation. If the distance required for the feed hold
|
// faster or slower than in normal operation. If the distance required for the feed hold
|
||||||
@ -240,7 +232,6 @@ ISR(TIMER1_COMPA_vect)
|
|||||||
// remain intact to ensure the stepper path is exactly the same. Feed hold is still
|
// remain intact to ensure the stepper path is exactly the same. Feed hold is still
|
||||||
// active and is released after the buffer has been reinitialized.
|
// active and is released after the buffer has been reinitialized.
|
||||||
st_go_idle();
|
st_go_idle();
|
||||||
sys.cycle_start = false;
|
|
||||||
bit_true(sys.execute,EXEC_CYCLE_STOP); // Flag main program that feed hold is complete.
|
bit_true(sys.execute,EXEC_CYCLE_STOP); // Flag main program that feed hold is complete.
|
||||||
} else {
|
} else {
|
||||||
st.trapezoid_adjusted_rate -= current_block->rate_delta;
|
st.trapezoid_adjusted_rate -= current_block->rate_delta;
|
||||||
@ -430,24 +421,18 @@ static void set_step_events_per_minute(uint32_t steps_per_minute)
|
|||||||
// variable will manage all of Grbl's processes and keep them separate.
|
// variable will manage all of Grbl's processes and keep them separate.
|
||||||
void st_cycle_start()
|
void st_cycle_start()
|
||||||
{
|
{
|
||||||
if (!sys.cycle_start) {
|
if (sys.state == STATE_QUEUED) {
|
||||||
if (!sys.feed_hold) {
|
sys.state = STATE_CYCLE;
|
||||||
if (bit_isfalse(sys.execute,EXEC_ALARM)) {
|
|
||||||
sys.cycle_start = true; // Only place this variable is set true.
|
|
||||||
st_wake_up();
|
st_wake_up();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Execute a feed hold with deceleration, only during cycle. Called by main program.
|
// Execute a feed hold with deceleration, only during cycle. Called by main program.
|
||||||
void st_feed_hold()
|
void st_feed_hold()
|
||||||
{
|
{
|
||||||
if (!sys.feed_hold) {
|
if (sys.state == STATE_CYCLE) {
|
||||||
if (sys.cycle_start) {
|
sys.state = STATE_HOLD;
|
||||||
sys.auto_start = false; // Disable planner auto start upon feed hold.
|
sys.auto_start = false; // Disable planner auto start upon feed hold.
|
||||||
sys.feed_hold = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -466,6 +451,8 @@ void st_cycle_reinitialize()
|
|||||||
set_step_events_per_minute(st.trapezoid_adjusted_rate);
|
set_step_events_per_minute(st.trapezoid_adjusted_rate);
|
||||||
st.trapezoid_tick_cycle_counter = CYCLES_PER_ACCELERATION_TICK/2; // Start halfway for midpoint rule.
|
st.trapezoid_tick_cycle_counter = CYCLES_PER_ACCELERATION_TICK/2; // Start halfway for midpoint rule.
|
||||||
st.step_events_completed = 0;
|
st.step_events_completed = 0;
|
||||||
|
sys.state = STATE_QUEUED;
|
||||||
|
} else {
|
||||||
|
sys.state = STATE_IDLE;
|
||||||
}
|
}
|
||||||
sys.feed_hold = false; // Release feed hold. Cycle is ready to re-start.
|
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,6 @@
|
|||||||
#define stepper_h
|
#define stepper_h
|
||||||
|
|
||||||
#include <avr/io.h>
|
#include <avr/io.h>
|
||||||
#include <avr/sleep.h>
|
|
||||||
|
|
||||||
// Some useful constants
|
// Some useful constants
|
||||||
#define STEP_MASK ((1<<X_STEP_BIT)|(1<<Y_STEP_BIT)|(1<<Z_STEP_BIT)) // All step bits
|
#define STEP_MASK ((1<<X_STEP_BIT)|(1<<Y_STEP_BIT)|(1<<Z_STEP_BIT)) // All step bits
|
||||||
@ -31,6 +30,10 @@
|
|||||||
#define STEPPING_MASK (STEP_MASK | DIRECTION_MASK) // All stepping-related bits (step/direction)
|
#define STEPPING_MASK (STEP_MASK | DIRECTION_MASK) // All stepping-related bits (step/direction)
|
||||||
#define STEPPERS_DISABLE_MASK (1<<STEPPERS_DISABLE_BIT)
|
#define STEPPERS_DISABLE_MASK (1<<STEPPERS_DISABLE_BIT)
|
||||||
|
|
||||||
|
#define TICKS_PER_MICROSECOND (F_CPU/1000000)
|
||||||
|
#define CYCLES_PER_ACCELERATION_TICK ((TICKS_PER_MICROSECOND*1000000)/ACCELERATION_TICKS_PER_SECOND)
|
||||||
|
|
||||||
|
|
||||||
// Initialize and setup the stepper motor subsystem
|
// Initialize and setup the stepper motor subsystem
|
||||||
void st_init();
|
void st_init();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user