├── .gitignore
├── README.md
├── TODO
├── lib
├── grbl
│ └── src
│ │ ├── config.hpp
│ │ ├── coolant_control.cpp
│ │ ├── coolant_control.hpp
│ │ ├── cpu_map.hpp
│ │ ├── credentials.hpp
│ │ ├── defaults.hpp
│ │ ├── eeprom.cpp
│ │ ├── eeprom.hpp
│ │ ├── gcode.cpp
│ │ ├── gcode.hpp
│ │ ├── grbl.hpp
│ │ ├── jog.cpp
│ │ ├── jog.hpp
│ │ ├── limits.cpp
│ │ ├── limits.hpp
│ │ ├── motion_control.cpp
│ │ ├── motion_control.hpp
│ │ ├── nuts_bolts.cpp
│ │ ├── nuts_bolts.hpp
│ │ ├── planner.cpp
│ │ ├── planner.hpp
│ │ ├── print.cpp
│ │ ├── print.hpp
│ │ ├── probe.cpp
│ │ ├── probe.hpp
│ │ ├── protocol.cpp
│ │ ├── protocol.hpp
│ │ ├── report.cpp
│ │ ├── report.hpp
│ │ ├── serial.cpp
│ │ ├── serial.hpp
│ │ ├── serial2socket.cpp
│ │ ├── serial2socket.hpp
│ │ ├── settings.cpp
│ │ ├── settings.hpp
│ │ ├── spindle_control.cpp
│ │ ├── spindle_control.hpp
│ │ ├── stepper.cpp
│ │ ├── stepper.hpp
│ │ ├── system.cpp
│ │ ├── system.hpp
│ │ ├── telnet_server.cpp
│ │ ├── telnet_server.hpp
│ │ ├── websocket.cpp
│ │ ├── websocket.hpp
│ │ ├── wifi.cpp
│ │ └── wifi.hpp
└── readme.txt
├── platformio.ini
├── schemas
├── spi-connection.fzz
└── spi-connection_schem.png
└── src
└── main.cpp
/.gitignore:
--------------------------------------------------------------------------------
1 | .pioenvs
2 | .piolibdeps
3 | .clang_complete
4 | .gcc-flags.json
5 | **/credentials.hpp
6 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # GRBLESP
2 |
3 | Implements the latest version of GRBL using ESP8266 only, being able to connect by serial port, raw socket or websocket.
4 | To overcome the problem of the lack of pins, it uses SPI to drive 4 shift registers of 8 bits each. The aim of having
5 | 32 pins is to be able to handle up to 8 axis.
6 |
7 | Interfaces
8 | ----------
9 |
10 | For the raw socket connection, you can use pyserial, which supports it through "socket" protocol.
11 | **socket://[IP_OF_ESP_DEVICE]:23**. It can be tested easily with [bCNC](https://github.com/vlachoudis/bCNC)
12 |
13 |
14 | For the websocket connection, the url is: **ws://[IP_OF_ESP_DEVICE]:80/ws**
15 |
16 |
17 | Wiring
18 | ------
19 |
20 | - GPIO0 controls inputs as RESET, FEED_HOLD, START_CYCLE and SAFETY_DOOR
21 |
22 | - GPIO2 controls all limits switches
23 |
24 | - GPIO12 remains unused (because it functions as SPI HMISO)
25 |
26 | - GPIO13 sends data to the shift registers (SPI HMOSI)
27 |
28 | - GPIO14 clock signal for the shift registers (SPI HSCLK)
29 |
30 | - GPIO15 serves as CHIP_SELECT for the SPI
31 |
32 | The board should use 4 x 8-bit shift registers. They are arranged this way:
33 | - 8 bits for step pins
34 | - 8 bits for direction pins
35 | - 8 bits for Misc, inputs and outputs, following this structure (although it might change still a bit):
36 |
37 | #define CONTROL_RESET_BIT 0
38 | #define CONTROL_FEED_HOLD_BIT 1
39 | #define CONTROL_CYCLE_START_BIT 2
40 | #define CONTROL_SAFETY_DOOR_BIT 3
41 | #define PROBE_BIT 4
42 | #define COOLANT_FLOOD_BIT 5
43 | #define COOLANT_MIST_BIT 6
44 | #define STEPPERS_DISABLE_BIT 7
45 |
46 | - 8 bits for limits. All inputs
47 |
48 | Probe, spindle, and probably other features, are not yet supported
49 |
50 | 
51 |
52 | #### J4
53 | |Pin|Function|Type|
54 | |-|-|-|
55 | | 1 | STEP X | (output) |
56 | | 2 | STEP Y | (output) |
57 | | 3 | STEP Z | (output) |
58 | | 4 | STEP A | (output) |
59 | | 5 | STEP B | (output) |
60 | | 6 | STEP C | (output) |
61 | | 7 | STEP D | (output) |
62 | | 8 | STEP E | (output) |
63 |
64 | #### J3
65 | |Pin|Function|Type|
66 | |-|-|-|
67 | | 1 | DIR X |(output) |
68 | | 2 | DIR Y |(output) |
69 | | 3 | DIR Z |(output) |
70 | | 4 | DIR A |(output) |
71 | | 5 | DIR B |(output) |
72 | | 6 | DIR C |(output) |
73 | | 7 | DIR D |(output) |
74 | | 8 | DIR E |(output) |
75 |
76 | #### J2
77 | |Pin|Function|Type|
78 | |-|-|-|
79 | | 1 | RESET | (input) |
80 | | 2 | FEED HOLD | (input) |
81 | | 3 | CYCLE START | (input) |
82 | | 4 | SAFETY DOOR | (input) |
83 | | 5 | PROBE | (input) |
84 | | 6 | COOLANT/FLOOD |(output) |
85 | | 7 | COOLANT/MIST |(output) |
86 | | 8 | STEPPERS_DISABLE |(output) |
87 |
88 | #### J1
89 | |Pin|Function|Type|
90 | |-|-|-|
91 | | 1 | LIMIT X | (input) |
92 | | 2 | LIMIT Y | (input) |
93 | | 3 | LIMIT Z | (input) |
94 | | 4 | LIMIT A | (input) |
95 | | 5 | LIMIT B | (input) |
96 | | 6 | LIMIT C | (input) |
97 | | 7 | LIMIT D | (input) |
98 | | 8 | LIMIT E | (input) |
99 |
--------------------------------------------------------------------------------
/TODO:
--------------------------------------------------------------------------------
1 |
2 | - Input system
3 | - Change AsyncWebSockets to WebSockets maybe?
4 | - Connecting bCNC through sockets!
--------------------------------------------------------------------------------
/lib/grbl/src/coolant_control.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | coolant_control.c - coolant control methods
3 | Part of Grbl
4 |
5 | Copyright (c) 2012-2016 Sungeun K. Jeon for Gnea Research LLC
6 |
7 | Grbl is free software: you can redistribute it and/or modify
8 | it under the terms of the GNU General Public License as published by
9 | the Free Software Foundation, either version 3 of the License, or
10 | (at your option) any later version.
11 |
12 | Grbl is distributed in the hope that it will be useful,
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | GNU General Public License for more details.
16 |
17 | You should have received a copy of the GNU General Public License
18 | along with Grbl. If not, see .
19 | */
20 |
21 | #include "grbl.hpp"
22 |
23 |
24 | void coolant_init()
25 | {
26 | COOLANT_FLOOD_PORT |= (1 << COOLANT_FLOOD_BIT); // Configure as output pin
27 | #ifdef ENABLE_M7
28 | COOLANT_MIST_PORT |= (1 << COOLANT_MIST_BIT);
29 | #endif
30 | coolant_stop();
31 | }
32 |
33 |
34 | // Returns current coolant output state. Overrides may alter it from programmed state.
35 | uint8_t coolant_get_state()
36 | {
37 | uint8_t cl_state = COOLANT_STATE_DISABLE;
38 | #ifdef INVERT_COOLANT_FLOOD_PIN
39 | if (bit_isfalse(COOLANT_FLOOD_PORT,(1 << COOLANT_FLOOD_BIT))) {
40 | #else
41 | if (bit_istrue(COOLANT_FLOOD_PORT,(1 << COOLANT_FLOOD_BIT))) {
42 | #endif
43 | cl_state |= COOLANT_STATE_FLOOD;
44 | }
45 | #ifdef ENABLE_M7
46 | #ifdef INVERT_COOLANT_MIST_PIN
47 | if (bit_isfalse(COOLANT_MIST_PORT,(1 << COOLANT_MIST_BIT))) {
48 | #else
49 | if (bit_istrue(COOLANT_MIST_PORT,(1 << COOLANT_MIST_BIT))) {
50 | #endif
51 | cl_state |= COOLANT_STATE_MIST;
52 | }
53 | #endif
54 | return(cl_state);
55 | }
56 |
57 |
58 | // Directly called by coolant_init(), coolant_set_state(), and mc_reset(), which can be at
59 | // an interrupt-level. No report flag set, but only called by routines that don't need it.
60 | void coolant_stop()
61 | {
62 | #ifdef INVERT_COOLANT_FLOOD_PIN
63 | COOLANT_FLOOD_PORT |= (1 << COOLANT_FLOOD_BIT);
64 | #else
65 | COOLANT_FLOOD_PORT &= ~(1 << COOLANT_FLOOD_BIT);
66 | #endif
67 | #ifdef ENABLE_M7
68 | #ifdef INVERT_COOLANT_MIST_PIN
69 | COOLANT_MIST_PORT |= (1 << COOLANT_MIST_BIT);
70 | #else
71 | COOLANT_MIST_PORT &= ~(1 << COOLANT_MIST_BIT);
72 | #endif
73 | #endif
74 | }
75 |
76 |
77 | // Main program only. Immediately sets flood coolant running state and also mist coolant,
78 | // if enabled. Also sets a flag to report an update to a coolant state.
79 | // Called by coolant toggle override, parking restore, parking retract, sleep mode, g-code
80 | // parser program end, and g-code parser coolant_sync().
81 | void coolant_set_state(uint8_t mode)
82 | {
83 | if (sys.abort) { return; } // Block during abort.
84 |
85 | if (mode & COOLANT_FLOOD_ENABLE) {
86 | #ifdef INVERT_COOLANT_FLOOD_PIN
87 | COOLANT_FLOOD_PORT &= ~(1 << COOLANT_FLOOD_BIT);
88 | #else
89 | COOLANT_FLOOD_PORT |= (1 << COOLANT_FLOOD_BIT);
90 | #endif
91 | } else {
92 | #ifdef INVERT_COOLANT_FLOOD_PIN
93 | COOLANT_FLOOD_PORT |= (1 << COOLANT_FLOOD_BIT);
94 | #else
95 | COOLANT_FLOOD_PORT &= ~(1 << COOLANT_FLOOD_BIT);
96 | #endif
97 | }
98 |
99 | #ifdef ENABLE_M7
100 | if (mode & COOLANT_MIST_ENABLE) {
101 | #ifdef INVERT_COOLANT_MIST_PIN
102 | COOLANT_MIST_PORT &= ~(1 << COOLANT_MIST_BIT);
103 | #else
104 | COOLANT_MIST_PORT |= (1 << COOLANT_MIST_BIT);
105 | #endif
106 | } else {
107 | #ifdef INVERT_COOLANT_MIST_PIN
108 | COOLANT_MIST_PORT |= (1 << COOLANT_MIST_BIT);
109 | #else
110 | COOLANT_MIST_PORT &= ~(1 << COOLANT_MIST_BIT);
111 | #endif
112 | }
113 | #endif
114 |
115 | sys.report_ovr_counter = 0; // Set to report change immediately
116 | }
117 |
118 |
119 | // G-code parser entry-point for setting coolant state. Forces a planner buffer sync and bails
120 | // if an abort or check-mode is active.
121 | void coolant_sync(uint8_t mode)
122 | {
123 | if (sys.state == STATE_CHECK_MODE) { return; }
124 | protocol_buffer_synchronize(); // Ensure coolant turns on when specified in program.
125 | coolant_set_state(mode);
126 | }
127 |
--------------------------------------------------------------------------------
/lib/grbl/src/coolant_control.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | coolant_control.h - spindle control methods
3 | Part of Grbl
4 |
5 | Copyright (c) 2012-2016 Sungeun K. Jeon for Gnea Research LLC
6 |
7 | Grbl is free software: you can redistribute it and/or modify
8 | it under the terms of the GNU General Public License as published by
9 | the Free Software Foundation, either version 3 of the License, or
10 | (at your option) any later version.
11 |
12 | Grbl is distributed in the hope that it will be useful,
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | GNU General Public License for more details.
16 |
17 | You should have received a copy of the GNU General Public License
18 | along with Grbl. If not, see .
19 | */
20 |
21 | #ifndef coolant_control_h
22 | #define coolant_control_h
23 |
24 | #define COOLANT_NO_SYNC false
25 | #define COOLANT_FORCE_SYNC true
26 |
27 | #define COOLANT_STATE_DISABLE 0 // Must be zero
28 | #define COOLANT_STATE_FLOOD PL_COND_FLAG_COOLANT_FLOOD
29 | #define COOLANT_STATE_MIST PL_COND_FLAG_COOLANT_MIST
30 |
31 |
32 | // Initializes coolant control pins.
33 | void coolant_init();
34 |
35 | // Returns current coolant output state. Overrides may alter it from programmed state.
36 | uint8_t coolant_get_state();
37 |
38 | // Immediately disables coolant pins.
39 | void coolant_stop();
40 |
41 | // Sets the coolant pins according to state specified.
42 | void coolant_set_state(uint8_t mode);
43 |
44 | // G-code parser entry-point for setting coolant states. Checks for and executes additional conditions.
45 | void coolant_sync(uint8_t mode);
46 |
47 | #endif
48 |
--------------------------------------------------------------------------------
/lib/grbl/src/cpu_map.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | cpu_map.hpp - Machine dependent code for the ESP8266 and family
3 | Part of Grbl
4 |
5 | Copyright (c) 2012-2016 Sungeun K. Jeon for Gnea Research LLC
6 |
7 | Grbl is free software: you can redistribute it and/or modify
8 | it under the terms of the GNU General Public License as published by
9 | the Free Software Foundation, either version 3 of the License, or
10 | (at your option) any later version.
11 |
12 | Grbl is distributed in the hope that it will be useful,
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | GNU General Public License for more details.
16 |
17 | You should have received a copy of the GNU General Public License
18 | along with Grbl. If not, see .
19 | */
20 |
21 | /* The cpu_map.h files serve as a central pin mapping selection file for different
22 | processor types or alternative pin layouts. This version of Grbl officially supports
23 | only the Arduino Mega328p. */
24 |
25 |
26 | #ifndef cpu_map_h
27 | #define cpu_map_h
28 |
29 | #define save_SREG() xt_rsil(2); // this routine will allow level 3 and above (returns an uint32_t)
30 | #define restore_SREG(state) xt_wsr_ps(state); sei(); // restore the state (uint32_t)
31 |
32 | volatile static union {
33 | uint32_t data;
34 | struct {
35 | uint8_t STEP_PORT_OFFSET:8; // All outputs
36 | uint8_t DIRECTION_PORT_OFFSET:8; // All outputs
37 | uint8_t MISC_PORT_OFFSET:8; // Inputs and outputs
38 | uint8_t LIMIT_PORT_OFFSET:8; // All inputs
39 | };
40 | } regs;
41 |
42 | // Used to modify SPI registers without altering Grbl's registers
43 | decltype(regs) regs_tmp;
44 |
45 | #ifdef CPU_MAP_ESP8266
46 |
47 | // Define serial port pins and interrupt vectors.
48 | #define SERIAL_RX USART_RX_vect
49 | #define SERIAL_UDRE USART_UDRE_vect
50 |
51 | // Define step pulse output pins. NOTE: All step bit pins must be on the same port.
52 | #define STEP_PORT regs.STEP_PORT_OFFSET
53 | #define X_STEP_BIT 0
54 | #define Y_STEP_BIT 1
55 | #define Z_STEP_BIT 2
56 | #define A_STEP_BIT 3
57 | #define B_STEP_BIT 4
58 | #define C_STEP_BIT 5
59 | #define D_STEP_BIT 6
60 | #define E_STEP_BIT 7
61 | #define STEP_MASK ((1< 62.5kHz
155 | // #define SPINDLE_TCCRB_INIT_MASK (1< 7.8kHz (Used in v0.9)
156 | // #define SPINDLE_TCCRB_INIT_MASK ((1< 1.96kHz
157 | #define SPINDLE_TCCRB_INIT_MASK (1< 0.98kHz (J-tech laser)
158 |
159 | // NOTE: On the 328p, these must be the same as the SPINDLE_ENABLE settings.
160 | #define SPINDLE_PWM_DDR DDRB
161 | #define SPINDLE_PWM_PORT PORTB
162 | #define SPINDLE_PWM_BIT 3 // Uno Digital Pin 11
163 |
164 | #define CONTROL_INPUT_GPIO_PIN D3 // GPIO_0 = D3
165 |
166 | #define LIMIT_INPUT_GPIO_PIN D4 // GPIO_2 = D4
167 |
168 | #define F_STEPPER_TIMER 80000000/2 // frequency in Hz of step pulse timer (SPI)
169 |
170 | #endif
171 |
172 | /*
173 | #ifdef CPU_MAP_CUSTOM_PROC
174 | // For a custom pin map or different processor, copy and edit one of the available cpu
175 | // map files and modify it to your needs. Make sure the defined name is also changed in
176 | // the config.h file.
177 | #endif
178 | */
179 |
180 | #endif /* CPU_MAP_H_ */
181 |
--------------------------------------------------------------------------------
/lib/grbl/src/credentials.hpp:
--------------------------------------------------------------------------------
1 | #ifndef credentials_h
2 | #define credentials_h
3 |
4 | #define WIFI_SSID "Whatever"
5 | #define WIFI_PASSWORD "mydummypassword"
6 | #define WIFI_HOSTNAME "grblesp"
7 |
8 |
9 | #endif
10 |
--------------------------------------------------------------------------------
/lib/grbl/src/eeprom.cpp:
--------------------------------------------------------------------------------
1 | // This file has been prepared for Doxygen automatic documentation generation.
2 | /*! \file ********************************************************************
3 | * Taken from ArduinoESP examples
4 | ******************************************************************************/
5 |
6 | #include
7 |
8 | /*! \brief Read byte from EEPROM.
9 | *
10 | * This function Initializes the EEPROM buffer.
11 | *
12 | */
13 | void eeprom_init()
14 | {
15 | EEPROM.begin(2048);
16 | }
17 |
18 | /*! \brief Read byte from EEPROM.
19 | *
20 | * This function reads one byte from a given EEPROM address.
21 | *
22 | * \note The CPU is halted for 4 clock cycles during EEPROM read.
23 | *
24 | * \param addr EEPROM address to read from.
25 | * \return The byte read from the EEPROM address.
26 | */
27 | unsigned char eeprom_get_char( unsigned int addr )
28 | {
29 | return EEPROM.read(addr); // Return the byte read from EEPROM.
30 | }
31 |
32 | /*! \brief Write byte to EEPROM.
33 | *
34 | * This function writes one byte to a given EEPROM address.
35 | *
36 | * \param addr EEPROM address to write to.
37 | * \param new_value New EEPROM value.
38 | */
39 | void eeprom_put_char( unsigned int addr, unsigned char new_value )
40 | {
41 | EEPROM.write(addr, new_value);
42 | }
43 |
44 | // Extensions added as part of Grbl
45 |
46 |
47 | void memcpy_to_eeprom_with_checksum(unsigned int destination, char *source, unsigned int size) {
48 | unsigned char checksum = 0;
49 | for(; size > 0; size--) {
50 | checksum = (checksum << 1) || (checksum >> 7);
51 | checksum += *source;
52 | eeprom_put_char(destination++, *(source++));
53 | }
54 | eeprom_put_char(destination, checksum);
55 | EEPROM.commit();
56 | }
57 |
58 | int memcpy_from_eeprom_with_checksum(char *destination, unsigned int source, unsigned int size) {
59 | unsigned char data, checksum = 0;
60 | for(; size > 0; size--) {
61 | data = eeprom_get_char(source++);
62 | checksum = (checksum << 1) || (checksum >> 7);
63 | checksum += data;
64 | *(destination++) = data;
65 | }
66 | return(checksum == eeprom_get_char(source));
67 | }
68 |
69 | // end of file
70 |
--------------------------------------------------------------------------------
/lib/grbl/src/eeprom.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | eeprom.h - EEPROM methods
3 | Part of Grbl
4 |
5 | Copyright (c) 2009-2011 Simen Svale Skogsrud
6 |
7 | Grbl is free software: you can redistribute it and/or modify
8 | it under the terms of the GNU General Public License as published by
9 | the Free Software Foundation, either version 3 of the License, or
10 | (at your option) any later version.
11 |
12 | Grbl is distributed in the hope that it will be useful,
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | GNU General Public License for more details.
16 |
17 | You should have received a copy of the GNU General Public License
18 | along with Grbl. If not, see .
19 | */
20 |
21 | #ifndef eeprom_h
22 | #define eeprom_h
23 |
24 | #ifdef ESP8266
25 | //extern "C" {
26 | #include
27 | //}
28 | #endif
29 |
30 | void eeprom_init();
31 | unsigned char eeprom_get_char(unsigned int addr);
32 | void eeprom_put_char(unsigned int addr, unsigned char new_value);
33 | void memcpy_to_eeprom_with_checksum(unsigned int destination, char *source, unsigned int size);
34 | int memcpy_from_eeprom_with_checksum(char *destination, unsigned int source, unsigned int size);
35 |
36 | #endif
37 |
--------------------------------------------------------------------------------
/lib/grbl/src/gcode.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | gcode.h - rs274/ngc parser.
3 | Part of Grbl
4 |
5 | Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC
6 | Copyright (c) 2009-2011 Simen Svale Skogsrud
7 |
8 | Grbl is free software: you can redistribute it and/or modify
9 | it under the terms of the GNU General Public License as published by
10 | the Free Software Foundation, either version 3 of the License, or
11 | (at your option) any later version.
12 |
13 | Grbl is distributed in the hope that it will be useful,
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | GNU General Public License for more details.
17 |
18 | You should have received a copy of the GNU General Public License
19 | along with Grbl. If not, see .
20 | */
21 |
22 | #ifndef gcode_h
23 | #define gcode_h
24 |
25 |
26 | // Define modal group internal numbers for checking multiple command violations and tracking the
27 | // type of command that is called in the block. A modal group is a group of g-code commands that are
28 | // mutually exclusive, or cannot exist on the same line, because they each toggle a state or execute
29 | // a unique motion. These are defined in the NIST RS274-NGC v3 g-code standard, available online,
30 | // and are similar/identical to other g-code interpreters by manufacturers (Haas,Fanuc,Mazak,etc).
31 | // NOTE: Modal group define values must be sequential and starting from zero.
32 | #define MODAL_GROUP_G0 0 // [G4,G10,G28,G28.1,G30,G30.1,G53,G92,G92.1] Non-modal
33 | #define MODAL_GROUP_G1 1 // [G0,G1,G2,G3,G38.2,G38.3,G38.4,G38.5,G80] Motion
34 | #define MODAL_GROUP_G2 2 // [G17,G18,G19] Plane selection
35 | #define MODAL_GROUP_G3 3 // [G90,G91] Distance mode
36 | #define MODAL_GROUP_G4 4 // [G91.1] Arc IJK distance mode
37 | #define MODAL_GROUP_G5 5 // [G93,G94] Feed rate mode
38 | #define MODAL_GROUP_G6 6 // [G20,G21] Units
39 | #define MODAL_GROUP_G7 7 // [G40] Cutter radius compensation mode. G41/42 NOT SUPPORTED.
40 | #define MODAL_GROUP_G8 8 // [G43.1,G49] Tool length offset
41 | #define MODAL_GROUP_G12 9 // [G54,G55,G56,G57,G58,G59] Coordinate system selection
42 | #define MODAL_GROUP_G13 10 // [G61] Control mode
43 |
44 | #define MODAL_GROUP_M4 11 // [M0,M1,M2,M30] Stopping
45 | #define MODAL_GROUP_M7 12 // [M3,M4,M5] Spindle turning
46 | #define MODAL_GROUP_M8 13 // [M7,M8,M9] Coolant control
47 | #define MODAL_GROUP_M9 14 // [M56] Override control
48 |
49 | // Define command actions for within execution-type modal groups (motion, stopping, non-modal). Used
50 | // internally by the parser to know which command to execute.
51 | // NOTE: Some macro values are assigned specific values to make g-code state reporting and parsing
52 | // compile a little smaller. Necessary due to being completely out of flash on the 328p. Although not
53 | // ideal, just be careful with values that state 'do not alter' and check both report.c and gcode.c
54 | // to see how they are used, if you need to alter them.
55 |
56 | // Modal Group G0: Non-modal actions
57 | #define NON_MODAL_NO_ACTION 0 // (Default: Must be zero)
58 | #define NON_MODAL_DWELL 4 // G4 (Do not alter value)
59 | #define NON_MODAL_SET_COORDINATE_DATA 10 // G10 (Do not alter value)
60 | #define NON_MODAL_GO_HOME_0 28 // G28 (Do not alter value)
61 | #define NON_MODAL_SET_HOME_0 38 // G28.1 (Do not alter value)
62 | #define NON_MODAL_GO_HOME_1 30 // G30 (Do not alter value)
63 | #define NON_MODAL_SET_HOME_1 40 // G30.1 (Do not alter value)
64 | #define NON_MODAL_ABSOLUTE_OVERRIDE 53 // G53 (Do not alter value)
65 | #define NON_MODAL_SET_COORDINATE_OFFSET 92 // G92 (Do not alter value)
66 | #define NON_MODAL_RESET_COORDINATE_OFFSET 102 //G92.1 (Do not alter value)
67 |
68 | // Modal Group G1: Motion modes
69 | #define MOTION_MODE_SEEK 0 // G0 (Default: Must be zero)
70 | #define MOTION_MODE_LINEAR 1 // G1 (Do not alter value)
71 | #define MOTION_MODE_CW_ARC 2 // G2 (Do not alter value)
72 | #define MOTION_MODE_CCW_ARC 3 // G3 (Do not alter value)
73 | #define MOTION_MODE_PROBE_TOWARD 140 // G38.2 (Do not alter value)
74 | #define MOTION_MODE_PROBE_TOWARD_NO_ERROR 141 // G38.3 (Do not alter value)
75 | #define MOTION_MODE_PROBE_AWAY 142 // G38.4 (Do not alter value)
76 | #define MOTION_MODE_PROBE_AWAY_NO_ERROR 143 // G38.5 (Do not alter value)
77 | #define MOTION_MODE_NONE 80 // G80 (Do not alter value)
78 |
79 | // Modal Group G2: Plane select
80 | #define PLANE_SELECT_XY 0 // G17 (Default: Must be zero)
81 | #define PLANE_SELECT_ZX 1 // G18 (Do not alter value)
82 | #define PLANE_SELECT_YZ 2 // G19 (Do not alter value)
83 |
84 | // Modal Group G3: Distance mode
85 | #define DISTANCE_MODE_ABSOLUTE 0 // G90 (Default: Must be zero)
86 | #define DISTANCE_MODE_INCREMENTAL 1 // G91 (Do not alter value)
87 |
88 | // Modal Group G4: Arc IJK distance mode
89 | #define DISTANCE_ARC_MODE_INCREMENTAL 0 // G91.1 (Default: Must be zero)
90 |
91 | // Modal Group M4: Program flow
92 | #define PROGRAM_FLOW_RUNNING 0 // (Default: Must be zero)
93 | #define PROGRAM_FLOW_PAUSED 3 // M0
94 | #define PROGRAM_FLOW_OPTIONAL_STOP 1 // M1 NOTE: Not supported, but valid and ignored.
95 | #define PROGRAM_FLOW_COMPLETED_M2 2 // M2 (Do not alter value)
96 | #define PROGRAM_FLOW_COMPLETED_M30 30 // M30 (Do not alter value)
97 |
98 | // Modal Group G5: Feed rate mode
99 | #define FEED_RATE_MODE_UNITS_PER_MIN 0 // G94 (Default: Must be zero)
100 | #define FEED_RATE_MODE_INVERSE_TIME 1 // G93 (Do not alter value)
101 |
102 | // Modal Group G6: Units mode
103 | #define UNITS_MODE_MM 0 // G21 (Default: Must be zero)
104 | #define UNITS_MODE_INCHES 1 // G20 (Do not alter value)
105 |
106 | // Modal Group G7: Cutter radius compensation mode
107 | #define CUTTER_COMP_DISABLE 0 // G40 (Default: Must be zero)
108 |
109 | // Modal Group G13: Control mode
110 | #define CONTROL_MODE_EXACT_PATH 0 // G61 (Default: Must be zero)
111 |
112 | // Modal Group M7: Spindle control
113 | #define SPINDLE_DISABLE 0 // M5 (Default: Must be zero)
114 | #define SPINDLE_ENABLE_CW PL_COND_FLAG_SPINDLE_CW // M3 (NOTE: Uses planner condition bit flag)
115 | #define SPINDLE_ENABLE_CCW PL_COND_FLAG_SPINDLE_CCW // M4 (NOTE: Uses planner condition bit flag)
116 |
117 | // Modal Group M8: Coolant control
118 | #define COOLANT_DISABLE 0 // M9 (Default: Must be zero)
119 | #define COOLANT_FLOOD_ENABLE PL_COND_FLAG_COOLANT_FLOOD // M8 (NOTE: Uses planner condition bit flag)
120 | #define COOLANT_MIST_ENABLE PL_COND_FLAG_COOLANT_MIST // M7 (NOTE: Uses planner condition bit flag)
121 |
122 | // Modal Group G8: Tool length offset
123 | #define TOOL_LENGTH_OFFSET_CANCEL 0 // G49 (Default: Must be zero)
124 | #define TOOL_LENGTH_OFFSET_ENABLE_DYNAMIC 1 // G43.1
125 |
126 | // Modal Group M9: Override control
127 | #ifdef DEACTIVATE_PARKING_UPON_INIT
128 | #define OVERRIDE_DISABLED 0 // (Default: Must be zero)
129 | #define OVERRIDE_PARKING_MOTION 1 // M56
130 | #else
131 | #define OVERRIDE_PARKING_MOTION 0 // M56 (Default: Must be zero)
132 | #define OVERRIDE_DISABLED 1 // Parking disabled.
133 | #endif
134 |
135 | // Modal Group G12: Active work coordinate system
136 | // N/A: Stores coordinate system value (54-59) to change to.
137 |
138 | // Define parameter word mapping.
139 | #define WORD_F 0
140 | #define WORD_I 1
141 | #define WORD_J 2
142 | #define WORD_K 3
143 | #define WORD_L 4
144 | #define WORD_N 5
145 | #define WORD_P 6
146 | #define WORD_R 7
147 | #define WORD_S 8
148 | #define WORD_T 9
149 | #define WORD_X 10
150 | #define WORD_Y 11
151 | #define WORD_Z 12
152 | #define WORD_A 13
153 | #define WORD_B 14
154 | #define WORD_C 15
155 | #define WORD_D 16
156 | #define WORD_E 17
157 |
158 | // Define g-code parser position updating flags
159 | #define GC_UPDATE_POS_TARGET 0 // Must be zero
160 | #define GC_UPDATE_POS_SYSTEM 1
161 | #define GC_UPDATE_POS_NONE 2
162 |
163 | // Define probe cycle exit states and assign proper position updating.
164 | #define GC_PROBE_FOUND GC_UPDATE_POS_SYSTEM
165 | #define GC_PROBE_ABORT GC_UPDATE_POS_NONE
166 | #define GC_PROBE_FAIL_INIT GC_UPDATE_POS_NONE
167 | #define GC_PROBE_FAIL_END GC_UPDATE_POS_TARGET
168 | #ifdef SET_CHECK_MODE_PROBE_TO_START
169 | #define GC_PROBE_CHECK_MODE GC_UPDATE_POS_NONE
170 | #else
171 | #define GC_PROBE_CHECK_MODE GC_UPDATE_POS_TARGET
172 | #endif
173 |
174 | // Define gcode parser flags for handling special cases.
175 | #define GC_PARSER_NONE 0 // Must be zero.
176 | #define GC_PARSER_JOG_MOTION bit(0)
177 | #define GC_PARSER_CHECK_MANTISSA bit(1)
178 | #define GC_PARSER_ARC_IS_CLOCKWISE bit(2)
179 | #define GC_PARSER_PROBE_IS_AWAY bit(3)
180 | #define GC_PARSER_PROBE_IS_NO_ERROR bit(4)
181 | #define GC_PARSER_LASER_FORCE_SYNC bit(5)
182 | #define GC_PARSER_LASER_DISABLE bit(6)
183 | #define GC_PARSER_LASER_ISMOTION bit(7)
184 |
185 |
186 | // NOTE: When this struct is zeroed, the above defines set the defaults for the system.
187 | typedef struct {
188 | uint8_t motion; // {G0,G1,G2,G3,G38.2,G80}
189 | uint8_t feed_rate; // {G93,G94}
190 | uint8_t units; // {G20,G21}
191 | uint8_t distance; // {G90,G91}
192 | // uint8_t distance_arc; // {G91.1} NOTE: Don't track. Only default supported.
193 | uint8_t plane_select; // {G17,G18,G19}
194 | // uint8_t cutter_comp; // {G40} NOTE: Don't track. Only default supported.
195 | uint8_t tool_length; // {G43.1,G49}
196 | uint8_t coord_select; // {G54,G55,G56,G57,G58,G59}
197 | // uint8_t control; // {G61} NOTE: Don't track. Only default supported.
198 | uint8_t program_flow; // {M0,M1,M2,M30}
199 | uint8_t coolant; // {M7,M8,M9}
200 | uint8_t spindle; // {M3,M4,M5}
201 | uint8_t override; // {M56}
202 | } gc_modal_t;
203 |
204 | typedef struct {
205 | float f; // Feed
206 | float ijk[N_AXIS]; // I,J,K... Axis arc offsets
207 | uint8_t l; // G10 or canned cycles parameters
208 | int32_t n; // Line number
209 | float p; // G10 or dwell parameters
210 | // float q; // G82 peck drilling
211 | float r; // Arc radius
212 | float s; // Spindle speed
213 | uint8_t t; // Tool selection
214 | float xyz[N_AXIS]; // X,Y,Z... Translational axes
215 | } gc_values_t;
216 |
217 |
218 | typedef struct {
219 | gc_modal_t modal;
220 |
221 | float spindle_speed; // RPM
222 | float feed_rate; // Millimeters/min
223 | uint8_t tool; // Tracks tool number. NOT USED.
224 | int32_t line_number; // Last line number sent
225 |
226 | float position[N_AXIS]; // Where the interpreter considers the tool to be at this point in the code
227 |
228 | float coord_system[N_AXIS]; // Current work coordinate system (G54+). Stores offset from absolute machine
229 | // position in mm. Loaded from EEPROM when called.
230 | float coord_offset[N_AXIS]; // Retains the G92 coordinate offset (work coordinates) relative to
231 | // machine zero in mm. Non-persistent. Cleared upon reset and boot.
232 | float tool_length_offset; // Tracks tool length offset value when enabled.
233 | } parser_state_t;
234 | extern parser_state_t gc_state;
235 |
236 |
237 | typedef struct {
238 | uint8_t non_modal_command;
239 | gc_modal_t modal;
240 | gc_values_t values;
241 | } parser_block_t;
242 |
243 |
244 | // Initialize the parser
245 | void gc_init();
246 |
247 | // Execute one block of rs275/ngc/g-code
248 | uint8_t gc_execute_line(char *line, uint8_t client);
249 |
250 | // Set g-code parser position. Input in steps.
251 | void gc_sync_position();
252 |
253 | #endif
254 |
--------------------------------------------------------------------------------
/lib/grbl/src/grbl.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | grbl.h - main Grbl include file
3 | Part of Grbl
4 |
5 | Copyright (c) 2015-2016 Sungeun K. Jeon for Gnea Research LLC
6 |
7 | Grbl is free software: you can redistribute it and/or modify
8 | it under the terms of the GNU General Public License as published by
9 | the Free Software Foundation, either version 3 of the License, or
10 | (at your option) any later version.
11 |
12 | Grbl is distributed in the hope that it will be useful,
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | GNU General Public License for more details.
16 |
17 | You should have received a copy of the GNU General Public License
18 | along with Grbl. If not, see .
19 | */
20 |
21 | #ifndef grbl_h
22 | #define grbl_h
23 |
24 | // Grbl versioning system
25 | #define GRBL_VERSION "1.1g"
26 | #define GRBL_VERSION_BUILD "20181112"
27 |
28 | #include
29 | #include
30 | #include
31 | #include
32 | #include
33 | #include
34 | #include
35 |
36 | // Define the Grbl system include files. NOTE: Do not alter organization.
37 | #include "config.hpp"
38 |
39 | #include "nuts_bolts.hpp"
40 | #include "settings.hpp"
41 | #include "system.hpp"
42 | #include "defaults.hpp"
43 | #include "cpu_map.hpp"
44 | #include "planner.hpp"
45 | #include "coolant_control.hpp"
46 | #include "eeprom.hpp"
47 | #include "gcode.hpp"
48 | #include "limits.hpp"
49 | #include "motion_control.hpp"
50 | #include "planner.hpp"
51 | #include "print.hpp"
52 | #include "probe.hpp"
53 | #include "protocol.hpp"
54 | #include "report.hpp"
55 | #include "serial.hpp"
56 | #ifdef ENABLE_WIFI
57 | #include "wifi.hpp"
58 | #ifdef ENABLE_WEBSOCKET
59 | #include "websocket.hpp"
60 | #include "serial2socket.hpp"
61 | #endif
62 | #ifdef ENABLE_TELNET
63 | #include "telnet_server.hpp"
64 | #endif
65 | #endif
66 | #include "spindle_control.hpp"
67 | #include "stepper.hpp"
68 | #include "jog.hpp"
69 |
70 | // ---------------------------------------------------------------------------------------
71 | // COMPILE-TIME ERROR CHECKING OF DEFINE VALUES:
72 |
73 | #ifndef HOMING_CYCLE_0
74 | #error "Required HOMING_CYCLE_0 not defined."
75 | #endif
76 |
77 | #if defined(USE_SPINDLE_DIR_AS_ENABLE_PIN) && !defined(VARIABLE_SPINDLE)
78 | #error "USE_SPINDLE_DIR_AS_ENABLE_PIN may only be used with VARIABLE_SPINDLE enabled"
79 | #endif
80 |
81 | #if defined(USE_SPINDLE_DIR_AS_ENABLE_PIN) && !defined(CPU_MAP_ATMEGA328P)
82 | #error "USE_SPINDLE_DIR_AS_ENABLE_PIN may only be used with a 328p processor"
83 | #endif
84 |
85 | #if !defined(USE_SPINDLE_DIR_AS_ENABLE_PIN) && defined(SPINDLE_ENABLE_OFF_WITH_ZERO_SPEED)
86 | #error "SPINDLE_ENABLE_OFF_WITH_ZERO_SPEED may only be used with USE_SPINDLE_DIR_AS_ENABLE_PIN enabled"
87 | #endif
88 |
89 | #if defined(PARKING_ENABLE)
90 | #if defined(HOMING_FORCE_SET_ORIGIN)
91 | #error "HOMING_FORCE_SET_ORIGIN is not supported with PARKING_ENABLE at this time."
92 | #endif
93 | #endif
94 |
95 | #if defined(ENABLE_PARKING_OVERRIDE_CONTROL)
96 | #if !defined(PARKING_ENABLE)
97 | #error "ENABLE_PARKING_OVERRIDE_CONTROL must be enabled with PARKING_ENABLE."
98 | #endif
99 | #endif
100 |
101 | #if defined(SPINDLE_PWM_MIN_VALUE)
102 | #if !(SPINDLE_PWM_MIN_VALUE > 0)
103 | #error "SPINDLE_PWM_MIN_VALUE must be greater than zero."
104 | #endif
105 | #endif
106 |
107 | #if (REPORT_WCO_REFRESH_BUSY_COUNT < REPORT_WCO_REFRESH_IDLE_COUNT)
108 | #error "WCO busy refresh is less than idle refresh."
109 | #endif
110 | #if (REPORT_OVR_REFRESH_BUSY_COUNT < REPORT_OVR_REFRESH_IDLE_COUNT)
111 | #error "Override busy refresh is less than idle refresh."
112 | #endif
113 | #if (REPORT_WCO_REFRESH_IDLE_COUNT < 2)
114 | #error "WCO refresh must be greater than one."
115 | #endif
116 | #if (REPORT_OVR_REFRESH_IDLE_COUNT < 1)
117 | #error "Override refresh must be greater than zero."
118 | #endif
119 |
120 | // ---------------------------------------------------------------------------------------
121 |
122 | #endif
123 |
--------------------------------------------------------------------------------
/lib/grbl/src/jog.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | jog.h - Jogging methods
3 | Part of Grbl
4 |
5 | Copyright (c) 2016 Sungeun K. Jeon for Gnea Research LLC
6 |
7 | Grbl is free software: you can redistribute it and/or modify
8 | it under the terms of the GNU General Public License as published by
9 | the Free Software Foundation, either version 3 of the License, or
10 | (at your option) any later version.
11 |
12 | Grbl is distributed in the hope that it will be useful,
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | GNU General Public License for more details.
16 |
17 | You should have received a copy of the GNU General Public License
18 | along with Grbl. If not, see .
19 | */
20 |
21 | #include "grbl.hpp"
22 |
23 |
24 | // Sets up valid jog motion received from g-code parser, checks for soft-limits, and executes the jog.
25 | uint8_t jog_execute(plan_line_data_t *pl_data, parser_block_t *gc_block)
26 | {
27 | // Initialize planner data struct for jogging motions.
28 | // NOTE: Spindle and coolant are allowed to fully function with overrides during a jog.
29 | pl_data->feed_rate = gc_block->values.f;
30 | pl_data->condition |= PL_COND_FLAG_NO_FEED_OVERRIDE;
31 | #ifdef USE_LINE_NUMBERS
32 | pl_data->line_number = gc_block->values.n;
33 | #endif
34 |
35 | if (bit_istrue(settings.flags,BITFLAG_SOFT_LIMIT_ENABLE)) {
36 | if (system_check_travel_limits(gc_block->values.xyz)) { return(STATUS_TRAVEL_EXCEEDED); }
37 | }
38 |
39 | // Valid jog command. Plan, set state, and execute.
40 | mc_line(gc_block->values.xyz,pl_data);
41 | if (sys.state == STATE_IDLE) {
42 | if (plan_get_current_block() != NULL) { // Check if there is a block to execute.
43 | sys.state = STATE_JOG;
44 | st_prep_buffer();
45 | st_wake_up(); // NOTE: Manual start. No state machine required.
46 | }
47 | }
48 |
49 | return(STATUS_OK);
50 | }
51 |
--------------------------------------------------------------------------------
/lib/grbl/src/jog.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | jog.h - Jogging methods
3 | Part of Grbl
4 |
5 | Copyright (c) 2016 Sungeun K. Jeon for Gnea Research LLC
6 |
7 | Grbl is free software: you can redistribute it and/or modify
8 | it under the terms of the GNU General Public License as published by
9 | the Free Software Foundation, either version 3 of the License, or
10 | (at your option) any later version.
11 |
12 | Grbl is distributed in the hope that it will be useful,
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | GNU General Public License for more details.
16 |
17 | You should have received a copy of the GNU General Public License
18 | along with Grbl. If not, see .
19 | */
20 |
21 | #ifndef jog_h
22 | #define jog_h
23 |
24 | #include "gcode.hpp"
25 |
26 | // System motion line numbers must be zero.
27 | #define JOG_LINE_NUMBER 0
28 |
29 | // Sets up valid jog motion received from g-code parser, checks for soft-limits, and executes the jog.
30 | uint8_t jog_execute(plan_line_data_t *pl_data, parser_block_t *gc_block);
31 |
32 | #endif
33 |
--------------------------------------------------------------------------------
/lib/grbl/src/limits.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | limits.c - code pertaining to limit-switches and performing the homing cycle
3 | Part of Grbl
4 |
5 | Copyright (c) 2012-2016 Sungeun K. Jeon for Gnea Research LLC
6 | Copyright (c) 2009-2011 Simen Svale Skogsrud
7 |
8 | Grbl is free software: you can redistribute it and/or modify
9 | it under the terms of the GNU General Public License as published by
10 | the Free Software Foundation, either version 3 of the License, or
11 | (at your option) any later version.
12 |
13 | Grbl is distributed in the hope that it will be useful,
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | GNU General Public License for more details.
17 |
18 | You should have received a copy of the GNU General Public License
19 | along with Grbl. If not, see .
20 | */
21 |
22 | #include "grbl.hpp"
23 | #include
24 |
25 | // Homing axis search distance multiplier. Computed by this value times the cycle travel.
26 | #ifndef HOMING_AXIS_SEARCH_SCALAR
27 | #define HOMING_AXIS_SEARCH_SCALAR 1.5 // Must be > 1 to ensure limit switch will be engaged.
28 | #endif
29 | #ifndef HOMING_AXIS_LOCATE_SCALAR
30 | #define HOMING_AXIS_LOCATE_SCALAR 5.0 // Must be > 1 to ensure limit switch is cleared.
31 | #endif
32 |
33 | void limits_init()
34 | {
35 | // Turn off all limit inputs
36 | LIMIT_PORT &= ~LIMIT_MASK;
37 | SPI.write(regs.data);
38 |
39 | // Attach interrupt to limit input pin
40 | pinMode(LIMIT_INPUT_GPIO_PIN, INPUT_PULLUP);
41 | attachInterrupt(digitalPinToInterrupt(LIMIT_INPUT_GPIO_PIN), pin_limit_vect, CHANGE);
42 | }
43 |
44 | // Disables hard limits.
45 | void limits_disable()
46 | {
47 | detachInterrupt(digitalPinToInterrupt(LIMIT_INPUT_GPIO_PIN));
48 | }
49 |
50 |
51 | // Returns limit state as a bit-wise uint8 variable. Each bit indicates an axis limit, where
52 | // triggered is 1 and not triggered is 0. Invert mask is applied. Axes are defined by their
53 | // number in bit position, i.e. Z_AXIS is (1<<2) or bit 2, and Y_AXIS is (1<<1) or bit 1.
54 | uint8_t limits_get_state()
55 | {
56 | uint8_t limit_state = 0;
57 |
58 | uint8_t pin = (LIMIT_PORT_INPUTS & LIMIT_MASK);
59 | #ifdef INVERT_LIMIT_PIN_MASK
60 | pin ^= INVERT_LIMIT_PIN_MASK;
61 | #endif
62 | if (bit_istrue(settings.flags,BITFLAG_INVERT_LIMIT_PINS)) { pin ^= LIMIT_MASK; }
63 | if (pin) {
64 | uint8_t idx;
65 | for (idx=0; idxcondition = (PL_COND_FLAG_SYSTEM_MOTION|PL_COND_FLAG_NO_FEED_OVERRIDE);
151 | #ifdef USE_LINE_NUMBERS
152 | pl_data->line_number = HOMING_CYCLE_LINE_NUMBER;
153 | #endif
154 |
155 | // Initialize variables used for homing computations.
156 | uint8_t n_cycle = (2*N_HOMING_LOCATE_CYCLE+1);
157 | uint8_t step_pin[N_AXIS];
158 | float target[N_AXIS];
159 | float max_travel = 0.0;
160 | uint8_t idx;
161 | for (idx=0; idxfeed_rate = homing_rate; // Set current homing rate.
223 | plan_buffer_line(target, pl_data); // Bypass mc_line(). Directly plan homing motion.
224 |
225 | sys.step_control = STEP_CONTROL_EXECUTE_SYS_MOTION; // Set to execute homing motion and clear existing flags.
226 | st_prep_buffer(); // Prep and fill segment buffer from newly planned block.
227 | st_wake_up(); // Initiate motion
228 | do {
229 | ///delay(0);
230 | if (approach) {
231 | // Check limit state. Lock out cycle axes when they change.
232 | limit_state = limits_get_state();
233 | for (idx=0; idx 0);
289 |
290 | // The active cycle axes should now be homed and machine limits have been located. By
291 | // default, Grbl defines machine space as all negative, as do most CNCs. Since limit switches
292 | // can be on either side of an axes, check and set axes machine zero appropriately. Also,
293 | // set up pull-off maneuver from axes limit switches that have been homed. This provides
294 | // some initial clearance off the switches and should also help prevent them from falsely
295 | // triggering when hard limits are enabled or when more than one axes shares a limit pin.
296 | int32_t set_axis_position;
297 | // Set machine positions for homed limit switches. Don't update non-homed axes.
298 | for (idx=0; idx.
20 | */
21 |
22 | #ifndef limits_h
23 | #define limits_h
24 |
25 |
26 | // Initialize the limits module
27 | void limits_init();
28 |
29 | // Disables hard limits.
30 | void limits_disable();
31 |
32 | // Returns limit state as a bit-wise uint8 variable.
33 | uint8_t limits_get_state();
34 |
35 | // Perform one portion of the homing cycle based on the input settings.
36 | void limits_go_home(uint8_t cycle_mask);
37 |
38 | // Check for soft limit violations
39 | void limits_soft_check(float *target);
40 |
41 | void pin_limit_vect();
42 |
43 | #endif
44 |
--------------------------------------------------------------------------------
/lib/grbl/src/motion_control.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | motion_control.c - high level interface for issuing motion commands
3 | Part of Grbl
4 |
5 | Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC
6 | Copyright (c) 2009-2011 Simen Svale Skogsrud
7 |
8 | Grbl is free software: you can redistribute it and/or modify
9 | it under the terms of the GNU General Public License as published by
10 | the Free Software Foundation, either version 3 of the License, or
11 | (at your option) any later version.
12 |
13 | Grbl is distributed in the hope that it will be useful,
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | GNU General Public License for more details.
17 |
18 | You should have received a copy of the GNU General Public License
19 | along with Grbl. If not, see .
20 | */
21 |
22 | #include "grbl.hpp"
23 |
24 |
25 | // Execute linear motion in absolute millimeter coordinates. Feed rate given in millimeters/second
26 | // unless invert_feed_rate is true. Then the feed_rate means that the motion should be completed in
27 | // (1 minute)/feed_rate time.
28 | // NOTE: This is the primary gateway to the grbl planner. All line motions, including arc line
29 | // segments, must pass through this routine before being passed to the planner. The seperation of
30 | // mc_line and plan_buffer_line is done primarily to place non-planner-type functions from being
31 | // in the planner and to let backlash compensation or canned cycle integration simple and direct.
32 | void mc_line(float *target, plan_line_data_t *pl_data)
33 | {
34 | // If enabled, check for soft limit violations. Placed here all line motions are picked up
35 | // from everywhere in Grbl.
36 | if (bit_istrue(settings.flags,BITFLAG_SOFT_LIMIT_ENABLE)) {
37 | // NOTE: Block jog state. Jogging is a special case and soft limits are handled independently.
38 | if (sys.state != STATE_JOG) { limits_soft_check(target); }
39 | }
40 |
41 | // If in check gcode mode, prevent motion by blocking planner. Soft limits still work.
42 | if (sys.state == STATE_CHECK_MODE) { return; }
43 |
44 | // NOTE: Backlash compensation may be installed here. It will need direction info to track when
45 | // to insert a backlash line motion(s) before the intended line motion and will require its own
46 | // plan_check_full_buffer() and check for system abort loop. Also for position reporting
47 | // backlash steps will need to be also tracked, which will need to be kept at a system level.
48 | // There are likely some other things that will need to be tracked as well. However, we feel
49 | // that backlash compensation should NOT be handled by Grbl itself, because there are a myriad
50 | // of ways to implement it and can be effective or ineffective for different CNC machines. This
51 | // would be better handled by the interface as a post-processor task, where the original g-code
52 | // is translated and inserts backlash motions that best suits the machine.
53 | // NOTE: Perhaps as a middle-ground, all that needs to be sent is a flag or special command that
54 | // indicates to Grbl what is a backlash compensation motion, so that Grbl executes the move but
55 | // doesn't update the machine position values. Since the position values used by the g-code
56 | // parser and planner are separate from the system machine positions, this is doable.
57 |
58 | // If the buffer is full: good! That means we are well ahead of the robot.
59 | // Remain in this loop until there is room in the buffer.
60 | do {
61 | protocol_execute_realtime(); // Check for any run-time commands
62 | if (sys.abort) { return; } // Bail, if system abort.
63 | if ( plan_check_full_buffer() ) { protocol_auto_cycle_start(); } // Auto-cycle start when buffer is full.
64 | else { break; }
65 | delay(0);
66 | } while (1);
67 |
68 | // Plan and queue motion into planner buffer
69 | if (plan_buffer_line(target, pl_data) == PLAN_EMPTY_BLOCK) {
70 | if (bit_istrue(settings.flags,BITFLAG_LASER_MODE)) {
71 | // Correctly set spindle state, if there is a coincident position passed. Forces a buffer
72 | // sync while in M3 laser mode only.
73 | if (pl_data->condition & PL_COND_FLAG_SPINDLE_CW) {
74 | spindle_sync(PL_COND_FLAG_SPINDLE_CW, pl_data->spindle_speed);
75 | }
76 | }
77 | }
78 | }
79 |
80 |
81 | // Execute an arc in offset mode format. position == current xyz, target == target xyz,
82 | // offset == offset from current xyz, axis_X defines circle plane in tool space, axis_linear is
83 | // the direction of helical travel, radius == circle radius, isclockwise boolean. Used
84 | // for vector transformation direction.
85 | // The arc is approximated by generating a huge number of tiny, linear segments. The chordal tolerance
86 | // of each segment is configured in settings.arc_tolerance, which is defined to be the maximum normal
87 | // distance from segment to the circle when the end points both lie on the circle.
88 | void mc_arc(float *target, plan_line_data_t *pl_data, float *position, float *offset, float radius,
89 | uint8_t axis_0, uint8_t axis_1, uint8_t axis_linear, uint8_t is_clockwise_arc)
90 | {
91 | float center_axis0 = position[axis_0] + offset[axis_0];
92 | float center_axis1 = position[axis_1] + offset[axis_1];
93 | float r_axis0 = -offset[axis_0]; // Radius vector from center to current location
94 | float r_axis1 = -offset[axis_1];
95 | float rt_axis0 = target[axis_0] - center_axis0;
96 | float rt_axis1 = target[axis_1] - center_axis1;
97 |
98 | // CCW angle between position and target from circle center. Only one atan2() trig computation required.
99 | float angular_travel = atan2(r_axis0*rt_axis1-r_axis1*rt_axis0, r_axis0*rt_axis0+r_axis1*rt_axis1);
100 | if (is_clockwise_arc) { // Correct atan2 output per direction
101 | if (angular_travel >= -ARC_ANGULAR_TRAVEL_EPSILON) { angular_travel -= 2*M_PI; }
102 | } else {
103 | if (angular_travel <= ARC_ANGULAR_TRAVEL_EPSILON) { angular_travel += 2*M_PI; }
104 | }
105 |
106 | // NOTE: Segment end points are on the arc, which can lead to the arc diameter being smaller by up to
107 | // (2x) settings.arc_tolerance. For 99% of users, this is just fine. If a different arc segment fit
108 | // is desired, i.e. least-squares, midpoint on arc, just change the mm_per_arc_segment calculation.
109 | // For the intended uses of Grbl, this value shouldn't exceed 2000 for the strictest of cases.
110 | uint16_t segments = floor(fabs(0.5*angular_travel*radius)/
111 | sqrt(settings.arc_tolerance*(2*radius - settings.arc_tolerance)) );
112 |
113 | if (segments) {
114 | // Multiply inverse feed_rate to compensate for the fact that this movement is approximated
115 | // by a number of discrete segments. The inverse feed_rate should be correct for the sum of
116 | // all segments.
117 | if (pl_data->condition & PL_COND_FLAG_INVERSE_TIME) {
118 | pl_data->feed_rate *= segments;
119 | bit_false(pl_data->condition,PL_COND_FLAG_INVERSE_TIME); // Force as feed absolute mode over arc segments.
120 | }
121 |
122 | float theta_per_segment = angular_travel/segments;
123 | float linear_per_segment = (target[axis_linear] - position[axis_linear])/segments;
124 |
125 | /* Vector rotation by transformation matrix: r is the original vector, r_T is the rotated vector,
126 | and phi is the angle of rotation. Solution approach by Jens Geisler.
127 | r_T = [cos(phi) -sin(phi);
128 | sin(phi) cos(phi] * r ;
129 |
130 | For arc generation, the center of the circle is the axis of rotation and the radius vector is
131 | defined from the circle center to the initial position. Each line segment is formed by successive
132 | vector rotations. Single precision values can accumulate error greater than tool precision in rare
133 | cases. So, exact arc path correction is implemented. This approach avoids the problem of too many very
134 | expensive trig operations [sin(),cos(),tan()] which can take 100-200 usec each to compute.
135 |
136 | Small angle approximation may be used to reduce computation overhead further. A third-order approximation
137 | (second order sin() has too much error) holds for most, if not, all CNC applications. Note that this
138 | approximation will begin to accumulate a numerical drift error when theta_per_segment is greater than
139 | ~0.25 rad(14 deg) AND the approximation is successively used without correction several dozen times. This
140 | scenario is extremely unlikely, since segment lengths and theta_per_segment are automatically generated
141 | and scaled by the arc tolerance setting. Only a very large arc tolerance setting, unrealistic for CNC
142 | applications, would cause this numerical drift error. However, it is best to set N_ARC_CORRECTION from a
143 | low of ~4 to a high of ~20 or so to avoid trig operations while keeping arc generation accurate.
144 |
145 | This approximation also allows mc_arc to immediately insert a line segment into the planner
146 | without the initial overhead of computing cos() or sin(). By the time the arc needs to be applied
147 | a correction, the planner should have caught up to the lag caused by the initial mc_arc overhead.
148 | This is important when there are successive arc motions.
149 | */
150 | // Computes: cos_T = 1 - theta_per_segment^2/2, sin_T = theta_per_segment - theta_per_segment^3/6) in ~52usec
151 | float cos_T = 2.0 - theta_per_segment*theta_per_segment;
152 | float sin_T = theta_per_segment*0.16666667*(cos_T + 4.0);
153 | cos_T *= 0.5;
154 |
155 | float sin_Ti;
156 | float cos_Ti;
157 | float r_axisi;
158 | uint16_t i;
159 | uint8_t count = 0;
160 |
161 | for (i = 1; i.
20 | */
21 |
22 | #ifndef motion_control_h
23 | #define motion_control_h
24 |
25 |
26 | // System motion commands must have a line number of zero.
27 | #define HOMING_CYCLE_LINE_NUMBER 0
28 | #define PARKING_MOTION_LINE_NUMBER 0
29 |
30 | #define HOMING_CYCLE_ALL 0 // Must be zero.
31 | #define HOMING_CYCLE_X bit(X_AXIS)
32 | #define HOMING_CYCLE_Y bit(Y_AXIS)
33 | #define HOMING_CYCLE_Z bit(Z_AXIS)
34 |
35 |
36 | // Execute linear motion in absolute millimeter coordinates. Feed rate given in millimeters/second
37 | // unless invert_feed_rate is true. Then the feed_rate means that the motion should be completed in
38 | // (1 minute)/feed_rate time.
39 | void mc_line(float *target, plan_line_data_t *pl_data);
40 |
41 | // Execute an arc in offset mode format. position == current xyz, target == target xyz,
42 | // offset == offset from current xyz, axis_XXX defines circle plane in tool space, axis_linear is
43 | // the direction of helical travel, radius == circle radius, is_clockwise_arc boolean. Used
44 | // for vector transformation direction.
45 | void mc_arc(float *target, plan_line_data_t *pl_data, float *position, float *offset, float radius,
46 | uint8_t axis_0, uint8_t axis_1, uint8_t axis_linear, uint8_t is_clockwise_arc);
47 |
48 | // Dwell for a specific number of seconds
49 | void mc_dwell(float seconds);
50 |
51 | // Perform homing cycle to locate machine zero. Requires limit switches.
52 | void mc_homing_cycle(uint8_t cycle_mask);
53 |
54 | // Perform tool length probe cycle. Requires probe switch.
55 | uint8_t mc_probe_cycle(float *target, plan_line_data_t *pl_data, uint8_t parser_flags);
56 |
57 | // Handles updating the override control state.
58 | void mc_override_ctrl_update(uint8_t override_state);
59 |
60 | // Plans and executes the single special motion case for parking. Independent of main planner buffer.
61 | void mc_parking_motion(float *parking_target, plan_line_data_t *pl_data);
62 |
63 | // Performs system reset. If in motion state, kills all motion and sets system alarm.
64 | void mc_reset();
65 |
66 | #endif
67 |
--------------------------------------------------------------------------------
/lib/grbl/src/nuts_bolts.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | nuts_bolts.c - Shared functions
3 | Part of Grbl
4 |
5 | Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC
6 | Copyright (c) 2009-2011 Simen Svale Skogsrud
7 |
8 | Grbl is free software: you can redistribute it and/or modify
9 | it under the terms of the GNU General Public License as published by
10 | the Free Software Foundation, either version 3 of the License, or
11 | (at your option) any later version.
12 |
13 | Grbl is distributed in the hope that it will be useful,
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | GNU General Public License for more details.
17 |
18 | You should have received a copy of the GNU General Public License
19 | along with Grbl. If not, see .
20 | */
21 |
22 | #include "grbl.hpp"
23 |
24 | #define MAX_INT_DIGITS 8 // Maximum number of digits in int32 (and float)
25 |
26 |
27 | // Extracts a floating point value from a string. The following code is based loosely on
28 | // the avr-libc strtod() function by Michael Stumpf and Dmitry Xmelkov and many freely
29 | // available conversion method examples, but has been highly optimized for Grbl. For known
30 | // CNC applications, the typical decimal value is expected to be in the range of E0 to E-4.
31 | // Scientific notation is officially not supported by g-code, and the 'E' character may
32 | // be a g-code word on some CNC systems. So, 'E' notation will not be recognized.
33 | // NOTE: Thanks to Radu-Eosif Mihailescu for identifying the issues with using strtod().
34 | uint8_t read_float(char *line, uint8_t *char_counter, float *float_ptr)
35 | {
36 | char *ptr = line + *char_counter;
37 | unsigned char c;
38 |
39 | // Grab first character and increment pointer. No spaces assumed in line.
40 | c = *ptr++;
41 |
42 | // Capture initial positive/minus character
43 | bool isnegative = false;
44 | if (c == '-') {
45 | isnegative = true;
46 | c = *ptr++;
47 | } else if (c == '+') {
48 | c = *ptr++;
49 | }
50 |
51 | // Extract number into fast integer. Track decimal in terms of exponent value.
52 | uint32_t intval = 0;
53 | int8_t exp = 0;
54 | uint8_t ndigit = 0;
55 | bool isdecimal = false;
56 | while(1) {
57 | c -= '0';
58 | if (c <= 9) {
59 | ndigit++;
60 | if (ndigit <= MAX_INT_DIGITS) {
61 | if (isdecimal) { exp--; }
62 | intval = (((intval << 2) + intval) << 1) + c; // intval*10 + c
63 | } else {
64 | if (!(isdecimal)) { exp++; } // Drop overflow digits
65 | }
66 | } else if (c == (('.'-'0') & 0xff) && !(isdecimal)) {
67 | isdecimal = true;
68 | } else {
69 | break;
70 | }
71 | c = *ptr++;
72 | }
73 |
74 | // Return if no digits have been read.
75 | if (!ndigit) { return(false); };
76 |
77 | // Convert integer into floating point.
78 | float fval;
79 | fval = (float)intval;
80 |
81 | // Apply decimal. Should perform no more than two floating point multiplications for the
82 | // expected range of E0 to E-4.
83 | if (fval != 0) {
84 | while (exp <= -2) {
85 | fval *= 0.01;
86 | exp += 2;
87 | }
88 | if (exp < 0) {
89 | fval *= 0.1;
90 | } else if (exp > 0) {
91 | do {
92 | fval *= 10.0;
93 | } while (--exp > 0);
94 | }
95 | }
96 |
97 | // Assign floating point value with correct sign.
98 | if (isnegative) {
99 | *float_ptr = -fval;
100 | } else {
101 | *float_ptr = fval;
102 | }
103 |
104 | *char_counter = ptr - line - 1; // Set char_counter to next statement
105 |
106 | return(true);
107 | }
108 |
109 |
110 | // Non-blocking delay function used for general operation and suspend features.
111 | void delay_sec(float seconds, uint8_t mode)
112 | {
113 | uint16_t i = ceil(1000/DWELL_TIME_STEP*seconds);
114 | while (i-- > 0) {
115 | ESP.wdtFeed();
116 | if (sys.abort) { return; }
117 | if (mode == DELAY_MODE_DWELL) {
118 | protocol_execute_realtime();
119 | } else { // DELAY_MODE_SYS_SUSPEND
120 | // Execute rt_system() only to avoid nesting suspend loops.
121 | protocol_exec_rt_system();
122 | if (sys.suspend & SUSPEND_RESTART_RETRACT) { return; } // Bail, if safety door reopens.
123 | }
124 | delay_ms(DWELL_TIME_STEP); // Delay DWELL_TIME_STEP increment
125 | }
126 | }
127 |
128 | // Delays variable defined milliseconds. Compiler compatibility fix for _delay_ms(),
129 | // which only accepts constants in future compiler releases.
130 | void delay_ms(uint16_t ms)
131 | {
132 | while ( ms-- ) { ESP.wdtFeed(); delayMicroseconds(950); }
133 | }
134 |
135 | // Simple hypotenuse computation function.
136 | float hypot_f(float x, float y) { return(sqrt(x*x + y*y)); }
137 |
138 |
139 | float convert_delta_vector_to_unit_vector(float *vector)
140 | {
141 | uint8_t idx;
142 | float magnitude = 0.0;
143 | for (idx=0; idx.
20 | */
21 |
22 | #ifndef nuts_bolts_h
23 | #define nuts_bolts_h
24 |
25 | #define SOME_LARGE_VALUE 1.0E+38
26 |
27 | // Axis array index values. Must start with 0 and be continuous.
28 | #define N_AXIS 8 // Number of axes
29 | #define X_AXIS 0 // Axis indexing value.
30 | #define Y_AXIS 1
31 | #define Z_AXIS 2
32 | #define A_AXIS 3
33 | #define B_AXIS 4
34 | #define C_AXIS 5
35 | #define D_AXIS 6
36 | #define E_AXIS 7
37 |
38 | // CoreXY motor assignments. DO NOT ALTER.
39 | // NOTE: If the A and B motor axis bindings are changed, this effects the CoreXY equations.
40 | #ifdef COREXY
41 | #define A_MOTOR X_AXIS // Must be X_AXIS
42 | #define B_MOTOR Y_AXIS // Must be Y_AXIS
43 | #endif
44 |
45 | // Conversions
46 | #define MM_PER_INCH (25.40)
47 | #define INCH_PER_MM (0.0393701)
48 | #define TICKS_PER_MICROSECOND (F_CPU / 16000000)
49 |
50 | #define DELAY_MODE_DWELL 0
51 | #define DELAY_MODE_SYS_SUSPEND 1
52 |
53 | // Useful macros
54 | #define clear_vector(a) memset(a, 0, sizeof(a))
55 | #define clear_vector_float(a) memset(a, 0.0, sizeof(float)*N_AXIS)
56 | // #define clear_vector_long(a) memset(a, 0.0, sizeof(long)*N_AXIS)
57 | #define max(a,b) (((a) > (b)) ? (a) : (b))
58 | #define min(a,b) (((a) < (b)) ? (a) : (b))
59 | #define isequal_position_vector(a,b) !(memcmp(a, b, sizeof(float)*N_AXIS))
60 |
61 | // Bit field and masking macros
62 | #ifndef bit
63 | #define bit(n) (1 << n)
64 | #endif
65 | #define bit_true(x,mask) (x) |= (mask)
66 | #define bit_false(x,mask) (x) &= ~(mask)
67 | #define bit_istrue(x,mask) ((x & mask) != 0)
68 | #define bit_isfalse(x,mask) ((x & mask) == 0)
69 |
70 | // Read a floating point value from a string. Line points to the input buffer, char_counter
71 | // is the indexer pointing to the current character of the line, while float_ptr is
72 | // a pointer to the result variable. Returns true when it succeeds
73 | uint8_t read_float(char *line, uint8_t *char_counter, float *float_ptr);
74 |
75 | // Non-blocking delay function used for general operation and suspend features.
76 | void delay_sec(float seconds, uint8_t mode);
77 |
78 | // Delays variable-defined milliseconds. Compiler compatibility fix for _delay_ms().
79 | void delay_ms(uint16_t ms);
80 |
81 | // Computes hypotenuse, avoiding avr-gcc's bloated version and the extra error checking.
82 | float hypot_f(float x, float y);
83 |
84 | float convert_delta_vector_to_unit_vector(float *vector);
85 | float limit_value_by_axis_maximum(float *max_value, float *unit_vec);
86 |
87 | #endif
88 |
--------------------------------------------------------------------------------
/lib/grbl/src/planner.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | planner.h - buffers movement commands and manages the acceleration profile plan
3 | Part of Grbl
4 |
5 | Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC
6 | Copyright (c) 2009-2011 Simen Svale Skogsrud
7 |
8 | Grbl is free software: you can redistribute it and/or modify
9 | it under the terms of the GNU General Public License as published by
10 | the Free Software Foundation, either version 3 of the License, or
11 | (at your option) any later version.
12 |
13 | Grbl is distributed in the hope that it will be useful,
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | GNU General Public License for more details.
17 |
18 | You should have received a copy of the GNU General Public License
19 | along with Grbl. If not, see .
20 | */
21 |
22 | #ifndef planner_h
23 | #define planner_h
24 |
25 |
26 | // The number of linear motions that can be in the plan at any give time
27 | #ifndef BLOCK_BUFFER_SIZE
28 | #ifdef USE_LINE_NUMBERS
29 | #define BLOCK_BUFFER_SIZE 15
30 | #else
31 | #define BLOCK_BUFFER_SIZE 16
32 | #endif
33 | #endif
34 |
35 | // Returned status message from planner.
36 | #define PLAN_OK true
37 | #define PLAN_EMPTY_BLOCK false
38 |
39 | // Define planner data condition flags. Used to denote running conditions of a block.
40 | #define PL_COND_FLAG_RAPID_MOTION bit(0)
41 | #define PL_COND_FLAG_SYSTEM_MOTION bit(1) // Single motion. Circumvents planner state. Used by home/park.
42 | #define PL_COND_FLAG_NO_FEED_OVERRIDE bit(2) // Motion does not honor feed override.
43 | #define PL_COND_FLAG_INVERSE_TIME bit(3) // Interprets feed rate value as inverse time when set.
44 | #define PL_COND_FLAG_SPINDLE_CW bit(4)
45 | #define PL_COND_FLAG_SPINDLE_CCW bit(5)
46 | #define PL_COND_FLAG_COOLANT_FLOOD bit(6)
47 | #define PL_COND_FLAG_COOLANT_MIST bit(7)
48 | #define PL_COND_MOTION_MASK (PL_COND_FLAG_RAPID_MOTION|PL_COND_FLAG_SYSTEM_MOTION|PL_COND_FLAG_NO_FEED_OVERRIDE)
49 | #define PL_COND_SPINDLE_MASK (PL_COND_FLAG_SPINDLE_CW|PL_COND_FLAG_SPINDLE_CCW)
50 | #define PL_COND_ACCESSORY_MASK (PL_COND_FLAG_SPINDLE_CW|PL_COND_FLAG_SPINDLE_CCW|PL_COND_FLAG_COOLANT_FLOOD|PL_COND_FLAG_COOLANT_MIST)
51 |
52 |
53 | // This struct stores a linear movement of a g-code block motion with its critical "nominal" values
54 | // are as specified in the source g-code.
55 | typedef struct {
56 | // Fields used by the bresenham algorithm for tracing the line
57 | // NOTE: Used by stepper algorithm to execute the block correctly. Do not alter these values.
58 | uint32_t steps[N_AXIS]; // Step count along each axis
59 | uint32_t step_event_count; // The maximum step axis count and number of steps required to complete this block.
60 | uint8_t direction_bits; // The direction bit set for this block (refers to *_DIRECTION_BIT in config.h)
61 |
62 | // Block condition data to ensure correct execution depending on states and overrides.
63 | uint8_t condition; // Block bitflag variable defining block run conditions. Copied from pl_line_data.
64 | #ifdef USE_LINE_NUMBERS
65 | int32_t line_number; // Block line number for real-time reporting. Copied from pl_line_data.
66 | #endif
67 |
68 | // Fields used by the motion planner to manage acceleration. Some of these values may be updated
69 | // by the stepper module during execution of special motion cases for replanning purposes.
70 | float entry_speed_sqr; // The current planned entry speed at block junction in (mm/min)^2
71 | float max_entry_speed_sqr; // Maximum allowable entry speed based on the minimum of junction limit and
72 | // neighboring nominal speeds with overrides in (mm/min)^2
73 | float acceleration; // Axis-limit adjusted line acceleration in (mm/min^2). Does not change.
74 | float millimeters; // The remaining distance for this block to be executed in (mm).
75 | // NOTE: This value may be altered by stepper algorithm during execution.
76 |
77 | // Stored rate limiting data used by planner when changes occur.
78 | float max_junction_speed_sqr; // Junction entry speed limit based on direction vectors in (mm/min)^2
79 | float rapid_rate; // Axis-limit adjusted maximum rate for this block direction in (mm/min)
80 | float programmed_rate; // Programmed rate of this block (mm/min).
81 |
82 | #ifdef VARIABLE_SPINDLE
83 | // Stored spindle speed data used by spindle overrides and resuming methods.
84 | float spindle_speed; // Block spindle speed. Copied from pl_line_data.
85 | #endif
86 | } plan_block_t;
87 |
88 |
89 | // Planner data prototype. Must be used when passing new motions to the planner.
90 | typedef struct {
91 | float feed_rate; // Desired feed rate for line motion. Value is ignored, if rapid motion.
92 | float spindle_speed; // Desired spindle speed through line motion.
93 | uint8_t condition; // Bitflag variable to indicate planner conditions. See defines above.
94 | #ifdef USE_LINE_NUMBERS
95 | int32_t line_number; // Desired line number to report when executing.
96 | #endif
97 | } plan_line_data_t;
98 |
99 |
100 | // Initialize and reset the motion plan subsystem
101 | void plan_reset(); // Reset all
102 | void plan_reset_buffer(); // Reset buffer only.
103 |
104 | // Add a new linear movement to the buffer. target[N_AXIS] is the signed, absolute target position
105 | // in millimeters. Feed rate specifies the speed of the motion. If feed rate is inverted, the feed
106 | // rate is taken to mean "frequency" and would complete the operation in 1/feed_rate minutes.
107 | uint8_t plan_buffer_line(float *target, plan_line_data_t *pl_data);
108 |
109 | // Called when the current block is no longer needed. Discards the block and makes the memory
110 | // availible for new blocks.
111 | void plan_discard_current_block();
112 |
113 | // Gets the planner block for the special system motion cases. (Parking/Homing)
114 | plan_block_t *plan_get_system_motion_block();
115 |
116 | // Gets the current block. Returns NULL if buffer empty
117 | plan_block_t *plan_get_current_block();
118 |
119 | // Called periodically by step segment buffer. Mostly used internally by planner.
120 | uint8_t plan_next_block_index(uint8_t block_index);
121 |
122 | // Called by step segment buffer when computing executing block velocity profile.
123 | float plan_get_exec_block_exit_speed_sqr();
124 |
125 | // Called by main program during planner calculations and step segment buffer during initialization.
126 | float plan_compute_profile_nominal_speed(plan_block_t *block);
127 |
128 | // Re-calculates buffered motions profile parameters upon a motion-based override change.
129 | void plan_update_velocity_profile_parameters();
130 |
131 | // Reset the planner position vector (in steps)
132 | void plan_sync_position();
133 |
134 | // Reinitialize plan with a partially completed block
135 | void plan_cycle_reinitialize();
136 |
137 | // Returns the number of available blocks are in the planner buffer.
138 | uint8_t plan_get_block_buffer_available();
139 |
140 | // Returns the number of active blocks are in the planner buffer.
141 | // NOTE: Deprecated. Not used unless classic status reports are enabled in config.h
142 | uint8_t plan_get_block_buffer_count();
143 |
144 | // Returns the status of the block ring buffer. True, if buffer is full.
145 | uint8_t plan_check_full_buffer();
146 |
147 | void plan_get_planner_mpos(float *target);
148 |
149 |
150 | #endif
151 |
--------------------------------------------------------------------------------
/lib/grbl/src/print.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | print.c - Functions for formatting output strings
3 | Part of Grbl
4 |
5 | Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC
6 | Copyright (c) 2009-2011 Simen Svale Skogsrud
7 |
8 | Grbl is free software: you can redistribute it and/or modify
9 | it under the terms of the GNU General Public License as published by
10 | the Free Software Foundation, either version 3 of the License, or
11 | (at your option) any later version.
12 |
13 | Grbl is distributed in the hope that it will be useful,
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | GNU General Public License for more details.
17 |
18 | You should have received a copy of the GNU General Public License
19 | along with Grbl. If not, see .
20 | */
21 |
22 | #include "grbl.hpp"
23 |
24 |
25 | /*void printString(const char *s)
26 | {
27 | while (*s)
28 | serial_write(*s++);
29 | }*/
30 |
31 |
32 | // Print a string stored in PGM-memory
33 | /*void printPgmString(const char *s)
34 | {
35 | char c;
36 | while ((c = pgm_read_byte_near(s++)))
37 | serial_write(c);
38 | }*/
39 |
40 |
41 | // void printIntegerInBase(unsigned long n, unsigned long base)
42 | // {
43 | // unsigned char buf[8 * sizeof(long)]; // Assumes 8-bit chars.
44 | // unsigned long i = 0;
45 | //
46 | // if (n == 0) {
47 | // serial_write('0');
48 | // return;
49 | // }
50 | //
51 | // while (n > 0) {
52 | // buf[i++] = n % base;
53 | // n /= base;
54 | // }
55 | //
56 | // for (; i > 0; i--)
57 | // serial_write(buf[i - 1] < 10 ?
58 | // '0' + buf[i - 1] :
59 | // 'A' + buf[i - 1] - 10);
60 | // }
61 |
62 |
63 | // Prints an uint8 variable in base 10.
64 | void print_uint8_base10(uint8_t n)
65 | {
66 | uint8_t digit_a = 0;
67 | uint8_t digit_b = 0;
68 | if (n >= 100) { // 100-255
69 | digit_a = '0' + n % 10;
70 | n /= 10;
71 | }
72 | if (n >= 10) { // 10-99
73 | digit_b = '0' + n % 10;
74 | n /= 10;
75 | }
76 | serial_write('0' + n);
77 | if (digit_b) { serial_write(digit_b); }
78 | if (digit_a) { serial_write(digit_a); }
79 | }
80 |
81 |
82 | // Prints an uint8 variable in base 2 with desired number of desired digits.
83 | void print_uint8_base2_ndigit(uint8_t n, uint8_t digits) {
84 | unsigned char buf[digits];
85 | uint8_t i = 0;
86 |
87 | for (; i < digits; i++) {
88 | buf[i] = n % 2 ;
89 | n /= 2;
90 | }
91 |
92 | for (; i > 0; i--)
93 | serial_write('0' + buf[i - 1]);
94 | }
95 |
96 |
97 | void print_uint32_base10(uint32_t n)
98 | {
99 | if (n == 0) {
100 | serial_write('0');
101 | return;
102 | }
103 |
104 | unsigned char buf[10];
105 | uint8_t i = 0;
106 |
107 | while (n > 0) {
108 | buf[i++] = n % 10;
109 | n /= 10;
110 | }
111 |
112 | for (; i > 0; i--)
113 | serial_write('0' + buf[i-1]);
114 | }
115 |
116 |
117 | void printInteger(long n)
118 | {
119 | if (n < 0) {
120 | serial_write('-');
121 | print_uint32_base10(-n);
122 | } else {
123 | print_uint32_base10(n);
124 | }
125 | }
126 |
127 |
128 | // Convert float to string by immediately converting to a long integer, which contains
129 | // more digits than a float. Number of decimal places, which are tracked by a counter,
130 | // may be set by the user. The integer is then efficiently converted to a string.
131 | // NOTE: AVR '%' and '/' integer operations are very efficient. Bitshifting speed-up
132 | // techniques are actually just slightly slower. Found this out the hard way.
133 | void printFloat(float n, uint8_t decimal_places)
134 | {
135 | if (n < 0) {
136 | serial_write('-');
137 | n = -n;
138 | }
139 |
140 | uint8_t decimals = decimal_places;
141 | while (decimals >= 2) { // Quickly convert values expected to be E0 to E-4.
142 | n *= 100;
143 | decimals -= 2;
144 | }
145 | if (decimals) { n *= 10; }
146 | n += 0.5; // Add rounding factor. Ensures carryover through entire value.
147 |
148 | // Generate digits backwards and store in string.
149 | unsigned char buf[13];
150 | uint8_t i = 0;
151 | uint32_t a = (long)n;
152 | while(a > 0) {
153 | buf[i++] = (a % 10) + '0'; // Get digit
154 | a /= 10;
155 | }
156 | while (i < decimal_places) {
157 | buf[i++] = '0'; // Fill in zeros to decimal point for (n < 1)
158 | }
159 | if (i == decimal_places) { // Fill in leading zero, if needed.
160 | buf[i++] = '0';
161 | }
162 |
163 | // Print the generated string.
164 | for (; i > 0; i--) {
165 | if (i == decimal_places) { serial_write('.'); } // Insert decimal point in right place.
166 | serial_write(buf[i-1]);
167 | }
168 | }
169 |
170 |
171 | // Floating value printing handlers for special variables types used in Grbl and are defined
172 | // in the config.h.
173 | // - CoordValue: Handles all position or coordinate values in inches or mm reporting.
174 | // - RateValue: Handles feed rate and current velocity in inches or mm reporting.
175 | void printFloat_CoordValue(float n) {
176 | if (bit_istrue(settings.flags,BITFLAG_REPORT_INCHES)) {
177 | printFloat(n*INCH_PER_MM,N_DECIMAL_COORDVALUE_INCH);
178 | } else {
179 | printFloat(n,N_DECIMAL_COORDVALUE_MM);
180 | }
181 | }
182 |
183 | void printFloat_RateValue(float n) {
184 | if (bit_istrue(settings.flags,BITFLAG_REPORT_INCHES)) {
185 | printFloat(n*INCH_PER_MM,N_DECIMAL_RATEVALUE_INCH);
186 | } else {
187 | printFloat(n,N_DECIMAL_RATEVALUE_MM);
188 | }
189 | }
190 |
191 | // Debug tool to print free memory in bytes at the called point.
192 | // NOTE: Keep commented unless using. Part of this function always gets compiled in.
193 | // void printFreeMemory()
194 | // {
195 | // extern int __heap_start, *__brkval;
196 | // uint16_t free; // Up to 64k values.
197 | // free = (int) &free - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
198 | // printInteger((int32_t)free);
199 | // printString(" ");
200 | // }
201 |
--------------------------------------------------------------------------------
/lib/grbl/src/print.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | print.h - Functions for formatting output strings
3 | Part of Grbl
4 |
5 | Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC
6 | Copyright (c) 2009-2011 Simen Svale Skogsrud
7 |
8 | Grbl is free software: you can redistribute it and/or modify
9 | it under the terms of the GNU General Public License as published by
10 | the Free Software Foundation, either version 3 of the License, or
11 | (at your option) any later version.
12 |
13 | Grbl is distributed in the hope that it will be useful,
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | GNU General Public License for more details.
17 |
18 | You should have received a copy of the GNU General Public License
19 | along with Grbl. If not, see .
20 | */
21 |
22 | #ifndef print_h
23 | #define print_h
24 |
25 |
26 | //void printString(const char *s);
27 |
28 | //void printPgmString(const char *s);
29 |
30 | //void printInteger(long n);
31 |
32 | //void print_uint32_base10(uint32_t n);
33 |
34 | // Prints an uint8 variable in base 10.
35 | //void print_uint8_base10(uint8_t n);
36 |
37 | // Prints an uint8 variable in base 2 with desired number of desired digits.
38 | //void print_uint8_base2_ndigit(uint8_t n, uint8_t digits);
39 |
40 | //void printFloat(float n, uint8_t decimal_places);
41 |
42 | // Floating value printing handlers for special variables types used in Grbl.
43 | // - CoordValue: Handles all position or coordinate values in inches or mm reporting.
44 | // - RateValue: Handles feed rate and current velocity in inches or mm reporting.
45 | //void printFloat_CoordValue(float n);
46 | //void printFloat_RateValue(float n);
47 |
48 | // Debug tool to print free memory in bytes at the called point. Not used otherwise.
49 | //void printFreeMemory();
50 |
51 | #endif
52 |
--------------------------------------------------------------------------------
/lib/grbl/src/probe.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | probe.c - code pertaining to probing methods
3 | Part of Grbl
4 |
5 | Copyright (c) 2014-2016 Sungeun K. Jeon for Gnea Research LLC
6 |
7 | Grbl is free software: you can redistribute it and/or modify
8 | it under the terms of the GNU General Public License as published by
9 | the Free Software Foundation, either version 3 of the License, or
10 | (at your option) any later version.
11 |
12 | Grbl is distributed in the hope that it will be useful,
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | GNU General Public License for more details.
16 |
17 | You should have received a copy of the GNU General Public License
18 | along with Grbl. If not, see .
19 | */
20 |
21 | #include "grbl.hpp"
22 |
23 |
24 | // Inverts the probe pin state depending on user settings and probing cycle mode.
25 | uint8_t probe_invert_mask;
26 |
27 |
28 | // Probe pin initialization routine.
29 | void probe_init()
30 | {
31 | /*PROBE_DDR &= ~(PROBE_MASK); // Configure as input pins
32 | #ifdef DISABLE_PROBE_PIN_PULL_UP
33 | PROBE_PORT &= ~(PROBE_MASK); // Normal low operation. Requires external pull-down.
34 | #else
35 | PROBE_PORT |= PROBE_MASK; // Enable internal pull-up resistors. Normal high operation.
36 | #endif
37 | */
38 | probe_configure_invert_mask(false); // Initialize invert mask.
39 | }
40 |
41 |
42 | // Called by probe_init() and the mc_probe() routines. Sets up the probe pin invert mask to
43 | // appropriately set the pin logic according to setting for normal-high/normal-low operation
44 | // and the probing cycle modes for toward-workpiece/away-from-workpiece.
45 | void probe_configure_invert_mask(uint8_t is_probe_away)
46 | {
47 | probe_invert_mask = 0; // Initialize as zero.
48 | if (bit_isfalse(settings.flags,BITFLAG_INVERT_PROBE_PIN)) { probe_invert_mask ^= PROBE_MASK; }
49 | if (is_probe_away) { probe_invert_mask ^= PROBE_MASK; }
50 | }
51 |
52 |
53 | // Returns the probe pin state. Triggered = true. Called by gcode parser and probe state monitor.
54 | uint8_t probe_get_state() {
55 | return((PROBE_BIT & PROBE_MASK) ^ probe_invert_mask);
56 | }
57 |
58 |
59 | // Monitors probe pin state and records the system position when detected. Called by the
60 | // stepper ISR per ISR tick.
61 | // NOTE: This function must be extremely efficient as to not bog down the stepper ISR.
62 | void probe_state_monitor()
63 | {
64 | if (probe_get_state()) {
65 | sys_probe_state = PROBE_OFF;
66 | memcpy(sys_probe_position, sys_position, sizeof(sys_position));
67 | bit_true(sys_rt_exec_state, EXEC_MOTION_CANCEL);
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/lib/grbl/src/probe.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | probe.h - code pertaining to probing methods
3 | Part of Grbl
4 |
5 | Copyright (c) 2014-2016 Sungeun K. Jeon for Gnea Research LLC
6 |
7 | Grbl is free software: you can redistribute it and/or modify
8 | it under the terms of the GNU General Public License as published by
9 | the Free Software Foundation, either version 3 of the License, or
10 | (at your option) any later version.
11 |
12 | Grbl is distributed in the hope that it will be useful,
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | GNU General Public License for more details.
16 |
17 | You should have received a copy of the GNU General Public License
18 | along with Grbl. If not, see .
19 | */
20 |
21 | #ifndef probe_h
22 | #define probe_h
23 |
24 | // Values that define the probing state machine.
25 | #define PROBE_OFF 0 // Probing disabled or not in use. (Must be zero.)
26 | #define PROBE_ACTIVE 1 // Actively watching the input pin.
27 |
28 | // Probe pin initialization routine.
29 | void probe_init();
30 |
31 | // Called by probe_init() and the mc_probe() routines. Sets up the probe pin invert mask to
32 | // appropriately set the pin logic according to setting for normal-high/normal-low operation
33 | // and the probing cycle modes for toward-workpiece/away-from-workpiece.
34 | void probe_configure_invert_mask(uint8_t is_probe_away);
35 |
36 | // Returns probe pin state. Triggered = true. Called by gcode parser and probe state monitor.
37 | uint8_t probe_get_state();
38 |
39 | // Monitors probe pin state and records the system position when detected. Called by the
40 | // stepper ISR per ISR tick.
41 | void probe_state_monitor();
42 |
43 | #endif
44 |
--------------------------------------------------------------------------------
/lib/grbl/src/protocol.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | protocol.h - controls Grbl execution protocol and procedures
3 | Part of Grbl
4 |
5 | Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC
6 | Copyright (c) 2009-2011 Simen Svale Skogsrud
7 |
8 | Grbl is free software: you can redistribute it and/or modify
9 | it under the terms of the GNU General Public License as published by
10 | the Free Software Foundation, either version 3 of the License, or
11 | (at your option) any later version.
12 |
13 | Grbl is distributed in the hope that it will be useful,
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | GNU General Public License for more details.
17 |
18 | You should have received a copy of the GNU General Public License
19 | along with Grbl. If not, see .
20 | */
21 |
22 | #ifndef protocol_h
23 | #define protocol_h
24 |
25 | // Line buffer size from the serial input stream to be executed.
26 | // NOTE: Not a problem except for extreme cases, but the line buffer size can be too small
27 | // and g-code blocks can get truncated. Officially, the g-code standards support up to 256
28 | // characters. In future versions, this will be increased, when we know how much extra
29 | // memory space we can invest into here or we re-write the g-code parser not to have this
30 | // buffer.
31 | #ifndef LINE_BUFFER_SIZE
32 | #define LINE_BUFFER_SIZE 200
33 | #endif
34 |
35 | // Starts Grbl main loop. It handles all incoming characters from the serial port and executes
36 | // them as they complete. It is also responsible for finishing the initialization procedures.
37 | void protocol_main_loop();
38 |
39 | // Checks and executes a realtime command at various stop points in main program
40 | void protocol_execute_realtime();
41 | void protocol_exec_rt_system();
42 |
43 | // Executes the auto cycle feature, if enabled.
44 | void protocol_auto_cycle_start();
45 |
46 | // Block until all buffered steps are executed
47 | void protocol_buffer_synchronize();
48 |
49 | #endif
50 |
--------------------------------------------------------------------------------
/lib/grbl/src/report.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | report.h - reporting and messaging methods
3 | Part of Grbl
4 |
5 | Copyright (c) 2012-2016 Sungeun K. Jeon for Gnea Research LLC
6 |
7 | Grbl is free software: you can redistribute it and/or modify
8 | it under the terms of the GNU General Public License as published by
9 | the Free Software Foundation, either version 3 of the License, or
10 | (at your option) any later version.
11 |
12 | Grbl is distributed in the hope that it will be useful,
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | GNU General Public License for more details.
16 |
17 | You should have received a copy of the GNU General Public License
18 | along with Grbl. If not, see .
19 | */
20 | #ifndef report_h
21 | #define report_h
22 |
23 | // Define Grbl status codes. Valid values (0-255)
24 | #define STATUS_OK 0
25 | #define STATUS_EXPECTED_COMMAND_LETTER 1
26 | #define STATUS_BAD_NUMBER_FORMAT 2
27 | #define STATUS_INVALID_STATEMENT 3
28 | #define STATUS_NEGATIVE_VALUE 4
29 | #define STATUS_SETTING_DISABLED 5
30 | #define STATUS_SETTING_STEP_PULSE_MIN 6
31 | #define STATUS_SETTING_READ_FAIL 7
32 | #define STATUS_IDLE_ERROR 8
33 | #define STATUS_SYSTEM_GC_LOCK 9
34 | #define STATUS_SOFT_LIMIT_ERROR 10
35 | #define STATUS_OVERFLOW 11
36 | #define STATUS_MAX_STEP_RATE_EXCEEDED 12
37 | #define STATUS_CHECK_DOOR 13
38 | #define STATUS_LINE_LENGTH_EXCEEDED 14
39 | #define STATUS_TRAVEL_EXCEEDED 15
40 | #define STATUS_INVALID_JOG_COMMAND 16
41 | #define STATUS_SETTING_DISABLED_LASER 17
42 |
43 | #define STATUS_GCODE_UNSUPPORTED_COMMAND 20
44 | #define STATUS_GCODE_MODAL_GROUP_VIOLATION 21
45 | #define STATUS_GCODE_UNDEFINED_FEED_RATE 22
46 | #define STATUS_GCODE_COMMAND_VALUE_NOT_INTEGER 23
47 | #define STATUS_GCODE_AXIS_COMMAND_CONFLICT 24
48 | #define STATUS_GCODE_WORD_REPEATED 25
49 | #define STATUS_GCODE_NO_AXIS_WORDS 26
50 | #define STATUS_GCODE_INVALID_LINE_NUMBER 27
51 | #define STATUS_GCODE_VALUE_WORD_MISSING 28
52 | #define STATUS_GCODE_UNSUPPORTED_COORD_SYS 29
53 | #define STATUS_GCODE_G53_INVALID_MOTION_MODE 30
54 | #define STATUS_GCODE_AXIS_WORDS_EXIST 31
55 | #define STATUS_GCODE_NO_AXIS_WORDS_IN_PLANE 32
56 | #define STATUS_GCODE_INVALID_TARGET 33
57 | #define STATUS_GCODE_ARC_RADIUS_ERROR 34
58 | #define STATUS_GCODE_NO_OFFSETS_IN_PLANE 35
59 | #define STATUS_GCODE_UNUSED_WORDS 36
60 | #define STATUS_GCODE_G43_DYNAMIC_AXIS_ERROR 37
61 | #define STATUS_GCODE_MAX_VALUE_EXCEEDED 38
62 |
63 | // Define Grbl alarm codes. Valid values (1-255). 0 is reserved.
64 | #define ALARM_HARD_LIMIT_ERROR EXEC_ALARM_HARD_LIMIT
65 | #define ALARM_SOFT_LIMIT_ERROR EXEC_ALARM_SOFT_LIMIT
66 | #define ALARM_ABORT_CYCLE EXEC_ALARM_ABORT_CYCLE
67 | #define ALARM_PROBE_FAIL_INITIAL EXEC_ALARM_PROBE_FAIL_INITIAL
68 | #define ALARM_PROBE_FAIL_CONTACT EXEC_ALARM_PROBE_FAIL_CONTACT
69 | #define ALARM_HOMING_FAIL_RESET EXEC_ALARM_HOMING_FAIL_RESET
70 | #define ALARM_HOMING_FAIL_DOOR EXEC_ALARM_HOMING_FAIL_DOOR
71 | #define ALARM_HOMING_FAIL_PULLOFF EXEC_ALARM_HOMING_FAIL_PULLOFF
72 | #define ALARM_HOMING_FAIL_APPROACH EXEC_ALARM_HOMING_FAIL_APPROACH
73 |
74 | // Define Grbl feedback message codes. Valid values (0-255).
75 | #define MESSAGE_CRITICAL_EVENT 1
76 | #define MESSAGE_ALARM_LOCK 2
77 | #define MESSAGE_ALARM_UNLOCK 3
78 | #define MESSAGE_ENABLED 4
79 | #define MESSAGE_DISABLED 5
80 | #define MESSAGE_SAFETY_DOOR_AJAR 6
81 | #define MESSAGE_CHECK_LIMITS 7
82 | #define MESSAGE_PROGRAM_END 8
83 | #define MESSAGE_RESTORE_DEFAULTS 9
84 | #define MESSAGE_SPINDLE_RESTORE 10
85 | #define MESSAGE_SLEEP_MODE 11
86 |
87 | #define CLIENT_SERIAL 1
88 | #define CLIENT_WEBSOCKET 2
89 | #define CLIENT_TELNET 3
90 | #define CLIENT_ALL 0xFF
91 | #define CLIENT_COUNT 3 // total number of client types regardless if they are used
92 |
93 | #define MSG_LEVEL_NONE 0 // set GRBL_MSG_LEVEL in config.h to the level you want to see
94 | #define MSG_LEVEL_ERROR 1
95 | #define MSG_LEVEL_WARNING 2
96 | #define MSG_LEVEL_INFO 3
97 | #define MSG_LEVEL_DEBUG 4
98 | #define MSG_LEVEL_VERBOSE 5
99 |
100 | // functions to send data to the user (from Grbl_Esp32)
101 | void grbl_send(uint8_t client, const char *text);
102 | void grbl_sendf(uint8_t client, const char *format, ...);
103 |
104 | // Prints system status messages.
105 | void report_status_message(uint8_t status_code, uint8_t client);
106 |
107 | // Prints system alarm messages.
108 | void report_alarm_message(uint8_t alarm_code);
109 |
110 | // Prints miscellaneous feedback messages.
111 | void report_feedback_message(uint8_t message_code);
112 |
113 | // Prints welcome message
114 | void report_init_message(uint8_t client);
115 |
116 | // Prints Grbl help and current global settings
117 | void report_grbl_help(uint8_t client);
118 |
119 | // Prints Grbl global settings
120 | void report_grbl_settings(uint8_t client);
121 |
122 | // Prints an echo of the pre-parsed line received right before execution.
123 | void report_echo_line_received(char *line, uint8_t client);
124 |
125 | // Prints realtime status report
126 | void report_realtime_status(uint8_t client);
127 |
128 | // Prints recorded probe position
129 | void report_probe_parameters(uint8_t client);
130 |
131 | // Prints Grbl NGC parameters (coordinate offsets, probe)
132 | void report_ngc_parameters(uint8_t client);
133 |
134 | // Prints current g-code parser mode state
135 | void report_gcode_modes(uint8_t client);
136 |
137 | // Prints startup line when requested and executed.
138 | void report_startup_line(uint8_t n, char *line, uint8_t client);
139 | void report_execute_startup_message(char *line, uint8_t status_code, uint8_t client);
140 |
141 | // Prints build info and user info
142 | void report_build_info(char *line, uint8_t client);
143 |
144 | #ifdef DEBUG
145 | void report_realtime_debug();
146 | #endif
147 |
148 | #endif
149 |
--------------------------------------------------------------------------------
/lib/grbl/src/serial.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | serial.c - Low level functions for sending and recieving bytes via the serial port
3 | Part of Grbl
4 |
5 | Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC
6 | Copyright (c) 2009-2011 Simen Svale Skogsrud
7 |
8 | Grbl is free software: you can redistribute it and/or modify
9 | it under the terms of the GNU General Public License as published by
10 | the Free Software Foundation, either version 3 of the License, or
11 | (at your option) any later version.
12 |
13 | Grbl is distributed in the hope that it will be useful,
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | GNU General Public License for more details.
17 |
18 | You should have received a copy of the GNU General Public License
19 | along with Grbl. If not, see .
20 | */
21 |
22 | #include "grbl.hpp"
23 | #include
24 |
25 | #define RX_RING_BUFFER (RX_BUFFER_SIZE+1)
26 | #define TX_RING_BUFFER (TX_BUFFER_SIZE+1)
27 |
28 | uint8_t serial_rx_buffer[CLIENT_COUNT][RX_RING_BUFFER];
29 | uint8_t serial_rx_buffer_head[CLIENT_COUNT] = {0};
30 | volatile uint8_t serial_rx_buffer_tail[CLIENT_COUNT] = {0};
31 |
32 | Ticker serial_poll_task;
33 |
34 | // Returns the number of bytes available in the RX serial buffer.
35 | uint8_t serial_get_rx_buffer_available(uint8_t client)
36 | {
37 | uint8_t client_idx = client - 1;
38 |
39 | uint8_t rtail = serial_rx_buffer_tail[client_idx]; // Copy to limit multiple calls to volatile
40 | if (serial_rx_buffer_head[client_idx] >= rtail) { return(RX_BUFFER_SIZE - (serial_rx_buffer_head[client_idx]-rtail)); }
41 | return((rtail-serial_rx_buffer_head[client_idx]-1));
42 | }
43 |
44 | void serial_init()
45 | {
46 | Serial.begin(BAUD_RATE);
47 |
48 | Serial.setDebugOutput(false);
49 | Serial.setTimeout(10);
50 | serial_poll_task.attach_ms(33, serial_poll_rx);
51 | }
52 |
53 | // Writes one byte to the TX serial buffer. Called by main program.
54 | void serial_write(uint8_t data) {
55 |
56 | // Wait until there is space in the buffer
57 | while (!Serial.availableForWrite()) {
58 | // TODO: Restructure st_prep_buffer() calls to be executed here during a long print.
59 | if (sys_rt_exec_state & EXEC_RESET) { return; } // Only check for abort to avoid an endless loop.
60 | }
61 |
62 | Serial.write((char)data);
63 | }
64 |
65 | // Fetches the first byte in the serial read buffer. Called by main program.
66 | uint8_t serial_read(uint8_t client)
67 | {
68 | uint8_t client_idx = client - 1;
69 |
70 | uint8_t tail = serial_rx_buffer_tail[client_idx]; // Temporary serial_rx_buffer_tail (to optimize for volatile)
71 | if (serial_rx_buffer_head[client_idx] == tail) {
72 | return SERIAL_NO_DATA;
73 | } else {
74 | // enter mutex
75 | cli();
76 | uint8_t data = serial_rx_buffer[client_idx][tail];
77 |
78 | tail++;
79 | if (tail == RX_RING_BUFFER) { tail = 0; }
80 | serial_rx_buffer_tail[client_idx] = tail;
81 | // exit mutex
82 | sei();
83 | return data;
84 | }
85 | }
86 |
87 | void serial_poll_rx()
88 | {
89 | uint8_t data = 0;
90 | uint8_t next_head;
91 | uint8_t client = CLIENT_SERIAL; // who sent the data
92 | uint8_t client_idx = 0; // index of data buffer
93 |
94 | while (Serial.available() > 0
95 | #if (defined ENABLE_WIFI) && (defined ENABLE_WEBSOCKET)
96 | || Serial2Socket.available() > 0
97 | #endif
98 | #if (defined ENABLE_WIFI) && (defined ENABLE_TELNET)
99 | || telnetServer.available() > 0
100 | #endif
101 | ) {
102 | if (Serial.available() > 0) {
103 | client = CLIENT_SERIAL;
104 | data = Serial.read();
105 | }
106 | #if (defined ENABLE_WIFI) && (defined ENABLE_WEBSOCKET)
107 | else if (Serial2Socket.available() > 0) {
108 | client = CLIENT_WEBSOCKET;
109 | data = Serial2Socket.read();
110 | }
111 | #endif
112 | #if (defined ENABLE_WIFI) && (defined ENABLE_TELNET)
113 | else if (telnetServer.available() > 0) {
114 | client = CLIENT_TELNET;
115 | data = telnetServer.read();
116 | }
117 | #endif
118 | client_idx = client - 1; // for zero based array
119 |
120 | // Pick off realtime command characters directly from the serial stream. These characters are
121 | // not passed into the main buffer, but these set system state flag bits for realtime execution.
122 | switch (data) {
123 | case CMD_RESET: mc_reset(); break; // Call motion control reset routine.
124 | case CMD_STATUS_REPORT: report_realtime_status(client); break;
125 | case CMD_CYCLE_START: system_set_exec_state_flag(EXEC_CYCLE_START); break; // Set as true
126 | case CMD_FEED_HOLD: system_set_exec_state_flag(EXEC_FEED_HOLD); break; // Set as true
127 | default :
128 | if (data > 0x7F) { // Real-time control characters are extended ACSII only.
129 | switch(data) {
130 | case CMD_SAFETY_DOOR: system_set_exec_state_flag(EXEC_SAFETY_DOOR); break; // Set as true
131 | case CMD_JOG_CANCEL:
132 | if (sys.state & STATE_JOG) { // Block all other states from invoking motion cancel.
133 | system_set_exec_state_flag(EXEC_MOTION_CANCEL);
134 | }
135 | break;
136 | #ifdef DEBUG
137 | case CMD_DEBUG_REPORT: bit_true(sys_rt_exec_debug,EXEC_DEBUG_REPORT); break;
138 | #endif
139 | case CMD_FEED_OVR_RESET: system_set_exec_motion_override_flag(EXEC_FEED_OVR_RESET); break;
140 | case CMD_FEED_OVR_COARSE_PLUS: system_set_exec_motion_override_flag(EXEC_FEED_OVR_COARSE_PLUS); break;
141 | case CMD_FEED_OVR_COARSE_MINUS: system_set_exec_motion_override_flag(EXEC_FEED_OVR_COARSE_MINUS); break;
142 | case CMD_FEED_OVR_FINE_PLUS: system_set_exec_motion_override_flag(EXEC_FEED_OVR_FINE_PLUS); break;
143 | case CMD_FEED_OVR_FINE_MINUS: system_set_exec_motion_override_flag(EXEC_FEED_OVR_FINE_MINUS); break;
144 | case CMD_RAPID_OVR_RESET: system_set_exec_motion_override_flag(EXEC_RAPID_OVR_RESET); break;
145 | case CMD_RAPID_OVR_MEDIUM: system_set_exec_motion_override_flag(EXEC_RAPID_OVR_MEDIUM); break;
146 | case CMD_RAPID_OVR_LOW: system_set_exec_motion_override_flag(EXEC_RAPID_OVR_LOW); break;
147 | case CMD_SPINDLE_OVR_RESET: system_set_exec_accessory_override_flag(EXEC_SPINDLE_OVR_RESET); break;
148 | case CMD_SPINDLE_OVR_COARSE_PLUS: system_set_exec_accessory_override_flag(EXEC_SPINDLE_OVR_COARSE_PLUS); break;
149 | case CMD_SPINDLE_OVR_COARSE_MINUS: system_set_exec_accessory_override_flag(EXEC_SPINDLE_OVR_COARSE_MINUS); break;
150 | case CMD_SPINDLE_OVR_FINE_PLUS: system_set_exec_accessory_override_flag(EXEC_SPINDLE_OVR_FINE_PLUS); break;
151 | case CMD_SPINDLE_OVR_FINE_MINUS: system_set_exec_accessory_override_flag(EXEC_SPINDLE_OVR_FINE_MINUS); break;
152 | case CMD_SPINDLE_OVR_STOP: system_set_exec_accessory_override_flag(EXEC_SPINDLE_OVR_STOP); break;
153 | case CMD_COOLANT_FLOOD_OVR_TOGGLE: system_set_exec_accessory_override_flag(EXEC_COOLANT_FLOOD_OVR_TOGGLE); break;
154 | #ifdef ENABLE_M7
155 | case CMD_COOLANT_MIST_OVR_TOGGLE: system_set_exec_accessory_override_flag(EXEC_COOLANT_MIST_OVR_TOGGLE); break;
156 | #endif
157 | }
158 | // Throw away any unfound extended-ASCII character by not passing it to the serial buffer.
159 | } else { // Write character to buffer
160 | // enter mutex
161 | cli();
162 | next_head = serial_rx_buffer_head[client_idx] + 1;
163 | if (next_head == RX_RING_BUFFER) { next_head = 0; }
164 |
165 | // Write data to buffer unless it is full.
166 | if (next_head != serial_rx_buffer_tail[client_idx]) {
167 | serial_rx_buffer[client_idx][serial_rx_buffer_head[client_idx]] = data;
168 | serial_rx_buffer_head[client_idx] = next_head;
169 | }
170 | // exit mutex
171 | sei();
172 | }
173 | }
174 | }
175 | Serial.flush();
176 | #ifdef ENABLE_WIFI
177 | wifi_handle();
178 | #endif
179 | #if (defined ENABLE_WIFI) && (defined ENABLE_WEBSOCKET)
180 | Serial2Socket.handle_flush();
181 | #endif
182 | }
183 |
184 | void serial_reset_read_buffer(uint8_t client)
185 | {
186 | for (uint8_t client_num = 1; client_num <= CLIENT_COUNT; client_num++) {
187 | if (client == client_num || client == CLIENT_ALL) {
188 | serial_rx_buffer_tail[client_num-1] = serial_rx_buffer_head[client_num-1];
189 | }
190 | }
191 | }
--------------------------------------------------------------------------------
/lib/grbl/src/serial.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | serial.c - Low level functions for sending and recieving bytes via the serial port
3 | Part of Grbl
4 |
5 | Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC
6 | Copyright (c) 2009-2011 Simen Svale Skogsrud
7 |
8 | Grbl is free software: you can redistribute it and/or modify
9 | it under the terms of the GNU General Public License as published by
10 | the Free Software Foundation, either version 3 of the License, or
11 | (at your option) any later version.
12 |
13 | Grbl is distributed in the hope that it will be useful,
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | GNU General Public License for more details.
17 |
18 | You should have received a copy of the GNU General Public License
19 | along with Grbl. If not, see .
20 | */
21 |
22 | #ifndef serial_h
23 | #define serial_h
24 |
25 | #ifndef RX_BUFFER_SIZE
26 | #define RX_BUFFER_SIZE 342
27 | #endif
28 | #ifndef TX_BUFFER_SIZE
29 | #ifdef USE_LINE_NUMBERS
30 | #define TX_BUFFER_SIZE 300
31 | #else
32 | #define TX_BUFFER_SIZE 278
33 | #endif
34 | #endif
35 |
36 | #define SERIAL_NO_DATA 0xff
37 |
38 | void serial_init();
39 |
40 | // Writes one byte to the TX serial buffer. Called by main program.
41 | void serial_write(uint8_t data);
42 |
43 | // Fetches the first byte in the serial read buffer. Called by main program.
44 | uint8_t serial_read(uint8_t client);
45 |
46 | // Reset and empty data in read buffer. Used by e-stop and reset.
47 | void serial_reset_read_buffer(uint8_t client);
48 |
49 | // Returns the number of bytes available in the RX serial buffer.
50 | uint8_t serial_get_rx_buffer_available(uint8_t client);
51 |
52 | // Serial rx "interrupt"
53 | void serial_poll_rx();
54 |
55 | #endif
56 |
--------------------------------------------------------------------------------
/lib/grbl/src/serial2socket.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | serial2socket.cpp - serial 2 socket functions class
3 |
4 | Copyright (c) 2014 Luc Lebosse. All rights reserved.
5 |
6 | This library is free software; you can redistribute it and/or
7 | modify it under the terms of the GNU Lesser General Public
8 | License as published by the Free Software Foundation; either
9 | version 2.1 of the License, or (at your option) any later version.
10 |
11 | This library is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | Lesser General Public License for more details.
15 |
16 | You should have received a copy of the GNU Lesser General Public
17 | License along with this library; if not, write to the Free Software
18 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 |
20 | This file was borrowed from the awesome project: https://github.com/bdring/Grbl_Esp32.git
21 | */
22 |
23 | #include "grbl.hpp"
24 |
25 | #ifdef ENABLE_WEBSOCKET
26 |
27 | Serial_2_Socket Serial2Socket;
28 |
29 | Serial_2_Socket::Serial_2_Socket(){
30 | _web_socket = NULL;
31 | _TXbufferSize = 0;
32 | _RXbufferSize = 0;
33 | _RXbufferpos = 0;
34 | }
35 | Serial_2_Socket::~Serial_2_Socket(){
36 | if (_web_socket) detachWS();
37 | _TXbufferSize = 0;
38 | _RXbufferSize = 0;
39 | _RXbufferpos = 0;
40 | }
41 | void Serial_2_Socket::begin(long speed){
42 | _TXbufferSize = 0;
43 | _RXbufferSize = 0;
44 | _RXbufferpos = 0;
45 | }
46 |
47 | void Serial_2_Socket::end(){
48 | _TXbufferSize = 0;
49 | _RXbufferSize = 0;
50 | _RXbufferpos = 0;
51 | }
52 |
53 | long Serial_2_Socket::baudRate(){
54 | return 0;
55 | }
56 |
57 | bool Serial_2_Socket::attachWS(void * web_socket){
58 | if (web_socket) {
59 | _web_socket = web_socket;
60 | _TXbufferSize=0;
61 | return true;
62 | }
63 | return false;
64 | }
65 |
66 | bool Serial_2_Socket::detachWS(){
67 | _web_socket = NULL;
68 | return true;
69 | }
70 |
71 | Serial_2_Socket::operator bool() const
72 | {
73 | return true;
74 | }
75 |
76 | int Serial_2_Socket::available(){
77 | return _RXbufferSize;
78 | }
79 |
80 | size_t Serial_2_Socket::write(uint8_t c)
81 | {
82 | if(!_web_socket) return 0;
83 | write(&c,1);
84 | return 1;
85 | }
86 |
87 | size_t Serial_2_Socket::write(const uint8_t *buffer, size_t size)
88 | {
89 | if((buffer == NULL) ||(!_web_socket)) {
90 | //if(buffer == NULL)printPgmString("[SOCKET]No buffer");
91 | //if(!_web_socket)printPgmString("[SOCKET]No socket");
92 | return 0;
93 | }
94 | if (_TXbufferSize==0)_lastflush = millis();
95 | //send full line
96 | if (_TXbufferSize + size > TXBUFFERSIZE) flush();
97 | //need periodic check to force to flush in case of no end
98 | for (int i = 0; i < size;i++){
99 | _TXbuffer[_TXbufferSize] = buffer[i];
100 | _TXbufferSize++;
101 | }
102 | //Serial.printf("[SOCKET]buffer size %d",_TXbufferSize);
103 | handle_flush();
104 | return size;
105 | }
106 |
107 | int Serial_2_Socket::peek(void){
108 | if (_RXbufferSize > 0)return _RXbuffer[_RXbufferpos];
109 | else return -1;
110 | }
111 |
112 | bool Serial_2_Socket::push(const char * data){
113 | int data_size = strlen(data);
114 | if ((data_size + _RXbufferSize) <= RXBUFFERSIZE){
115 | int current = _RXbufferpos + _RXbufferSize;
116 | if (current > RXBUFFERSIZE) current = current - RXBUFFERSIZE;
117 | for (int i = 0; i < data_size; i++){
118 | if (current > (RXBUFFERSIZE-1)) current = 0;
119 | _RXbuffer[current] = data[i];
120 | current ++;
121 | }
122 | _RXbufferSize+=strlen(data);
123 | return true;
124 | }
125 | return false;
126 | }
127 |
128 | int Serial_2_Socket::read(void){
129 | if (_RXbufferSize > 0) {
130 | int v = _RXbuffer[_RXbufferpos];
131 | _RXbufferpos++;
132 | if (_RXbufferpos > (RXBUFFERSIZE-1))_RXbufferpos = 0;
133 | _RXbufferSize--;
134 | return v;
135 | } else return -1;
136 | }
137 |
138 | void Serial_2_Socket::handle_flush() {
139 | if (_TXbufferSize > 0) {
140 | if ((_TXbufferSize>=TXBUFFERSIZE) || ((millis()- _lastflush) > FLUSHTIMEOUT)) {
141 | //Serial.printf("[SOCKET]need flush, buffer size %d\n",_TXbufferSize);
142 | flush();
143 | }
144 | }
145 | }
146 |
147 | void Serial_2_Socket::flush(void){
148 | if (_TXbufferSize > 0){
149 | if (((AsyncWebSocket *)_web_socket)->count() > 0) {
150 | //Serial.printf("[SOCKET]flush data, buffer size %d",_TXbufferSize);
151 | ((AsyncWebSocket *)_web_socket)->textAll(_TXbuffer,_TXbufferSize);
152 | } else {
153 | //Serial.printf("[SOCKET]Cannot flush, buffer size %d",_TXbufferSize);
154 | }
155 | //refresh timout
156 | _lastflush = millis();
157 | //reset buffer
158 | _TXbufferSize = 0;
159 | }
160 | }
161 |
162 | #endif
163 |
--------------------------------------------------------------------------------
/lib/grbl/src/serial2socket.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | serial2socket.h - serial 2 socket functions class
3 |
4 | Copyright (c) 2014 Luc Lebosse. All rights reserved.
5 |
6 | This library is free software; you can redistribute it and/or
7 | modify it under the terms of the GNU Lesser General Public
8 | License as published by the Free Software Foundation; either
9 | version 2.1 of the License, or (at your option) any later version.
10 |
11 | This library is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | Lesser General Public License for more details.
15 |
16 | You should have received a copy of the GNU Lesser General Public
17 | License along with this library; if not, write to the Free Software
18 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 |
20 | This file was borrowed from the awesome project: https://github.com/bdring/Grbl_Esp32.git
21 | */
22 |
23 | #ifndef _SERIAL_2_SOCKET_H_
24 | #define _SERIAL_2_SOCKET_H_
25 |
26 | #include
27 | #define TXBUFFERSIZE 1200
28 | #define RXBUFFERSIZE 128
29 | #define FLUSHTIMEOUT 300
30 | class Serial_2_Socket: public Print{
31 | public:
32 | Serial_2_Socket();
33 | ~Serial_2_Socket();
34 | size_t write(uint8_t c);
35 | size_t write(const uint8_t *buffer, size_t size);
36 |
37 | inline size_t write(const char * s)
38 | {
39 | return write((uint8_t*) s, strlen(s));
40 | }
41 | inline size_t write(unsigned long n)
42 | {
43 | return write((uint8_t) n);
44 | }
45 | inline size_t write(long n)
46 | {
47 | return write((uint8_t) n);
48 | }
49 | inline size_t write(unsigned int n)
50 | {
51 | return write((uint8_t) n);
52 | }
53 | inline size_t write(int n)
54 | {
55 | return write((uint8_t) n);
56 | }
57 | long baudRate();
58 | void begin(long speed);
59 | void end();
60 | int available();
61 | int peek(void);
62 | int read(void);
63 | bool push (const char * data);
64 | void flush(void);
65 | void handle_flush();
66 | operator bool() const;
67 | bool attachWS(void * web_socket);
68 | bool detachWS();
69 | private:
70 | uint32_t _lastflush;
71 | void * _web_socket;
72 | uint8_t _TXbuffer[TXBUFFERSIZE];
73 | uint16_t _TXbufferSize;
74 | uint8_t _RXbuffer[RXBUFFERSIZE];
75 | uint16_t _RXbufferSize;
76 | uint16_t _RXbufferpos;
77 | };
78 |
79 | extern Serial_2_Socket Serial2Socket;
80 |
81 | #endif
82 |
--------------------------------------------------------------------------------
/lib/grbl/src/settings.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | settings.c - eeprom configuration handling
3 | Part of Grbl
4 |
5 | Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC
6 | Copyright (c) 2009-2011 Simen Svale Skogsrud
7 |
8 | Grbl is free software: you can redistribute it and/or modify
9 | it under the terms of the GNU General Public License as published by
10 | the Free Software Foundation, either version 3 of the License, or
11 | (at your option) any later version.
12 |
13 | Grbl is distributed in the hope that it will be useful,
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | GNU General Public License for more details.
17 |
18 | You should have received a copy of the GNU General Public License
19 | along with Grbl. If not, see .
20 | */
21 |
22 | #include "grbl.hpp"
23 |
24 | settings_t settings;
25 |
26 | // Method to store startup lines into EEPROM
27 | void settings_store_startup_line(uint8_t n, char *line)
28 | {
29 | #ifdef FORCE_BUFFER_SYNC_DURING_EEPROM_WRITE
30 | protocol_buffer_synchronize(); // A startup line may contain a motion and be executing.
31 | #endif
32 | uint32_t addr = n*(LINE_BUFFER_SIZE+1)+EEPROM_ADDR_STARTUP_BLOCK;
33 | memcpy_to_eeprom_with_checksum(addr,(char*)line, LINE_BUFFER_SIZE);
34 | }
35 |
36 |
37 | // Method to store build info into EEPROM
38 | // NOTE: This function can only be called in IDLE state.
39 | void settings_store_build_info(char *line)
40 | {
41 | // Build info can only be stored when state is IDLE.
42 | memcpy_to_eeprom_with_checksum(EEPROM_ADDR_BUILD_INFO,(char*)line, LINE_BUFFER_SIZE);
43 | }
44 |
45 |
46 | // Method to store coord data parameters into EEPROM
47 | void settings_write_coord_data(uint8_t coord_select, float *coord_data)
48 | {
49 | #ifdef FORCE_BUFFER_SYNC_DURING_EEPROM_WRITE
50 | protocol_buffer_synchronize();
51 | #endif
52 | uint32_t addr = coord_select*(sizeof(float)*N_AXIS+1) + EEPROM_ADDR_PARAMETERS;
53 | memcpy_to_eeprom_with_checksum(addr,(char*)coord_data, sizeof(float)*N_AXIS);
54 | }
55 |
56 |
57 | // Method to store Grbl global settings struct and version number into EEPROM
58 | // NOTE: This function can only be called in IDLE state.
59 | void write_global_settings()
60 | {
61 | eeprom_put_char(0, SETTINGS_VERSION);
62 | memcpy_to_eeprom_with_checksum(EEPROM_ADDR_GLOBAL, (char*)&settings, sizeof(settings_t));
63 | }
64 |
65 |
66 | // Method to restore EEPROM-saved Grbl global settings back to defaults.
67 | void settings_restore(uint8_t restore_flag) {
68 | if (restore_flag & SETTINGS_RESTORE_DEFAULTS) {
69 | settings.pulse_microseconds = DEFAULT_STEP_PULSE_MICROSECONDS;
70 | settings.stepper_idle_lock_time = DEFAULT_STEPPER_IDLE_LOCK_TIME;
71 | settings.step_invert_mask = DEFAULT_STEPPING_INVERT_MASK;
72 | settings.dir_invert_mask = DEFAULT_DIRECTION_INVERT_MASK;
73 | settings.status_report_mask = DEFAULT_STATUS_REPORT_MASK;
74 | settings.junction_deviation = DEFAULT_JUNCTION_DEVIATION;
75 | settings.arc_tolerance = DEFAULT_ARC_TOLERANCE;
76 |
77 | settings.rpm_max = DEFAULT_SPINDLE_RPM_MAX;
78 | settings.rpm_min = DEFAULT_SPINDLE_RPM_MIN;
79 |
80 | settings.homing_dir_mask = DEFAULT_HOMING_DIR_MASK;
81 | settings.homing_feed_rate = DEFAULT_HOMING_FEED_RATE;
82 | settings.homing_seek_rate = DEFAULT_HOMING_SEEK_RATE;
83 | settings.homing_debounce_delay = DEFAULT_HOMING_DEBOUNCE_DELAY;
84 | settings.homing_pulloff = DEFAULT_HOMING_PULLOFF;
85 |
86 | settings.flags = 0;
87 | if (DEFAULT_REPORT_INCHES) { settings.flags |= BITFLAG_REPORT_INCHES; }
88 | if (DEFAULT_LASER_MODE) { settings.flags |= BITFLAG_LASER_MODE; }
89 | if (DEFAULT_INVERT_ST_ENABLE) { settings.flags |= BITFLAG_INVERT_ST_ENABLE; }
90 | if (DEFAULT_HARD_LIMIT_ENABLE) { settings.flags |= BITFLAG_HARD_LIMIT_ENABLE; }
91 | if (DEFAULT_HOMING_ENABLE) { settings.flags |= BITFLAG_HOMING_ENABLE; }
92 | if (DEFAULT_SOFT_LIMIT_ENABLE) { settings.flags |= BITFLAG_SOFT_LIMIT_ENABLE; }
93 | if (DEFAULT_INVERT_LIMIT_PINS) { settings.flags |= BITFLAG_INVERT_LIMIT_PINS; }
94 | if (DEFAULT_INVERT_PROBE_PIN) { settings.flags |= BITFLAG_INVERT_PROBE_PIN; }
95 |
96 | settings.steps_per_mm[X_AXIS] = DEFAULT_X_STEPS_PER_MM;
97 | settings.steps_per_mm[Y_AXIS] = DEFAULT_Y_STEPS_PER_MM;
98 | settings.steps_per_mm[Z_AXIS] = DEFAULT_Z_STEPS_PER_MM;
99 | settings.steps_per_mm[A_AXIS] = DEFAULT_A_STEPS_PER_MM;
100 | settings.steps_per_mm[B_AXIS] = DEFAULT_B_STEPS_PER_MM;
101 | settings.steps_per_mm[C_AXIS] = DEFAULT_C_STEPS_PER_MM;
102 | settings.steps_per_mm[D_AXIS] = DEFAULT_D_STEPS_PER_MM;
103 | settings.steps_per_mm[E_AXIS] = DEFAULT_E_STEPS_PER_MM;
104 | settings.max_rate[X_AXIS] = DEFAULT_X_MAX_RATE;
105 | settings.max_rate[Y_AXIS] = DEFAULT_Y_MAX_RATE;
106 | settings.max_rate[Z_AXIS] = DEFAULT_Z_MAX_RATE;
107 | settings.max_rate[A_AXIS] = DEFAULT_A_MAX_RATE;
108 | settings.max_rate[B_AXIS] = DEFAULT_B_MAX_RATE;
109 | settings.max_rate[C_AXIS] = DEFAULT_C_MAX_RATE;
110 | settings.max_rate[D_AXIS] = DEFAULT_D_MAX_RATE;
111 | settings.max_rate[E_AXIS] = DEFAULT_E_MAX_RATE;
112 | settings.acceleration[X_AXIS] = DEFAULT_X_ACCELERATION;
113 | settings.acceleration[Y_AXIS] = DEFAULT_Y_ACCELERATION;
114 | settings.acceleration[Z_AXIS] = DEFAULT_Z_ACCELERATION;
115 | settings.acceleration[A_AXIS] = DEFAULT_A_ACCELERATION;
116 | settings.acceleration[B_AXIS] = DEFAULT_B_ACCELERATION;
117 | settings.acceleration[C_AXIS] = DEFAULT_C_ACCELERATION;
118 | settings.acceleration[D_AXIS] = DEFAULT_D_ACCELERATION;
119 | settings.acceleration[E_AXIS] = DEFAULT_E_ACCELERATION;
120 | settings.max_travel[X_AXIS] = (-DEFAULT_X_MAX_TRAVEL);
121 | settings.max_travel[Y_AXIS] = (-DEFAULT_Y_MAX_TRAVEL);
122 | settings.max_travel[Z_AXIS] = (-DEFAULT_Z_MAX_TRAVEL);
123 | settings.max_travel[A_AXIS] = (-DEFAULT_A_MAX_TRAVEL);
124 | settings.max_travel[B_AXIS] = (-DEFAULT_B_MAX_TRAVEL);
125 | settings.max_travel[C_AXIS] = (-DEFAULT_C_MAX_TRAVEL);
126 | settings.max_travel[D_AXIS] = (-DEFAULT_D_MAX_TRAVEL);
127 | settings.max_travel[E_AXIS] = (-DEFAULT_E_MAX_TRAVEL);
128 |
129 |
130 | write_global_settings();
131 | }
132 |
133 | if (restore_flag & SETTINGS_RESTORE_PARAMETERS) {
134 | uint8_t idx;
135 | float coord_data[N_AXIS];
136 | memset(&coord_data, 0, sizeof(coord_data));
137 | for (idx=0; idx <= SETTING_INDEX_NCOORD; idx++) { settings_write_coord_data(idx, coord_data); }
138 | }
139 |
140 | if (restore_flag & SETTINGS_RESTORE_STARTUP_LINES) {
141 | #if N_STARTUP_LINE > 0
142 | eeprom_put_char(EEPROM_ADDR_STARTUP_BLOCK, 0);
143 | eeprom_put_char(EEPROM_ADDR_STARTUP_BLOCK+1, 0); // Checksum
144 | #endif
145 | #if N_STARTUP_LINE > 1
146 | eeprom_put_char(EEPROM_ADDR_STARTUP_BLOCK+(LINE_BUFFER_SIZE+1), 0);
147 | eeprom_put_char(EEPROM_ADDR_STARTUP_BLOCK+(LINE_BUFFER_SIZE+2), 0); // Checksum
148 | #endif
149 | }
150 |
151 | if (restore_flag & SETTINGS_RESTORE_BUILD_INFO) {
152 | eeprom_put_char(EEPROM_ADDR_BUILD_INFO , 0);
153 | eeprom_put_char(EEPROM_ADDR_BUILD_INFO+1 , 0); // Checksum
154 | }
155 | }
156 |
157 |
158 | // Reads startup line from EEPROM. Updated pointed line string data.
159 | uint8_t settings_read_startup_line(uint8_t n, char *line)
160 | {
161 | uint32_t addr = n*(LINE_BUFFER_SIZE+1)+EEPROM_ADDR_STARTUP_BLOCK;
162 | if (!(memcpy_from_eeprom_with_checksum((char*)line, addr, LINE_BUFFER_SIZE))) {
163 | // Reset line with default value
164 | line[0] = 0; // Empty line
165 | settings_store_startup_line(n, line);
166 | return(false);
167 | }
168 | return(true);
169 | }
170 |
171 |
172 | // Reads startup line from EEPROM. Updated pointed line string data.
173 | uint8_t settings_read_build_info(char *line)
174 | {
175 | if (!(memcpy_from_eeprom_with_checksum((char*)line, EEPROM_ADDR_BUILD_INFO, LINE_BUFFER_SIZE))) {
176 | // Reset line with default value
177 | line[0] = 0; // Empty line
178 | settings_store_build_info(line);
179 | return(false);
180 | }
181 | return(true);
182 | }
183 |
184 |
185 | // Read selected coordinate data from EEPROM. Updates pointed coord_data value.
186 | uint8_t settings_read_coord_data(uint8_t coord_select, float *coord_data)
187 | {
188 | uint32_t addr = coord_select*(sizeof(float)*N_AXIS+1) + EEPROM_ADDR_PARAMETERS;
189 | if (!(memcpy_from_eeprom_with_checksum((char*)coord_data, addr, sizeof(float)*N_AXIS))) {
190 | // Reset with default zero vector
191 | clear_vector_float(coord_data);
192 | settings_write_coord_data(coord_select,coord_data);
193 | return(false);
194 | }
195 | return(true);
196 | }
197 |
198 |
199 | // Reads Grbl global settings struct from EEPROM.
200 | uint8_t read_global_settings() {
201 | // Check version-byte of eeprom
202 | uint8_t version = eeprom_get_char(0);
203 | if (version == SETTINGS_VERSION) {
204 | // Read settings-record and check checksum
205 | if (!(memcpy_from_eeprom_with_checksum((char*)&settings, EEPROM_ADDR_GLOBAL, sizeof(settings_t)))) {
206 | return(false);
207 | }
208 | } else {
209 | return(false);
210 | }
211 | return(true);
212 | }
213 |
214 |
215 | // A helper method to set settings from command line
216 | uint8_t settings_store_global_setting(uint8_t parameter, float value) {
217 | if (value < 0.0) { return(STATUS_NEGATIVE_VALUE); }
218 | if (parameter >= AXIS_SETTINGS_START_VAL) {
219 | // Store axis configuration. Axis numbering sequence set by AXIS_SETTING defines.
220 | // NOTE: Ensure the setting index corresponds to the report.c settings printout.
221 | parameter -= AXIS_SETTINGS_START_VAL;
222 | uint8_t set_idx = 0;
223 | while (set_idx < AXIS_N_SETTINGS) {
224 | if (parameter < N_AXIS) {
225 | // Valid axis setting found.
226 | switch (set_idx) {
227 | case 0:
228 | #ifdef MAX_STEP_RATE_HZ
229 | if (value*settings.max_rate[parameter] > (MAX_STEP_RATE_HZ*60.0)) { return(STATUS_MAX_STEP_RATE_EXCEEDED); }
230 | #endif
231 | settings.steps_per_mm[parameter] = value;
232 | break;
233 | case 1:
234 | #ifdef MAX_STEP_RATE_HZ
235 | if (value*settings.steps_per_mm[parameter] > (MAX_STEP_RATE_HZ*60.0)) { return(STATUS_MAX_STEP_RATE_EXCEEDED); }
236 | #endif
237 | settings.max_rate[parameter] = value;
238 | break;
239 | case 2: settings.acceleration[parameter] = value*60*60; break; // Convert to mm/min^2 for grbl internal use.
240 | case 3: settings.max_travel[parameter] = -value; break; // Store as negative for grbl internal use.
241 | }
242 | break; // Exit while-loop after setting has been configured and proceed to the EEPROM write call.
243 | } else {
244 | set_idx++;
245 | // If axis index greater than N_AXIS or setting index greater than number of axis settings, error out.
246 | if ((parameter < AXIS_SETTINGS_INCREMENT) || (set_idx == AXIS_N_SETTINGS)) { return(STATUS_INVALID_STATEMENT); }
247 | parameter -= AXIS_SETTINGS_INCREMENT;
248 | }
249 | }
250 | } else {
251 | // Store non-axis Grbl settings
252 | uint8_t int_value = trunc(value);
253 | switch(parameter) {
254 | case 0:
255 | if (int_value < 3) { return(STATUS_SETTING_STEP_PULSE_MIN); }
256 | settings.pulse_microseconds = int_value; break;
257 | case 1: settings.stepper_idle_lock_time = int_value; break;
258 | case 2:
259 | settings.step_invert_mask = int_value;
260 | st_generate_step_dir_invert_masks(); // Regenerate step and direction port invert masks.
261 | break;
262 | case 3:
263 | settings.dir_invert_mask = int_value;
264 | st_generate_step_dir_invert_masks(); // Regenerate step and direction port invert masks.
265 | break;
266 | case 4: // Reset to ensure change. Immediate re-init may cause problems.
267 | if (int_value) { settings.flags |= BITFLAG_INVERT_ST_ENABLE; }
268 | else { settings.flags &= ~BITFLAG_INVERT_ST_ENABLE; }
269 | break;
270 | case 5: // Reset to ensure change. Immediate re-init may cause problems.
271 | if (int_value) { settings.flags |= BITFLAG_INVERT_LIMIT_PINS; }
272 | else { settings.flags &= ~BITFLAG_INVERT_LIMIT_PINS; }
273 | break;
274 | case 6: // Reset to ensure change. Immediate re-init may cause problems.
275 | if (int_value) { settings.flags |= BITFLAG_INVERT_PROBE_PIN; }
276 | else { settings.flags &= ~BITFLAG_INVERT_PROBE_PIN; }
277 | probe_configure_invert_mask(false);
278 | break;
279 | case 10: settings.status_report_mask = int_value; break;
280 | case 11: settings.junction_deviation = value; break;
281 | case 12: settings.arc_tolerance = value; break;
282 | case 13:
283 | if (int_value) { settings.flags |= BITFLAG_REPORT_INCHES; }
284 | else { settings.flags &= ~BITFLAG_REPORT_INCHES; }
285 | system_flag_wco_change(); // Make sure WCO is immediately updated.
286 | break;
287 | case 20:
288 | if (int_value) {
289 | if (bit_isfalse(settings.flags, BITFLAG_HOMING_ENABLE)) { return(STATUS_SOFT_LIMIT_ERROR); }
290 | settings.flags |= BITFLAG_SOFT_LIMIT_ENABLE;
291 | } else { settings.flags &= ~BITFLAG_SOFT_LIMIT_ENABLE; }
292 | break;
293 | case 21:
294 | if (int_value) { settings.flags |= BITFLAG_HARD_LIMIT_ENABLE; }
295 | else { settings.flags &= ~BITFLAG_HARD_LIMIT_ENABLE; }
296 | limits_init(); // Re-init to immediately change. NOTE: Nice to have but could be problematic later.
297 | break;
298 | case 22:
299 | if (int_value) { settings.flags |= BITFLAG_HOMING_ENABLE; }
300 | else {
301 | settings.flags &= ~BITFLAG_HOMING_ENABLE;
302 | settings.flags &= ~BITFLAG_SOFT_LIMIT_ENABLE; // Force disable soft-limits.
303 | }
304 | break;
305 | case 23: settings.homing_dir_mask = int_value; break;
306 | case 24: settings.homing_feed_rate = value; break;
307 | case 25: settings.homing_seek_rate = value; break;
308 | case 26: settings.homing_debounce_delay = int_value; break;
309 | case 27: settings.homing_pulloff = value; break;
310 | case 30: settings.rpm_max = value; spindle_init(); break; // Re-initialize spindle rpm calibration
311 | case 31: settings.rpm_min = value; spindle_init(); break; // Re-initialize spindle rpm calibration
312 | case 32:
313 | #ifdef VARIABLE_SPINDLE
314 | if (int_value) { settings.flags |= BITFLAG_LASER_MODE; }
315 | else { settings.flags &= ~BITFLAG_LASER_MODE; }
316 | #else
317 | return(STATUS_SETTING_DISABLED_LASER);
318 | #endif
319 | break;
320 | default:
321 | return(STATUS_INVALID_STATEMENT);
322 | }
323 | }
324 | write_global_settings();
325 | return(STATUS_OK);
326 | }
327 |
328 | void settings_init()
329 | {
330 | if(!read_global_settings()) {
331 | report_status_message(STATUS_SETTING_READ_FAIL, CLIENT_SERIAL);
332 | settings_restore(SETTINGS_RESTORE_ALL); // Force restore all EEPROM data.
333 | report_grbl_settings(CLIENT_SERIAL); // only the serial could be working at this point
334 | }
335 | }
336 |
337 | // Returns step pin mask according to Grbl internal axis indexing.
338 | uint8_t get_step_pin_mask(uint8_t axis_idx)
339 | {
340 | if ( axis_idx == X_AXIS ) { return((1<.
20 | */
21 |
22 | #ifndef settings_h
23 | #define settings_h
24 |
25 | #include "grbl.hpp"
26 |
27 |
28 | // Version of the EEPROM data. Will be used to migrate existing data from older versions of Grbl
29 | // when firmware is upgraded. Always stored in byte 0 of eeprom
30 | #define SETTINGS_VERSION 10 // NOTE: Check settings_reset() when moving to next version.
31 |
32 | // Define bit flag masks for the boolean settings in settings.flag.
33 | #define BIT_REPORT_INCHES 0
34 | #define BIT_LASER_MODE 1
35 | #define BIT_INVERT_ST_ENABLE 2
36 | #define BIT_HARD_LIMIT_ENABLE 3
37 | #define BIT_HOMING_ENABLE 4
38 | #define BIT_SOFT_LIMIT_ENABLE 5
39 | #define BIT_INVERT_LIMIT_PINS 6
40 | #define BIT_INVERT_PROBE_PIN 7
41 |
42 | #define BITFLAG_REPORT_INCHES bit(BIT_REPORT_INCHES)
43 | #define BITFLAG_LASER_MODE bit(BIT_LASER_MODE)
44 | #define BITFLAG_INVERT_ST_ENABLE bit(BIT_INVERT_ST_ENABLE)
45 | #define BITFLAG_HARD_LIMIT_ENABLE bit(BIT_HARD_LIMIT_ENABLE)
46 | #define BITFLAG_HOMING_ENABLE bit(BIT_HOMING_ENABLE)
47 | #define BITFLAG_SOFT_LIMIT_ENABLE bit(BIT_SOFT_LIMIT_ENABLE)
48 | #define BITFLAG_INVERT_LIMIT_PINS bit(BIT_INVERT_LIMIT_PINS)
49 | #define BITFLAG_INVERT_PROBE_PIN bit(BIT_INVERT_PROBE_PIN)
50 |
51 | // Define status reporting boolean enable bit flags in settings.status_report_mask
52 | #define BITFLAG_RT_STATUS_POSITION_TYPE bit(0)
53 | #define BITFLAG_RT_STATUS_BUFFER_STATE bit(1)
54 |
55 | // Define settings restore bitflags.
56 | #define SETTINGS_RESTORE_DEFAULTS bit(0)
57 | #define SETTINGS_RESTORE_PARAMETERS bit(1)
58 | #define SETTINGS_RESTORE_STARTUP_LINES bit(2)
59 | #define SETTINGS_RESTORE_BUILD_INFO bit(3)
60 | #ifndef SETTINGS_RESTORE_ALL
61 | #define SETTINGS_RESTORE_ALL 0xFF // All bitflags
62 | #endif
63 |
64 | // Define EEPROM memory address location values for Grbl settings and parameters
65 | // NOTE: The Atmega328p has 1KB EEPROM. The upper half is reserved for parameters and
66 | // the startup script. The lower half contains the global settings and space for future
67 | // developments.
68 | #define EEPROM_ADDR_GLOBAL 1U
69 | #define EEPROM_ADDR_PARAMETERS 1024U
70 | #define EEPROM_ADDR_STARTUP_BLOCK 1536U
71 | #define EEPROM_ADDR_BUILD_INFO 1792U
72 |
73 | // Define EEPROM address indexing for coordinate parameters
74 | #define N_COORDINATE_SYSTEM 6 // Number of supported work coordinate systems (from index 1)
75 | #define SETTING_INDEX_NCOORD N_COORDINATE_SYSTEM+1 // Total number of system stored (from index 0)
76 | // NOTE: Work coordinate indices are (0=G54, 1=G55, ... , 6=G59)
77 | #define SETTING_INDEX_G28 N_COORDINATE_SYSTEM // Home position 1
78 | #define SETTING_INDEX_G30 N_COORDINATE_SYSTEM+1 // Home position 2
79 | // #define SETTING_INDEX_G92 N_COORDINATE_SYSTEM+2 // Coordinate offset (G92.2,G92.3 not supported)
80 |
81 | // Define Grbl axis settings numbering scheme. Starts at START_VAL, every INCREMENT, over N_SETTINGS.
82 | #define AXIS_N_SETTINGS 4
83 | #define AXIS_SETTINGS_START_VAL 100 // NOTE: Reserving settings values >= 100 for axis settings. Up to 255.
84 | #define AXIS_SETTINGS_INCREMENT 10 // Must be greater than the number of axis settings
85 |
86 | // Global persistent settings (Stored from byte EEPROM_ADDR_GLOBAL onwards)
87 | typedef struct {
88 | // Axis settings
89 | float steps_per_mm[N_AXIS];
90 | float max_rate[N_AXIS];
91 | float acceleration[N_AXIS];
92 | float max_travel[N_AXIS];
93 |
94 | // Remaining Grbl settings
95 | uint8_t pulse_microseconds;
96 | uint8_t step_invert_mask;
97 | uint8_t dir_invert_mask;
98 | uint8_t stepper_idle_lock_time; // If max value 255, steppers do not disable.
99 | uint8_t status_report_mask; // Mask to indicate desired report data.
100 | float junction_deviation;
101 | float arc_tolerance;
102 |
103 | float rpm_max;
104 | float rpm_min;
105 |
106 | uint8_t flags; // Contains default boolean settings
107 |
108 | uint8_t homing_dir_mask;
109 | float homing_feed_rate;
110 | float homing_seek_rate;
111 | uint16_t homing_debounce_delay;
112 | float homing_pulloff;
113 | } settings_t;
114 | extern settings_t settings;
115 |
116 | // Initialize the configuration subsystem (load settings from EEPROM)
117 | void settings_init();
118 |
119 | // Helper function to clear and restore EEPROM defaults
120 | void settings_restore(uint8_t restore_flag);
121 |
122 | // A helper method to set new settings from command line
123 | uint8_t settings_store_global_setting(uint8_t parameter, float value);
124 |
125 | // Stores the protocol line variable as a startup line in EEPROM
126 | void settings_store_startup_line(uint8_t n, char *line);
127 |
128 | // Reads an EEPROM startup line to the protocol line variable
129 | uint8_t settings_read_startup_line(uint8_t n, char *line);
130 |
131 | // Stores build info user-defined string
132 | void settings_store_build_info(char *line);
133 |
134 | // Reads build info user-defined string
135 | uint8_t settings_read_build_info(char *line);
136 |
137 | // Writes selected coordinate data to EEPROM
138 | void settings_write_coord_data(uint8_t coord_select, float *coord_data);
139 |
140 | // Reads selected coordinate data from EEPROM
141 | uint8_t settings_read_coord_data(uint8_t coord_select, float *coord_data);
142 |
143 | // Returns the step pin mask according to Grbl's internal axis numbering
144 | uint8_t get_step_pin_mask(uint8_t i);
145 |
146 | // Returns the direction pin mask according to Grbl's internal axis numbering
147 | uint8_t get_direction_pin_mask(uint8_t i);
148 |
149 | // Returns the limit pin mask according to Grbl's internal axis numbering
150 | uint8_t get_limit_pin_mask(uint8_t i);
151 |
152 |
153 | #endif
154 |
--------------------------------------------------------------------------------
/lib/grbl/src/spindle_control.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | spindle_control.c - spindle control methods
3 | Part of Grbl
4 |
5 | Copyright (c) 2012-2017 Sungeun K. Jeon for Gnea Research LLC
6 | Copyright (c) 2009-2011 Simen Svale Skogsrud
7 |
8 | Grbl is free software: you can redistribute it and/or modify
9 | it under the terms of the GNU General Public License as published by
10 | the Free Software Foundation, either version 3 of the License, or
11 | (at your option) any later version.
12 |
13 | Grbl is distributed in the hope that it will be useful,
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | GNU General Public License for more details.
17 |
18 | You should have received a copy of the GNU General Public License
19 | along with Grbl. If not, see .
20 | */
21 |
22 | #include "grbl.hpp"
23 |
24 | #ifdef VARIABLE_SPINDLE
25 | static float pwm_gradient; // Precalulated value to speed up rpm to PWM conversions.
26 | #endif
27 |
28 |
29 | void spindle_init()
30 | {
31 | #ifdef VARIABLE_SPINDLE
32 |
33 | // Configure variable spindle PWM and enable pin, if requried. On the Uno, PWM and enable are
34 | // combined unless configured otherwise.
35 | //SPINDLE_PWM_DDR |= (1<= settings.rpm_max) || (rpm >= RPM_MAX)) {
150 | rpm = RPM_MAX;
151 | pwm_value = SPINDLE_PWM_MAX_VALUE;
152 | } else if (rpm <= RPM_MIN) {
153 | if (rpm == 0.0) { // S0 disables spindle
154 | pwm_value = SPINDLE_PWM_OFF_VALUE;
155 | } else {
156 | rpm = RPM_MIN;
157 | pwm_value = SPINDLE_PWM_MIN_VALUE;
158 | }
159 | } else {
160 | // Compute intermediate PWM value with linear spindle speed model via piecewise linear fit model.
161 | #if (N_PIECES > 3)
162 | if (rpm > RPM_POINT34) {
163 | pwm_value = floor(RPM_LINE_A4*rpm - RPM_LINE_B4);
164 | } else
165 | #endif
166 | #if (N_PIECES > 2)
167 | if (rpm > RPM_POINT23) {
168 | pwm_value = floor(RPM_LINE_A3*rpm - RPM_LINE_B3);
169 | } else
170 | #endif
171 | #if (N_PIECES > 1)
172 | if (rpm > RPM_POINT12) {
173 | pwm_value = floor(RPM_LINE_A2*rpm - RPM_LINE_B2);
174 | } else
175 | #endif
176 | {
177 | pwm_value = floor(RPM_LINE_A1*rpm - RPM_LINE_B1);
178 | }
179 | }
180 | sys.spindle_speed = rpm;
181 | return(pwm_value);
182 | }
183 |
184 | #else
185 |
186 | // Called by spindle_set_state() and step segment generator. Keep routine small and efficient.
187 | uint8_t spindle_compute_pwm_value(float rpm) // 328p PWM register is 8-bit.
188 | {
189 | uint8_t pwm_value;
190 | rpm *= (0.010*sys.spindle_speed_ovr); // Scale by spindle speed override value.
191 | // Calculate PWM register value based on rpm max/min settings and programmed rpm.
192 | if ((settings.rpm_min >= settings.rpm_max) || (rpm >= settings.rpm_max)) {
193 | // No PWM range possible. Set simple on/off spindle control pin state.
194 | sys.spindle_speed = settings.rpm_max;
195 | pwm_value = SPINDLE_PWM_MAX_VALUE;
196 | } else if (rpm <= settings.rpm_min) {
197 | if (rpm == 0.0) { // S0 disables spindle
198 | sys.spindle_speed = 0.0;
199 | pwm_value = SPINDLE_PWM_OFF_VALUE;
200 | } else { // Set minimum PWM output
201 | sys.spindle_speed = settings.rpm_min;
202 | pwm_value = SPINDLE_PWM_MIN_VALUE;
203 | }
204 | } else {
205 | // Compute intermediate PWM value with linear spindle speed model.
206 | // NOTE: A nonlinear model could be installed here, if required, but keep it VERY light-weight.
207 | sys.spindle_speed = rpm;
208 | pwm_value = floor((rpm-settings.rpm_min)*pwm_gradient) + SPINDLE_PWM_MIN_VALUE;
209 | }
210 | return(pwm_value);
211 | }
212 |
213 | #endif
214 | #endif
215 |
216 |
217 | // Immediately sets spindle running state with direction and spindle rpm via PWM, if enabled.
218 | // Called by g-code parser spindle_sync(), parking retract and restore, g-code program end,
219 | // sleep, and spindle stop override.
220 | #ifdef VARIABLE_SPINDLE
221 | void spindle_set_state(uint8_t state, float rpm)
222 | #else
223 | void _spindle_set_state(uint8_t state)
224 | #endif
225 | {
226 | if (sys.abort) { return; } // Block during abort.
227 | if (state == SPINDLE_DISABLE) { // Halt or set spindle direction and rpm.
228 |
229 | #ifdef VARIABLE_SPINDLE
230 | sys.spindle_speed = 0.0;
231 | #endif
232 | spindle_stop();
233 |
234 | } else {
235 |
236 | #ifndef USE_SPINDLE_DIR_AS_ENABLE_PIN
237 | if (state == SPINDLE_ENABLE_CW) {
238 | //SPINDLE_DIRECTION_PORT &= ~(1<.
20 | */
21 |
22 | #ifndef spindle_control_h
23 | #define spindle_control_h
24 |
25 | #define SPINDLE_NO_SYNC false
26 | #define SPINDLE_FORCE_SYNC true
27 |
28 | #define SPINDLE_STATE_DISABLE 0 // Must be zero.
29 | #define SPINDLE_STATE_CW bit(0)
30 | #define SPINDLE_STATE_CCW bit(1)
31 |
32 |
33 | // Initializes spindle pins and hardware PWM, if enabled.
34 | void spindle_init();
35 |
36 | // Returns current spindle output state. Overrides may alter it from programmed states.
37 | uint8_t spindle_get_state();
38 |
39 | // Called by g-code parser when setting spindle state and requires a buffer sync.
40 | // Immediately sets spindle running state with direction and spindle rpm via PWM, if enabled.
41 | // Called by spindle_sync() after sync and parking motion/spindle stop override during restore.
42 | #ifdef VARIABLE_SPINDLE
43 |
44 | // Called by g-code parser when setting spindle state and requires a buffer sync.
45 | void spindle_sync(uint8_t state, float rpm);
46 |
47 | // Sets spindle running state with direction, enable, and spindle PWM.
48 | void spindle_set_state(uint8_t state, float rpm);
49 |
50 | // Sets spindle PWM quickly for stepper ISR. Also called by spindle_set_state().
51 | // NOTE: 328p PWM register is 8-bit.
52 | void spindle_set_speed(uint8_t pwm_value);
53 |
54 | // Computes 328p-specific PWM register value for the given RPM for quick updating.
55 | uint8_t spindle_compute_pwm_value(float rpm);
56 |
57 | #else
58 |
59 | // Called by g-code parser when setting spindle state and requires a buffer sync.
60 | #define spindle_sync(state, rpm) _spindle_sync(state)
61 | void _spindle_sync(uint8_t state);
62 |
63 | // Sets spindle running state with direction and enable.
64 | #define spindle_set_state(state, rpm) _spindle_set_state(state)
65 | void _spindle_set_state(uint8_t state);
66 |
67 | #endif
68 |
69 | // Stop and start spindle routines. Called by all spindle routines and stepper ISR.
70 | void spindle_stop();
71 |
72 |
73 | #endif
74 |
--------------------------------------------------------------------------------
/lib/grbl/src/stepper.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | stepper.h - stepper motor driver: executes motion plans of planner.c using the stepper motors
3 | Part of Grbl
4 |
5 | Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC
6 | Copyright (c) 2009-2011 Simen Svale Skogsrud
7 |
8 | Grbl is free software: you can redistribute it and/or modify
9 | it under the terms of the GNU General Public License as published by
10 | the Free Software Foundation, either version 3 of the License, or
11 | (at your option) any later version.
12 |
13 | Grbl is distributed in the hope that it will be useful,
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | GNU General Public License for more details.
17 |
18 | You should have received a copy of the GNU General Public License
19 | along with Grbl. If not, see .
20 | */
21 |
22 | #ifndef stepper_h
23 | #define stepper_h
24 |
25 | #ifndef SEGMENT_BUFFER_SIZE
26 | #define SEGMENT_BUFFER_SIZE 6
27 | #endif
28 |
29 | // Initialize and setup the stepper motor subsystem
30 | void stepper_init();
31 |
32 | // Enable steppers, but cycle does not start unless called by motion control or realtime command.
33 | void st_wake_up();
34 |
35 | // Immediately disables steppers
36 | void st_go_idle();
37 |
38 | // Generate the step and direction port invert masks.
39 | void st_generate_step_dir_invert_masks();
40 |
41 | // Reset the stepper subsystem variables
42 | void st_reset();
43 |
44 | // Changes the run state of the step segment buffer to execute the special parking motion.
45 | void st_parking_setup_buffer();
46 |
47 | // Restores the step segment buffer to the normal run state after a parking motion.
48 | void st_parking_restore_buffer();
49 |
50 | // Reloads step segment buffer. Called continuously by realtime execution system.
51 | void st_prep_buffer();
52 |
53 | // Called by planner_recalculate() when the executing block is updated by the new plan.
54 | void st_update_plan_block_parameters();
55 |
56 | // Called by realtime status reporting if realtime rate reporting is enabled in config.h.
57 | float st_get_realtime_rate();
58 |
59 | #endif
60 |
--------------------------------------------------------------------------------
/lib/grbl/src/system.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | system.c - Handles system level commands and real-time processes
3 | Part of Grbl
4 |
5 | Copyright (c) 2014-2016 Sungeun K. Jeon for Gnea Research LLC
6 |
7 | Grbl is free software: you can redistribute it and/or modify
8 | it under the terms of the GNU General Public License as published by
9 | the Free Software Foundation, either version 3 of the License, or
10 | (at your option) any later version.
11 |
12 | Grbl is distributed in the hope that it will be useful,
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | GNU General Public License for more details.
16 |
17 | You should have received a copy of the GNU General Public License
18 | along with Grbl. If not, see .
19 | */
20 |
21 | #include "grbl.hpp"
22 | #include
23 |
24 | void system_init()
25 | {
26 | SPI.begin();
27 | SPI.setHwCs(true);
28 | SPI.setFrequency(F_STEPPER_TIMER);
29 |
30 | // Turn off all control inputs
31 | CONTROL_PORT &= ~CONTROL_MASK;
32 | SPI.write(regs.data);
33 |
34 | // Attach interrupt to control input pin
35 | pinMode(CONTROL_INPUT_GPIO_PIN, INPUT_PULLUP);
36 | attachInterrupt(digitalPinToInterrupt(CONTROL_INPUT_GPIO_PIN), pin_control_vect, CHANGE);
37 | }
38 |
39 |
40 | // Returns control pin state as a uint8 bitfield. Each bit indicates the input pin state, where
41 | // triggered is 1 and not triggered is 0. Invert mask is applied. Bitfield organization is
42 | // defined by the CONTROL_PIN_INDEX in the header file.
43 | IRAM_ATTR uint8_t system_control_get_state()
44 | {
45 | uint8_t control_state = 0;
46 | uint8_t pin = (CONTROL_PORT_INPUTS & CONTROL_MASK);
47 | #ifdef INVERT_CONTROL_PIN_MASK
48 | pin ^= INVERT_CONTROL_PIN_MASK;
49 | #endif
50 | if (pin) {
51 | #ifdef ENABLE_SAFETY_DOOR_INPUT_PIN
52 | if (bit_istrue(pin,(1< 255)) { return(STATUS_INVALID_STATEMENT); }
302 | return(settings_store_global_setting((uint8_t)parameter, value));
303 | }
304 | }
305 | }
306 | return(STATUS_OK); // If '$' command makes it to here, then everything's ok.
307 | }
308 |
309 |
310 |
311 | void system_flag_wco_change()
312 | {
313 | #ifdef FORCE_BUFFER_SYNC_DURING_WCO_CHANGE
314 | protocol_buffer_synchronize();
315 | #endif
316 | sys.report_wco_counter = 0;
317 | }
318 |
319 |
320 | // Returns machine position of axis 'idx'. Must be sent a 'step' array.
321 | // NOTE: If motor steps and machine position are not in the same coordinate frame, this function
322 | // serves as a central place to compute the transformation.
323 | float system_convert_axis_steps_to_mpos(int32_t *steps, uint8_t idx)
324 | {
325 | float pos;
326 | #ifdef COREXY
327 | if (idx==X_AXIS) {
328 | pos = (float)system_convert_corexy_to_x_axis_steps(steps) / settings.steps_per_mm[idx];
329 | } else if (idx==Y_AXIS) {
330 | pos = (float)system_convert_corexy_to_y_axis_steps(steps) / settings.steps_per_mm[idx];
331 | } else {
332 | pos = steps[idx]/settings.steps_per_mm[idx];
333 | }
334 | #else
335 | pos = steps[idx]/settings.steps_per_mm[idx];
336 | #endif
337 | return(pos);
338 | }
339 |
340 |
341 | void system_convert_array_steps_to_mpos(float *position, int32_t *steps)
342 | {
343 | uint8_t idx;
344 | for (idx=0; idx -settings.max_travel[idx]) { return(true); }
374 | } else {
375 | if (target[idx] > 0 || target[idx] < settings.max_travel[idx]) { return(true); }
376 | }
377 | #else
378 | // NOTE: max_travel is stored as negative
379 | if (target[idx] > 0 || target[idx] < settings.max_travel[idx]) { return(true); }
380 | #endif
381 | }
382 | return(false);
383 | }
384 |
385 |
386 | // Special handlers for setting and clearing Grbl's real-time execution flags.
387 | void system_set_exec_state_flag(uint8_t mask) {
388 | //uint8_t sreg = save_SREG();
389 | //cli();
390 | sys_rt_exec_state |= (mask);
391 | //restore_SREG(sreg);
392 | }
393 |
394 | void system_clear_exec_state_flag(uint8_t mask) {
395 | //uint8_t sreg = save_SREG();
396 | //cli();
397 | sys_rt_exec_state &= ~(mask);
398 | //restore_SREG(sreg);
399 | //sei();
400 | }
401 |
402 | void system_set_exec_alarm(uint8_t code) {
403 | //uint8_t sreg = save_SREG();
404 | //cli();
405 | sys_rt_exec_alarm = code;
406 | //restore_SREG(sreg);
407 | }
408 |
409 | void system_clear_exec_alarm() {
410 | //uint8_t sreg = save_SREG();
411 | //cli();
412 | sys_rt_exec_alarm = 0;
413 | //restore_SREG(sreg);
414 | // sei();
415 | }
416 |
417 | void system_set_exec_motion_override_flag(uint8_t mask) {
418 | //uint8_t sreg = save_SREG();
419 | //cli();
420 | sys_rt_exec_motion_override |= (mask);
421 | //restore_SREG(sreg);
422 | }
423 |
424 | void system_set_exec_accessory_override_flag(uint8_t mask) {
425 | //uint8_t sreg = save_SREG();
426 | //cli();
427 | sys_rt_exec_accessory_override |= (mask);
428 | //restore_SREG(sreg);
429 | }
430 |
431 | void system_clear_exec_motion_overrides() {
432 | //uint8_t sreg = save_SREG();
433 | //cli();
434 | sys_rt_exec_motion_override = 0;
435 | //restore_SREG(sreg);
436 | // sei();
437 | }
438 |
439 | void system_clear_exec_accessory_overrides() {
440 | //uint8_t sreg = save_SREG();
441 | //cli();
442 | sys_rt_exec_accessory_override = 0;
443 | //restore_SREG(sreg);
444 | // sei();
445 | }
446 |
--------------------------------------------------------------------------------
/lib/grbl/src/system.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | system.h - Header for system level commands and real-time processes
3 | Part of Grbl
4 |
5 | Copyright (c) 2014-2016 Sungeun K. Jeon for Gnea Research LLC
6 |
7 | Grbl is free software: you can redistribute it and/or modify
8 | it under the terms of the GNU General Public License as published by
9 | the Free Software Foundation, either version 3 of the License, or
10 | (at your option) any later version.
11 |
12 | Grbl is distributed in the hope that it will be useful,
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | GNU General Public License for more details.
16 |
17 | You should have received a copy of the GNU General Public License
18 | along with Grbl. If not, see .
19 | */
20 |
21 | #ifndef system_h
22 | #define system_h
23 |
24 | #include "grbl.hpp"
25 |
26 | // Define system executor bit map. Used internally by realtime protocol as realtime command flags,
27 | // which notifies the main program to execute the specified realtime command asynchronously.
28 | // NOTE: The system executor uses an unsigned 8-bit volatile variable (8 flag limit.) The default
29 | // flags are always false, so the realtime protocol only needs to check for a non-zero value to
30 | // know when there is a realtime command to execute.
31 | #define EXEC_STATUS_REPORT bit(0) // bitmask 00000001
32 | #define EXEC_CYCLE_START bit(1) // bitmask 00000010
33 | #define EXEC_CYCLE_STOP bit(2) // bitmask 00000100
34 | #define EXEC_FEED_HOLD bit(3) // bitmask 00001000
35 | #define EXEC_RESET bit(4) // bitmask 00010000
36 | #define EXEC_SAFETY_DOOR bit(5) // bitmask 00100000
37 | #define EXEC_MOTION_CANCEL bit(6) // bitmask 01000000
38 | #define EXEC_SLEEP bit(7) // bitmask 10000000
39 |
40 | // Alarm executor codes. Valid values (1-255). Zero is reserved.
41 | #define EXEC_ALARM_HARD_LIMIT 1
42 | #define EXEC_ALARM_SOFT_LIMIT 2
43 | #define EXEC_ALARM_ABORT_CYCLE 3
44 | #define EXEC_ALARM_PROBE_FAIL_INITIAL 4
45 | #define EXEC_ALARM_PROBE_FAIL_CONTACT 5
46 | #define EXEC_ALARM_HOMING_FAIL_RESET 6
47 | #define EXEC_ALARM_HOMING_FAIL_DOOR 7
48 | #define EXEC_ALARM_HOMING_FAIL_PULLOFF 8
49 | #define EXEC_ALARM_HOMING_FAIL_APPROACH 9
50 |
51 | // Override bit maps. Realtime bitflags to control feed, rapid, spindle, and coolant overrides.
52 | // Spindle/coolant and feed/rapids are separated into two controlling flag variables.
53 | #define EXEC_FEED_OVR_RESET bit(0)
54 | #define EXEC_FEED_OVR_COARSE_PLUS bit(1)
55 | #define EXEC_FEED_OVR_COARSE_MINUS bit(2)
56 | #define EXEC_FEED_OVR_FINE_PLUS bit(3)
57 | #define EXEC_FEED_OVR_FINE_MINUS bit(4)
58 | #define EXEC_RAPID_OVR_RESET bit(5)
59 | #define EXEC_RAPID_OVR_MEDIUM bit(6)
60 | #define EXEC_RAPID_OVR_LOW bit(7)
61 | // #define EXEC_RAPID_OVR_EXTRA_LOW bit(*) // *NOT SUPPORTED*
62 |
63 | #define EXEC_SPINDLE_OVR_RESET bit(0)
64 | #define EXEC_SPINDLE_OVR_COARSE_PLUS bit(1)
65 | #define EXEC_SPINDLE_OVR_COARSE_MINUS bit(2)
66 | #define EXEC_SPINDLE_OVR_FINE_PLUS bit(3)
67 | #define EXEC_SPINDLE_OVR_FINE_MINUS bit(4)
68 | #define EXEC_SPINDLE_OVR_STOP bit(5)
69 | #define EXEC_COOLANT_FLOOD_OVR_TOGGLE bit(6)
70 | #define EXEC_COOLANT_MIST_OVR_TOGGLE bit(7)
71 |
72 | // Define system state bit map. The state variable primarily tracks the individual functions
73 | // of Grbl to manage each without overlapping. It is also used as a messaging flag for
74 | // critical events.
75 | #define STATE_IDLE 0 // Must be zero. No flags.
76 | #define STATE_ALARM bit(0) // In alarm state. Locks out all g-code processes. Allows settings access.
77 | #define STATE_CHECK_MODE bit(1) // G-code check mode. Locks out planner and motion only.
78 | #define STATE_HOMING bit(2) // Performing homing cycle
79 | #define STATE_CYCLE bit(3) // Cycle is running or motions are being executed.
80 | #define STATE_HOLD bit(4) // Active feed hold
81 | #define STATE_JOG bit(5) // Jogging mode.
82 | #define STATE_SAFETY_DOOR bit(6) // Safety door is ajar. Feed holds and de-energizes system.
83 | #define STATE_SLEEP bit(7) // Sleep state.
84 |
85 | // Define system suspend flags. Used in various ways to manage suspend states and procedures.
86 | #define SUSPEND_DISABLE 0 // Must be zero.
87 | #define SUSPEND_HOLD_COMPLETE bit(0) // Indicates initial feed hold is complete.
88 | #define SUSPEND_RESTART_RETRACT bit(1) // Flag to indicate a retract from a restore parking motion.
89 | #define SUSPEND_RETRACT_COMPLETE bit(2) // (Safety door only) Indicates retraction and de-energizing is complete.
90 | #define SUSPEND_INITIATE_RESTORE bit(3) // (Safety door only) Flag to initiate resume procedures from a cycle start.
91 | #define SUSPEND_RESTORE_COMPLETE bit(4) // (Safety door only) Indicates ready to resume normal operation.
92 | #define SUSPEND_SAFETY_DOOR_AJAR bit(5) // Tracks safety door state for resuming.
93 | #define SUSPEND_MOTION_CANCEL bit(6) // Indicates a canceled resume motion. Currently used by probing routine.
94 | #define SUSPEND_JOG_CANCEL bit(7) // Indicates a jog cancel in process and to reset buffers when complete.
95 |
96 | // Define step segment generator state flags.
97 | #define STEP_CONTROL_NORMAL_OP 0 // Must be zero.
98 | #define STEP_CONTROL_END_MOTION bit(0)
99 | #define STEP_CONTROL_EXECUTE_HOLD bit(1)
100 | #define STEP_CONTROL_EXECUTE_SYS_MOTION bit(2)
101 | #define STEP_CONTROL_UPDATE_SPINDLE_PWM bit(3)
102 |
103 | // Define control pin index for Grbl internal use. Pin maps may change, but these values don't.
104 | #ifdef ENABLE_SAFETY_DOOR_INPUT_PIN
105 | #define N_CONTROL_PIN 4
106 | #define CONTROL_PIN_INDEX_SAFETY_DOOR bit(0)
107 | #define CONTROL_PIN_INDEX_RESET bit(1)
108 | #define CONTROL_PIN_INDEX_FEED_HOLD bit(2)
109 | #define CONTROL_PIN_INDEX_CYCLE_START bit(3)
110 | #else
111 | #define N_CONTROL_PIN 3
112 | #define CONTROL_PIN_INDEX_RESET bit(0)
113 | #define CONTROL_PIN_INDEX_FEED_HOLD bit(1)
114 | #define CONTROL_PIN_INDEX_CYCLE_START bit(2)
115 | #endif
116 |
117 | // Define spindle stop override control states.
118 | #define SPINDLE_STOP_OVR_DISABLED 0 // Must be zero.
119 | #define SPINDLE_STOP_OVR_ENABLED bit(0)
120 | #define SPINDLE_STOP_OVR_INITIATE bit(1)
121 | #define SPINDLE_STOP_OVR_RESTORE bit(2)
122 | #define SPINDLE_STOP_OVR_RESTORE_CYCLE bit(3)
123 |
124 |
125 | // Define global system variables
126 | typedef struct {
127 | uint8_t state; // Tracks the current system state of Grbl.
128 | uint8_t abort; // System abort flag. Forces exit back to main loop for reset.
129 | uint8_t suspend; // System suspend bitflag variable that manages holds, cancels, and safety door.
130 | uint8_t soft_limit; // Tracks soft limit errors for the state machine. (boolean)
131 | uint8_t step_control; // Governs the step segment generator depending on system state.
132 | uint8_t probe_succeeded; // Tracks if last probing cycle was successful.
133 | uint8_t homing_axis_lock; // Locks axes when limits engage. Used as an axis motion mask in the stepper ISR.
134 | uint8_t f_override; // Feed rate override value in percent
135 | uint8_t r_override; // Rapids override value in percent
136 | uint8_t spindle_speed_ovr; // Spindle speed value in percent
137 | uint8_t spindle_stop_ovr; // Tracks spindle stop override states
138 | uint8_t report_ovr_counter; // Tracks when to add override data to status reports.
139 | uint8_t report_wco_counter; // Tracks when to add work coordinate offset data to status reports.
140 | #ifdef ENABLE_PARKING_OVERRIDE_CONTROL
141 | uint8_t override_ctrl; // Tracks override control states.
142 | #endif
143 | #ifdef VARIABLE_SPINDLE
144 | float spindle_speed;
145 | #endif
146 | } system_t;
147 | extern system_t sys;
148 |
149 | // NOTE: These position variables may need to be declared as volatiles, if problems arise.
150 | extern int32_t sys_position[N_AXIS]; // Real-time machine (aka home) position vector in steps.
151 | extern int32_t sys_probe_position[N_AXIS]; // Last probe position in machine coordinates and steps.
152 |
153 | extern volatile uint8_t sys_probe_state; // Probing state value. Used to coordinate the probing cycle with stepper ISR.
154 | extern volatile uint8_t sys_rt_exec_state; // Global realtime executor bitflag variable for state management. See EXEC bitmasks.
155 | extern volatile uint8_t sys_rt_exec_alarm; // Global realtime executor bitflag variable for setting various alarms.
156 | extern volatile uint8_t sys_rt_exec_motion_override; // Global realtime executor bitflag variable for motion-based overrides.
157 | extern volatile uint8_t sys_rt_exec_accessory_override; // Global realtime executor bitflag variable for spindle/coolant overrides.
158 |
159 | #ifdef DEBUG
160 | #define EXEC_DEBUG_REPORT bit(0)
161 | extern volatile uint8_t sys_rt_exec_debug;
162 | #endif
163 |
164 | // Initialize the serial protocol
165 | void system_init();
166 |
167 | // Returns bitfield of control pin states, organized by CONTROL_PIN_INDEX. (1=triggered, 0=not triggered).
168 | uint8_t system_control_get_state();
169 |
170 | // Returns if safety door is open or closed, based on pin state.
171 | uint8_t system_check_safety_door_ajar();
172 |
173 | // Executes an internal system command, defined as a string starting with a '$'
174 | uint8_t system_execute_line(char *line, uint8_t client);
175 |
176 | // Execute the startup script lines stored in EEPROM upon initialization
177 | void system_execute_startup(char *line);
178 |
179 |
180 | void system_flag_wco_change();
181 |
182 | // Returns machine position of axis 'idx'. Must be sent a 'step' array.
183 | float system_convert_axis_steps_to_mpos(int32_t *steps, uint8_t idx);
184 |
185 | // Updates a machine 'position' array based on the 'step' array sent.
186 | void system_convert_array_steps_to_mpos(float *position, int32_t *steps);
187 |
188 | // CoreXY calculation only. Returns x or y-axis "steps" based on CoreXY motor steps.
189 | #ifdef COREXY
190 | int32_t system_convert_corexy_to_x_axis_steps(int32_t *steps);
191 | int32_t system_convert_corexy_to_y_axis_steps(int32_t *steps);
192 | #endif
193 |
194 | // Checks and reports if target array exceeds machine travel limits.
195 | uint8_t system_check_travel_limits(float *target);
196 |
197 | // Special handlers for setting and clearing Grbl's real-time execution flags.
198 | void system_set_exec_state_flag(uint8_t mask);
199 | void system_clear_exec_state_flag(uint8_t mask);
200 | void system_set_exec_alarm(uint8_t code);
201 | void system_clear_exec_alarm();
202 | void system_set_exec_motion_override_flag(uint8_t mask);
203 | void system_set_exec_accessory_override_flag(uint8_t mask);
204 | void system_clear_exec_motion_overrides();
205 | void system_clear_exec_accessory_overrides();
206 |
207 | void pin_control_vect();
208 |
209 | #endif
210 |
--------------------------------------------------------------------------------
/lib/grbl/src/telnet_server.cpp:
--------------------------------------------------------------------------------
1 |
2 |
3 | #include "config.h"
4 | #include "telnet_server.hpp"
5 | #include "grbl.hpp"
6 | #include "report.hpp"
7 |
8 | Telnet_Server telnetServer;
9 | bool Telnet_Server::_setupdone = false;
10 | uint16_t Telnet_Server::_port = 0;
11 | AsyncServer *Telnet_Server::_telnetServer = NULL;
12 | AsyncClient *Telnet_Server::_telnetClients[MAX_TELNET_CLIENTS] = {NULL};
13 |
14 | Telnet_Server::Telnet_Server(){
15 | _RXbufferSize = 0;
16 | _RXbufferpos = 0;
17 | }
18 | Telnet_Server::~Telnet_Server(){
19 | end();
20 | }
21 |
22 | bool Telnet_Server::begin(){
23 | bool no_error = true;
24 | end();
25 | _RXbufferSize = 0;
26 | _RXbufferpos = 0;
27 | #ifdef ENABLE_TELNET
28 | int8_t penabled = 1;
29 | #else
30 | int8_t penabled = 0;
31 | #endif
32 | _port = TELNET_SERVER_PORT;
33 |
34 | if (penabled == 0) return false;
35 | _telnetServer = new AsyncServer(_port);
36 | _telnetServer->setNoDelay(true);
37 | String s = "[MSG:TELNET Started " + String(_port) + "]\r\n";
38 | grbl_send(CLIENT_ALL,(char *)s.c_str());
39 |
40 | //start telnet server
41 | _telnetServer->onClient(&Telnet_Server::handleNewClient, _telnetServer);
42 | _telnetServer->begin();
43 | _setupdone = true;
44 | return no_error;
45 | }
46 |
47 | void Telnet_Server::end(){
48 | _setupdone = false;
49 | _RXbufferSize = 0;
50 | _RXbufferpos = 0;
51 | if (_telnetServer) {
52 | delete _telnetServer;
53 | _telnetServer = NULL;
54 | }
55 | }
56 |
57 | size_t Telnet_Server::write(const uint8_t *buffer, size_t size){
58 | size_t wsize = 0;
59 | if ( !_setupdone || _telnetServer == NULL) {
60 | return 0;
61 | }
62 | //push UART data to all connected telnet clients
63 | for(uint8_t i = 0; i < MAX_TELNET_CLIENTS; i++){
64 | if (_telnetClients[i] != NULL && _telnetClients[i]->connected()){
65 | wsize = _telnetClients[i]->write((const char*)buffer, size);
66 | ///delay(0);
67 | }
68 | }
69 | return wsize;
70 | }
71 |
72 | static void handleError(void* arg, AsyncClient* client, int8_t error) {
73 | Serial.printf("\n connection error %s from client %s \n", client->errorToString(error), client->remoteIP().toString().c_str());
74 | }
75 |
76 | void Telnet_Server::handleData(void* arg, AsyncClient* client, void *data, size_t len) {
77 | //printf("Received '%.*s'\n", len, (uint8_t*)data);
78 | telnetServer.push((uint8_t *)data, len);
79 | }
80 |
81 | void Telnet_Server::handleDisconnect(void* arg, AsyncClient* client) {
82 | Serial.printf("\n client %s disconnected \n", client->remoteIP().toString().c_str());
83 | uint8_t i = 0;
84 | for (i = 0; i < MAX_TELNET_CLIENTS; i++) {
85 | //find free/disconnected spot
86 | if (_telnetClients[i] != NULL && _telnetClients[i] == client) {
87 | _telnetClients[i] = NULL;
88 | break;
89 | }
90 | }
91 | }
92 |
93 | static void handleTimeOut(void* arg, AsyncClient* client, uint32_t time) {
94 | Serial.printf("\n client ACK timeout ip: %s \n", client->remoteIP().toString().c_str());
95 | }
96 |
97 | void Telnet_Server::handleNewClient(void* arg, AsyncClient* client)
98 | {
99 | //Serial.printf("\n client connected ip: %s \n", client->remoteIP().toString().c_str());
100 | client->onData(&handleData, NULL);
101 | client->onError(&handleError, NULL);
102 | client->onDisconnect(&handleDisconnect, NULL);
103 | client->onTimeout(&handleTimeOut, NULL);
104 |
105 | uint8_t i = 0;
106 | for (i = 0; i < MAX_TELNET_CLIENTS; i++) {
107 | //find free/disconnected spot
108 | if (_telnetClients[i] == NULL || !_telnetClients[i]->connected()){
109 | _telnetClients[i] = client;
110 | break;
111 | }
112 | }
113 |
114 | if (i >= MAX_TELNET_CLIENTS) {
115 | //no free/disconnected spot so reject
116 | client->stop();
117 | }
118 | }
119 |
120 | int Telnet_Server::peek(void){
121 | //Serial.printf("TELNET PEEK");
122 | if (_RXbufferSize > 0)return _RXbuffer[_RXbufferpos];
123 | else return -1;
124 | }
125 |
126 | int Telnet_Server::available(){
127 | return _RXbufferSize;
128 | }
129 |
130 | int Telnet_Server::get_rx_buffer_available(){
131 | return TELNET_RXBUFFERSIZE - _RXbufferSize;
132 | }
133 |
134 | bool Telnet_Server::push(uint8_t data){
135 | if ((1 + _RXbufferSize) <= TELNET_RXBUFFERSIZE){
136 | int current = _RXbufferpos + _RXbufferSize;
137 | if (current > TELNET_RXBUFFERSIZE) current = current - TELNET_RXBUFFERSIZE;
138 | if (current > (TELNET_RXBUFFERSIZE-1)) current = 0;
139 | _RXbuffer[current] = data;
140 | _RXbufferSize++;
141 | return true;
142 | }
143 | return false;
144 | }
145 |
146 | bool Telnet_Server::push(const uint8_t * data, int data_size){
147 | if ((data_size + _RXbufferSize) <= TELNET_RXBUFFERSIZE) {
148 | int data_processed = 0;
149 | int current = _RXbufferpos + _RXbufferSize;
150 | if (current > TELNET_RXBUFFERSIZE) current = current - TELNET_RXBUFFERSIZE;
151 | for (int i = 0; i < data_size; i++){
152 | if (current > (TELNET_RXBUFFERSIZE-1)) current = 0;
153 | _RXbuffer[current] = data[i];
154 | current++;
155 | data_processed++;
156 | }
157 | _RXbufferSize+=data_processed;
158 | return true;
159 | }
160 | return false;
161 | }
162 |
163 | int Telnet_Server::read(void){
164 | if (_RXbufferSize > 0) {
165 | int v = _RXbuffer[_RXbufferpos];
166 | _RXbufferpos++;
167 | if (_RXbufferpos > (TELNET_RXBUFFERSIZE-1))_RXbufferpos = 0;
168 | _RXbufferSize--;
169 | return v;
170 | } else return -1;
171 | }
172 |
--------------------------------------------------------------------------------
/lib/grbl/src/telnet_server.hpp:
--------------------------------------------------------------------------------
1 |
2 | #ifndef _TELNET_SERVER_H
3 | #define _TELNET_SERVER_H
4 |
5 | #include
6 | #include
7 | #include "config.h"
8 |
9 | // how many clients should be able to telnet
10 | #define MAX_TELNET_CLIENTS 1
11 | #define TELNET_RXBUFFERSIZE 1200
12 | #define TELNET_SERVER_PORT 23
13 |
14 | class Telnet_Server {
15 | public:
16 | Telnet_Server();
17 | ~Telnet_Server();
18 | bool begin();
19 | void end();
20 | size_t write(const uint8_t *buffer, size_t size);
21 | int read(void);
22 | int peek(void);
23 | int available();
24 | int get_rx_buffer_available();
25 | bool push (uint8_t data);
26 | bool push (const uint8_t * data, int datasize);
27 | void clearClients();
28 | static void handleNewClient(void* arg, AsyncClient *client);
29 | static void handleData(void* arg, AsyncClient* client, void *data, size_t len);
30 | static void handleDisconnect(void* arg, AsyncClient* client);
31 | static uint16_t port(){return _port;}
32 | private:
33 | static bool _setupdone;
34 | static AsyncServer *_telnetServer;
35 | static AsyncClient *_telnetClients[MAX_TELNET_CLIENTS];
36 | static uint16_t _port;
37 | uint32_t _lastflush;
38 | uint8_t _RXbuffer[TELNET_RXBUFFERSIZE];
39 | uint16_t _RXbufferSize;
40 | uint16_t _RXbufferpos;
41 | };
42 |
43 | extern Telnet_Server telnetServer;
44 |
45 | #endif
46 |
--------------------------------------------------------------------------------
/lib/grbl/src/websocket.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | websocket.cpp - Take advantage of the Wifi connection by using websockets instead
3 | of a serial connection
4 | */
5 | #include "grbl.hpp"
6 | #include
7 |
8 | #ifdef ENABLE_WEBSOCKET
9 |
10 | AsyncWebServer webSocketServer(WEBSOCKET_SERVER_PORT);
11 | AsyncWebSocket ws("/ws");
12 | //AsyncEventSource events("/events");
13 |
14 | void websocket_init()
15 | {
16 | ws.onEvent(onWsEvent);
17 | webSocketServer.addHandler(&ws);
18 | webSocketServer.begin();
19 | Serial2Socket.attachWS(&ws);
20 | }
21 |
22 | void onWsEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventType type, void * arg, uint8_t *data, size_t len){
23 | if(type == WS_EVT_CONNECT){
24 | //Serial.printf("ws[%s][%u] connect\n", server->url(), client->id());
25 | //client->printf("Hello Client %u :)", client->id());
26 | client->ping();
27 | } else if(type == WS_EVT_DISCONNECT){
28 | Serial.printf("ws[%s][%u] disconnect: %u\n", server->url(), client->id());
29 | } else if(type == WS_EVT_ERROR){
30 | Serial.printf("ws[%s][%u] error(%u): %s\n", server->url(), client->id(), *((uint16_t*)arg), (char*)data);
31 | } else if(type == WS_EVT_PONG){
32 | Serial.printf("ws[%s][%u] pong[%u]: %s\n", server->url(), client->id(), len, (len)?(char*)data:"");
33 | } else if(type == WS_EVT_DATA){
34 | AwsFrameInfo * info = (AwsFrameInfo*)arg;
35 | String msg = "";
36 | if (info->final && info->index == 0 && info->len == len){
37 | //the whole message is in a single frame and we got all of it's data
38 | for(size_t i=0; i < info->len; i++) {
39 | msg += (char)data[i];
40 | }
41 | msg += '\n';
42 | Serial2Socket.push(msg.c_str());
43 | }
44 | }
45 | }
46 |
47 | #endif
48 |
--------------------------------------------------------------------------------
/lib/grbl/src/websocket.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | websocket.hpp - Take advantage of the Wifi connection by using websockets instead
3 | of a websocket connection
4 | */
5 |
6 | #ifndef websocket_h
7 | #define websocket_h
8 |
9 | #include
10 |
11 | #define WEBSOCKET_SERVER_PORT 80
12 | #define WEBSOCKET_NO_DATA 0xff
13 |
14 | void websocket_init();
15 |
16 | // Called on every event received by websocket
17 | void onWsEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventType type, void * arg, uint8_t *data, size_t len);
18 |
19 | // Writes one byte to the TX websocket buffer. Called by main program.
20 | void websocket_write(uint8_t data);
21 |
22 | // Fetches the first byte in the websocket read buffer. Called by main program.
23 | uint8_t websocket_read();
24 |
25 | // Reset and empty data in read buffer. Used by e-stop and reset.
26 | void websocket_reset_read_buffer();
27 |
28 | // Returns the number of bytes available in the RX websocket buffer.
29 | uint8_t websocket_get_rx_buffer_available();
30 |
31 | // Returns the number of bytes used in the RX websocket buffer.
32 | // NOTE: Deprecated. Not used unless classic status reports are enabled in config.h.
33 | uint8_t websocket_get_rx_buffer_count();
34 |
35 | // Returns the number of bytes used in the TX websocket buffer.
36 | // NOTE: Not used except for debugging and ensuring no TX bottlenecks.
37 | uint8_t websocket_get_tx_buffer_count();
38 |
39 | // Handles connections/disconnection events on the websocket server
40 | void websocket_check_connection();
41 |
42 | #endif
43 |
--------------------------------------------------------------------------------
/lib/grbl/src/wifi.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | wifi.cpp - Handles connection to wifi and makes web, websockets and telnet
3 | connections available
4 | */
5 |
6 | #include
7 | //#include
8 | #include "credentials.hpp"
9 | #include "report.hpp"
10 | #include "config.hpp"
11 | #ifdef ENABLE_WEBSOCKET
12 | #include "websocket.hpp"
13 | #include "serial2socket.hpp"
14 | #endif
15 | #ifdef ENABLE_TELNET
16 | #include "telnet_server.hpp"
17 | #endif
18 |
19 | void wifi_init()
20 | {
21 | WiFi.mode(WIFI_STA);
22 | WiFi.hostname(WIFI_HOSTNAME);
23 | WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
24 | while (WiFi.status() != WL_CONNECTED) {
25 | delay(500);
26 | }
27 | Serial.print("\n[Connected: ");
28 | Serial.print(WiFi.localIP());
29 | Serial.println("]");
30 |
31 | //MDNS.addService("http", "tcp", WEBSOCKET_SERVER_PORT);
32 |
33 | #ifdef ENABLE_TELNET
34 | telnetServer.begin();
35 | #endif
36 | #ifdef ENABLE_WEBSOCKET
37 | websocket_init();
38 | #endif
39 | //be sure we are not is mixed mode in setup
40 | WiFi.scanNetworks(true);
41 | }
42 |
43 | void wifi_handle()
44 | {
45 | if (WiFi.getMode() == WIFI_AP_STA) {
46 | if (WiFi.scanComplete() != WIFI_SCAN_RUNNING) {
47 | WiFi.enableSTA(false);
48 | }
49 | }
50 | #ifdef ENABLE_OTA
51 | ArduinoOTA.handle();
52 | #endif
53 | #ifdef ENABLE_HTTP
54 | web_server.handle();
55 | #endif
56 | }
57 |
--------------------------------------------------------------------------------
/lib/grbl/src/wifi.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | wifi.cpp - Handles connection to wifi and makes web, websockets and telnet
3 | connections available
4 | */
5 |
6 | #ifndef wifi_h
7 | #define wifi_h
8 |
9 | #include "grbl.hpp"
10 |
11 | void wifi_init();
12 | void wifi_handle();
13 |
14 | #endif
15 |
--------------------------------------------------------------------------------
/lib/readme.txt:
--------------------------------------------------------------------------------
1 |
2 | This directory is intended for the project specific (private) libraries.
3 | PlatformIO will compile them to static libraries and link to executable file.
4 |
5 | The source code of each library should be placed in separate directory, like
6 | "lib/private_lib/[here are source files]".
7 |
8 | For example, see how can be organized `Foo` and `Bar` libraries:
9 |
10 | |--lib
11 | | |--Bar
12 | | | |--docs
13 | | | |--examples
14 | | | |--src
15 | | | |- Bar.c
16 | | | |- Bar.h
17 | | |--Foo
18 | | | |- Foo.c
19 | | | |- Foo.h
20 | | |- readme.txt --> THIS FILE
21 | |- platformio.ini
22 | |--src
23 | |- main.c
24 |
25 | Then in `src/main.c` you should use:
26 |
27 | #include
28 | #include
29 |
30 | // rest H/C/CPP code
31 |
32 | PlatformIO will find your libraries automatically, configure preprocessor's
33 | include paths and build them.
34 |
35 | More information about PlatformIO Library Dependency Finder
36 | - http://docs.platformio.org/page/librarymanager/ldf.html
37 |
--------------------------------------------------------------------------------
/platformio.ini:
--------------------------------------------------------------------------------
1 | ; PlatformIO Project Configuration File
2 | ;
3 | ; Build options: build flags, source filter
4 | ; Upload options: custom upload port, speed and extra flags
5 | ; Library options: dependencies, extra library storages
6 | ; Advanced options: extra scripting
7 | ;
8 | ; Please visit documentation for the other options and examples
9 | ; https://docs.platformio.org/page/projectconf.html
10 |
11 | [env:esp12e]
12 | platform = espressif8266@4.0.1
13 | framework = arduino
14 | board = esp12e
15 | upload_resetmethod = nodemcu
16 | upload_speed = 230400
17 | upload_port = /dev/ttyUSB0
18 | monitor_port = /dev/ttyUSB0
19 | monitor_speed = 115200
20 | monitor_echo = yes
21 | lib_deps =
22 | me-no-dev/ESPAsyncWebServer@1.2.4
23 | me-no-dev/ESPAsyncTCP@1.2.2
24 | lib_ignore = RPAsyncTCP, AsyncTCP
25 | build_flags = -DVTABLES_IN_FLASH
26 |
--------------------------------------------------------------------------------
/schemas/spi-connection.fzz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gcobos/grblesp/497762bd6390b6384049f1aac3e59b2b0a4b04dd/schemas/spi-connection.fzz
--------------------------------------------------------------------------------
/schemas/spi-connection_schem.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gcobos/grblesp/497762bd6390b6384049f1aac3e59b2b0a4b04dd/schemas/spi-connection_schem.png
--------------------------------------------------------------------------------
/src/main.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | main.c - An embedded CNC Controller with rs274/ngc (g-code) support
3 | Part of Grbl
4 |
5 | Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC
6 | Copyright (c) 2009-2011 Simen Svale Skogsrud
7 |
8 | Grbl is free software: you can redistribute it and/or modify
9 | it under the terms of the GNU General Public License as published by
10 | the Free Software Foundation, either version 3 of the License, or
11 | (at your option) any later version.
12 |
13 | Grbl is distributed in the hope that it will be useful,
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | GNU General Public License for more details.
17 |
18 | You should have received a copy of the GNU General Public License
19 | along with Grbl. If not, see .
20 | */
21 |
22 | #include
23 | #include "grbl.hpp"
24 |
25 | // Declare system global variable structure
26 | system_t sys;
27 | int32_t sys_position[N_AXIS]; // Real-time machine (aka home) position vector in steps.
28 | int32_t sys_probe_position[N_AXIS]; // Last probe position in machine coordinates and steps.
29 | volatile uint8_t sys_probe_state; // Probing state value. Used to coordinate the probing cycle with stepper ISR.
30 | volatile uint8_t sys_rt_exec_state; // Global realtime executor bitflag variable for state management. See EXEC bitmasks.
31 | volatile uint8_t sys_rt_exec_alarm; // Global realtime executor bitflag variable for setting various alarms.
32 | volatile uint8_t sys_rt_exec_motion_override; // Global realtime executor bitflag variable for motion-based overrides.
33 | volatile uint8_t sys_rt_exec_accessory_override; // Global realtime executor bitflag variable for spindle/coolant overrides.
34 | #ifdef DEBUG
35 | volatile uint8_t sys_rt_exec_debug;
36 | #endif
37 |
38 | void setup(void){
39 | // Initialize system upon power-up.
40 | serial_init(); // Setup serial connection
41 | eeprom_init(); // Initialize EEPROM
42 | settings_init(); // Load Grbl settings from EEPROM
43 | stepper_init(); // Configure stepper pins and interrupt timers
44 | system_init(); // Configure pinout pins and pin-change interrupt
45 |
46 | memset(sys_position,0,sizeof(sys_position)); // Clear machine position.
47 | sei(); // Enable interrupts
48 |
49 | // Initialize system state.
50 | #ifdef FORCE_INITIALIZATION_ALARM
51 | // Force Grbl into an ALARM state upon a power-cycle or hard reset.
52 | sys.state = STATE_ALARM;
53 | #else
54 | sys.state = STATE_IDLE;
55 | #endif
56 |
57 | // Check for power-up and set system alarm if homing is enabled to force homing cycle
58 | // by setting Grbl's alarm state. Alarm locks out all g-code commands, including the
59 | // startup scripts, but allows access to settings and internal commands. Only a homing
60 | // cycle '$H' or kill alarm locks '$X' will disable the alarm.
61 | // NOTE: The startup script will run after successful completion of the homing cycle, but
62 | // not after disabling the alarm locks. Prevents motion startup blocks from crashing into
63 | // things uncontrollably. Very bad.
64 | #ifdef HOMING_INIT_LOCK
65 | if (bit_istrue(settings.flags,BITFLAG_HOMING_ENABLE)) { sys.state = STATE_ALARM; }
66 | #endif
67 |
68 | #ifdef ENABLE_WIFI
69 | wifi_init();
70 | #endif
71 | }
72 |
73 | void loop(void)
74 | {
75 | // Grbl initialization loop upon power-up or a system abort. For the latter, all processes
76 | // will return to this loop to be cleanly re-initialized.
77 |
78 | // Reset system variables.
79 | uint8_t prior_state = sys.state;
80 | memset(&sys, 0, sizeof(system_t)); // Clear system struct variable.
81 | sys.state = prior_state;
82 | sys.f_override = DEFAULT_FEED_OVERRIDE; // Set to 100%
83 | sys.r_override = DEFAULT_RAPID_OVERRIDE; // Set to 100%
84 | sys.spindle_speed_ovr = DEFAULT_SPINDLE_SPEED_OVERRIDE; // Set to 100%
85 | memset(sys_probe_position,0,sizeof(sys_probe_position)); // Clear probe position.
86 | sys_probe_state = 0;
87 | sys_rt_exec_state = 0;
88 | sys_rt_exec_alarm = 0;
89 | sys_rt_exec_motion_override = 0;
90 | sys_rt_exec_accessory_override = 0;
91 |
92 | // Reset Grbl primary systems.
93 | serial_reset_read_buffer(CLIENT_ALL); // Clear serial read buffer
94 | gc_init(); // Set g-code parser to default state
95 | spindle_init();
96 | coolant_init();
97 | limits_init();
98 | probe_init();
99 | plan_reset(); // Clear block buffer and planner variables
100 | st_reset(); // Clear stepper subsystem variables.
101 |
102 | // Sync cleared gcode and planner positions to current system position.
103 | plan_sync_position();
104 | gc_sync_position();
105 |
106 | // Print welcome message. Indicates an initialization has occured at power-up or with a reset.
107 | report_init_message(CLIENT_ALL);
108 |
109 | // Start Grbl main loop. Processes program inputs and executes them.
110 | protocol_main_loop();
111 | }
112 |
--------------------------------------------------------------------------------