Update de grbl avec un plus grand buffer et un peu de doc en plus

This commit is contained in:
Geekoid
2019-12-18 21:26:27 +01:00
parent c24dd1bb34
commit dd41d3358a
159 changed files with 38922 additions and 18 deletions

View File

@ -0,0 +1,153 @@
This file defines the [ESP...] style commands. They can be used via serial, Bluetooth or Wifi
These are used for basic wireless settings as well as SD card commands
Some commands need to be authenticated with a password. Authentication
is optional via #define ENABLE_AUTHENTICATION in the config.h file.
The default password is "admin"
============== Examples (assumes "admin" password): ===============
Command: [ESP800]pwd=admin
Reply: FW version:1.1f # FW target:grbl-embedded # FW HW:Direct SD # primary sd:/sd # secondary sd:none # authentication:yes # webcommunication: Sync: 81# hostname:grblesp
Command: [ESP111]
Reply: 192.168.1.11
Command: [ESP121]pwd=admin
Reply: 80
Command: [ESP121]pwd=admin
Reply: 80
Command: [ESP121]81 pwd=admin
Reply: ok
Command: [ESP121]pwd=admin
Reply: 81
=============== Command Reference ========================
* Set/Get STA SSID
[ESP100]<SSID>pwd=<admin password>
* Set STA Password
[ESP101]<Password>pwd=<admin password>
* Set/Get STA IP mode (DHCP/STATIC)
[ESP102]<mode>pwd=<admin password>
* Set/Get STA IP/Mask/GW
[ESP103]IP=<IP> MSK=<IP> GW=<IP> pwd=<admin password>
* Set/Get AP SSID
[ESP105]<SSID>pwd=<admin password>
* Change AP Password
[ESP106]<Password>pwd=<admin password>
* Set/Get AP IP
[ESP107]<IP>pwd=<admin password>
* Set/Get AP channel
[ESP108]<channel>pwd=<admin password>
* Set/Get radio state which can be STA, AP, BT, OFF
[ESP110]<state>pwd=<admin password>
* Get current IP
[ESP111]<header answer>
* Get/Set hostname
[ESP112]<Hostname> pwd=<admin password>
* Get/Set immediate Radio (WiFi/BT) state which can be ON, OFF
[ESP115]<state>pwd=<admin password>
* Get/Set HTTP state which can be ON, OFF
[ESP120]<state>pwd=<admin password>
* Get/Set HTTP port
[ESP121]<port>pwd=<admin password>
* Get/Set Telnet state which can be ON, OFF
[ESP130]<state>pwd=<admin password>
* Get/Set Telnet port
[ESP131]<port>pwd=<admin password>
* Get/Set btname
[ESP140]< Bluetooth name> pwd=<admin password>
* Get SD Card Status
[ESP200] pwd=<user/admin password>
* Get SD Card Content
[ESP210] pwd=<user/admin password>
* Delete SD Card file / directory
[ESP215]<file/dir name>pwd=<user/admin password>
* Print SD file
[ESP220] <Filename> pwd=<user/admin password>
*Get full EEPROM settings content
but do not give any passwords
[ESP400] pwd=<user/admin password>
*Set EEPROM setting
position in EEPROM, type: B(byte), I(integer/long), S(string), A(IP address / mask)
[ESP401]P=<position> T=<type> V=<value> pwd=<user/admin password>
Positions:
HOSTNAME_ENTRY "ESP_HOSTNAME" String
STA_SSID_ENTRY "STA_SSID" String
STA_PWD_ENTRY "STA_PWD" String
STA_IP_ENTRY "STA_IP" IP
STA_GW_ENTRY "STA_GW" IP
STA_MK_ENTRY "STA_MK" IP
ESP_WIFI_MODE "WIFI_MODE" Byte (0=OFF, STA=1, AP=2)
AP_SSID_ENTRY "AP_SSID" String
AP_PWD_ENTRY "AP_PWD" String
AP_IP_ENTRY "AP_IP" IP
AP_CHANNEL_ENTRY "AP_CHANNEL" Byte
HTTP_ENABLE_ENTRY "HTTP_ON" Byte (0=Disabled, 1=Enabled)
HTTP_PORT_ENTRY "HTTP_PORT" Integer
TELNET_ENABLE_ENTRY "TELNET_ON" Byte (0=Disabled, 1=Enabled)
TELNET_PORT_ENTRY "TELNET_PORT" Integer
STA_IP_MODE_ENTRY "STA_IP_MODE" Byte (0=DHCP, 1=STATIC)
*Get available AP list (limited to 30)
output is JSON or plain text according parameter
[ESP410] pwd=<user/admin password>
*Get current settings of ESP3D
output is JSON or plain text according parameter
[ESP420]pwd=<user/admin password>
* Restart ESP
[ESP444]RESTART pwd=<admin password>
* Change / Reset user password
[ESP555]<password>pwd=<admin password>
if no password set it use default one
* Send Notification
[ESP600]msg [pwd=<admin password>]
* Set/Get Notification settings
[ESP610]type=<NONE/PUSHOVER/EMAIL/LINE> T1=<token1> T2=<token2> TS=<Settings> [pwd=<admin password>]
Get will give type and settings only, not the protected T1/T2
* Read SPIFFS file and send each line to serial
[ESP700]<filename> pwd=<user/admin password>
* Format SPIFFS
[ESP710]FORMAT pwd=<admin password>
* SPIFFS total size and used size
[ESP720]<header answer> pwd=<user/admin password>
* Get fw version and basic information
[ESP800]<header answer>

View File

