Pid HotEnd working
This commit is contained in:
@@ -9,6 +9,8 @@ import octoprint.plugin
|
|||||||
|
|
||||||
CMD_PID_SAVE = "pid_save"
|
CMD_PID_SAVE = "pid_save"
|
||||||
CMD_PID_START = "pid_start"
|
CMD_PID_START = "pid_start"
|
||||||
|
CMD_PID_LOAD_CURRENT_VALUES = "pid_getCurrentValues"
|
||||||
|
CMD_PID_GET_VALUES = "pid_getValues"
|
||||||
|
|
||||||
regexPID = "Kp:\s*(?P<P>\d{1,3}.\d{1,3})\s*Ki:\s*(?P<I>\d{1,3}.\d{1,3})\s*Kd:\s*(?P<D>\d{1,3}.\d{1,3})"
|
regexPID = "Kp:\s*(?P<P>\d{1,3}.\d{1,3})\s*Ki:\s*(?P<I>\d{1,3}.\d{1,3})\s*Kd:\s*(?P<D>\d{1,3}.\d{1,3})"
|
||||||
regexGetPid = "\s*Kp:\s*(?P<p>\d{1,3}.\d{1,3})\s*Ki:\s*(?P<i>\d{1,3}.\d{1,3})\s*Kd:\s*(?P<d>\d{1,3}.\d{1,3})"
|
regexGetPid = "\s*Kp:\s*(?P<p>\d{1,3}.\d{1,3})\s*Ki:\s*(?P<i>\d{1,3}.\d{1,3})\s*Kd:\s*(?P<d>\d{1,3}.\d{1,3})"
|
||||||
@@ -19,40 +21,72 @@ PIDStopedI = "#define DEFAULT_Ki\s*(?P<I>\d{1,3}.\d{1,3})"
|
|||||||
PIDStopedD = "#define DEFAULT_Kd\s*(?P<D>\d{1,3}.\d{1,3})"
|
PIDStopedD = "#define DEFAULT_Kd\s*(?P<D>\d{1,3}.\d{1,3})"
|
||||||
regexFinished = "PID Autotune finished!.*\n#define DEFAULT_Kp\s*(?P<P>\d{1,3}.\d{1,3}).*\n#define DEFAULT_Ki\s*(?P<I>\d{1,3}.\d{1,3})\n#define DEFAULT_Kd\s*(?P<D>\d{1,3}.\d{1,3})"
|
regexFinished = "PID Autotune finished!.*\n#define DEFAULT_Kp\s*(?P<P>\d{1,3}.\d{1,3}).*\n#define DEFAULT_Ki\s*(?P<I>\d{1,3}.\d{1,3})\n#define DEFAULT_Kd\s*(?P<D>\d{1,3}.\d{1,3})"
|
||||||
class API(octoprint.plugin.SimpleApiPlugin):
|
class API(octoprint.plugin.SimpleApiPlugin):
|
||||||
|
pidHotEndCycles = []
|
||||||
|
pidCurrentValues = {}
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def apiCommands():
|
def apiCommands():
|
||||||
return {
|
return {
|
||||||
|
CMD_PID_LOAD_CURRENT_VALUES: [],
|
||||||
CMD_PID_SAVE : [],
|
CMD_PID_SAVE : [],
|
||||||
|
CMD_PID_GET_VALUES: [],
|
||||||
CMD_PID_START: ["fanSpeed", "noCycles", "hotEndIndex", "targetTemp"]
|
CMD_PID_START: ["fanSpeed", "noCycles", "hotEndIndex", "targetTemp"]
|
||||||
}
|
}
|
||||||
|
|
||||||
def apiGateWay(self, command, data):
|
def apiGateWay(self, command, data):
|
||||||
self._logger.debug("DIPGateway")
|
self._logger.debug("DIPGateway")
|
||||||
if command == CMD_PID_START:
|
if command == CMD_PID_LOAD_CURRENT_VALUES:
|
||||||
self.pidCycles = []
|
#catch for "echo: p:28.27 i:2.82 d:70.81" or "M301 P27.08 I2.51 D73.09"
|
||||||
|
|
||||||
for i in range(0,data['noCycles']):
|
getPid = re.compile(r".*p:??(?P<p>\d{1,3}.\d{1,3})\s*i:?(?P<i>\d{1,3}.\d{1,3})\s*d:?(?P<d>\d{1,3}.\d{1,3})", flags=re.IGNORECASE)
|
||||||
|
|
||||||
|
hasResult301 = Event()
|
||||||
|
hasResult304 = Event()
|
||||||
|
self.registerRegexMsg(getPid, self.m301_m304CodeResponse, hasResult301, "hotEnd")
|
||||||
|
self.registerRegexMsg(getPid, self.m301_m304CodeResponse, hasResult304, "bed")
|
||||||
|
|
||||||
|
self._printer.commands(["M301", "M304"])
|
||||||
|
hasResult301.wait(5)
|
||||||
|
hasResult304.wait(5)
|
||||||
|
|
||||||
|
return flask.jsonify({
|
||||||
|
"data": self.pidCurrentValues
|
||||||
|
})
|
||||||
|
|
||||||
|
if command == CMD_PID_START:
|
||||||
|
self.pidHotEndCycles = []
|
||||||
|
|
||||||
|
#Two cycles are for tuning
|
||||||
|
for i in range(0, data['noCycles'] - 2):
|
||||||
self.registerRegexMsg(regexGetPid, self.m106CodeResponse)
|
self.registerRegexMsg(regexGetPid, self.m106CodeResponse)
|
||||||
|
|
||||||
self._printer.commands(["M106 S%(fanSpeed)s" % data, "M303 C%(noCycles)s E%(hotEndIndex)s S%(targetTemp)s U1" % data])
|
self._printer.commands(["M106 S%(fanSpeed)s" % data, "M303 C%(noCycles)s E%(hotEndIndex)s S%(targetTemp)s U1" % data])
|
||||||
self._logger.debug("cycles %s", self.pidCycles)
|
self._logger.debug("cycles %s", self.pidHotEndCycles)
|
||||||
|
|
||||||
if command == CMD_PID_SAVE:
|
if command == CMD_PID_SAVE:
|
||||||
self._logger.debug("DIPSave-")
|
self._logger.debug("DIPSave-")
|
||||||
return flask.jsonify({
|
return flask.jsonify({
|
||||||
"data": self.pidCycles
|
"data": self.pidCycles
|
||||||
})
|
})
|
||||||
|
if command == CMD_PID_GET_VALUES:
|
||||||
|
self._logger.debug("pid_getValues-")
|
||||||
|
return flask.jsonify({
|
||||||
|
"data": self.pidCycles
|
||||||
|
})
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def m301_m304CodeResponse(self, line, regex, event, storingKey):
|
||||||
|
self._logger.debug("m301_m304CodeResponse: %s", line)
|
||||||
|
match = regex.match(line)
|
||||||
|
if match:
|
||||||
|
self.pidCurrentValues[storingKey] = {
|
||||||
|
"P": match.group("p"),
|
||||||
|
"I": match.group("i"),
|
||||||
|
"D": match.group("d")
|
||||||
|
}
|
||||||
|
if event:
|
||||||
|
event.set()
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def m106CodeResponse(self, line):
|
def m106CodeResponse(self, line):
|
||||||
self._logger.debug("m106CodeResponse: %s", line)
|
self._logger.debug("m106CodeResponse: %s", line)
|
||||||
# isM106Response = re.compile(regexFinished).match(line)
|
self.pidHotEndCycles.append(line)
|
||||||
# if isM106Response:
|
|
||||||
# p = isM106Response.group("P")
|
|
||||||
# i = isM106Response.group("I")
|
|
||||||
# d = isM106Response.group("D")
|
|
||||||
# self._logger.debug("P:%s, I:%s, d:%d", p, i, d)
|
|
||||||
# self._logger.debug("line: %s", line)
|
|
||||||
self.pidCycles.append(line)
|
|
||||||
self._logger.debug("cycles %s", self.pidCycles)
|
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ class Hooks():
|
|||||||
reg = waiter["regex"]
|
reg = waiter["regex"]
|
||||||
waiter["callCount"] = waiter["callCount"] + 1
|
waiter["callCount"] = waiter["callCount"] + 1
|
||||||
if reg.match(line):
|
if reg.match(line):
|
||||||
args = (line, *waiter["args"])
|
args = (line, reg, *waiter["args"])
|
||||||
if isinstance(waiter["func"], types.FunctionType):
|
if isinstance(waiter["func"], types.FunctionType):
|
||||||
args = (self, *args)
|
args = (self, *args)
|
||||||
threading.Thread(target=waiter["func"], args=args).start()
|
threading.Thread(target=waiter["func"], args=args).start()
|
||||||
|
|||||||
@@ -55,6 +55,12 @@
|
|||||||
text-align: left;
|
text-align: left;
|
||||||
max-width: 40px;
|
max-width: 40px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#tab_plugin_CalibrationTools span.numberDisplay {
|
||||||
|
min-width: 50px;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ $(function () {
|
|||||||
self.loadEStepsActive(true);
|
self.loadEStepsActive(true);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
self.startExtrusionActive = ko.observable(true)
|
self.startExtrusionActive = ko.observable(false)
|
||||||
self.startExtrusion = function () {
|
self.startExtrusion = function () {
|
||||||
self.startExtrusionActive(true);
|
self.startExtrusionActive(true);
|
||||||
OctoPrint.simpleApiCommand("CalibrationTools", "eSteps_startExtrusion", {
|
OctoPrint.simpleApiCommand("CalibrationTools", "eSteps_startExtrusion", {
|
||||||
@@ -79,7 +79,7 @@ $(function () {
|
|||||||
hide: false
|
hide: false
|
||||||
});
|
});
|
||||||
}).always(function (response) {
|
}).always(function (response) {
|
||||||
self.startExtrusionActive(true);
|
self.startExtrusionActive(false);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,8 +5,19 @@ $(function () {
|
|||||||
self.settingsViewModel = parameters[1];
|
self.settingsViewModel = parameters[1];
|
||||||
self.controlViewModel = parameters[2];
|
self.controlViewModel = parameters[2];
|
||||||
|
|
||||||
self.bedCurrentTemp = ko.observable(0);
|
self.pidCurrentValues = {
|
||||||
self.bedCurrentTarget = ko.observable(0);
|
"hotEnd": {
|
||||||
|
"P": ko.observable(0),
|
||||||
|
"I": ko.observable(0),
|
||||||
|
"D": ko.observable(0)
|
||||||
|
},
|
||||||
|
"bed": {
|
||||||
|
"P": ko.observable(0),
|
||||||
|
"I": ko.observable(0),
|
||||||
|
"D": ko.observable(0)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
self.isAdmin = ko.observable(false);
|
self.isAdmin = ko.observable(false);
|
||||||
self.pid = {
|
self.pid = {
|
||||||
fanSpeed: ko.observable(255),
|
fanSpeed: ko.observable(255),
|
||||||
@@ -15,10 +26,26 @@ $(function () {
|
|||||||
targetTemp: ko.observable(200)
|
targetTemp: ko.observable(200)
|
||||||
};
|
};
|
||||||
|
|
||||||
OctoPrint.printer.getBedState().done(function (bedState) {
|
/**
|
||||||
self.bedCurrentTemp(bedState.bed.actual);
|
* Get current PIDs settings for bed and hotEnd
|
||||||
self.bedCurrentTarget(bedState.bed.target);
|
*/
|
||||||
});
|
self.getCurrentValues = function () {
|
||||||
|
OctoPrint.simpleApiCommand("CalibrationTools", "pid_getCurrentValues").done(function (response) {
|
||||||
|
self.pidCurrentValues.hotEnd.P(response.data.hotEnd.P);
|
||||||
|
self.pidCurrentValues.hotEnd.I(response.data.hotEnd.I);
|
||||||
|
self.pidCurrentValues.hotEnd.D(response.data.hotEnd.D);
|
||||||
|
self.pidCurrentValues.bed.P(response.data.bed.P);
|
||||||
|
self.pidCurrentValues.bed.I(response.data.bed.I);
|
||||||
|
self.pidCurrentValues.bed.D(response.data.bed.D);
|
||||||
|
}).fail(function (response) {
|
||||||
|
new PNotify({
|
||||||
|
title: "Error on getting current PID values ",
|
||||||
|
text: response.responseJSON.error,
|
||||||
|
type: "error",
|
||||||
|
hide: false
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
self.onBeforeBinding = self.onUserLoggedIn = self.onUserLoggedOut = function () {
|
self.onBeforeBinding = self.onUserLoggedIn = self.onUserLoggedOut = function () {
|
||||||
self.pid.fanSpeed(self.settingsViewModel.settings.plugins.CalibrationTools.pid.fanSpeed());
|
self.pid.fanSpeed(self.settingsViewModel.settings.plugins.CalibrationTools.pid.fanSpeed());
|
||||||
@@ -43,7 +70,7 @@ $(function () {
|
|||||||
console.log(response);
|
console.log(response);
|
||||||
}).fail(function (response) {
|
}).fail(function (response) {
|
||||||
new PNotify({
|
new PNotify({
|
||||||
title: "Error on starting extrusion ",
|
title: "Error on starting PID autotune ",
|
||||||
text: response.responseJSON.error,
|
text: response.responseJSON.error,
|
||||||
type: "error",
|
type: "error",
|
||||||
hide: false
|
hide: false
|
||||||
|
|||||||
@@ -43,7 +43,7 @@
|
|||||||
<div class="span6"></div>
|
<div class="span6"></div>
|
||||||
<div class="span6">
|
<div class="span6">
|
||||||
<button class="btn btn-success"
|
<button class="btn btn-success"
|
||||||
data-bind="click: $root.startExtrusion, enable: $root.startExtrusionActive() && $root.is_admin() && $root.controlViewModel.isOperational() && (!$root.controlViewModel.isPrinting())"
|
data-bind="click: $root.startExtrusion, enable: !$root.startExtrusionActive() && $root.is_admin() && $root.controlViewModel.isOperational() && (!$root.controlViewModel.isPrinting())"
|
||||||
title="This will trigger M90, M83, G1 E100 F50, M82, G90 in order for extruding filament">
|
title="This will trigger M90, M83, G1 E100 F50, M82, G90 in order for extruding filament">
|
||||||
<i class="fas fa-play" style="color:false" data-color="false"></i>  
|
<i class="fas fa-play" style="color:false" data-color="false"></i>  
|
||||||
Start extrusion
|
Start extrusion
|
||||||
@@ -65,7 +65,7 @@
|
|||||||
<span class="add-on" title="Current value for number of steps/mm for E axe in EEPROM">steps/mm</span>
|
<span class="add-on" title="Current value for number of steps/mm for E axe in EEPROM">steps/mm</span>
|
||||||
<button class="btn" data-bind="click: $root.loadESteps, enable: $root.loadEStepsActive() && $root.controlViewModel.isOperational() && (!$root.controlViewModel.isPrinting())"
|
<button class="btn" data-bind="click: $root.loadESteps, enable: $root.loadEStepsActive() && $root.controlViewModel.isOperational() && (!$root.controlViewModel.isPrinting())"
|
||||||
title="Loads current value of steps/mm from EEPROM by calling M92">
|
title="Loads current value of steps/mm from EEPROM by calling M92">
|
||||||
<i class="fas fa-sync-alt" style="color:false" data-color="false"></i>  
|
<i class="fas fa-sync-alt" style="color:false" data-color="false"></i>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,12 +1,47 @@
|
|||||||
{% import "macros.jinja2" as snipped %}
|
{% import "macros.jinja2" as snipped %}
|
||||||
|
|
||||||
Current bed temperature: <span data-bind="text: bedCurrentTemp"></span>° Bed target temperature <span data-bind="text: $root.bedCurrentTarget"></span>°
|
{{ snipped.subSection("Hot-end tuning", true) }}
|
||||||
{{ snipped.subSection("Tool tuning", true) }}
|
<div class="row-fluid">
|
||||||
|
<div class="span5">
|
||||||
|
<label for="hotEndPid" class="pull-right" style="margin-top: 5px;" title="Current hot-end PID">
|
||||||
|
Current hot-end PID
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="span7">
|
||||||
|
<div class="input-prepend input-append" id="hotEndPid">
|
||||||
|
<span class="add-on" title="Proportional gain">P</span>
|
||||||
|
<span class="add-on numberDisplay" title="Proportional gain" data-bind="text: $root.pidCurrentValues.hotEnd.P()"></span>
|
||||||
|
<span class="add-on" title="Integral gain">I</span>
|
||||||
|
<span class="add-on numberDisplay" title="Integral gain" data-bind="text: $root.pidCurrentValues.hotEnd.I()"></span>
|
||||||
|
<span class="add-on" title="Derivative">D</span>
|
||||||
|
<span class="add-on numberDisplay" title="Derivative" data-bind="text: $root.pidCurrentValues.hotEnd.D()"></span>
|
||||||
|
<button class="btn" data-bind="click: $root.getCurrentValues, enable: $root.controlViewModel.isOperational() && (!$root.controlViewModel.isPrinting())" title="Load current PIDs">
|
||||||
|
<i class="fas fa-sync-alt" style="color:false" data-color="false"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row-fluid">
|
||||||
|
<div class="span5">
|
||||||
|
<label for="bedPid" class="pull-right" style="margin-top: 5px;" title="Current bed PID">
|
||||||
|
Current bed PID
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="span7">
|
||||||
|
<div class="input-prepend input-append" id="bedPid">
|
||||||
|
<span class="add-on" title="Proportional gain">P</span>
|
||||||
|
<span class="add-on numberDisplay" title="Proportional gain" data-bind="text: $root.pidCurrentValues.bed.P()"></span>
|
||||||
|
<span class="add-on" title="Integral gain">I</span>
|
||||||
|
<span class="add-on numberDisplay" title="Integral gain" data-bind="text: $root.pidCurrentValues.bed.I()"></span>
|
||||||
|
<span class="add-on" title="Derivative">D</span>
|
||||||
|
<span class="add-on numberDisplay" title="Derivative" data-bind="text: $root.pidCurrentValues.bed.D()"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="row-fluid">
|
<div class="row-fluid">
|
||||||
<div class="span5">
|
<div class="span5">
|
||||||
<label for="fanSpeed" class="pull-right" style="margin-top: 5px;" title="x">
|
<label for="fanSpeed" class="pull-right" style="margin-top: 5px;" title="Fan speed">
|
||||||
Turn fan to max
|
Turn fan to max
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
@@ -50,9 +85,6 @@ Current bed temperature: <span data-bind="text: bedCurrentTemp"></span>° Be
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
Save M501
|
|
||||||
|
|
||||||
|
|
||||||
{{ snipped.subSection("Heated bed tuning", true) }}
|
{{ snipped.subSection("Heated bed tuning", true) }}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user