Those following this blog will know that I have had some issues with my printer reporting incorrect temperatures. As mentioned in my last post I tried a different thermistor (also EPCOS, so similar Beta value) with no improvement.
Today I decided to sort it out. Instead of going the normal route and measuring the resistance at different temperatures and then feeding this into the formula mentioned on the Wiki, I took a number of readings at 5 degree intervals. Noting both the the Printrun declared value and the multimeter value.
The thermocouple probe on my multimeter is slightly under 3mm diameter so I stuck it down the HotEnd and measured the internal temperature. I figured that this way I'll be reporting the actual temperature inside even if the temperature at the thermistor is slightly different. (I think nophead did something similar ages ago, but I couldn't find the post in a hurry - but this makes me feel I'm in good company).
For the heated bed I stuck the thermocouple to the bed with some Kapton tape.
When I had completed the above readings I plugged them into a spreadsheet. I then compared these values to tables supplied with Sprinter and the ones on the Wiki. none matched up exactly, but then again I wasn't measuring that accurately or at the actual thermistor.
I had also previously read this article on the Brokentoaster blog which suggested that we should have thermistor tables which, rather than being spread evenly across the ADC range, are focussed on the temperature ranges that we care about. This makes a lot of sense to me, as having finer resolution near our target temperatures should hopefully help with keeping the temperature stable (irrespective of the mechanism employed by the firmware). I also noted that the number of entries in the tables varied considerably for the different thermistors.
So, I played around with the createTemperatureLookup.py script original created by nophead and provided with Sprinter, and together with my spreadsheet I ended up creating new tables which have more entries and are focussed on the temperature ranges I care about for the thermistor in question. The resulting two tables (in Sprinter "thermistortables.h" format) are:
EDIT: It would appear these changes don't work. I'll report back in a new post when I have figured it out.
const short temptable_8[NUMTEMPS_8][2] = {
{1, 864},
{190, 175},
{379, 132},
{393, 130},
{407, 127},
{421, 125},
{435, 123},
{449, 121},
{463, 119},
{477, 117},
{491, 115},
{505, 113},
{519, 110},
{533, 109},
{547, 107},
{561, 105},
{575, 103},
{589, 101},
{603, 99},
{617, 97},
{631, 95},
{645, 93},
{659, 91},
{673, 89},
{687, 87},
{701, 85},
{715, 83},
{729, 81},
{743, 79},
{757, 77},
{771, 74},
{785, 72},
{799, 70},
{813, 68},
{827, 65},
{841, 63},
{855, 60},
{869, 57},
{883, 54},
{897, 51},
{911, 48},
{925, 44},
{939, 40},
{953, 35},
{967, 30},
{974, 26},
{995, 14},
{1016, -9}
};
#endif
#if (THERMISTORHEATER == 9) || (THERMISTORBED == 9) // CRK - ParCan Tweaked for hot end range and based on actual readings
#define NUMTEMPS_9 48
const short temptable_9[NUMTEMPS_9][2] = {
{1, 608},
{13, 312},
{25, 265},
{33, 248},
{41, 234},
{49, 224},
{57, 215},
{65, 208},
{73, 202},
{81, 196},
{89, 191},
{97, 187},
{105, 182},
{113, 179},
{121, 175},
{129, 172},
{137, 169},
{145, 166},
{153, 163},
{161, 161},
{169, 158},
{177, 156},
{185, 154},
{193, 152},
{201, 150},
{209, 148},
{217, 146},
{233, 143},
{241, 141},
{249, 139},
{257, 138},
{265, 136},
{273, 135},
{281, 133},
{289, 132},
{297, 130},
{305, 129},
{313, 128},
{321, 126},
{329, 125},
{337, 124},
{345, 123},
{353, 121},
{361, 120},
{369, 119},
{693, 79},
{1017, -8},
{1021, -21}
};
#endif
I will see how these values work out for now and report back if they aren't working.
OK, I figured it out (with a little help from the "#define DEBUG_HEAT_MGMT" debug flag in "configuration.h". Seems I was a little too gung-ho on editing out the values at the lower temperature ranges. I've changed the spread a little and have uploaded the following tables which so far are showing readings which compare favourably with my multi-meter.
#if (THERMISTORHEATER == 8) || (THERMISTORBED == 8) // CRK - EPCOS 100K Tweaked for bed range and based on actual readings
#define NUMTEMPS_8 51
const short temptable_8[NUMTEMPS_8][2] = {
{1, 864},
{78, 232},
{155, 187},
{232, 163},
{309, 145},
{386, 131},
{393, 130},
{407, 127},
{421, 125},
{435, 123},
{449, 121},
{463, 119},
{477, 117},
{491, 115},
{505, 113},
{519, 110},
{533, 109},
{547, 107},
{561, 105},
{575, 103},
{589, 101},
{603, 99},
{617, 97},
{631, 95},
{645, 93},
{659, 91},
{673, 89},
{687, 87},
{701, 85},
{715, 83},
{729, 81},
{743, 79},
{757, 77},
{771, 74},
{785, 72},
{799, 70},
{813, 68},
{827, 65},
{841, 63},
{855, 60},
{869, 57},
{883, 54},
{897, 51},
{911, 48},
{925, 44},
{939, 40},
{953, 35},
{967, 30},
{974, 26},
{995, 14},
{1016, -9}
};
#endif
#if (THERMISTORHEATER == 9) || (THERMISTORBED == 9) // CRK - ParCan Tweaked for hot end range and based on actual readings
#define NUMTEMPS_9 41
const short temptable_9[NUMTEMPS_9][2] = {
{1, 608},
{13, 312},
{25, 265},
{33, 248},
{41, 234},
{49, 224},
{57, 215},
{65, 208},
{73, 202},
{81, 196},
{89, 191},
{97, 187},
{105, 182},
{113, 179},
{121, 175},
{129, 172},
{137, 169},
{145, 166},
{153, 163},
{161, 161},
{169, 158},
{177, 156},
{185, 154},
{193, 152},
{201, 150},
{205, 149},
{261, 137},
{317, 127},
{373, 118},
{429, 111},
{485, 104},
{541, 97},
{597, 90},
{653, 83},
{709, 77},
{765, 69},
{821, 61},
{877, 52},
{933, 40},
{989, 19},
{1021, -21}
};
#endif
BTW: If you plan to do something similar, you also have to edit the if statements elsewhere in the thermistortables.h file.
More bed levelling
Since coming back from a week away I have not been able to get anything to print properly, so I figured I need to go back to basics, as I knew I had taken things apart and then not re-calibrated.
Due to the hassle with levelling the 4 corners of the bed each time (each corner affecting the other 3), I decided to convert my bed into having 3 mounting points. This will work if you have a firm bed. (I use a piece of Dibond, so I qualify). I made up a new plate which I have fixed to the rear y-axis bearing carriers. This extends past the back of the bed (over the y-axis motor) and has a bolt in the center. The bed (which is also over long) has a corresponding hole in the middle.
Bed levelling should now simply be a function of levelling the front left-to-right. The ideal place to do this is in line with the front mounting points, as then the lever effect of the rear adjustment doesn't come into play (mine is at y=37.5mm). Once you have the front sorted, then move the extruder to the rear centre (y=max, x=xmax/2=>85 for me). The way I have made it, I can home the z-axis at this position and then simply adjust the single nut until I get to zero on the z-axis.
I also fitted a z-axis end-stop adjuster. This is fantastic, as it allows you to level you bed to dead-zero and then tweak the z-height later if you need to raise or lower it slightly. I have included pictures of these changes. The z-endstop adjuster is a bit of a bodge, but I was using whatever bits I could lay my hands on while trying to doing it quickly and without a printer (obviously).
At the same time I fitted the new end-stop holders that I printed. The quality of the printing is shocking so they will need to be re-done, but they work (although are de-laminating). As mentioned before, the x & z ones are from thingiverse. I created a derivative of this for the y-axis, but haven't uploaded it yet, as I want to prove it works correctly first.
Thanks for the article, looking at some similar problems with my ptc read-out table.
ReplyDeleteDo you use the steinhart equation or the B-value equation to calculate the lookup tables? (couldn't find the script you were talking about)
steinhart would probably make the most sense as you are creating a table anyway right?
http://www.resistorguide.com/ntc-thermistor/
Joe,
DeleteThanks for commenting. The script is reference on the Thermistor page of RepRap.org (http://reprap.org/wiki/Thermistor) - search for "this Python Script", direct link: (http://reprap.svn.sourceforge.net/viewvc/reprap/trunk/reprap/firmware/Arduino/utilities/createTemperatureLookup.py?view=markup&pathrev=3448). The script was originally written by Nophead.
To be honest I didn't get into the actually maths of it myself, I ended up taking the experimental route as described above.
Thanks for the great article.
ReplyDeleteThermistors are temperature-sensing elements made of semiconductor material that has been sintered in order to display large changes in resistance in proportion to small changes in temperature. This resistance can be measured by using a small and measured direct current, or dc, passed through the thermistor in order to measure the voltage drop produced. Thermistors are an incredibly accurate category of temperature sensors.http://www.resistorguide.com/ntc-thermistor/