mirror of
https://github.com/Ultimaker/Cura.git
synced 2025-07-12 01:07:52 -06:00
Add Anneal After Print PostProcessingPlugin
This new plugin generates annealing gcode with the following features: - Bed and chamber heating options - Provides progress bar and time remaining feedback - Beep on annealing start - Gradual annealing cooldown to desired temperature
This commit is contained in:
parent
271868eafd
commit
836a7cc2d1
1 changed files with 160 additions and 0 deletions
160
plugins/PostProcessingPlugin/scripts/AnnealAfterPrint.py
Normal file
160
plugins/PostProcessingPlugin/scripts/AnnealAfterPrint.py
Normal file
|
@ -0,0 +1,160 @@
|
|||
# Copyright (c) 2021 Anson Liu
|
||||
# The PostProcessingPlugin is released under the terms of the AGPLv3 or higher.
|
||||
|
||||
from ..Script import Script
|
||||
|
||||
class AnnealAfterPrint(Script):
|
||||
"""Adds timed annealing GCODE after objects finish printing.
|
||||
|
||||
Bed annealing works best with a glass bed and a plastic container placed on top of the object during annealing.
|
||||
"""
|
||||
|
||||
def getSettingDataString(self):
|
||||
return """{
|
||||
"name": "Anneal After Print",
|
||||
"key": "AnnealAfterPrint",
|
||||
"metadata": {},
|
||||
"version": 2,
|
||||
"settings":
|
||||
{
|
||||
"heatingElement":
|
||||
{
|
||||
"label": "Heating Element",
|
||||
"description": "Printer heating element to use for annealing.",
|
||||
"type": "enum",
|
||||
"options":
|
||||
{
|
||||
"bed": "Bed",
|
||||
"chamber": "Chamber",
|
||||
"all": "Bed and Chamber"
|
||||
},
|
||||
"default_value": "bed"
|
||||
},
|
||||
"annealBedTemp":
|
||||
{
|
||||
"label": "Bed Temperature",
|
||||
"description": "Bed temperature annealing. Recommended bed temperature is greater of build plate printing or vendor specified annealing temperature for material. E.g. PC 90-110 C, PLA 60-90 C",
|
||||
"unit": "C",
|
||||
"type": "float",
|
||||
"default_value": 0,
|
||||
"minimum_value": 0,
|
||||
"enabled": "heatingElement == \\\"bed\\\" or heatingElement == \\\"all\\\""
|
||||
},
|
||||
"annealChamberTemp":
|
||||
{
|
||||
"label": "Chamber Temperature",
|
||||
"description": "Chamber temperature for annealing.",
|
||||
"unit": "C",
|
||||
"type": "float",
|
||||
"default_value": 0,
|
||||
"minimum_value": 0,
|
||||
"enabled": "heatingElement == \\\"chamber\\\" or heatingElement == \\\"all\\\""
|
||||
},
|
||||
"annealMinutes":
|
||||
{
|
||||
"label": "Annealing Target Temperature Duration",
|
||||
"description": "Duration in minutes to anneal at target temperature. After duration ends gradually cool down to End Cooling Temperature.",
|
||||
"unit": "min",
|
||||
"type": "int",
|
||||
"default_value": 120,
|
||||
"minimum_value": 0
|
||||
},
|
||||
"reminderBeep":
|
||||
{
|
||||
"label": "Beep on annealing start",
|
||||
"description": "",
|
||||
"type": "bool",
|
||||
"default_value": false
|
||||
},
|
||||
"endCoolingTemp":
|
||||
{
|
||||
"label": "End Cooling Temperature",
|
||||
"description": "Temperature to end gradual cooling at. After annealing at target temperature for specified duration temperature decreases by 1 degree after 1 minute at each step.",
|
||||
"unit": "C",
|
||||
"type": "float",
|
||||
"default_value": 50,
|
||||
"minimum_value": 0
|
||||
}
|
||||
}
|
||||
}"""
|
||||
|
||||
def generateAnnealCode(self, annealBedTemp, annealChamberTemp, annealMinutes, initialBeep, endCoolingTemp):
|
||||
anneal_code = ';Generated Annealing GCODE by Anson Liu'
|
||||
|
||||
if initialBeep:
|
||||
anneal_code += '\nM300 ;play beep for plastic container placement reminder'
|
||||
|
||||
anneal_code += '\nM117 '
|
||||
if annealBedTemp:
|
||||
anneal_code += 'Place plastic container over objects on bed now! '
|
||||
anneal_code += 'Waiting until annealing temp reached...'
|
||||
anneal_code += '\nM73 P00 ;reset progress bar to 0'
|
||||
|
||||
if annealBedTemp:
|
||||
anneal_code += '\nM190 R{} ;wait for buildplate to reach temp in C even if cooling'.format(annealBedTemp)
|
||||
if annealChamberTemp:
|
||||
anneal_code += '\nM191 R{} ;wait for chamber to reach temp in C even if cooling'.format(annealChamberTemp)
|
||||
|
||||
anneal_code += '\nM117 '
|
||||
if annealBedTemp:
|
||||
anneal_code += 'Keep plastic container over objects. '
|
||||
anneal_code += 'Annealing...'
|
||||
anneal_code += '\nM73 P00' # reset progress bar to 0
|
||||
|
||||
def generateDwellAndProgressCode(minutes): # Update progress bar and time every minute
|
||||
dp_code = 'M73 P0 R{}'.format(minutes)
|
||||
for x in range(1, minutes+1):
|
||||
dwellWaitSeconds = 60
|
||||
dp_code += '\nG4 S{}'.format(dwellWaitSeconds)
|
||||
progress = round(x/minutes * 100, 2)
|
||||
remainingMinutes = minutes - x
|
||||
dp_code += '\nM73 P{} R{}'.format(progress, remainingMinutes)
|
||||
|
||||
return dp_code
|
||||
|
||||
anneal_code += '\n' + generateDwellAndProgressCode(int(annealMinutes))
|
||||
|
||||
anneal_code += '\nM117 Annealing complete. Gradually lowering bed temperature...'
|
||||
|
||||
for x in reversed(range(endCoolingTemp, max(annealBedTemp, annealChamberTemp))):
|
||||
if annealBedTemp and annealBedTemp > x:
|
||||
anneal_code += '\nM190 S{}'.format(x) # Wait for buildplate only if heating
|
||||
if annealChamberTemp and annealChamberTemp > x:
|
||||
anneal_code += '\nM191 S{}'.format(x)
|
||||
anneal_code += '\nG4 S60' # Wait 60 seconds after reaching each cooldown temperature
|
||||
|
||||
if annealBedTemp:
|
||||
anneal_code += '\nM140 S0'
|
||||
if annealChamberTemp:
|
||||
anneal_code += '\nM141 S0'
|
||||
anneal_code += '\nM117 Annealing complete.'
|
||||
|
||||
return anneal_code
|
||||
|
||||
def execute(self, data):
|
||||
heating_element = self.getSettingValueByKey("heatingElement")
|
||||
|
||||
# Set bed and chamber temp to true/false value based on heating element selection
|
||||
anneal_bed_temp = 0
|
||||
anneal_chamber_temp = 0
|
||||
if heating_element == "bed" or heating_element == "all":
|
||||
anneal_bed_temp = self.getSettingValueByKey("annealBedTemp")
|
||||
if heating_element == "chamber" or heating_element == "all":
|
||||
anneal_chamber_temp = self.getSettingValueByKey("annealChamberTemp")
|
||||
|
||||
anneal_minutes = self.getSettingValueByKey("annealMinutes")
|
||||
initial_beep = self.getSettingValueByKey("firmware_config")
|
||||
final_cooling_temp = self.getSettingValueByKey("endCoolingTemp")
|
||||
|
||||
# Test printing the generated anneal code
|
||||
#print(self.generateAnnealCode(110, 120, False, 50))
|
||||
anneal_code = self.generateAnnealCode(anneal_bed_temp, anneal_chamber_temp, anneal_minutes, initial_beep, final_cooling_temp)
|
||||
|
||||
try:
|
||||
end_of_gcode_index = data[-1].index(';End sof Gcode')
|
||||
except ValueError:
|
||||
data[-1] += anneal_code + '\n'
|
||||
else:
|
||||
data[-1] = data[-1][:end_of_gcode_index] + anneal_code + '\n' + data[-1][end_of_gcode_index:]
|
||||
|
||||
return data
|
Loading…
Add table
Add a link
Reference in a new issue