Customizable Temperature Tower Version 2

by quirxi, published

Customizable Temperature Tower Version 2 by quirxi Oct 30, 2017
7 Share
Download All Files

Thing Apps Enabled

Order This Printed View All Apps


Design Tools


Liked By

View All

Give a Shout Out

If you print this Thing and display it in public proudly give attribution by printing and displaying this tag.

Print Thing Tag

Thing Statistics

12778Views 2868Downloads Found in 3D Printing Tests


[2018-03-28] User i_has_it found out that the only thing to make it work with S3D is to adapt the layer change script like that:


[2018-01-25] Thanks to user groenewaldd's hints in the comments i have adapted the script to work for slic3r and Cura.

This is practically a remix of https://www.thingiverse.com/thing:2614204.
The difference is that it has an overhang on the right side with a pointy cone on top of it. This is supposed to show how exact your printer prints (and cools) small pointy details.
You also can change the direction of where the highest and the lowest temperature will print: on top or on the bottom of the tower.

Usage example in Slic3r:

1. Generate the tower with openscad:

$ openscad tempTower.scad 

Set the following variables in the openscad window to your liking:

// temperature of the first lowest block
start_temp = 220;
// temperature of the last highest block
end_temp = 185;
// change in temperature between successively printed blocks
temp_step = 5;

Render and export the model to .stl and close openscad.

2. Generate gcode with Slic3r:

  1. Open the .stl file in Slic3r.
  2. Set layer height to 0.2mm. If not, multiply the skip and block parameters by (0.2mm/new_layer_height).
  3. Add the following to:
    "Printer Settings" -> "Custom G-code" -> "Before layer change G-code":

    This makes it possible for the 'setLayerTemperatur.py' script to recognize the single layers.

  4. Set the initial temperature in the filament settings. The pedestal on which the temperature tower stands will be printed with this temperature.
  5. Save the .gcode file of the model.

Attention: maybe you will have to disable the 'Enable variable layer height feature:' checkbox in the printer settings in order to avoid messing up the temperature distribution over the tower height!

3. Write temperature settings to gcode file with setLayerTemperatur.py:

  1. On the commandline:

    $ ./setLayerTemperatur.py -h
    usage: setLayerTemperatur.py [-h] -s STARTTEMP -e ENDTEMP -t TEMPSTEP -f GCODEFILE
    Sets the proper temperatures to the corresponding layers of a gcode file
    exported from Slic3r. This allows the temperature tower to have different
    temperatures per block.
    optional arguments:
      -h, --help            show this help message and exit
    required arguments:
      -s STARTTEMP, --startTemp STARTTEMP
                            Temperature of the first (lowest) block.
      -e ENDTEMP, --endTemp ENDTEMP
                            Temperature of the last (highest) block.
      -t TEMPSTEP, --tempStep TEMPSTEP
                            Temperature change between successively printed
      -f GCODEFILE, --gcodeFile GCODEFILE
                            The .gcode file to process.
    $ ./setLayerTemperatur.py -s 240 -e 215 -t 5 -f tempTower_PETG_Black.gcode 
    startTemp: 240
    endTemp:   215
    tempStep:  5
    gcodeFile: "tempTower_PETG_Black.gcode"
    outFile: "OUT_tempTower_PETG_Black.gcode"
    step: -5
    -> M104 S240
    -> M104 S235
    -> M104 S230
    -> M104 S225
    -> M104 S220
    -> M104 S215
    By now the different temperatures should have been written to a new .gcode file that starts with "OUT_" and ends with the name of your old .gcode file. This file you can send to your printer and the tower should be printed out with the different temperature settings.

More from 3D Printing Tests

view more

All Apps

Auto-magically prepare your 3D models for 3D printing. A cloud based 3D models Preparing and Healing solution for 3D Printing, MakePrintable provides features for model repairing, wall thickness...

App Info Launch App

Kiri:Moto is an integrated cloud-based slicer and tool-path generator for 3D Printing, CAM / CNC and Laser cutting. *** 3D printing mode provides model slicing and GCode output using built-in...

App Info Launch App
KiriMoto Thing App

With 3D Slash, you can edit 3d models like a stonecutter. A unique interface: as fun as a building game! The perfect tool for non-designers and children to create in 3D.

App Info Launch App

Print through a distributed network of 3D printing enthusiasts from across the US, at a fraction of the cost of the competitors. We want to change the world for the better through technology, an...