@ -0,0 +1,10 @@
"Alarm Code in v1.1+"," Alarm Message in v1.0-"," Alarm Description"
"1","Hard limit","Hard limit has been triggered. Machine position is likely lost due to sudden halt. Re-homing is highly recommended."
"2","Soft limit","Soft limit alarm. G-code motion target exceeds machine travel. Machine position retained. Alarm may be safely unlocked."
"3","Abort during cycle","Reset while in motion. Machine position is likely lost due to sudden halt. Re-homing is highly recommended."
"4","Probe fail","Probe fail. Probe is not in the expected initial state before starting probe cycle when G38.2 and G38.3 is not triggered and G38.4 and G38.5 is triggered."
"5","Probe fail","Probe fail. Probe did not contact the workpiece within the programmed travel for G38.2 and G38.4."
"6","Homing fail","Homing fail. The active homing cycle was reset."
"7","Homing fail","Homing fail. Safety door was opened during homing cycle."
"8","Homing fail","Homing fail. Pull off travel failed to clear limit switch. Try increasing pull-off setting or check wiring."
"9","Homing fail","Homing fail. Could not find limit switch within search distances. Try increasing max travel, decreasing pull-off distance, or check wiring."
1 Alarm Code in v1.1+ Alarm Message in v1.0- Alarm Description
2 1 Hard limit Hard limit has been triggered. Machine position is likely lost due to sudden halt. Re-homing is highly recommended.
3 2 Soft limit Soft limit alarm. G-code motion target exceeds machine travel. Machine position retained. Alarm may be safely unlocked.
4 3 Abort during cycle Reset while in motion. Machine position is likely lost due to sudden halt. Re-homing is highly recommended.
5 4 Probe fail Probe fail. Probe is not in the expected initial state before starting probe cycle when G38.2 and G38.3 is not triggered and G38.4 and G38.5 is triggered.
6 5 Probe fail Probe fail. Probe did not contact the workpiece within the programmed travel for G38.2 and G38.4.
7 6 Homing fail Homing fail. The active homing cycle was reset.
8 7 Homing fail Homing fail. Safety door was opened during homing cycle.
9 8 Homing fail Homing fail. Pull off travel failed to clear limit switch. Try increasing pull-off setting or check wiring.
10 9 Homing fail Homing fail. Could not find limit switch within search distances. Try increasing max travel, decreasing pull-off distance, or check wiring.

View File

@ -0,0 +1,22 @@
OPT: Code, Build-Option Description,State
V,Variable spindle,Enabled
N,Line numbers,Enabled
M,Mist coolant M7,Enabled
C,CoreXY,Enabled
P,Parking motion,Enabled
Z,Homing force origin,Enabled
H,Homing single axis commands,Enabled
T,Two limit switches on axis,Enabled
A,Allow feed rate overrides in probe cycles,Enabled
D,Use spindle direction as enable pin,Enabled
0,Spindle enable off when speed is zero,Enabled
S,Software limit pin debouncing,Enabled
R,Parking override control,Enabled
+,Safety door input pin,Enabled
*,Restore all EEPROM command,Disabled
$,Restore EEPROM `$` settings command,Disabled
#,Restore EEPROM parameter data command,Disabled
I,Build info write user string command,Disabled
E,Force sync upon EEPROM write,Disabled
W,Force sync upon work coordinate offset change,Disabled
L,Homing initialization auto-lock,Disabled
1 OPT: Code Build-Option Description State
2 V Variable spindle Enabled
3 N Line numbers Enabled
4 M Mist coolant M7 Enabled
5 C CoreXY Enabled
6 P Parking motion Enabled
7 Z Homing force origin Enabled
8 H Homing single axis commands Enabled
9 T Two limit switches on axis Enabled
10 A Allow feed rate overrides in probe cycles Enabled
11 D Use spindle direction as enable pin Enabled
12 0 Spindle enable off when speed is zero Enabled
13 S Software limit pin debouncing Enabled
14 R Parking override control Enabled
15 + Safety door input pin Enabled
16 * Restore all EEPROM command Disabled
17 $ Restore EEPROM `$` settings command Disabled
18 # Restore EEPROM parameter data command Disabled
19 I Build info write user string command Disabled
20 E Force sync upon EEPROM write Disabled
21 W Force sync upon work coordinate offset change Disabled
22 L Homing initialization auto-lock Disabled

View File

@ -0,0 +1,44 @@
"Error Code in v1.1+","Error Message in v1.0-","Error Description"
"1","Expected command letter","G-code words consist of a letter and a value. Letter was not found."
"2","Bad number format","Missing the expected G-code word value or numeric value format is not valid."
"3","Invalid statement","Grbl '$' system command was not recognized or supported."
"4","Value < 0","Negative value received for an expected positive value."
"5","Setting disabled","Homing cycle failure. Homing is not enabled via settings."
"6","Value < 3 usec","Minimum step pulse time must be greater than 3usec."
"7","EEPROM read fail. Using defaults","An EEPROM read failed. Auto-restoring affected EEPROM to default values."
"8","Not idle","Grbl '$' command cannot be used unless Grbl is IDLE. Ensures smooth operation during a job."
"9","G-code lock","G-code commands are locked out during alarm or jog state."
"10","Homing not enabled","Soft limits cannot be enabled without homing also enabled."
"11","Line overflow","Max characters per line exceeded. Received command line was not executed."
"12","Step rate > 30kHz","Grbl '$' setting value cause the step rate to exceed the maximum supported."
"13","Check Door","Safety door detected as opened and door state initiated."
"14","Line length exceeded","Build info or startup line exceeded EEPROM line length limit. Line not stored."
"15","Travel exceeded","Jog target exceeds machine travel. Jog command has been ignored."
"16","Invalid jog command","Jog command has no '=' or contains prohibited g-code."
"17","Setting disabled","Laser mode requires PWM output."
"20","Unsupported command","Unsupported or invalid g-code command found in block."
"21","Modal group violation","More than one g-code command from same modal group found in block."
"22","Undefined feed rate","Feed rate has not yet been set or is undefined."
"23","Invalid gcode ID:23","G-code command in block requires an integer value."
"24","Invalid gcode ID:24","More than one g-code command that requires axis words found in block."
"25","Invalid gcode ID:25","Repeated g-code word found in block."
"26","Invalid gcode ID:26","No axis words found in block for g-code command or current modal state which requires them."
"27","Invalid gcode ID:27","Line number value is invalid."
"28","Invalid gcode ID:28","G-code command is missing a required value word."
"29","Invalid gcode ID:29","G59.x work coordinate systems are not supported."
"30","Invalid gcode ID:30","G53 only allowed with G0 and G1 motion modes."
"31","Invalid gcode ID:31","Axis words found in block when no command or current modal state uses them."
"32","Invalid gcode ID:32","G2 and G3 arcs require at least one in-plane axis word."
"33","Invalid gcode ID:33","Motion command target is invalid."
"34","Invalid gcode ID:34","Arc radius value is invalid."
"35","Invalid gcode ID:35","G2 and G3 arcs require at least one in-plane offset word."
"36","Invalid gcode ID:36","Unused value words found in block."
"37","Invalid gcode ID:37","G43.1 dynamic tool length offset is not assigned to configured tool length axis."
"38","Invalid gcode ID:38","Tool number greater than max supported value."
"39","Parameter P exceeded max ID:39","Parameter P exceeded max"
"60","SD failed to mount"
"61","SD card failed to open file for reading"
"62","SD card failed to open directory"
"63","SD Card directory not found"
"64","SD Card file empty"
"70","Bluetooth failed to start"
Can't render this file because it has a wrong number of fields in line 39.

