t-oster / LibLaserCut

a platform independant library to control Lasercutters. This is the base library for VisiCut
http://visicut.org
Other
60 stars 55 forks source link

GRBL response failure #68

Closed iceblu3710 closed 7 years ago

iceblu3710 commented 7 years ago

I notice in the grbl driver you remove the response string from the config screen but the generic driver still checks the response.

generic driver:

protected String identificationLine = "Grbl";

grbl driver:

result.remove(GenericGcodeDriver.SETTING_IDENTIFICATION_STRING);

The 0.9 release of GRBL now responds Grbl 0.9j ['$' for help] so the system fails immediately when trying to send the job. Would be nice to just leave this as a configurable option when setting up the driver.

madleech commented 7 years ago

The generic driver checks for if (line.startsWith(getIdentificationLine())) so as long as grbl is responding with a string starting with "Grbl" it should work fine?

iceblu3710 commented 7 years ago

Looking around when I am more awake I believe if (line.startsWith(getIdentificationLine())) is actually working but that the if (isWaitForOKafterEachLine()) as the error is Exception: Lasercutter did not respond 'ok', but 'Grbl 0.9j...

Similarly to my original assumption though is result.remove(GenericGcodeDriver.SETTING_WAIT_FOR_OK); so I can not set the grbl driver to not wait for ok's

iceblu3710 commented 7 years ago

Had a sudden idea and it worked!

Export setting then unzip the settings.vcsettings folder. In there find the XML for your machine and change as required.

<waitForOKafterEachLine>false</waitForOKafterEachLine>

Now I can upload fine even though the setting is not directly accessible via the GUI. I recommend we add the setting to the GUI though as this is a bit of a kludge.

madleech commented 7 years ago

Hmm, the 'ok' response is essential part of the flow control in Grbl. Otherwise Visicut will send all the gcode at once, leading to a full serial buffer in Grbl and commands getting lost. Grbl can only hold about 10 gcode commands at a time, so after executing each one it sends back 'ok' letting the host know it is ready for the next command.

You could try a couple of things:

Also what is your hardware setup? Custom board or regular Arduino?

iceblu3710 commented 7 years ago

Running on ArduinoUno with grbl stepper shield. Test gcode

G21   ;Units: mm
G90   ;ABS Pos
M3    ;Enable Laser
G0 X132.994400 Y132.994400 F2000 S0
G1 X137.972800 Y132.994400 S1000.000000 F800
G1 X137.972800 Y137.972800
G1 X132.994400 Y137.972800
G1 X132.994400 Y132.994400
M5          ;Disable Laser
G0 X0 Y0    ;Home

Universal Gcode Sender

**** Connected to /dev/ttyACM0 @ 115200 baud ****

Grbl 0.9j ['$' for help]
>>> G21
>>> G90
>>> M3
>>> G0X132.9944Y132.9944F2000S0
>>> G1X137.9728Y132.9944S1000F800
>>> G1X137.9728Y137.9728
>>> G1X132.9944Y137.9728
ok
ok
ok
>>> G1X132.9944Y132.9944
ok
>>> M5
>>> G0X0Y0
ok
ok
ok
ok
ok

**** Finished sending file. ****

ok

Command line output - Wait for ok = false

Serial timeout not supported. Driver may hang if device does not respond properly.
< Grbl 0.9j ['$' for help]
< ok1   ;Units: mm
< ok0   ;ABS Pos
< ok    ;Enable Laser
< ok          ;Disable Laser
< ok X0 Y0    ;Home

Command line output - Wait for ok = true

Serial timeout not supported. Driver may hang if device does not respond properly.
< Grbl 0.9j ['$' for help]
< Grbl 0.9j ['$' for help]
java.io.IOException: Lasercutter did not respond 'ok', but 'Grbl 0.9j ['$' for help]'instead.
    at com.t_oster.liblasercut.drivers.GenericGcodeDriver.sendLine(GenericGcodeDriver.java:535)
    at com.t_oster.liblasercut.drivers.GenericGcodeDriver.writeInitializationCode(GenericGcodeDriver.java:502)
    at com.t_oster.liblasercut.drivers.GenericGcodeDriver.sendJob(GenericGcodeDriver.java:807)
    at com.t_oster.visicut.VisicutModel.sendJob(VisicutModel.java:756)
    at com.t_oster.visicut.gui.MainView$64.run(MainView.java:2188)
madleech commented 7 years ago

Thanks that is helpful, I'll do some tests later. I expect that the board is resetting, and then the Grbl driver is sending a soft reset as well, resulting in two resets. Should be possible to work around that.

madleech commented 7 years ago

Ok I was on the right track. When Visicut connects it toggles the DTR pin causing a hard reset of the Arduino. While this is happening the serial input stream is opened. After waiting 5 seconds for the reset to complete, a 0x18 soft reset is sent.

The problem is that the serial input stream has now witnessed 2 resets, and so consists of a pair of Grbl 0.9j ['$' for help] lines. waitForIdentificationLine() then reads off the first one and is happy, but the next command to run gets the second Grbl init line rather than the ok that it was expecting... and hence the issue.

Solution is simple enough... flush the serial buffer after hard resetting, before sending the soft reset. Never showed up in my testing because I have a custom board for my laser cutter without DTR connected.

PR #69 fixes this. Feel free to pull the branch and check if fixes your issue.