App Info Launch App

Treatstock is an online platform that offers decentralized manufacturing services such as 3D printing and CNC machining for clients all over the world. We offer free and instant access to comparati...

App Info Launch App

3D print your favourite design with NinjaPrototype, a professional 3D manufacture with consistent quality and speed.

App Info Launch App

I needed to change the Openscad file to use the Arial Font as the Helvetica was having issues rendering the number 3.... But it it perfect! Thank you very much for your design!

Glad that you like it :)

To make this work with S3D, the layer change script should be like following:


Great looking out, this method worked for me also.

Thank you for that information!
Did you successfully try it out with this parameter ?
If it works I will put it in the description.

Yes, it works, S3D inserts proper layer numbers. Then I successfully prepared gcode with your script and printed the tower.
Thank you for your efforts!

Also thank you for for your effort! :)
I added it to the description, so that other users can benefit from your finding, too.

I was playing with this and built towers for temperature, flow %, and fan %. When I built the fan tower I changed start_temp to 100, end_temp to 0, and temp_step to -10. Everything worked, but having a 0 value for temp caused the text to not be shown on that level.

I made some minor tweaks to the attached file so I can get the "0" to show up.

Beyond that change, this has been great. Thanks for putting it together.

Hey - thank you for debugging it!
I have merged your version and a bug fixed (non-manifold vertices) into the newest version and put it online.

thanks for your effort ...

Comments deleted.

Can you copy and paste output of the "dir" command and the exact command line of setLayerTemperature.py and the error response ?
Its difficult for me to track down the error when I dont know what exactly is going on ...

Great Model. I print one right now :)
only thing i noticed is, that the tip of the cone is in the next temp range? i think the last 1mm is in the next range.

I noticed that too. I may try lowering the tip per Mystikal's suggestion.

Think you are right - thank you for your input!
Just wonder how I can make the cone lower without loosing its pointed shape ?

Line #83, change




I know what you mean.
I tried on line 83 with: "cylinder($fn = 20, h=block[Z]/2, r1=1, r2=0, center=false);"
For me the cone looks a bit small. Not sure if its still big enough for showing the properties of the material ?

Shouldn't it be the higher temperatures first? I have PLA that won't print below 200°C.

You can decide yourself if the temperature higher or lower temperature comes first. See the description on the Thing Detail page:
// temperature of the first lowest block
start_temp = 220;
// temperature of the last highest block
end_temp = 185;
// change in temperature between successively printed blocks
temp_step = 5;

I ran my first successful tower (using PETG) with temperatures descending on the way up because the filament wasn't bonding well enough at the lower temperatures. That right side pillar will come loose rather easily (and did in my first attempt) if the filament doesn't bond well.

but if it higher at first it might collapse

I have PLA that won't even print at 190. So in this case there will be no tower at all.

PLA Temperature Calibration Tower
by Cidaero

The point with this model is, that you can set any desired temperature in increasing or decreasing direction yourself.
So its up to you - you just have to follow the instructions in the "Thing Details" tab.

Yeah but doing that requires installing openscad and python. Some people like me don't like to install unnecessary things on their computer.

I ended up making my own.

did you add supports, for the bridge?

Adding supports defeats the purpose of the model. You want to see how well the filament bridges the gap.

I am not sure what you exactly mean? Can you explain it more detailed please?
If you mean the support settings in the slicer software then the answer is no.

Why not adding a layer height parameter so the tower can be tested against various layer heights. Material behave different on thinner layers. Would be a good improvement i think.
Someone managed it with S3D? Since s3d has only [current_Z_position] which reflects the Z in mm.

Thank you!

Maybe this would be a great idea. I am just travelling now, but i will have a look and see if it could work when i am back home at the end of February.

Great model. Thanks to lord_alan for pointing me to it.

Just an idea to easily make this compatible with both Slic3r and Cura:

Cura already includes comments on layer changes by default. If you update the Python script to rather match the built-in Cura format and update the code you're injecting into Slic3r to match then the same script will work for both slicers, i.e.

Update line 49 in setLayerTemperatur.py from:

layerList.append("; Layer " + str(currentLayerNr) + '\n')


layerList.append(";LAYER:" + str(currentLayerNr) + '\n')

The above will ensure the Python script works with Cura gcode out of the box without having to change anything in Cura itself.