View File

@ -0,0 +1,46 @@
"$-Code"," Setting"," Units"," Setting Description"
"0","Step pulse time","microseconds","Sets time length per step. Minimum 3usec."
"1","Step idle delay","milliseconds","Sets a short hold delay when stopping to let dynamics settle before disabling steppers. Value 255 keeps motors enabled with no delay."
"2","Step pulse invert","mask","Inverts the step signal. Set axis bit to invert (00000ZYX)."
"3","Step direction invert","mask","Inverts the direction signal. Set axis bit to invert (00000ZYX)."
"4","Invert step enable pin","boolean","Inverts the stepper driver enable pin signal."
"5","Invert limit pins","boolean","Inverts the all of the limit input pins."
"6","Invert probe pin","boolean","Inverts the probe input pin signal."
"10","Status report options","mask","Alters data included in status reports."
"11","Junction deviation","millimeters","Sets how fast Grbl travels through consecutive motions. Lower value slows it down."
"12","Arc tolerance","millimeters","Sets the G2 and G3 arc tracing accuracy based on radial error. Beware: A very small value may effect performance."
"13","Report in inches","boolean","Enables inch units when returning any position and rate value that is not a settings value."
"20","Soft limits enable","boolean","Enables soft limits checks within machine travel and sets alarm when exceeded. Requires homing."
"21","Hard limits enable","boolean","Enables hard limits. Immediately halts motion and throws an alarm when switch is triggered."
"22","Homing cycle enable","boolean","Enables homing cycle. Requires limit switches on all axes."
"23","Homing direction invert","mask","Homing searches for a switch in the positive direction. Set axis bit (00000ZYX) to search in negative direction."
"24","Homing locate feed rate","mm/min","Feed rate to slowly engage limit switch to determine its location accurately."
"25","Homing search seek rate","mm/min","Seek rate to quickly find the limit switch before the slower locating phase."
"26","Homing switch debounce delay","milliseconds","Sets a short delay between phases of homing cycle to let a switch debounce."
"27","Homing switch pull-off distance","millimeters","Retract distance after triggering switch to disengage it. Homing will fail if switch isn't cleared."
"30","Maximum spindle speed","RPM","Maximum spindle speed. Sets PWM to 100% duty cycle."
"31","Minimum spindle speed","RPM","Minimum spindle speed. Sets PWM to 0.4% or lowest duty cycle."
"32","Laser-mode enable","boolean","Enables laser mode. Consecutive G1/2/3 commands will not halt when spindle speed is changed."
"33","Spindle PWM Freq","16-bit","Spindle PWM Freq"
"34","Spindle PWM Off Value","16-bit","Spindle PWM Off Value"
"35","Spindle PWM Min Value","16-bit","Spindle PWM Min Value"
"36","Spindle PWM Max Value","16-bit","Spindle PWM Max Value"
"80-84","User integer Values","unsigned 16-bit","Reserved for custom machine use"
"90-94","User Floating point value","float","Reserved for custom machine use"
"100","X-axis travel resolution","step/mm","X-axis travel resolution in steps per millimeter."
"101","Y-axis travel resolution","step/mm","Y-axis travel resolution in steps per millimeter."
"102","Z-axis travel resolution","step/mm","Z-axis travel resolution in steps per millimeter."
"110","X-axis maximum rate","mm/min","X-axis maximum rate. Used as G0 rapid rate."
"111","Y-axis maximum rate","mm/min","Y-axis maximum rate. Used as G0 rapid rate."
"112","Z-axis maximum rate","mm/min","Z-axis maximum rate. Used as G0 rapid rate."
"120","X-axis acceleration","mm/sec^2","X-axis acceleration. Used for motion planning to not exceed motor torque and lose steps."
"121","Y-axis acceleration","mm/sec^2","Y-axis acceleration. Used for motion planning to not exceed motor torque and lose steps."
"122","Z-axis acceleration","mm/sec^2","Z-axis acceleration. Used for motion planning to not exceed motor torque and lose steps."
"130","X-axis maximum travel","millimeters","Maximum X-axis travel distance from homing switch. Determines valid machine space for soft-limits and homing search distances."
"131","Y-axis maximum travel","millimeters","Maximum Y-axis travel distance from homing switch. Determines valid machine space for soft-limits and homing search distances."
"132","Z-axis maximum travel","millimeters","Maximum Z-axis travel distance from homing switch. Determines valid machine space for soft-limits and homing search distances."
"140-145","Motor run current","Amps","Motor run current for SPI (Trinamic) type motors"
"150-155","Motor hold current","Percent","Hold current in percent of run current for SPI (Trinamic) type motors"
"160-165","Motor microstepping","micros/step","Number of microsteps per step for SPI (Trinamic) type motors"
"170-175","Motor Stallguard Value","0-255","Value of Stallguard setting for SPI (Trinamic) type motors"
1 $-Code Setting Units Setting Description
2 0 Step pulse time microseconds Sets time length per step. Minimum 3usec.
3 1 Step idle delay milliseconds Sets a short hold delay when stopping to let dynamics settle before disabling steppers. Value 255 keeps motors enabled with no delay.
4 2 Step pulse invert mask Inverts the step signal. Set axis bit to invert (00000ZYX).
5 3 Step direction invert mask Inverts the direction signal. Set axis bit to invert (00000ZYX).
6 4 Invert step enable pin boolean Inverts the stepper driver enable pin signal.
7 5 Invert limit pins boolean Inverts the all of the limit input pins.
8 6 Invert probe pin boolean Inverts the probe input pin signal.
9 10 Status report options mask Alters data included in status reports.
10 11 Junction deviation millimeters Sets how fast Grbl travels through consecutive motions. Lower value slows it down.
11 12 Arc tolerance millimeters Sets the G2 and G3 arc tracing accuracy based on radial error. Beware: A very small value may effect performance.
12 13 Report in inches boolean Enables inch units when returning any position and rate value that is not a settings value.
13 20 Soft limits enable boolean Enables soft limits checks within machine travel and sets alarm when exceeded. Requires homing.
14 21 Hard limits enable boolean Enables hard limits. Immediately halts motion and throws an alarm when switch is triggered.
15 22 Homing cycle enable boolean Enables homing cycle. Requires limit switches on all axes.
16 23 Homing direction invert mask Homing searches for a switch in the positive direction. Set axis bit (00000ZYX) to search in negative direction.
17 24 Homing locate feed rate mm/min Feed rate to slowly engage limit switch to determine its location accurately.
18 25 Homing search seek rate mm/min Seek rate to quickly find the limit switch before the slower locating phase.
19 26 Homing switch debounce delay milliseconds Sets a short delay between phases of homing cycle to let a switch debounce.
20 27 Homing switch pull-off distance millimeters Retract distance after triggering switch to disengage it. Homing will fail if switch isn't cleared.
21 30 Maximum spindle speed RPM Maximum spindle speed. Sets PWM to 100% duty cycle.
22 31 Minimum spindle speed RPM Minimum spindle speed. Sets PWM to 0.4% or lowest duty cycle.
23 32 Laser-mode enable boolean Enables laser mode. Consecutive G1/2/3 commands will not halt when spindle speed is changed.
24 33 Spindle PWM Freq 16-bit Spindle PWM Freq
25 34 Spindle PWM Off Value 16-bit Spindle PWM Off Value
26 35 Spindle PWM Min Value 16-bit Spindle PWM Min Value
27 36 Spindle PWM Max Value 16-bit Spindle PWM Max Value
28 80-84 User integer Values unsigned 16-bit Reserved for custom machine use
29 90-94 User Floating point value float Reserved for custom machine use
30 100 X-axis travel resolution step/mm X-axis travel resolution in steps per millimeter.
31 101 Y-axis travel resolution step/mm Y-axis travel resolution in steps per millimeter.
32 102 Z-axis travel resolution step/mm Z-axis travel resolution in steps per millimeter.
33 110 X-axis maximum rate mm/min X-axis maximum rate. Used as G0 rapid rate.
34 111 Y-axis maximum rate mm/min Y-axis maximum rate. Used as G0 rapid rate.
35 112 Z-axis maximum rate mm/min Z-axis maximum rate. Used as G0 rapid rate.
36 120 X-axis acceleration mm/sec^2 X-axis acceleration. Used for motion planning to not exceed motor torque and lose steps.
37 121 Y-axis acceleration mm/sec^2 Y-axis acceleration. Used for motion planning to not exceed motor torque and lose steps.
38 122 Z-axis acceleration mm/sec^2 Z-axis acceleration. Used for motion planning to not exceed motor torque and lose steps.
39 130 X-axis maximum travel millimeters Maximum X-axis travel distance from homing switch. Determines valid machine space for soft-limits and homing search distances.
40 131 Y-axis maximum travel millimeters Maximum Y-axis travel distance from homing switch. Determines valid machine space for soft-limits and homing search distances.
41 132 Z-axis maximum travel millimeters Maximum Z-axis travel distance from homing switch. Determines valid machine space for soft-limits and homing search distances.
42 140-145 Motor run current Amps Motor run current for SPI (Trinamic) type motors
43 150-155 Motor hold current Percent Hold current in percent of run current for SPI (Trinamic) type motors
44 160-165 Motor microstepping micros/step Number of microsteps per step for SPI (Trinamic) type motors
45 170-175 Motor Stallguard Value 0-255 Value of Stallguard setting for SPI (Trinamic) type motors

