def main(): argParser = argparse.ArgumentParser(description='%s, Direct Drive USB Print.' % sys.argv[0]) argParser.add_argument("-d", dest="device", action="store", type=str, help="Device to use, default: /dev/ttyACM0.", default="/dev/ttyACM0") argParser.add_argument("-b", dest="baud", action="store", type=int, help="Baudrate, default 115200.", default=115200) # argParser.add_argument("-b", dest="baud", action="store", type=int, help="Baudrate, default 230400.", default=230400) # argParser.add_argument("-b", dest="baud", action="store", type=int, help="Baudrate, default 500000.", default=500000) # argParser.add_argument("-b", dest="baud", action="store", type=int, help="Baudrate, default 1000000.", default=1000000) argParser.add_argument("-t0", dest="t0", action="store", type=int, help="Temp 0 (heated bed), default comes from mat. profile.") argParser.add_argument("-t1", dest="t1", action="store", type=int, help="Temp 1 (hotend 1), default comes from mat. profile.") argParser.add_argument("-mat", dest="mat", action="store", help="Name of generic material profile to use [pla, abs...], default is pla.", default="pla_1.75mm") argParser.add_argument("-smat", dest="smat", action="store", help="Name of specific material profile to use.") argParser.add_argument("-noz", dest="nozzle", action="store", help="Name of nozzle profile to use [nozzle40, nozzle80...], default is nozzle40.", default="nozzle40") argParser.add_argument("-np", dest="noPrime", action="store_const", const=True, help="Debug: don't prime nozzle, to test extrusion-less moves.") # fake endstops as long we have no real ones argParser.add_argument("-F", dest="fakeendstop", action="store", type=bool, help="Debug: fake endstops", default=False) argParser.add_argument("-nc", dest="noCoolDown", action="store", type=bool, help="Debug: don't wait for heater cool down after print.", default=False) argParser.add_argument("-fr", dest="feedrate", action="store", type=float, help="Feedrate for move commands.", default=0) subparsers = argParser.add_subparsers(dest="mode", help='Mode: mon(itor)|print|store|reset|pre(process).') sp = subparsers.add_parser("autoTune", help=u"Autotune hotend PID values.") sp = subparsers.add_parser("binmon", help=u"Monitor serial printer interface (binary responses).") sp = subparsers.add_parser("changenozzle", help=u"Heat hotend and change nozzle.") sp = subparsers.add_parser("mon", help=u"Monitor serial printer interface (asci).") sp = subparsers.add_parser("print", help=u"Download and print file at once.") sp.add_argument("gfile", help="Input GCode file.") # sp = subparsers.add_parser("store", help=u"Store file as USB.G on sd-card.") # sp.add_argument("gfile", help="Input GCode file.") sp = subparsers.add_parser("writeEepromFloat", help=u"Store float value into eeprom.") sp.add_argument("name", help="Valuename.") sp.add_argument("value", action="store", type=float, help="value (float).") # sp = subparsers.add_parser("reset", help=u"Try to stop/reset printer.") sp = subparsers.add_parser("pre", help=u"Preprocess gcode, for debugging purpose.") sp.add_argument("gfile", help="Input GCode file.") sp = subparsers.add_parser("dumpeeprom", help=u"dump eeprom settings.") sp = subparsers.add_parser("factoryReset", help=u"FactoryReset of eeprom settings, new bed leveling needed.") sp = subparsers.add_parser("test", help=u"Debug: tests for debugging purpose.") sp = subparsers.add_parser("disableSteppers", help=u"Disable stepper current (this dis-homes the printer).") sp = subparsers.add_parser("home", help=u"Home the printer.") sp = subparsers.add_parser("measureTempFlowrateCurve", help=u"Determine temperature/flowrate characteristic.") sp = subparsers.add_parser("moverel", help=u"Debug: Move axis manually, relative coords.") sp.add_argument("axis", help="Axis (XYZAB).", type=str) sp.add_argument("distance", action="store", help="Move-distance (+/-) in mm.", type=float) sp = subparsers.add_parser("moveabs", help=u"Debug: Move axis manually, absolute coords.") sp.add_argument("axis", help="Axis (XYZAB).", type=str) sp.add_argument("distance", action="store", help="Move-distance (+/-) in mm.", type=float) sp = subparsers.add_parser("insertFilament", help=u"Insert filament (heatup, forward filament).") sp = subparsers.add_parser("removeFilament", help=u"Remove filament (heatup, retract filament).") sp = subparsers.add_parser("bedLeveling", help=u"Do bed leveling sequence.") sp = subparsers.add_parser("bedLevelAdjust", help=u"Adjust bedleveling offset - dangerous.") sp.add_argument("distance", action="store", help="Adjust-distance (+/-) in mm.", type=float) sp = subparsers.add_parser("heatHotend", help=u"Heat up hotend (to clean it, etc).") sp = subparsers.add_parser("genTempTable", help=u"Generate extrusion rate limit table.") sp = subparsers.add_parser("getEndstops", help=u"Get current endstop state.") sp = subparsers.add_parser("getFilSensor", help=u"Get current filament position.") sp = subparsers.add_parser("getpos", help=u"Get current printer and virtual position.") sp = subparsers.add_parser("getTemps", help=u"Get current temperatures (Bed, Extruder1, [Extruder2]).") sp = subparsers.add_parser("getTempTable", help=u"Output temperature-speed table.") sp = subparsers.add_parser("getStatus", help=u"Get current printer status.") sp = subparsers.add_parser("zRepeatability", help=u"Debug: Move Z to 10 random positions to test repeatability.") sp = subparsers.add_parser("stop", help=u"Stop print, cooldown, home, disable steppers.") sp = subparsers.add_parser("stepResponse", help=u"Measure and plot stepResponse of hotend PID.") sp = subparsers.add_parser("retract", help=u"Debug: Do the end-of-print retract manually after heating up.") sp = subparsers.add_parser("fanspeed", help=u"Set fan speed manually.") sp.add_argument("speed", help="Fanspeed 0 - 255.", type=int) sp = subparsers.add_parser("testFilSensor", help=u"Debug: move filament manually, output filament sensor measurement.") sp.add_argument("distance", action="store", help="Move-distance (+/-) in mm.", type=float) sp = subparsers.add_parser("calibrateFilSensor", help=u"Debug: helper to determine the ratio of stepper to flowrate sensor.") # sp.add_argument("distance", action="store", help="Move-distance (+/-) in mm.", type=float) args = argParser.parse_args() # print "args: ", args (parser, planner, printer) = initParser(args, mode=args.mode) steps_per_mm = PrinterProfile.getStepsPerMMVector() if args.mode == 'autoTune': util.zieglerNichols(args, parser) elif args.mode == 'changenozzle': util.changeNozzle(args, parser) elif args.mode == "binmon": printer.initSerial(args.device, args.baud) while True: try: (cmd, payload) = printer.readResponse() except RxTimeout: pass else: print "Response cmd :", cmd print "Response payload:", payload.encode("hex") printer.checkErrorResponse(cmd, payload, False) elif args.mode == 'print': util.commonInit(args, parser) t0 = MatProfile.getBedTemp() t1 = MatProfile.getHotendBaseTemp() # Send heat up command print "\nPre-Heating bed...\n" printer.heatUp(HeaterBed, t0) print "\nPre-Heating extruder...\n" printer.heatUp(HeaterEx1, 150) # Send printing moves # f = open(args.gfile) f = parser.preParse(args.gfile) # Send priming moves if not args.noPrime: util.prime(parser) lineNr = 0 printStarted = False for line in f: parser.execute_line(line) # # Send more than one 512 byte block for dlprint # if lineNr > 1000 and (lineNr % 250) == 0: # check temp and start print if not printStarted: print "\nHeating bed (t0: %d)...\n" % t0 printer.heatUp(HeaterBed, t0, t0) print "\nHeating extruder (t1: %d)...\n" % t1 printer.heatUp(HeaterEx1, t1, wait=0.95 * t1) # Send print command printer.sendCommandParamV(CmdMove, [MoveTypeNormal]) printStarted = True else: # Stop sending moves on error status = printer.getStatus() pprint.pprint(status) if not printer.stateMoving(status): break lineNr += 1 print "Parsed %d gcode lines." % lineNr # # Add a move to lift the nozzle from the print if not ultigcode flavor # if not parser.ultiGcodeFlavor: util.endOfPrintLift(parser) planner.finishMoves() printer.sendCommand(CmdEOT) # XXX start print if less than 1000 lines or temp not yet reached: if not printStarted: print "\nHeating bed (t0: %d)...\n" % t0 printer.heatUp(HeaterBed, t0, t0) print "\nHeating extruder (t1: %d)...\n" % t1 printer.heatUp(HeaterEx1, t1, wait=0.95 * t1) # Send print command printer.sendCommandParamV(CmdMove, [MoveTypeNormal]) printer.waitForState(StateIdle) printer.coolDown(HeaterEx1) printer.coolDown(HeaterBed) ddhome.home(parser, args.fakeendstop) printer.sendCommand(CmdDisableSteppers) if not args.noCoolDown: printer.coolDown(HeaterEx1, wait=150) printer.coolDown(HeaterBed, wait=55) printer.readMore() ### Simulator/profiling ### printer.sendCommand(CmdExit) elif args.mode == "pre": # Virtuelle position des druckkopfes falls 'gehomed' homePosMM = util.MyPoint( X = planner.X_HOME_POS, Y = planner.Y_HOME_POS, Z = planner.Z_HOME_POS, # - 20, ) parser.set_position(homePosMM) f = parser.preParse(args.gfile) lineNr = 0 for line in f: parser.execute_line(line) lineNr += 1 print "Parsed %d gcode lines." % lineNr planner.finishMoves() elif args.mode == "mon": printer.initSerial(args.device, args.baud) while True: printer.readMore() elif args.mode == 'dumpeeprom': printer.commandInit(args) resp = printer.query(CmdGetEepromVersion) if util.handleGenericResponse(resp): print "Eepromversion: ", util.getResponseString(resp[1], 1) settingsDict = printer.getEepromSettings() print "eepromSettings: ", pprint.pprint(settingsDict) elif args.mode == 'factoryReset': printer.commandInit(args) printer.sendCommand(CmdEepromFactory) elif args.mode == 'disableSteppers': printer.commandInit(args) printer.sendCommand(CmdDisableSteppers) elif args.mode == 'measureTempFlowrateCurve': util.measureTempFlowrateCurve(args, parser) elif args.mode == 'moverel': assert(args.axis.upper() in "XYZAB") printer.commandInit(args) axis = util.dimIndex[args.axis.upper()] util.manualMove(parser, axis, args.distance, args.feedrate) elif args.mode == 'moveabs': assert(args.axis.upper() in "XYZAB") printer.commandInit(args) axis = util.dimIndex[args.axis.upper()] util.manualMove(parser, axis, args.distance, args.feedrate, True) elif args.mode == 'insertFilament': util.insertFilament(args, parser) elif args.mode == 'removeFilament': util.removeFilament(args, parser) elif args.mode == 'bedLeveling': util.bedLeveling(args, parser) elif args.mode == 'bedLevelAdjust': util.bedLevelAdjust(args, parser) elif args.mode == 'heatHotend': util.heatHotend(args, parser) elif args.mode == 'genTempTable': util.genTempTable(printer) elif args.mode == 'getEndstops': printer.commandInit(args) res = printer.getEndstops() print "Endstop state: ", res elif args.mode == 'getFilSensor': printer.commandInit(args) print "Filament pos:", printer.getFilSensor() elif args.mode == 'getpos': printer.commandInit(args) res = printer.getPos() curPosMM = util.MyPoint( X = res[0] / float(steps_per_mm[0]), Y = res[1] / float(steps_per_mm[1]), Z = res[2] / float(steps_per_mm[2]), A = res[3] / float(steps_per_mm[3]), # B = res[4] / float(steps_per_mm[4]), ) (homePosMM, homePosStepped) = planner.getHomePos() print "Printer pos [steps]:", res print "Printer pos [mm]:", curPosMM print "Virtual home pos [mm]: ", homePosMM elif args.mode == 'getTemps': printer.commandInit(args) printer.getTemps() elif args.mode == 'getTempTable': printer.commandInit(args) (baseTemp, tempTable) = printer.getTempTable() print "tempTable: ", pprint.pprint(tempTable) util.printTempTable(printer, baseTemp, tempTable) elif args.mode == 'getStatus': printer.commandInit(args) status = printer.getStatus() print "Status: " pprint.pprint(status) elif args.mode == 'home': printer.commandInit(args) ddhome.home(parser, args.fakeendstop) elif args.mode == 'zRepeatability': util.zRepeatability(parser) elif args.mode == 'stepResponse': util.stepResponse(args, parser) elif args.mode == 'retract': util.retract(args, parser) elif args.mode == 'stop': printer.commandInit(args) util.stopMove(args, parser) elif args.mode == 'fanspeed': printer.commandInit(args) printer.sendCommandParamV(CmdFanSpeed, [packedvalue.uint8_t(args.speed)]) elif args.mode == 'testFilSensor': ddtest.testFilSensor(args, parser) elif args.mode == 'calibrateFilSensor': ddtest.calibrateFilSensor(args, parser) elif args.mode == 'test': printer.commandInit(args) util.downloadTempTable(printer) printer.readMore() elif args.mode == "writeEepromFloat": util.writeEEpromFloat(args, parser) else: print "Unknown command: ", args.mode assert(0)
def printFile(self): try: self.parser.reset() self.planner.reset() ddhome.home(self.parser, self.args.fakeendstop) util.downloadTempTable(self.planner) self.printer.sendPrinterInit() # Send heat up command self.log("\nPre-Heating bed (t0: %d)...\n" % self.mat_t0) self.printer.heatUp(HeaterBed, self.mat_t0) t = int(self.mat_t1 * 0.5) self.log("\nPre-Heating extruder (t1: %d)...\n" % t) self.printer.heatUp(HeaterEx1, t) # Send printing moves f = self.parser.preParse(self.fn.get_value()) # Send priming moves util.prime(self.parser) lineNr = 0 printStarted = False lastUpdate = time.time() for line in f: self.parser.execute_line(line) # # Send more than one 512 byte block for dlprint # # if lineNr > 1000 and (lineNr % 250) == 0: if time.time() > (lastUpdate + 0.5): # check temp and start print if lineNr > 1000 and not printStarted: self.log("\nHeating bed (t0: %d)...\n" % self.mat_t0) self.printer.heatUp(HeaterBed, self.mat_t0, wait=self.mat_t0) self.log("\nHeating extruder (t1: %d)...\n" % self.mat_t1) self.printer.heatUp(HeaterEx1, self.mat_t1, self.mat_t1 - 1) # Send print command self.printer.sendCommandParamV(CmdMove, [MoveTypeNormal]) printStarted = True status = self.printer.getStatus() # self.guiQueue.put(SyncCall(self.updateStatus, status)) if printStarted and not self.printer.stateMoving(status): break lastUpdate = time.time() lineNr += 1 print "Parsed %d gcode lines." % lineNr # # Add a move to lift the nozzle from the print if not ultigcode flavor # # if not self.parser.ultiGcodeFlavor: util.endOfPrintLift(self.parser) self.planner.finishMoves() self.printer.sendCommand(CmdEOT) # XXX start print if less than 1000 lines or temp not yet reached: if not printStarted: self.log("\nHeating bed (t0: %d)...\n" % self.mat_t0) self.printer.heatUp(HeaterBed, self.mat_t0, self.mat_t0) self.log("\nHeating extruder (t1: %d)...\n" % self.mat_t1) self.printer.heatUp(HeaterEx1, self.mat_t1, self.mat_t1 - 1) # Send print command self.printer.sendCommandParamV(CmdMove, [MoveTypeNormal]) status = self.printer.getStatus() # self.guiQueue.put(SyncCall(self.updateStatus, status)) while status['state'] != StateIdle: time.sleep(2) status = self.printer.getStatus() # self.guiQueue.put(SyncCall(self.updateStatus, status)) self.printer.coolDown(HeaterEx1) self.printer.coolDown(HeaterBed) ddhome.home(self.parser, self.args.fakeendstop) self.printer.sendCommand(CmdDisableSteppers) except stoppableThread.StopThread: # Stop of current action requested self.printThread.incStopCount() self.log("printFile(): Caught StopThread, bailing out.") return except FatalPrinterError, ex: self.log("printFile(): Caught FatalPrinterError: ", ex.msg) # Reset line numbers in case of a printer restart. self.printer.resetLineNumber()
def printFile(self): try: self.parser.reset() self.planner.reset() ddhome.home(self.parser, self.args.fakeendstop) util.downloadTempTable(self.printer) self.printer.sendPrinterInit() # Send heat up command self.log( "\nPre-Heating bed (t0: %d)...\n" % self.mat_t0) self.printer.heatUp(HeaterBed, self.mat_t0) t = int(self.mat_t1 * 0.5) self.log( "\nPre-Heating extruder (t1: %d)...\n" % t) self.printer.heatUp(HeaterEx1, t) # Send printing moves f = self.parser.preParse(self.fn.get_value()) # Send priming moves util.prime(self.parser) lineNr = 0 printStarted = False lastUpdate = time.time() for line in f: self.parser.execute_line(line) # # Send more than one 512 byte block for dlprint # # if lineNr > 1000 and (lineNr % 250) == 0: if time.time() > (lastUpdate + 0.5): # check temp and start print if lineNr > 1000 and not printStarted: self.log( "\nHeating bed (t0: %d)...\n" % self.mat_t0 ) self.printer.heatUp(HeaterBed, self.mat_t0, wait=self.mat_t0) self.log( "\nHeating extruder (t1: %d)...\n" % self.mat_t1 ) self.printer.heatUp(HeaterEx1, self.mat_t1, wait=self.mat_t1 - 10) # Send print command self.printer.sendCommandParamV(CmdMove, [MoveTypeNormal]) printStarted = True status = self.printer.getStatus() # self.guiQueue.put(SyncCall(self.updateStatus, status)) if printStarted and not self.printer.stateMoving(status): break lastUpdate = time.time() lineNr += 1 print "Parsed %d gcode lines." % lineNr # # Add a move to lift the nozzle from the print if not ultigcode flavor # if not self.parser.ultiGcodeFlavor: util.endOfPrintLift(self.parser) self.planner.finishMoves() self.printer.sendCommand(CmdEOT) # XXX start print if less than 1000 lines or temp not yet reached: if not printStarted: self.log( "\nHeating bed (t0: %d)...\n" % self.mat_t0 ) self.printer.heatUp(HeaterBed, self.mat_t0, self.mat_t0) self.log( "\nHeating extruder (t1: %d)...\n" % self.mat_t1 ) self.printer.heatUp(HeaterEx1, self.mat_t1, wait=self.mat_t1 - 10) # Send print command self.printer.sendCommandParamV(CmdMove, [MoveTypeNormal]) status = self.printer.getStatus() # self.guiQueue.put(SyncCall(self.updateStatus, status)) while status['state'] != StateIdle: time.sleep(2) status = self.printer.getStatus() # self.guiQueue.put(SyncCall(self.updateStatus, status)) self.printer.coolDown(HeaterEx1) self.printer.coolDown(HeaterBed) ddhome.home(self.parser, self.args.fakeendstop) self.printer.sendCommand(CmdDisableSteppers) except stoppableThread.StopThread: # Stop of current action requested self.printThread.incStopCount() self.log("printFile(): Caught StopThread, bailing out.") return except FatalPrinterError, ex: self.log("printFile(): Caught FatalPrinterError", ex.msg) # Reset line numbers in case of a printer restart. self.printer.resetLineNumber()