/** Unified enable+delay+disable to allow us to use G1 E */ public synchronized void enableMotor(long millis) throws RetryException { if (fiveD == false) { super.enableMotor(millis); } else { super.enableMotor(); double feedrate = machine.currentTool().getMotorSpeedRPM(); double distance = millis * feedrate / 60 / 1000; if (machine.currentTool().getMotorDirection() != 1) { distance *= -1; } sendCommand(_getToolCode() + "G1 E" + (ePosition.get() + distance) + " F" + feedrate); super.disableMotor(); } }
public synchronized void loadXML(Node xml) { super.loadXML(xml); // load from our XML config, if we have it. if (XML.hasChildNode(xml, "waitforstart")) { Node startNode = XML.getChildNodeByName(xml, "waitforstart"); String enabled = XML.getAttributeValue(startNode, "enabled"); if (enabled != null) waitForStart = Boolean.parseBoolean(enabled); String timeout = XML.getAttributeValue(startNode, "timeout"); if (timeout != null) waitForStartTimeout = Long.parseLong(timeout); String retries = XML.getAttributeValue(startNode, "retries"); if (retries != null) waitForStartRetries = Integer.parseInt(retries); } if (XML.hasChildNode(xml, "pulserts")) { pulseRTS = Boolean.parseBoolean(XML.getChildNodeValue(xml, "pulserts")); } if (XML.hasChildNode(xml, "checksums")) { hasChecksums = Boolean.parseBoolean(XML.getChildNodeValue(xml, "checksums")); } if (XML.hasChildNode(xml, "fived")) { fiveD = Boolean.parseBoolean(XML.getChildNodeValue(xml, "fived")); } if (XML.hasChildNode(xml, "debugLevel")) { debugLevel = Integer.parseInt(XML.getChildNodeValue(xml, "debugLevel")); } if (XML.hasChildNode(xml, "limitFeedrate")) { rcFeedrateLimit = Double.parseDouble(XML.getChildNodeValue(xml, "limitFeedrate")); } if (XML.hasChildNode(xml, "okAfterResend")) { okAfterResend = Boolean.parseBoolean(XML.getChildNodeValue(xml, "okAfterResend")); } if (XML.hasChildNode(xml, "okAfterStart")) { okAfterStart = Boolean.parseBoolean(XML.getChildNodeValue(xml, "okAfterStart")); } if (XML.hasChildNode(xml, "alwaysRelativeE")) { alwaysRelativeE = Boolean.parseBoolean(XML.getChildNodeValue(xml, "alwaysRelativeE")); } if (XML.hasChildNode(xml, "hasEmergencyStop")) { hasEmergencyStop = Boolean.parseBoolean(XML.getChildNodeValue(xml, "hasEmergencyStop")); } if (XML.hasChildNode(xml, "hasSoftStop")) { hasSoftStop = Boolean.parseBoolean(XML.getChildNodeValue(xml, "hasSoftStop")); } if (XML.hasChildNode(xml, "introduceNoise")) { double introduceNoise = Double.parseDouble(XML.getChildNodeValue(xml, "introduceNoise")); if (introduceNoise != 0) { Base.logger.warning( "Purposefully injecting noise into communications. This is NOT for production."); Base.logger.warning( "Turn this off by removing introduceNoise from the machines XML file of your machine."); introduceNoiseEveryN = (int) (1 / introduceNoise); } } }
public void setMotorSpeedPWM(int pwm) throws RetryException { if (fiveD == false) { sendCommand(_getToolCode() + "M108 S" + df.format(pwm)); } super.setMotorSpeedPWM(pwm); }
public void disableMotor() throws RetryException { if (fiveD == false) { sendCommand(_getToolCode() + "M103"); } else { extrusionUpdater.stopExtruding(); } super.disableMotor(); }
/** * ************************************************************************* Motor interface * functions * * @throws RetryException ************************************************************************ */ public void setMotorRPM(double rpm, int toolhead) throws RetryException { if (fiveD == false) { sendCommand(_getToolCode() + "M108 R" + df.format(rpm)); } else { extrusionUpdater.setFeedrate(rpm); } super.setMotorRPM(rpm, toolhead); }
public void changeGearRatio(int ratioIndex) { // gear ratio codes are M40-M46 int code = 40 + ratioIndex; code = Math.max(40, code); code = Math.min(46, code); sendCommand("M" + code); super.changeGearRatio(ratioIndex); }
public void enableSpindle() throws RetryException { String command = _getToolCode(); if (machine.currentTool().getSpindleDirection() == ToolModel.MOTOR_CLOCKWISE) command += "M3"; else command += "M4"; sendCommand(command); super.enableSpindle(); }
@Override public void homeAxes(EnumSet<AxisId> axes, boolean positive, double feedrate) throws RetryException { Base.logger.info("homing " + axes.toString()); StringBuffer buf = new StringBuffer("G28"); for (AxisId axis : axes) { buf.append(" " + axis + "0"); } sendCommand(buf.toString()); invalidatePosition(); super.homeAxes(axes, false, 0); }
public synchronized void enableMotor() throws RetryException { String command = _getToolCode(); if (fiveD == false) { if (machine.currentTool().getMotorDirection() == ToolModel.MOTOR_CLOCKWISE) command += "M101"; else command += "M102"; sendCommand(command); } else { extrusionUpdater.setDirection( machine.currentTool().getMotorDirection() == 1 ? Direction.forward : Direction.reverse); extrusionUpdater.startExtruding(); } super.enableMotor(); }
/** * ************************************************************************* commands for * interfacing with the driver directly * * @throws RetryException ************************************************************************ */ public void queuePoint(Point5d p) throws RetryException { String cmd = "G1 F" + df.format(getCurrentFeedrate()); sendCommand(cmd); cmd = "G1 X" + df.format(p.x()) + " Y" + df.format(p.y()) + " Z" + df.format(p.z()) + " F" + df.format(getCurrentFeedrate()); sendCommand(cmd); super.queuePoint(p); }
public void setCurrentPosition(Point5d p) throws RetryException { sendCommand("G92 X" + df.format(p.x()) + " Y" + df.format(p.y()) + " Z" + df.format(p.z())); super.setCurrentPosition(p); }
public synchronized void dispose() { bufferLock.lock(); flushBuffer(); super.dispose(); bufferLock.unlock(); }
public void disableSpindle() throws RetryException { sendCommand(_getToolCode() + "M5"); super.disableSpindle(); }
public void serialByteReceivedEvent(ByteFifo fifo) { readResponseLock.lock(); serialInUse.lock(); byte[] response = fifo.dequeueLine(); int responseLength = response.length; serialInUse.unlock(); // 0 is now an acceptable value; it merely means that we timed out // waiting for input if (responseLength < 0) { // This signifies EOF. FIXME: How do we handle this? Base.logger.severe("SerialPassthroughDriver.readResponse(): EOF occured"); readResponseLock.unlock(); return; } else if (responseLength != 0) { String line; try { // convert to string and remove any trailing \r or \n's line = new String(response, 0, responseLength, "US-ASCII").trim().toLowerCase(); } catch (UnsupportedEncodingException e) { Base.logger.severe("US-ASCII required. Terminating."); readResponseLock.unlock(); throw new RuntimeException(e); } // System.out.println("received: " + line); if (debugLevel > 1) Base.logger.info("<< " + line); if (line.length() == 0) Base.logger.fine("empty line received"); else if (line.startsWith("echo:")) { // if echo is turned on relay it to the user for debugging Base.logger.info(line); } else if (line.startsWith("ok t:") || line.startsWith("t:")) { Pattern r = Pattern.compile("t:([0-9\\.]+)"); Matcher m = r.matcher(line); if (m.find()) { String temp = m.group(1); machine.currentTool().setCurrentTemperature(Double.parseDouble(temp)); } r = Pattern.compile("^ok.*b:([0-9\\.]+)$"); m = r.matcher(line); if (m.find()) { String bedTemp = m.group(1); machine.currentTool().setPlatformCurrentTemperature(Double.parseDouble(bedTemp)); } } else if (line.startsWith("ok c:") || line.startsWith("c:")) { Pattern r = Pattern.compile("c: *x:?([-0-9\\.]+) *y:?([-0-9\\.]+) *z:?([-0-9\\.]+)"); Matcher m = r.matcher(line); if (m.find()) { double x = Double.parseDouble(m.group(1)); double y = Double.parseDouble(m.group(2)); double z = Double.parseDouble(m.group(3)); // super to avoid parroting back a G92 try { super.setCurrentPosition(new Point5d(x, y, z)); // Base.logger.fine("setting currentposition to:"+x+","+y+","+z+"."); } catch (RetryException e) { // do or do not, there is no retry } } } if (line.startsWith("ok")) { synchronized (okReceived) { okReceived.set(true); okReceived.notifyAll(); } bufferLock.lock(); // Notify the thread waitining in this gcode's sendCommand method that the gcode has been // received. if (buffer.isEmpty()) { Base.logger.severe("Received OK with nothing queued!"); } else { String notifier = buffer.removeLast(); if (debugLevel > 1) Base.logger.info("FW Accepted: " + notifier); synchronized (notifier) { notifier.notifyAll(); } } bufferLock.unlock(); synchronized (bufferLock) { /*let any sendCommand method waiting to send know that the buffer is now smaller and may be able to fit their command.*/ bufferLock.notifyAll(); } } // old arduino firmware sends "start" else if (line.contains("start")) { // Reset line number first in case gcode is sent below lineNumber.set(-1); boolean active = !buffer.isEmpty(); flushBuffer(); if (isInitialized()) { sendInitializationGcode(false); // If there were outstanding commands try to abort any print in progress. // This is a poor test: but do we know if we're printing at this level? // tried setInitialized(false); but that didn't work well if (active) { Base.logger.severe("Firmware reset with active commands!"); setError("Firmware reset with active commands!"); } } if (okAfterStart) { // firmware sends "ok" after start, put something here to consume it: bufferLock.lock(); buffer.addLast(";start-ok"); bufferLock.unlock(); } // todo: set version synchronized (startReceived) { startReceived.set(true); startReceived.notifyAll(); } // Wake up connect task to try again synchronized (okReceived) { okReceived.set(false); okReceived.notifyAll(); } } else if (line.startsWith("extruder fail")) { setError("Extruder failed: cannot extrude as this rate."); } else if (line.startsWith("resend:") || line.startsWith("rs ")) { // Bad checksum, resend requested Matcher badLineMatch = resendLinePattern.matcher(line); // Is it a Dud M or G code? String dudLetter = getRegexMatch("dud ([a-z]) code", line, 1); if (badLineMatch.find()) { int badLineNumber = Integer.parseInt(badLineMatch.group(1)); if (debugLevel > 1) Base.logger.warning("Received resend request for line " + badLineNumber); Queue<String> resend = new LinkedList<String>(); boolean found = false; // Search backwards for the bad line in our buffer. // Firmware flushed everything after this line, so // build a queue of lines to resend. bufferLock.lock(); lineSearch: while (!buffer.isEmpty()) { String bufferedLine = buffer.removeLast(); if (debugLevel > 1) Base.logger.info("Searching: " + bufferedLine); int bufferedLineNumber = Integer.parseInt( getRegexMatch(gcodeLineNumberPattern, bufferedLine.toLowerCase(), 1)); if (dudLetter != null && bufferedLineNumber == badLineNumber) { Base.logger.info("Dud " + dudLetter + " code: Dropping " + bufferedLine); synchronized (bufferedLine) { bufferedLine.notifyAll(); } found = true; break lineSearch; } resend.add(bufferedLine); if (bufferedLineNumber == badLineNumber) { found = true; break lineSearch; } } if (okAfterResend) { // firmware sends "ok" after resend, put something here to consume it: buffer.addLast(";resend-ok"); } bufferLock.unlock(); if (!found) { int restartLineNumber = Integer.parseInt( getRegexMatch(gcodeLineNumberPattern, resend.element().toLowerCase(), 1)); Base.logger.severe( "resend for line " + badLineNumber + " not in our buffer. Resuming from " + restartLineNumber); this.resendCommand(applyChecksum("N" + (restartLineNumber - 1) + " M110")); } // resend the lines while (!resend.isEmpty()) { String bufferedLine = resend.remove(); this.resendCommand(bufferedLine); } } else { // Malformed resend line request received. Resetting the line number Base.logger.warning( "malformed line resend request, " + "resetting line number. Malformed Data: \n" + line); this.resendCommand(applyChecksum("N" + (lineNumber.get() - 1) + " M110")); } } else if (line.startsWith("t:") || line.startsWith("c:")) { // temperature, position handled above } else { Base.logger.severe("Unknown: " + line); } } readResponseLock.unlock(); }
public void enableDrives() throws RetryException { sendCommand("M17"); super.enableDrives(); }
public void readTemperature() { sendCommand(_getToolCode() + "M105"); super.readTemperature(); }
/** * ************************************************************************* Valve interface * functions * * @throws RetryException ************************************************************************ */ public void openValve() throws RetryException { sendCommand(_getToolCode() + "M126"); super.openValve(); }
public void openClamp(int clampIndex) { sendCommand("M11 Q" + clampIndex); super.openClamp(clampIndex); }
public void disableFan() throws RetryException { sendCommand(_getToolCode() + "M107"); super.disableFan(); }
public void disableMistCoolant() { sendCommand(_getToolCode() + "M9"); super.disableMistCoolant(); }
/** * ************************************************************************* Mist Coolant * interface functions ************************************************************************ */ public void enableMistCoolant() { sendCommand(_getToolCode() + "M8"); super.enableMistCoolant(); }
/** * ************************************************************************* Flood Coolant * interface functions ************************************************************************ */ public void enableFloodCoolant() { sendCommand(_getToolCode() + "M7"); super.enableFloodCoolant(); }
public void setPlatformTemperature(double temperature) throws RetryException { sendCommand(_getToolCode() + "M140 S" + df.format(temperature)); super.setPlatformTemperature(temperature); }
public void closeClamp(int clampIndex) { sendCommand("M10 Q" + clampIndex); super.closeClamp(clampIndex); }
/** * ************************************************************************* Collet interface * functions ************************************************************************ */ public void openCollet() { sendCommand(_getToolCode() + "M21"); super.openCollet(); }
public void disableDrives() throws RetryException { sendCommand("M18"); sendCommand("M84"); // Klimentkip super.disableDrives(); }
public void closeCollet() { sendCommand(_getToolCode() + "M22"); super.closeCollet(); }
public void closeValve() throws RetryException { sendCommand(_getToolCode() + "M127"); super.closeValve(); }
/** * ************************************************************************* Spindle interface * functions * * @throws RetryException ************************************************************************ */ public void setSpindleRPM(double rpm) throws RetryException { sendCommand(_getToolCode() + "S" + df.format(rpm)); super.setSpindleRPM(rpm); }