View File

@ -0,0 +1,373 @@
"""
---------------------
The MIT License (MIT)
Copyright (c) 2017-2018 Sungeun K. Jeon for Gnea Research LLC
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
---------------------
"""
"""
This Python script produces a continuous piece-wise line fit of actual spindle speed over
programmed speed/PWM, which must be measured and provided by the user. A plot of the data
and line fit will be auto-generated and saved in the working directory as 'line_fit.png'.
REQUIREMENTS:
- Python 2.7 or 3.x with SciPy, NumPy, and Matplotlib Python Libraries
- For the most people, the easiest way to run this script is on the free cloud service
https://repl.it/site/languages/python3. No account necessary. Unlimited runs.
- Last checked on 4/5/2018. This site has been regularly evolving and becoming more
powerful. Things may not work exactly as shown. Please report any issues.
- To use, go to the website and start the Python REPL. Copy and paste this script into
the main.py file in the browser editor. Click 'Run' and a solution should appear in
the text output in the REPL console window. You can edit the script directly in the
browser and re-run the script as many times as you need. A free account is only
necessary if you want to save files on their servers.
- This script will also automatically generate a png image with the plot of the data
with the piece-wise linear fit over it, but this will not show up by default on this
website. To enable this, just click the 'Add File' icon and create a dummy file.
Name it anything, like dummy.py. Leave this file blank. Doing this places the REPL
in multiple file mode and will enable viewing the plot. Click the 'Run' icon. The
solution will be presented again in the console, and the data plot will appear in
the file list called 'line_fit.png'. Click the file to view the plot.
- For offline Python installs, most Mac and Linux computers have Python pre-installed
with the required libraries. If not, a quick google search will show you how to
install them. For Windows, Python installations are bit more difficult. Anaconda and
Pyzo seem to work well.
USAGE:
- First, make sure you are using the stock build of Grbl for the 328p processor. Most
importantly, the SPINDLE_PWM_MAX_VALUE and SPINDLE_PWM_MIN_VALUE should be unaltered
from defaults, otherwise change them back to 255.0 and 1.0 respectively for this test.
- Next, program the max and min rpm Grbl settings to '$30=255' and '$31=1'. This sets
the internal PWM values equal to 'S' spindle speed for the standard Grbl build.
- Check if your spindle does not turn on at very low voltages by setting 'S' spindle
speed to 'S1'. If it does not turn on or turns at a non-useful rpm, increase 'S' by
one until it does. Write down this 'S' value for later. You'll start the rpm data
collection from this point onward and will need to update the SPINDLE_PWM_MIN_VALUE
in cpu_map.h afterwards.
- Collect actual spindle speed with a tachometer or similar means over a range of 'S'
and PWM values. Start by setting the spindle 'S' speed to the minimum useful 'S' from
the last step and measure and record actual spindle rpm. Next, increase 'S' spindle
speed over equally sized intervals and repeat the measurement. Increments of 20 rpm
should be more than enough, but decrease increment size, if highly nonlinear. Complete
the data collection the 'S' spindle speed equal to '$30' max rpm, or at the max useful
rpm, and record the actual rpm output. Make sure to collect rpm data all the way
throughout useful output rpm. The actual operating range within this model may be set
later within Grbl with the '$30' and '$31' settings.
- In some cases, spindle PWM output can have discontinuities or not have a useful rpm
in certain ranges. For example, a known controller board has the spindle rpm drop
completely at voltages above ~4.5V. If you have discontinuities like this at the low
or high range of rpm, simply trim them from the data set. Don't include them. For
Grbl to compensate, you'll need to alter the SPINDLE_PWM_MIN_VALUE and/or
SPINDLE_PWM_MAX_VALUE in cpu_map.h to where your data set ends. This script will
indicate if you need to do that in the solution output.
- Keep in mind that spindles without control electronics can slow down drastically when
cutting and under load. How much it slows down is dependent on a lot of factors, such
as feed rate, chip load, cutter diameter, flutes, cutter type, lubricant/coolant,
material being cut, etc. Even spindles with controllers can still slow down if the
load is higher than the max current the controller can provide. It's recommended to
frequently re-check and measure actual spindle speed during a job. You can always use
spindle speed overrides to tweak it temporarily to the desired speed.
- Edit this script and enter the measured rpm values and their corresponding 'S' spindle
speed values in the data arrays below. Set the number of piecewise lines you would
like to use, from one to four lines. For most cases, four lines is perfectly fine.
In certain scenarios (laser engraving), this may significantly degrade performance and
should be reduced if possible.
- Run the Python script. Visually assess the line fit from the plot. It will not likely
to what you want on the first go. Dial things in by altering the line fit junction
points 'PWM_pointX' in this script to move where the piecewise line junctions are
located along the plot x-axis. It may be desired to tweak the junction points so the
model solution is more accurate in the region that the spindle typically running.
Re-run the script and tweak the junction points until you are satified with the model.
- Record the solution and enter the RPM_POINT and RPM_LINE values into config.h. Set the
number of piecewise lines used in this model in config.h. Also set the '$30' and '$31'
max and min rpm values to the solution values or in a range between them in Grbl '$'
settings. And finally, alter the SPINDLE_PWM_MIN_VALUE in cpu_map.h, if your spindle
needs to be above a certain voltage to produce a useful low rpm.
- Once the solution is entered. Recompile and flash Grbl. This solution model is only
valid for this particular set of data. If the machine is altered, you will need to
perform this experiment again and regenerate a new model here.
OUTPUT:
The solver produces a set of values that define the piecewise fit and can be used by
Grbl to quickly and efficiently compute spindle PWM output voltage for a desired RPM.
The first two are the RPM_MAX ($30) and RPM_MIN ($31) Grbl settings. These must be
programmed into Grbl manually or setup in defaults.h for new systems. Altering these
values within Grbl after a piece-wise linear model is installed will not change alter
model. It will only alter the range of spindle speed rpm values Grbl output.
For example, if the solver produces an RPM_MAX of 9000 and Grbl is programmed with
$30=8000, S9000 may be programmed, but Grbl will only produce the output voltage to run
at 8000 rpm. In other words, Grbl will only output voltages the range between
max(RPM_MIN,$31) and min(RPM_MAX,$30).
The remaining values define the slopes and offsets of the line segments and the junction
points between line segments, like so for n_pieces=3:
PWM_output = RPM_LINE_A1 * rpm - RPM_LINE_B1 [ RPM_MIN < rpm < RPM_POINT12 ]
PWM_output = RPM_LINE_A2 * rpm - RPM_LINE_B2 [ RPM_POINT12 < rpm < RPM_POINT23 ]
PWM_output = RPM_LINE_A3 * rpm - RPM_LINE_B3 [ RPM_POINT23 < rpm < RPM_MAX ]
NOTE: The script solves in terms of PWM but the final equations and values are expressed
in terms of rpm in the form 'PWM = a*rpm - b'.
"""
from scipy import optimize
import numpy as np
# ----------------------------------------------------------------------------------------
# Configure spindle PWM line fit solver
n_pieces = 4 # Number of line segments used for data fit. Only 1 to 4 line segments supported.
# Programmed 'S' spindle speed values. Must start with minimum useful PWM or 'S' programmed
# value and end with the maximum useful PWM or 'S' programmed value. Order of the array must
# be synced with the RPM_measured array below.
# NOTE: ** DO NOT USE DATA FROM AN EXISTING PIECEWISE LINE FIT. USE DEFAULT GRBL MODEL ONLY. **
PWM_set = np.array([2,18,36,55,73,91,109,127,146,164,182,200,218,237,254], dtype=float)
# Actual RPM measured at the spindle. Must be in the ascending value and equal in length
# as the PWM_set array. Must include the min and max measured rpm output in the first and
# last array entries, respectively.
RPM_measured = np.array([213.,5420,7145,8282,9165,9765,10100,10500,10700,10900,11100,11250,11400,11550,11650], dtype=float)
# Configure line fit points by 'S' programmed rpm or PWM value. Values must be between
# PWM_max and PWM_min. Typically, alter these values to space the points evenly between
# max and min PWM range. However, they may be tweaked to maximize accuracy in the places
# you normally operate for highly nonlinear curves. Plot to visually assess how well the
# solution fits the data.
PWM_point1 = 20.0 # (S) Point between segments 0 and 1. Used when n_pieces >= 2.
PWM_point2 = 80.0 # (S) Point between segments 1 and 2. Used when n_pieces >= 3.
PWM_point3 = 150.0 # (S) Point between segments 2 and 3. Used when n_pieces = 4.
# ----------------------------------------------------------------------------------------
# Advanced settings
# The optimizer requires an initial guess of the solution. Change value if solution fails.
slope_i = 100.0; # > 0.0
PWM_max = max(PWM_set) # Maximum PWM set in measured range
PWM_min = min(PWM_set) # Minimum PWM set in measured range
plot_figure = True # Set to False, if matplotlib is not available.
# ----------------------------------------------------------------------------------------
# DO NOT ALTER ANYTHING BELOW.
def piecewise_linear_1(x,b,k1):
return np.piecewise(x, [(x>=PWM_min)&(x<=PWM_max)], [lambda x:k1*(x-PWM_min)+b])
def piecewise_linear_2(x,b,k1,k2):
c = [b,
b+k1*(PWM_point1-PWM_min)]
funcs = [lambda x:k1*(x-PWM_min)+c[0],
lambda x:k2*(x-PWM_point1)+c[1]]
conds = [(x<PWM_point1)&(x>=PWM_min),
(x<=PWM_max)&(x>=PWM_point1)]
return np.piecewise(x, conds, funcs)
def piecewise_linear_3(x,b,k1,k2,k3):
c = [b,
b+k1*(PWM_point1-PWM_min),
b+k1*(PWM_point1-PWM_min)+k2*(PWM_point2-PWM_point1)]
funcs = [lambda x:k1*(x-PWM_min)+c[0],
lambda x:k2*(x-PWM_point1)+c[1],
lambda x:k3*(x-PWM_point2)+c[2]]
conds = [(x<PWM_point1)&(x>=PWM_min),
(x<PWM_point2)&(x>=PWM_point1),
(x<=PWM_max)&(x>=PWM_point2)]
return np.piecewise(x, conds, funcs)
def piecewise_linear_4(x,b,k1,k2,k3,k4):
c = [b,
b+k1*(PWM_point1-PWM_min),
b+k1*(PWM_point1-PWM_min)+k2*(PWM_point2-PWM_point1),
b+k1*(PWM_point1-PWM_min)+k2*(PWM_point2-PWM_point1)+k3*(PWM_point3-PWM_point2)]
funcs = [lambda x:k1*(x-PWM_min)+c[0],
lambda x:k2*(x-PWM_point1)+c[1],
lambda x:k3*(x-PWM_point2)+c[2],
lambda x:k4*(x-PWM_point3)+c[3]]
conds = [(x<PWM_point1)&(x>=PWM_min),
(x<PWM_point2)&(x>=PWM_point1),
(x<PWM_point3)&(x>=PWM_point2),
(x<=PWM_max)&(x>=PWM_point3)]
return np.piecewise(x, conds, funcs)
# ----------------------------------------------------------------------------------------
print("\nCONFIG:")
print(" N_pieces: %i" % n_pieces)
print(" PWM_min: %.1f" % PWM_min)
print(" PWM_max: %.1f" % PWM_max)
if n_pieces > 1:
print(" PWM_point1: %.1f" % PWM_point1)
if n_pieces > 2:
print(" PWM_point2: %.1f" % PWM_point2)
if n_pieces > 3:
print(" PWM_point3: %.1f" % PWM_point3)
print(" N_data: %i" % len(RPM_measured))
print(" PWM_set: ", PWM_set)
print(" RPM_measured: ", RPM_measured)
if n_pieces == 1:
piece_func = piecewise_linear_1
p_initial = [RPM_measured[0],slope_i]
p , e = optimize.curve_fit(piece_func, PWM_set, RPM_measured, p0=p_initial)
a = [p[1]]
b = [ p[0]-p[1]*PWM_min]
rpm = [ p[0],
p[0]+p[1]*(PWM_point1-PWM_min)]
elif n_pieces == 2:
piece_func = piecewise_linear_2
p_initial = [RPM_measured[0],slope_i,slope_i]
p , e = optimize.curve_fit(piece_func, PWM_set, RPM_measured, p0=p_initial)
a = [p[1],p[2]]
b = [ p[0]-p[1]*PWM_min,
p[0]+p[1]*(PWM_point1-PWM_min)-p[2]*PWM_point1]
rpm = [ p[0],
p[0]+p[1]*(PWM_point1-PWM_min),
p[0]+p[1]*(PWM_point1-PWM_min)+p[2]*(PWM_max-PWM_point1)]
elif n_pieces == 3:
piece_func = piecewise_linear_3
p_initial = [RPM_measured[0],slope_i,slope_i,slope_i]
p , e = optimize.curve_fit(piece_func, PWM_set, RPM_measured, p0=p_initial)
a = [p[1],p[2],p[3]]
b = [ p[0]-p[1]*PWM_min,
p[0]+p[1]*(PWM_point1-PWM_min)-p[2]*PWM_point1,
p[0]+p[1]*(PWM_point1-PWM_min)+p[2]*(PWM_point2-PWM_point1)-p[3]*PWM_point2]
rpm = [ p[0],
p[0]+p[1]*(PWM_point1-PWM_min),
p[0]+p[1]*(PWM_point1-PWM_min)+p[2]*(PWM_point2-PWM_point1),
p[0]+p[1]*(PWM_point1-PWM_min)+p[2]*(PWM_point2-PWM_point1)+p[3]*(PWM_max-PWM_point2) ]
elif n_pieces == 4:
piece_func = piecewise_linear_4
p_initial = [RPM_measured[0],slope_i,slope_i,slope_i,slope_i]
p , e = optimize.curve_fit(piece_func, PWM_set, RPM_measured, p0=p_initial)
a = [p[1],p[2],p[3],p[4]]
b = [ p[0]-p[1]*PWM_min,
p[0]+p[1]*(PWM_point1-PWM_min)-p[2]*PWM_point1,
p[0]+p[1]*(PWM_point1-PWM_min)+p[2]*(PWM_point2-PWM_point1)-p[3]*PWM_point2,
p[0]+p[1]*(PWM_point1-PWM_min)+p[2]*(PWM_point2-PWM_point1)+p[3]*(PWM_point3-PWM_point2)-p[4]*PWM_point3 ]
rpm = [ p[0],
p[0]+p[1]*(PWM_point1-PWM_min),
p[0]+p[1]*(PWM_point1-PWM_min)+p[2]*(PWM_point2-PWM_point1),
p[0]+p[1]*(PWM_point1-PWM_min)+p[2]*(PWM_point2-PWM_point1)+p[3]*(PWM_point3-PWM_point2),
p[0]+p[1]*(PWM_point1-PWM_min)+p[2]*(PWM_point2-PWM_point1)+p[3]*(PWM_point3-PWM_point2)+p[4]*(PWM_max-PWM_point3) ]
else :
print("ERROR: Unsupported number of pieces. Check and alter n_pieces")
quit()
print("\nSOLUTION:\n\n[Update these #define values and uncomment]\n[ENABLE_PIECEWISE_LINEAR_SPINDLE in config.h.]")
print("#define N_PIECES %.0f" % n_pieces)
print("#define RPM_MAX %.1f" % rpm[-1])
print("#define RPM_MIN %.1f" % rpm[0])
if n_pieces > 1:
print("#define RPM_POINT12 %.1f" % rpm[1])
if n_pieces > 2:
print("#define RPM_POINT23 %.1f" %rpm[2])
if n_pieces > 3:
print("#define RPM_POINT34 %.1f" %rpm[3])
print("#define RPM_LINE_A1 %.6e" % (1./a[0]))
print("#define RPM_LINE_B1 %.6e" % (b[0]/a[0]))
if n_pieces > 1:
print("#define RPM_LINE_A2 %.6e" % (1./a[1]))
print("#define RPM_LINE_B2 %.6e" % (b[1]/a[1]))
if n_pieces > 2:
print("#define RPM_LINE_A3 %.6e" % (1./a[2]))
print("#define RPM_LINE_B3 %.6e" % (b[2]/a[2]))
if n_pieces > 3:
print("#define RPM_LINE_A4 %.6e" % (1./a[3]))
print("#define RPM_LINE_B4 %.6e" % (b[3]/a[3]))
print("\n[To operate over full model range, manually write these]")
print("['$' settings or alter values in defaults.h. Grbl will]")
print("[operate between min($30,RPM_MAX) and max($31,RPM_MIN)]")
print("$30=%.1f (rpm max)" % rpm[-1])
print("$31=%.1f (rpm min)" % rpm[0])
if (PWM_min > 1)|(PWM_max<255):
print("\n[Update the following #define values in cpu_map.h]")
if (PWM_min >1) :
print("#define SPINDLE_PWM_MIN_VALUE %.0f" % PWM_min)
if PWM_max <255:
print("#define SPINDLE_PWM_MAX_VALUE %.0f" % PWM_max)
else:
print("\n[No cpu_map.h changes required.]")
print("\n")
test_val = (1./a[0])*rpm[0] - (b[0]/a[0])
if test_val < 0.0 :
print("ERROR: Solution is negative at RPM_MIN. Adjust junction points or increase n_pieces.\n")
if plot_figure:
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
fig = plt.figure()
ax = fig.add_subplot(111)
xd = np.linspace(PWM_min, PWM_max, 10000)
ax.plot(PWM_set, RPM_measured, "o")
ax.plot(xd, piece_func(xd, *p),'g')
plt.xlabel("Programmed PWM")
plt.ylabel("Measured RPM")
# Check solution by plotting in terms of rpm.
# x = np.linspace(rpm[0], rpm[1], 10000)
# ax.plot((1./a[0])*x-(b[0]/a[0]),x,'r:')
# if n_pieces > 1:
# x = np.linspace(rpm[1], rpm[2], 10000)
# ax.plot((1./a[1])*x-(b[1]/a[1]),x,'r:')
# if n_pieces > 2:
# x = np.linspace(rpm[2], rpm[3], 10000)
# ax.plot((1./a[2])*x-(b[2]/a[2]),x,'r:')
# if n_pieces > 3:
# x = np.linspace(rpm[3], rpm[-1], 10000)
# ax.plot((1./a[3])*x-(b[3]/a[3]),x,'r:')
fig.savefig("line_fit.png")

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