Then to get the updated script to work with Slic3r, update the instructions to configure the "Before layer change G-code" to inject the following instead:


I first updated your script to pass in an argument to select which slicer to support but I soon abandoned the approach since the above would be even simpler for users to work with, i.e. Cura just works as-is and Slic3r requires the same amount of work as it does now.

Thanks for your input !
I just updated the setLayerTemperatur.py script according to your instructions.
Would be great if you could test it out and report back if it works for you on Cura.

Thanks! I can confirm I've tested your update and it works on Cura :)

Cool ! Thank you ! :)

That's a great suggestion!

I think your python script fails in python3 because the print statements are now functions... I think this might work but I don;t have python3 to hand...

except (IOError, OSError) as e:
print ("I/O error({0}) in "{1}": {2}", format(e.errno, e.filename, e.strerror))
except: #handle other exceptions such as attribute errors
print ("Unexpected error:", sys.exc_info()[0])

A few edits are needed to make this work under Python 3. I got it working with these changes:

Change line 13 to:
import argparse, sys

Lines 33 and 34 should be:
gcodeInput = open(args.gcodeFile, 'r', encoding="utf-8")
gcodeOutput = open(outFile, 'w', encoding="utf-8")

And add parentheses around the exception print statements at the end:
print("I/O error({0}) in "{1}": {2}".format(e.errno, e.filename, e.strerror))
print("Unexpected error:", sys.exc_info()[0])

I tried to follow your instructions but run into the problem that python 2.7 did not like the 'encoding="utf8"' parameter. So I had a look at the python 3 documentation at https://docs.python.org/3/tutorial/inputoutput.html#reading-and-writing-files and there it says that the original style should also work with python3. Are you sure the encoding is really needed in python3 ?
I have put the parentheses around the exception print statements as you suggested.
Thanks for your input !

Have you tried running it under Python3 without the encoding? It fails for me with:
"Unexpected error: <class 'UnicodeDecodeError'>"
My notes were to get it running under Python 3.6.3 in Windows: a minimal patch. Feel free to edit it to make it backwards-compatible if you'd like :)

I dont have windows 10 and Python 3.6 installed right now and just not enough spare time to test it. I hope I will have more time to try it out when I come back from holidays :P ....

Hello, I'm also having problem running the script.
I'm on Windows 10 running python 3.6.4, and whenever I'm executing the script it throws the following error:
File "setLayerTemperatur.py", line 72
print "I/O error({0}) in "{1}": {2}".format(e.errno, e.filename, e.strerror)
SyntaxError: invalid syntax

I'm really not a python-guy and would love some assistance. :)

Edit: I ran the script on a linux-box, and got it sorted out. :)

how do i do step 3. Write temperature settings to gcode file with setLayerTemperatur.py:

That's where im stuck at

Where exactly is the problem ? For me the example is quite clear - but maybe that only because i wrote it ? ;)

    $ ./setLayerTemperatur.py -s 240 -e 215 -t 5 -f tempTower_PETG_Black.gcode 
    startTemp: 240
    endTemp:   215
    tempStep:  5
    gcodeFile: "tempTower_PETG_Black.gcode"
    outFile: "OUT_tempTower_PETG_Black.gcode"
    step: -5
    -> M104 S240
    -> M104 S235
    -> M104 S230
    -> M104 S225
    -> M104 S220
    -> M104 S215

Hmm, not sure why this didn't work. I like the features of this tower. I customized the tower to start at 220 and finish at 175. I ran the python script and it appeared to run fine. However, the print started at 220 and then dropped to 200 after the first layer (this was a setting in Slc3r) and the temp never changed from there.... just remained at 200. Any suggestions? Thanks,

Can you give me a bit more information what you have done exactly? How did you call the script ? Probably you have used the original gcode file and not the generated gcode file that started with 'OUT_' ? When you open the generated gcode file you should see how the temperature changes at each 35th layer (from layer10 on) with the 'M104' command like this:

; Layer 10
M104 S190
; Layer 45
M104 S195
; Layer 80
M104 S200
; Layer 115
M104 S205
; Layer 150
M104 S210
; Layer 185
M104 S215
; Layer 220
M104 S220

for me, the .find() command didn't work running from bash in windows 10. Had to use:
if currentLayerStr != "" and ";LAYER:" in LINE != -1:

but even then, the OUT_ file has temperatures set at lines far high in the output file yet 90% of the remaining file seems printed without temperature.. was it meant to cut layers not required? I uncommented the debug print lines in your code.

startTemp: 195
endTemp: 215
tempStep: 5
gcodeFile: "tempTower.gcode"
outFile: "OUT_tempTower.gcode"
step: 5
currentTemp: 195
-> layerLine: ";LAYER:10
currentTemp: 200
-> layerLine: ";LAYER:45
currentTemp: 205
-> layerLine: ";LAYER:80
currentTemp: 210
-> layerLine: ";LAYER:115
currentTemp: 215
-> layerLine: ";LAYER:150
currentLayerStr: ";LAYER:10
-> M104 S195
currentLayerStr: ";LAYER:45
-> M104 S200
currentLayerStr: ";LAYER:80
-> M104 S205
currentLayerStr: ";LAYER:115
-> M104 S210
currentLayerStr: ";LAYER:150
-> M104 S215

I'm still seeing LAYER5 all the way to


I'll print one tonight. The gcode is ready, but I had to modify the python script because it was giving me an error about gcodeInput. Had to change "gcodeInput = open(args.gcodeFile, 'rw')" to "gcodeInput = open(args.gcodeFile, 'r')", seems like you can't have both r and w (using the latest python version on W10 if it helps).

I did the same - then worked like a charm in Win10. Is "w" really neccessary at all in the script in that argument?

No - it is not necessary. I already have removed the "w" flag from the latest version of the script as far as I can remember :)

Ah, thanks for that input. I never have tried it on Win10 - think that is why i dont have run into that bug. I will try it out on a computer running Win10.

I get an error of "line 73, in
NameError: name 'gcodeOutput' is not defined"

Running on a Mac, OS10.13.2. Python 2.7.4

I was able provoke this error when I tried to write the output file into a directory where I had no write permissions.
The output file could not be created and so the close() call failed.
Can you make sure that you have write permissions in your the output directory ?
Have updated the "setLayerTemperatur.py" script now so that it prints out a better error message. I would be grateful if you could test it out.

It looks like it is trying to create a directory at the root level of the drive for the output file? Now I get
I/O error(2) in "OUT_/Users/Barry/Desktop/temp_tower/245_205temptower.gcode": No such file or directory

How did you call the script ? Can you paste the command line in here ?
For me it looks like if you were using an absolute path to the gcode file, or if it were some OSX behaviour I do not know of.
If you were using an absolute path please try to put your gcode file into the current directory or cd into the directory where the gcode file is and use a relative path, ok ?

Well, getting closer. Here is what generated an OUT file:
python ../setLayerTemperatur.py -s 245 -e 205 -t 5 -f 245_205temptower.gcode
startTemp: 245
endTemp: 205
tempStep: 5
gcodeFile: "245_205temptower.gcode"
outFile: "OUT_245_205temptower.gcode"
step: -5

File was generated in the same directory as the original gcode file.
BUT, the OUT file has no M104 commands other than the start (245) and end (0) settings. No layers.

Can you see lines that start with "; Layer" in your original gcode file ?

Did you add the following settings to slicer:

"Printer Settings" -> "Custom G-code" -> "Before layer change G-code":

; Layer [layer_num]


This makes it possible for the 'setLayerTemperatur.py' script to recognize the single layers.

If yes - then could me send your gcode file so that I can debug it ?

Stupid me. I have been messing with things so much that I changed to a different printer setting that didn't have that code in it. Looks like it is working now. Thanks for the quick support!

I'll give it a shot!

I also get the same error running python 3.6.4

Comments deleted.

Glad that you like it and thanks for posting the results :)

Judging from your pictures i also would say that 195° C looks best. How is the layer adhesion at this temperature ?
I also have tried out PETG and it looked better at lower temperature but I tended to use it a bit hotter because I was worried about reduced layer adhesion at that low temperatures.

P.S.: did you notice that: https://www.thingiverse.com/thing:2525886 already ? ;)

Chili Oil Pourer
by quirxi

Sorry - I never saw your reply until now. That chilli oil pourer looks great! I am mad crazy into chillis - grow about 50 plants a year :-)

I did a test print with this yesterday to test some PETG (Real Filament brand) I had printing with for a while. The results surprised me in that I had been printing way too hot.

Thanks by the way - It's a nicely designed tool and I love OpenSCAD :-)