def heatHotend(args, parser): planner = parser.planner printer = planner.printer printer.commandInit(args) t1 = MatProfile.getHotendBaseTemp() printer.heatUp(HeaterEx1, t1, wait=t1-5) raw_input("Press return to stop heating...") if not args.noCoolDown: printer.coolDown(HeaterEx1, wait=150)
def genTempTable(printer): baseTemp = MatProfile.getHotendBaseTemp() area04 = pow(0.4, 2)*math.pi/4 extrusionLow = MatProfile.getBaseExtrusionRate() * (NozzleProfile.getArea() / area04) f = MatProfile.getAutoTempFactor() mmpermm3 = 1 / MatProfile.getMatArea() spm = PrinterProfile.getStepsPerMM(A_AXIS) of = open("/tmp/temptable0.txt", "w") of.write("# xxx mat, nozzle, settings...\n") of.write("# basetemp: %d, autoTempFactor: %f\n" % (baseTemp, f)) of.write("# temp rate steprate timer\n") print "TempTable (basetemp: %d):" % baseTemp table = [] for i in range(NExtrusionLimit): t = baseTemp + i*2 dspeed = i*2 / f speed = extrusionLow + dspeed steprate = speed * mmpermm3 * spm tvs = 1.0/steprate timerValue = int(fTimer / steprate) print " Temp: %d, max extrusion: %.1f mm³/s, steps/s: %d, steprate: %d us, timervalue: %d" % (t, speed, int(steprate), int(tvs*1000000), timerValue) table.append(timerValue) of.write("%d %4.1f %d %d\n" % (t, speed, int(steprate), timerValue)) of.close() return (baseTemp, table)
def retract(args, parser, doCooldown = True): planner = parser.planner printer = planner.printer commonInit(args, parser) t1 = MatProfile.getHotendBaseTemp() printer.heatUp(HeaterEx1, t1, wait=t1 - 5) # hack # parser.retracted = False parser.execute_line("G10") planner.finishMoves() printer.sendCommandParamV(CmdMove, [MoveTypeNormal]) printer.sendCommand(CmdEOT) printer.waitForState(StateIdle) if doCooldown: printer.coolDown(HeaterEx1,wait=150)
def removeFilament(args, parser): planner = parser.planner printer = planner.printer printer.commandInit(args) ddhome.home(parser, args.fakeendstop) printer.sendPrinterInit() # Move to mid-position # MAX_POS = (X_MAX_POS, Y_MAX_POS, Z_MAX_POS) # feedrate = PrinterProfile.getMaxFeedrate(Z_AXIS) # parser.execute_line("G0 F%d Z%f" % (feedrate*60, MAX_POS[Z_AXIS])) feedrate = PrinterProfile.getMaxFeedrate(X_AXIS) parser.execute_line("G0 F%d X%f Y%f" % (feedrate*60, planner.MAX_POS[X_AXIS]/2, planner.MAX_POS[Y_AXIS]/2)) planner.finishMoves() printer.sendCommandParamV(CmdMove, [MoveTypeNormal]) printer.sendCommand(CmdEOT) printer.waitForState(StateIdle) t1 = MatProfile.getHotendBaseTemp() printer.heatUp(HeaterEx1, t1, wait=t1) # Etwas vorwärts um den retract-pfropfen einzuschmelzen manualMove(parser, A_AXIS, PrinterProfile.getRetractLength() + 5, 5) manualMove(parser, A_AXIS, -1.3*FILAMENT_REVERSAL_LENGTH) if not args.noCoolDown: printer.coolDown(HeaterEx1,wait=150)
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 printWorker(self): parser = argparse.ArgumentParser(description='%s, Direct Drive USB Print.' % sys.argv[0]) parser.add_argument("-d", dest="device", action="store", type=str, help="Device to use, default: /dev/ttyACM0.", default="/dev/ttyACM0") parser.add_argument("-b", dest="baud", action="store", type=int, help="Baudrate, default 115200.", default=115200) parser.add_argument("-f", dest="file", action="store", type=str, help="Gcode to print") parser.add_argument("-F", dest="fakeendstop", action="store", type=bool, help="fake endstops", default=False) parser.add_argument("-nc", dest="noCoolDown", action="store", type=bool, help="Debug: don't wait for heater cool down after print.", default=False) parser.add_argument("-t0", dest="t0", action="store", type=int, help="Temp 0 (heated bed), default comes from mat. profile.") parser.add_argument("-t1", dest="t1", action="store", type=int, help="Temp 1 (hotend 1), default comes from mat. profile.") parser.add_argument("-mat", dest="mat", action="store", help="Name of material profile to use [pla, abs...], default is pla.", default="pla_1.75mm") parser.add_argument("-smat", dest="smat", action="store", help="Name of specific material profile to use.") parser.add_argument("-noz", dest="nozzle", action="store", help="Name of nozzle profile to use [nozzle40, nozzle80...], default is nozzle40.", default="nozzle40") self.args = parser.parse_args() self.args.mode = "dlprint" # print "args: ", self.args (self.parser, self.planner, self.printer) = ddprint.initParser(self.args, gui=self) # util.commonInit(self.args, self.parser) try: self.printer.commandInit(self.args) except SerialException: msg = "Can't open serial device '%s' (baudrate: %d)!\n\nPress OK to exit." % (self.args.device, self.args.baud) self.guiQueue.put(SyncCall(self.quit, msg)) return self.mat_t0 = MatProfile.getBedTemp() self.mat_t1 = MatProfile.getHotendBaseTemp() # self.fn.set_value(self.args.file) self.guiQueue.put(SyncCall(self.fn.set_value, self.args.file)) while True: try: while True: # self.guiQueue.put("hi") # self.guiQueue.put(SyncCall(self.appLog.buffer, ["juhu"])) workDone = False while not self.cmdQueue.empty(): obj = self.cmdQueue.get() obj.call() workDone = True if time.time() - self.lastUpdate > 2.5: # status = self.printer.getStatus() # self.guiQueue.put(SyncCall(self.updateStatus, status)) self.printer.getStatus() workDone = True self.lastUpdate = time.time() if not workDone: time.sleep(0.1) except stoppableThread.StopThread: self.printThread.incStopCount() self.log("caught StopThread, continue....")
def insertFilament(args, parser): planner = parser.planner printer = planner.printer def manualMoveE(): current_position = parser.getRealPos() aofs = current_position[A_AXIS] print "cura: ", aofs kbd = GetChar("Enter (f)orward (b)ackwards (F)orward 10mm (B)ackwards 10mm (q)uit") ch = " " while ch not in "q\n": ch = kbd.getc() print "ch: ", ch if ch == "f": # filament forward, 'small' step aofs += 1 elif ch == "F": # filament forward, 'big' step aofs += 10 elif ch == "b": # filament backwards, 'small' step aofs -= 1 elif ch == "B": # filament backwards, 'big' step aofs -= 10 printer.sendPrinterInit() # XXX hardcoded feedrate parser.execute_line("G0 F%d A%f" % (5*60, aofs)) planner.finishMoves() printer.sendCommandParamV(CmdMove, [MoveTypeNormal]) printer.sendCommand(CmdEOT) printer.waitForState(StateIdle, wait=0.1) commonInit(args, parser) # Move to mid-position feedrate = PrinterProfile.getMaxFeedrate(X_AXIS) parser.execute_line("G0 F%d X%f Y%f" % (feedrate*60, planner.MAX_POS[X_AXIS]/2, planner.MAX_POS[Y_AXIS]/2)) planner.finishMoves() printer.sendCommandParamV(CmdMove, [MoveTypeNormal]) printer.sendCommand(CmdEOT) printer.waitForState(StateIdle) t1 = MatProfile.getHotendBaseTemp() printer.heatUp(HeaterEx1, t1, wait=t1 - 5) print "\nInsert filament.\n" manualMoveE() print "\nForwarding filament.\n" manualMove(parser, A_AXIS, FILAMENT_REVERSAL_LENGTH * 0.85) print "\nExtrude filament.\n" manualMoveE() # # Retract # printer.sendPrinterInit() parser.execute_line("G10") planner.finishMoves() printer.sendCommandParamV(CmdMove, [MoveTypeNormal]) printer.sendCommand(CmdEOT) printer.waitForState(StateIdle) if not args.noCoolDown: printer.coolDown(HeaterEx1, wait=150)
def measureTempFlowrateCurve(args, parser): def writeDataSet(f, dataSet): for dataStr in dataSet: f.write(dataStr) f.write("\n") f.write("E\n") fssteps_per_mm = 265.0 # xxx hardcoded, get from profile or printer... planner = parser.planner printer = planner.printer printer.commandInit(args) ddhome.home(parser, args.fakeendstop) # Disable flowrate limit printer.sendCommandParamV(CmdEnableFRLimit, [packedvalue.uint8_t(0)]) # Move to mid-position printer.sendPrinterInit() feedrate = PrinterProfile.getMaxFeedrate(X_AXIS) parser.execute_line("G0 F%d X%f Y%f" % (feedrate*60, planner.MAX_POS[X_AXIS]/2, planner.MAX_POS[Y_AXIS]/2)) planner.finishMoves() printer.sendCommandParamV(CmdMove, [MoveTypeNormal]) printer.sendCommand(CmdEOT) printer.waitForState(StateIdle) current_position = parser.getRealPos() apos = current_position[A_AXIS] t1 = MatProfile.getHotendBaseTemp() # start temperature area04 = pow(0.4, 2)*math.pi/4 flowrate = MatProfile.getBaseExtrusionRate() * (NozzleProfile.getArea() / area04) aFilament = MatProfile.getMatArea() print "t1: ", t1 print "flowrate: ", flowrate print "aFilament: ", aFilament print "feedrate: ", flowrate / aFilament # xxx todo if using small nozzles assert(flowrate > 2) f = open("temp-flowrate-curve.gnuplot", "w") f.write(""" set grid set yrange [0:35] # Startwert steigung a=0.5 # Startwert y-achse b=5 f(x)=b+a*(x-%d) fit f(x) "-" using 1:3 noerror via a,b\n""" % t1) dataSet = [] printer.sendCommandParamV(CmdFanSpeed, [packedvalue.uint8_t(100)]) retracted = False while t1 <= MatProfile.getHotendMaxTemp(): print "Heating:", t1 printer.heatUp(HeaterEx1, t1, wait=t1) # time.sleep(10) # temp settle wait = 5 while wait: time.sleep(1) temps = printer.getTemps() if abs(t1 - int(temps[HeaterEx1])) <= 1: wait -= 1 else: wait = 5 print "temp wait: ", wait flowrate -= 1 ratio = 1.0 while ratio >= 0.9: feedrate = flowrate / aFilament # distance = 5 * feedrate # xxx distance = 50 apos += distance print "Feedrate for flowrate:", feedrate, flowrate printer.sendPrinterInit() if retracted: parser.execute_line("G11") parser.execute_line("G0 F%d %s%f" % (feedrate*60, dimNames[A_AXIS], apos)) parser.execute_line("G10") planner.finishMoves() printer.sendCommand(CmdEOT) printer.sendCommandParamV(CmdMove, [MoveTypeNormal]) printer.waitForState(StateIdle) time.sleep(0.25) fssteps = printer.getFilSensor() fsdist = fssteps / fssteps_per_mm ratio = fsdist / distance actualFlowrate = flowrate * ratio print "t1, flowrate, fsdist, distance, ratio:", t1, flowrate, fsdist, distance, ratio flowrate += 1 retracted = True print "Feeder grip:", t1, flowrate-1, ratio dataStr = "%f %f %.2f %.3f" % (t1, flowrate - 1, actualFlowrate, ratio) f.write(dataStr + "\n") f.flush() dataSet.append(dataStr) t1 += 2 # next temp f.write("E\n") f.write(""" plot "-" using 1:2 with linespoints title "Target Flowrate", \\ "-" using 1:3 with linespoints title "Actual Flowrate", \\ "-" using 1:3 with linespoints smooth bezier title "Actual Flowrate smooth", \\ f(x) title sprintf("y=B+A*x, A=%.2f, B=%.1f, TempFactor 1/A: %.2f", a, b, 1/a)\n""") writeDataSet(f, dataSet) writeDataSet(f, dataSet) writeDataSet(f, dataSet) f.close() printer.coolDown(HeaterEx1) # Enable flowrate limit printer.sendCommandParamV(CmdEnableFRLimit, [packedvalue.uint8_t(1)])
def streamMoves(self, moves, finish = False): if debugMoves: print "Streaming %d moves..." % len(moves) if debugPlot and not self.plotfile: self.plottime = 0 self.plotfile=open("/tmp/accel_%d.plt" % moves[0].moveNumber, "w") self.plotfile.write("set grid\n") self.plotfile.write("set label 2 at graph 0.01, graph 0.95 'Note: Trapez top not included, e-only moves green.'\n") self.plotfile.write('plot "-" using 1:2:3 with linespoints lc variable\n') ################################################################################# # Backwards move planning self.joinMovesBwd(moves) ################################################################################# for move in moves: # move.pprint("sanicheck") move.sanityCheck(self.jerk) self.planAcceleration(move) self.planSteps(move) # # Collect some statistics # if move.isHeadMove(): self.pathData.maxExtrusionRate.stat(move) # # Collect moves if AutoTemp # if UseExtrusionAutoTemp: if move.isExtrudingMove(util.A_AXIS): # Collect moves and sum up path time self.pathData.time += move.getTime() # Sum extrusion volume self.pathData.extrusionAmount += move.getAdjustedExtrusionVolume(util.A_AXIS, NozzleProfile, MatProfile) self.pathData.atMoves.append(move) else: self.streamMove(move) move.streamed = True # Help garbage collection move.lastMove = errorMove move.nextMove = errorMove if UseExtrusionAutoTemp: if self.pathData.time >= ATInterval or finish: if self.pathData.time > 0: # Compute temperature for this segment and add tempcommand into the stream # Average speed: avgSpeed = self.pathData.extrusionAmount / self.pathData.time # UseAutoTemp: Adjust temp between Tbase and HotendMaxTemp, if speed is greater than 20 mm/s # UseExtrusionAutoTemp: Adjust temp between Tbase and HotendMaxTemp, if speed is greater than 5 mm³/s newTemp = MatProfile.getHotendBaseTemp() # Extruder 1 temp # extrusionLow = self.ExtrusionAmountLow * pow(NozzleProfile.getSize(), 2) if avgSpeed > self.ExtrusionAmountLow: f = MatProfile.getAutoTempFactor() # newTemp += min((avgSpeed - self.ExtrusionAmountLow * pow(NozzleProfile.getSize(), 2)) * f, ATMaxTempIncrease) newTemp += (avgSpeed - self.ExtrusionAmountLow) * f # newTemp *= 1.15 # xxx sync withtemp-speed-adjust newTemp = min(newTemp, MatProfile.getHotendMaxTemp()) if debugAutoTemp: print "AutoTemp: collected %d moves with %.2f s duration." % (len(self.pathData.atMoves), self.pathData.time) print "AutoTemp: amount: %.2f, avg extrusion rate: %.2f mm³/s." % (self.pathData.extrusionAmount, avgSpeed) print "AutoTemp: new temp: %.2f." % (newTemp) self.pathData.maxExtrusionRate.avgStat(avgSpeed) if newTemp != self.pathData.lastTemp and self.args.mode != "pre": # Schedule target temp command self.printer.sendCommandParamV( CmdSyncTargetTemp, [packedvalue.uint8_t(HeaterEx1), packedvalue.uint16_t(newTemp)]) self.pathData.lastTemp = newTemp for move in self.pathData.atMoves: self.streamMove(move) self.pathData.atMoves = [] self.pathData.time = self.pathData.extrusionAmount = 0 # Reset path time
def addMove(self, move): # print "addmove ...", move.comment if debugMoves: print "***** Start addMove() *****" move.moveNumber = self.pathData.incCount() if not self.pathData.path: # First move of this path, startspeed is jerkspeed # jerkSpeed = move.vVector().constrain(self.jerk) or move.vVector() # move.setNominalStartFr(jerkSpeed) move.setNominalJerkStartSpeed(self.jerk) # self.prepareMoveEnd(move) self.pathData.path.append(move) if UseExtrusionAutoTemp: self.pathData.time = 0 # Reset path time self.pathData.extrusionAmount = 0 self.pathData.lastTemp = MatProfile.getHotendBaseTemp() # # Zum end-speed können wir nichts sagen, da der nächste move noch nicht # bekannt ist. # if debugMoves: print "***** End addMove() *****" return lastMove = self.pathData.path[-1] lastMove.nextMove = move move.lastMove = lastMove util.joinSpeed(lastMove, move, self.jerk, self.min_speeds) self.pathData.path.append(move) if len(self.pathData.path) < 3: # Wir brauchen mind. 3 moves um einen 'PathBlock' zu bilden if debugMoves: print "***** End addMove() *****" return if self.isIsolationMove(lastMove): l = len(self.pathData.path) pathBlock = self.pathData.path[:l-2] if debugMoves: print "Move #:", lastMove.moveNumber, " is a isolation move." print "Streaming block of moves, len: %d/%d" % (len(pathBlock), l), ", blocks: ", pathBlock[0].moveNumber, " - ", pathBlock[-1].moveNumber self.streamMoves(pathBlock) del self.pathData.path[:l-2] assert(len(self.pathData.path) == 2) if debugMoves: print "***** End addMove() *****"