View File

@ -0,0 +1,66 @@
#!/usr/bin/env python
"""\
Simple g-code streaming script for grbl
Provided as an illustration of the basic communication interface
for grbl. When grbl has finished parsing the g-code block, it will
return an 'ok' or 'error' response. When the planner buffer is full,
grbl will not send a response until the planner buffer clears space.
G02/03 arcs are special exceptions, where they inject short line
segments directly into the planner. So there may not be a response
from grbl for the duration of the arc.
---------------------
The MIT License (MIT)
Copyright (c) 2012 Sungeun K. Jeon
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
---------------------
"""
import serial
import time
# Open grbl serial port
s = serial.Serial('/dev/tty.usbmodem1811',115200)
# Open g-code file
f = open('grbl.gcode','r');
# Wake up grbl
s.write("\r\n\r\n")
time.sleep(2) # Wait for grbl to initialize
s.flushInput() # Flush startup text in serial input
# Stream g-code to grbl
for line in f:
l = line.strip() # Strip all EOL characters for consistency
print 'Sending: ' + l,
s.write(l + '\n') # Send g-code block to grbl
grbl_out = s.readline() # Wait for grbl response with carriage return
print ' : ' + grbl_out.strip()
# Wait here until grbl is finished to close serial port and file.
raw_input(" Press <Enter> to exit and disable grbl.")
# Close file and serial port
f.close()
s.close()

