Skip to content

Commit

Permalink
Implement character-counting protocol for Grbl. Closes t-oster#74
Browse files Browse the repository at this point in the history
  • Loading branch information
jekhor committed Jan 7, 2017
1 parent 904b520 commit 05777da
Show file tree
Hide file tree
Showing 4 changed files with 134 additions and 17 deletions.
Binary file not shown.
Binary file not shown.
19 changes: 16 additions & 3 deletions src/com/t_oster/liblasercut/drivers/GenericGcodeDriver.java
Original file line number Diff line number Diff line change
Expand Up @@ -495,7 +495,7 @@ protected void line(PrintStream out, double x, double y, double resolution) thro
sendLine("G1 X%f Y%f"+append, x, y);
}

private void writeInitializationCode() throws IOException {
protected void writeInitializationCode() throws IOException {
if (preJobGcode != null)
{
for (String line : preJobGcode.split(","))
Expand All @@ -506,7 +506,7 @@ private void writeInitializationCode() throws IOException {
}


private void writeShutdownCode() throws IOException {
protected void writeShutdownCode() throws IOException {
if (postJobGcode != null)
{
for (String line : postJobGcode.split(","))
Expand Down Expand Up @@ -671,7 +671,7 @@ protected String connect_serial(CommPortIdentifier i, ProgressListener pl) throw
* Used to buffer the file before uploading via http
*/
private ByteArrayOutputStream outputBuffer;
private String jobName;
protected String jobName;
protected void connect(ProgressListener pl) throws IOException, PortInUseException, NoSuchPortException, UnsupportedCommOperationException
{
outputBuffer = null;
Expand Down Expand Up @@ -791,6 +791,17 @@ else if (this.port != null)

}


/* sendJobPrepare() and sendJobFinish() can be overrided in children to
* perform device-specific setup before and after sending job over serial
* line
*/
protected void sendJobPrepare() throws IOException {
}

protected void sendJobFinish() throws IOException {
}

@Override
public void sendJob(LaserJob job, ProgressListener pl, List<String> warnings) throws IllegalJobException, Exception {
pl.progressChanged(this, 0);
Expand All @@ -805,6 +816,7 @@ public void sendJob(LaserJob job, ProgressListener pl, List<String> warnings) th
connect(pl);
pl.taskChanged(this, "sending");
try {
sendJobPrepare();
writeInitializationCode();
pl.progressChanged(this, 20);
int i = 0;
Expand All @@ -825,6 +837,7 @@ public void sendJob(LaserJob job, ProgressListener pl, List<String> warnings) th
pl.progressChanged(this, 20 + (int) (i*(double) 60/max));
}
writeShutdownCode();
sendJobFinish();
disconnect(job.getName()+".gcode");
}
catch (IOException e) {
Expand Down
132 changes: 118 additions & 14 deletions src/com/t_oster/liblasercut/drivers/Grbl.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.ArrayDeque;

/**
* This class implements a driver for Grbl based firmwares.
Expand All @@ -33,8 +34,11 @@
*/
public class Grbl extends GenericGcodeDriver
{
protected ArrayDeque<Integer> commandLenQueue;

public Grbl()
{
commandLenQueue = new ArrayDeque<Integer>();
//set some grbl-specific defaults
setLineend("CR");
setIdentificationLine("Grbl");
Expand Down Expand Up @@ -105,20 +109,109 @@ public void setAutoHome(boolean auto_home)
this.autoHome = auto_home;
}

protected boolean simpleStreamMode = true;

public boolean isSimpleStreamMode()
{
return simpleStreamMode;
}

public void setSimpleStreamMode(boolean mode) throws IOException
{
if (mode != simpleStreamMode) {
if (!simpleStreamMode)
waitForCommandsCompletion();
else
commandLenQueue.clear();

simpleStreamMode = mode;
}
}

@Override
public String getModelName()
{
return "Grbl Gcode Driver";
}

protected void sendLineWithoutWait(String text, Object... parameters) throws IOException
{
boolean wasSetWaitingForOk = isWaitForOKafterEachLine();
setWaitForOKafterEachLine(false);
sendLine(text, parameters);
setWaitForOKafterEachLine(wasSetWaitingForOk);
}

@Override
protected String waitForLine() throws IOException
{
String line = "";
while ("".equals(line))
{//skip empty lines
line = in.readLine();
}

//TODO: remove
if (isSimpleStreamMode() || !"ok".equals(line))
System.out.println("< "+line);
else {
int len = commandLenQueue.peek();
// Debug: print counted chars still remains in the buffer AFTER receiving this 'ok' response
System.out.println(String.format(FORMAT_LOCALE, "%d< %s", getBufferedCommandsLen() - len, line));
}

return line;
}

protected static final int GRBL_BUF_LEN = 128;

protected Integer getBufferedCommandsLen()
{
Integer len = 0;
for (Integer c : commandLenQueue)
len += c;
return len;
}

protected void sendLineSimple(String text, Object... parameters) throws IOException
{
super.sendLine(text, parameters);
}

protected void sendLineCC(String text, Object... parameters) throws IOException
{
String outStr = String.format(FORMAT_LOCALE, text+LINEEND(), parameters);
int len = outStr.length();

// Read all received responses from grbl or wait for needed free space in the serial buffer
while (in.ready() || (getBufferedCommandsLen() + len > GRBL_BUF_LEN)) {
String line = waitForLine();
if (!"ok".equals(line))
{
throw new IOException("Lasercutter did not respond 'ok', but '"+line+"'instead.");
}
commandLenQueue.remove();
}

commandLenQueue.add(len);
out.print(outStr);
//TODO: Remove
System.out.println(String.format(FORMAT_LOCALE, "%d> %s", getBufferedCommandsLen(), outStr));
out.flush();
}

protected void waitForCommandsCompletion() throws IOException
{
while (!commandLenQueue.isEmpty()) {
String line = waitForLine();
if (!"ok".equals(line))
{
throw new IOException("Lasercutter did not respond 'ok', but '"+line+"'instead.");
}
commandLenQueue.remove();
}
}


/**
* Initializes Grbl, handling issuing of soft-reset and initial homing
Expand Down Expand Up @@ -186,28 +279,39 @@ protected void move(PrintStream out, double x, double y, double resolution) thro
sendLine("G0 X%f Y%f", x, y);
}
}

/**
* Send a line of gcode to the cutter, stripping out any whitespace in the process
* @param text
* @param parameters
* @throws IOException
*/
@Override

protected void sendLine(String text, Object... parameters) throws IOException
{
out.format(FORMAT_LOCALE, text.replace(" ", "")+LINEEND(), parameters);
//TODO: Remove
System.out.println(String.format(FORMAT_LOCALE, "> "+text+LINEEND(), parameters));
out.flush();
if (isWaitForOKafterEachLine())
{
String line = waitForLine();
if (!"ok".equals(line))
{
throw new IOException("Lasercutter did not respond 'ok', but '"+line+"'instead.");
}
}
if (isSimpleStreamMode())
sendLineSimple(text, parameters);
else
sendLineCC(text, parameters);
}

@Override
protected void sendJobPrepare() throws IOException {
setSimpleStreamMode(false);
}

@Override
protected void sendJobFinish() throws IOException {
setSimpleStreamMode(true);
}

@Override
protected void setKeysMissingFromDeserialization()
{
super.setKeysMissingFromDeserialization();
commandLenQueue = new ArrayDeque<Integer>();
simpleStreamMode = true;
}

@Override
Expand Down

0 comments on commit 05777da

Please sign in to comment.