New U and V parameters for M308
-
Searching for some way to simulate my proposal from https://forum.duet3d.com/topic/33669/multilinear-sensor-sensor-table-for-m308?_=1709926750748 ), I just saw the new M308 U and V parameters in the post-rc3 changelog.
Sadly, these do not allow a non-linear (polynomial or other) analog signal... hence one question, if I may: is it possible to redefine the new U and V values on the fly when a sensor has reached a given temperature while the printer is heating up, e.g by adding some conditions to daemon.g, or would this only have an effect after the heating process has finished?
-
-
@NeoDue yes you can change the U and V parameters on the fly, however the temperature reading will jump when you do so if the new parameters result in a different correction at the current temperature. If the jump is too great then a heating fault may be triggered.
-
@dc42 thanks! Hm, due to the error caused by only having "linear-analog" available, I had to increase the allowed error anyway... let's see how this works
-
-
-
Okay, I fear I need some additional input about these values.
I have my hotend temp sensors configured as "linear-analog" since the hotends have preamplifier built in which gives a... well, largely linear output signal (see link in 1st post).
That works well for temperatures between 120 and 320°C which is good for printing. But at room temperature, the readings are more than 10°C too low. (2nd graph in the link).
Now I want to add a correction factor using U and V on these readings to switch to a more realistic input curve for low temperatures (i.e. the blue line on the third picture in th link),
but I guess these values are applied on the raw ADC output, not on the voltage value, correct? That means however I need to know the ADC output value that corresponds to 3.3V max input value to get these values. Can anyone point me to where I can find that?Edit: should have looked at the Github repo of RRF first... in case anyone needs it: the U and V values seem to be applied to the final temperature values, not the input voltage or the ADC output of the controller.
-
Okay, in general this works quite nicely... the linear approximation of the temperature sensor works fine for temperatures above 120°C but shows 16.8°C when it ought to show 23.3°, assuming the bed temperatur sensor is correct. With these values I get U=7.62 and V=-0.0635.
Thus, daemon.g has these lines added (switching point shifted to 110°C since heat-up is much faster than cool-down and daemon.g is running only every 10s):
if heat.heaters[1].current < 110 M308 S1 U7.62 V-0.0635 else M308 S1 U0 V0 if heat.heaters[2].current < 110 M308 S2 U7.62 V-0.0635 else M308 S2 U0 V0
... and this brings the printer to be precise at printing temperatures and at low temperatures. The jump @dc42 mentioned is in the low single degree area and therefore does not cause problems.
The only issue that occurs if doing so is that temperature readings are getting somewhat erratic spikes - it seems that if M308 is called at some specific time relative to the temperature polling interval, the Duet returns 2000°C:
Neither of the two peaks in the pictures happened at the moment the switch occurred though. The expected "switching jump" is barely visible on the other hand.Since I did not find a suitable way to prevent those spikes, I guess I'd better disable that enhancement for now... does anyone have an idea about this?
-
Sometimes it is just the obvious things - such as using the values that have been added to the object model to check if M308 is really necessary...
So here is the final version which reduces occurrance of these 2000° spikes to the moment the switch occurs:
- I moved all values to config.g since I prefer to have all configuration data in there:
; values for bilinear temperature sensor curve if !exists(global.HE_Temp_temp) global HE_Temp_switchtemp = 110 ; switching temperature - to avoid random switching (spikes!) this should be a temperature that is not used for printing or calibration if !exists(global.HE_Temp_offset) global HE_Temp_offset = 7.62 ; offset correction if !exists(global.HE_Temp_slope) global HE_Temp_slope = -0.0635 ; slope correction
- in daemon.g, hotend temperatures are checked. If necessary, offset and slope correction is applied/removed, but only if that has not already happened, which is checked by reading one of the values from the object model:
;----------------------------------------------------------------------------- ; change / reset temperature curve for low temperatures ;----------------------------------------------------------------------------- if heat.heaters[1].current < global.HE_Temp_switchtemp && sensors.analog[1].offsetAdj != global.HE_Temp_offset M308 S1 U{global.HE_Temp_offset} V{global.HE_Temp_slope} elif heat.heaters[1].current > global.HE_Temp_switchtemp && sensors.analog[1].offsetAdj == global.HE_Temp_offset M308 S1 U0 V0 if heat.heaters[2].current < global.HE_Temp_switchtemp && sensors.analog[2].offsetAdj != global.HE_Temp_offset M308 S2 U{global.HE_Temp_offset} V{global.HE_Temp_slope} elif heat.heaters[2].current > global.HE_Temp_switchtemp && sensors.analog[2].offsetAdj == global.HE_Temp_offset M308 S2 U0 V0
In my case, daemon.g is executed every 10s. During this time, the hotend temperature may rise up to 40°C. But since the two curves are close enough over this range, this means the error is acceptable and will not trigger a heater fault.
While implementing a multilinear sensor would still be nice, this does work as a workaround - problem solved
-
-
@NeoDue are you saying that when you change the U and V parameters, you sometimes get 2000C spikes in the reading? That's not intended.
-
@dc42 yes, that is what happens. I guess about one M308 U... V... out of maybe 20...50 creates such a brief 2000° spike here when I run the 1st variant of the code posted above in daemon.g.
Not all of those show up in the temperature graph of DWC though, some only cause a short 2000°C display in the temperature display of the heater list in DWC. I guess that results from separate polling threads of DWC for those two.
-
@NeoDue please try the new firmware at https://www.dropbox.com/scl/fo/udf8q0i37gm0yxfy39pay/h?rlkey=k70l8wh3wbgk80mc07d7sce36&dl=0. Also make sure that you are only providing the S, U and V parameters in those M308 commands (as it the case in the code that you posted). If you also supply Y and P parameters then the sensor will get destroyed and recreated, which is likely to result in temperature spikes.
Edit: I just found the cause of that issue so I have updated that firmware at 14:22 UTC.
-
@dc42 I have been watching for half an hour now using the initial daemon.g code - no more 2000°C spikes with the new firmware!
Now that was a supersonic bugfix!
Thanks!