View File

@ -0,0 +1,202 @@
#!/usr/bin/env python
"""\
Stream g-code to grbl controller
This script differs from the simple_stream.py script by
tracking the number of characters in grbl's serial read
buffer. This allows grbl to fetch the next line directly
from the serial buffer and does not have to wait for a
response from the computer. This effectively adds another
buffer layer to prevent buffer starvation.
CHANGELOG:
- 20170531: Status report feedback at 1.0 second intervals.
Configurable baudrate and report intervals. Bug fixes.
- 20161212: Added push message feedback for simple streaming
- 20140714: Updated baud rate to 115200. Added a settings
write mode via simple streaming method. MIT-licensed.
TODO:
- Add realtime control commands during streaming.
---------------------
The MIT License (MIT)
Copyright (c) 2012-2017 Sungeun K. Jeon
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
---------------------
"""
import serial
import re
import time
import sys
import argparse
import threading
RX_BUFFER_SIZE = 128
BAUD_RATE = 115200
ENABLE_STATUS_REPORTS = True
REPORT_INTERVAL = 1.0 # seconds
is_run = True # Controls query timer
# Define command line argument interface
parser = argparse.ArgumentParser(description='Stream g-code file to grbl. (pySerial and argparse libraries required)')
parser.add_argument('gcode_file', type=argparse.FileType('r'),
help='g-code filename to be streamed')
parser.add_argument('device_file',
help='serial device path')
parser.add_argument('-q','--quiet',action='store_true', default=False,
help='suppress output text')
parser.add_argument('-s','--settings',action='store_true', default=False,
help='settings write mode')
parser.add_argument('-c','--check',action='store_true', default=False,
help='stream in check mode')
args = parser.parse_args()
# Periodic timer to query for status reports
# TODO: Need to track down why this doesn't restart consistently before a release.
def send_status_query():
s.write('?')
def periodic_timer() :
while is_run:
send_status_query()
time.sleep(REPORT_INTERVAL)
# Initialize
s = serial.Serial(args.device_file,BAUD_RATE)
f = args.gcode_file
verbose = True
if args.quiet : verbose = False
settings_mode = False
if args.settings : settings_mode = True
check_mode = False
if args.check : check_mode = True
# Wake up grbl
print "Initializing Grbl..."
s.write("\r\n\r\n")
# Wait for grbl to initialize and flush startup text in serial input
time.sleep(2)
s.flushInput()
if check_mode :
print "Enabling Grbl Check-Mode: SND: [$C]",
s.write("$C\n")
while 1:
grbl_out = s.readline().strip() # Wait for grbl response with carriage return
if grbl_out.find('error') >= 0 :
print "REC:",grbl_out
print " Failed to set Grbl check-mode. Aborting..."
quit()
elif grbl_out.find('ok') >= 0 :
if verbose: print 'REC:',grbl_out
break
start_time = time.time();
# Start status report periodic timer
if ENABLE_STATUS_REPORTS :
timerThread = threading.Thread(target=periodic_timer)
timerThread.daemon = True
timerThread.start()
# Stream g-code to grbl
l_count = 0
error_count = 0
if settings_mode:
# Send settings file via simple call-response streaming method. Settings must be streamed
# in this manner since the EEPROM accessing cycles shut-off the serial interrupt.
print "SETTINGS MODE: Streaming", args.gcode_file.name, " to ", args.device_file
for line in f:
l_count += 1 # Iterate line counter
# l_block = re.sub('\s|\(.*?\)','',line).upper() # Strip comments/spaces/new line and capitalize
l_block = line.strip() # Strip all EOL characters for consistency
if verbose: print "SND>"+str(l_count)+": \"" + l_block + "\""
s.write(l_block + '\n') # Send g-code block to grbl
while 1:
grbl_out = s.readline().strip() # Wait for grbl response with carriage return
if grbl_out.find('ok') >= 0 :
if verbose: print " REC<"+str(l_count)+": \""+grbl_out+"\""
break
elif grbl_out.find('error') >= 0 :
if verbose: print " REC<"+str(l_count)+": \""+grbl_out+"\""
error_count += 1
break
else:
print " MSG: \""+grbl_out+"\""
else:
# Send g-code program via a more agressive streaming protocol that forces characters into
# Grbl's serial read buffer to ensure Grbl has immediate access to the next g-code command
# rather than wait for the call-response serial protocol to finish. This is done by careful
# counting of the number of characters sent by the streamer to Grbl and tracking Grbl's
# responses, such that we never overflow Grbl's serial read buffer.
g_count = 0
c_line = []
for line in f:
l_count += 1 # Iterate line counter
l_block = re.sub('\s|\(.*?\)','',line).upper() # Strip comments/spaces/new line and capitalize
# l_block = line.strip()
c_line.append(len(l_block)+1) # Track number of characters in grbl serial read buffer
grbl_out = ''
while sum(c_line) >= RX_BUFFER_SIZE-1 | s.inWaiting() :
out_temp = s.readline().strip() # Wait for grbl response
if out_temp.find('ok') < 0 and out_temp.find('error') < 0 :
print " MSG: \""+out_temp+"\"" # Debug response
else :
if out_temp.find('error') >= 0 : error_count += 1
g_count += 1 # Iterate g-code counter
if verbose: print " REC<"+str(g_count)+": \""+out_temp+"\""
del c_line[0] # Delete the block character count corresponding to the last 'ok'
s.write(l_block + '\n') # Send g-code block to grbl
if verbose: print "SND>"+str(l_count)+": \"" + l_block + "\""
# Wait until all responses have been received.
while l_count > g_count :
out_temp = s.readline().strip() # Wait for grbl response
if out_temp.find('ok') < 0 and out_temp.find('error') < 0 :
print " MSG: \""+out_temp+"\"" # Debug response
else :
if out_temp.find('error') >= 0 : error_count += 1
g_count += 1 # Iterate g-code counter
del c_line[0] # Delete the block character count corresponding to the last 'ok'
if verbose: print " REC<"+str(g_count)+": \""+out_temp + "\""
# Wait for user input after streaming is completed
print "\nG-code streaming finished!"
end_time = time.time();
is_run = False;
print " Time elapsed: ",end_time-start_time,"\n"
if check_mode :
if error_count > 0 :
print "CHECK FAILED:",error_count,"errors found! See output for details.\n"
else :
print "CHECK PASSED: No errors found in g-code program.\n"
else :
print "WARNING: Wait until Grbl completes buffered g-code blocks before exiting."
raw_input(" Press <Enter> to exit and disable Grbl.")
# Close file and serial port
f.close()
s.close()