tag:blogger.com,1999:blog-36154787728152902002024-03-11T04:23:31.514+01:003D printer improvementsFrom the community for the community, mostly via heavily customized toolsJeremie Francoishttp://www.blogger.com/profile/02984201174566394892noreply@blogger.comBlogger80125tag:blogger.com,1999:blog-3615478772815290200.post-11212757026587012912017-05-07T05:28:00.001+02:002018-05-24T20:17:24.239+02:00Replacing LinuxCNC with a Smoothieboard for CNC milling. Not as easy as for 3D printing!<div dir="ltr" style="text-align: left;" trbidi="on">
I was running <a href="http://linuxcnc.org/">LinuxCNC</a> for the last years and I wanted a smaller setup, with room for improvement. Since I had a Smoothieboard around, which is a very capable 32 bit ARM controller for 3D printers, I thought it would be a good idea to give it a try.<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhToWMUs99iCirdnfbtO6dTmCA0eH1I7Ip6T65fvzn5tOpEYqIAxMZyuFCSBdtplPi8ldjYYyly25DYHR1YApZBWLcHt6x5dGgtJhvgtT8Fmt-5pSlbDFzmF4me-rf8eqYFrmMK6ugFrEl5/s1600/linuxcnc_vs_smoothieboard_cnc_milling.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="438" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhToWMUs99iCirdnfbtO6dTmCA0eH1I7Ip6T65fvzn5tOpEYqIAxMZyuFCSBdtplPi8ldjYYyly25DYHR1YApZBWLcHt6x5dGgtJhvgtT8Fmt-5pSlbDFzmF4me-rf8eqYFrmMK6ugFrEl5/s640/linuxcnc_vs_smoothieboard_cnc_milling.jpg" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">A bulky, obsolete but usual milling setup with a PC running LinuxCNC (a <a href="http://wiki.linuxcnc.org/cgi-bin/wiki.pl?Hardware_Requirements">parallel-port is required</a>),<br />
versus a Pipo X8 which is interfaced to a Smoothieboard (hidden in the CNC driving box itself).</td></tr>
</tbody></table>
But the move is not a piece of cake when you expect a drop-in replacement. In fact, I must admit this board is somehow hostile <i>as a firmware for <a href="https://en.wikipedia.org/wiki/Milling_(machining)">milling</a></i> in its current status (Smoothieware), even though the hardware is fully capable (Smoothieboard). In this post, I wanted to share my experience so far. Sure I could have asked for help (and yes, I did <a href="https://en.wikipedia.org/wiki/RTFM">RTFM</a> eventually). But it takes time, it will not solve the issues below and I think most people would have done like me: just try, then investigate.<br />
<br />
<div>
With time, I think it may be sorted out, probably with help from others if they are welcomed (and hopefully without breaking more mill bits). But my expectation here was to benefit from Smoothie as much as one can benefit from it for 3D printers. Even though my current overall hardware setup is much convenient and lighter, the milling process ends up requiring more manual and careful operations than before. More annoyingly, I would end up having to tweak and modify an existing <a href="https://en.wikipedia.org/wiki/Computer-aided_manufacturing">CAM tool</a> just to handle the specific "milling behaviors" of this board. I would think that the reciprocal would benefit everybody though.</div>
<br />
<a name='more'></a><br />
Smoothieware is a firmware that runs on Smoothieboards and a few other 32 bit ARM controllers, like the Azteeg X5 Mini or the Cohesion3D ReMix. It is modern and it is an <a href="http://smoothieware.org/from-marlin">easy upgrade</a> for 3D printers that still run on outdated <a href="http://www.tridimake.com/2015/05/github-kills-marlin-which-branch-to.html">Marlin dead-ends</a>. It is extremely easy to setup compared to the latter: for example, you simply change one value in a text file from your explorer to tell that your printer is a delta!<br />
<br />
But the board and the firmware are also known for driving other types of CNC machines.<br />
<h2 style="text-align: left;">
Why drop LinuxCNC in the first place?</h2>
LinuxCNC is a very capable piece of software for driving a milling machine, including very professional ones. Actually, it comes with a special Linux operating system, and as such, it is not just an application that you can install on your usual computer.<br />
<br />
Moreover, the PC that runs LinuxCNC needs to have a parallel port. Yes. The kind of plug that no printer uses anymore anywhere.<br />
<br />
Why? LinuxCNC handles everything, including the precise timing of the electric pulses for the stepper motors, that are precisely what the controller boards like RAMPS or Smoothieboards handle for 3D printers.<br />
<br />
In fact, parallel port interfaces are the only <a href="https://courses.engr.illinois.edu/ece390/resources/parallel.html">"real time" ports</a> that exist on regular PC, unless you buy expensive special hardware cards. If you try to drive stepper motors with other interfaces you will get timing issues, because they have some buffering and delays that introduce jitter in the signals (which in turns means shaking, vibrations, poor movement).<br />
<br />
So my existing problem was I had to use an old, heavy and specific PC with a parallel port just for milling. All the laptops I could try did not have a proper "real-time ready" parallel port either.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh7DSok4-TMgbTKd0TE3iPkA5sEwjq0MarbWvqAxjmwxV7XVjbeD93AyE6aQQKs38gcfan5UqfNUZ8K00lkP1blbU_jMGGWI4JQjAQbShcWUmYKJ0m5CT7I2MmTshWodEVRLp9ZK-qcbMNU/s1600/smoothieboard_in_cnc_driver.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="396" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh7DSok4-TMgbTKd0TE3iPkA5sEwjq0MarbWvqAxjmwxV7XVjbeD93AyE6aQQKs38gcfan5UqfNUZ8K00lkP1blbU_jMGGWI4JQjAQbShcWUmYKJ0m5CT7I2MmTshWodEVRLp9ZK-qcbMNU/s640/smoothieboard_in_cnc_driver.jpg" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">A smoothieboard added within the stepper controller which came with my CNC.<br />
It is plugged directly onto the various driving and probing signals, and it does<br />
all the timings properly. This way I can get rid of the former, bulky, obsolete desktop PC.<br />
BTW, I found a use for a <a href="http://www.oz4.us/2017/03/recycling-cd-cases-cnc-mill-electronics.html">CD-Rom case</a>!</td></tr>
</tbody></table>
As shown above, a Smoothieboard is small enough to fit in the case of my existing stepper driver controller, so I thought it would be a very compact solution.<br />
<br />
I also wanted some hardware options to hack around the CNC: sensors, <a href="https://goo.gl/photos/2MGi1avCAxeK9gw17">automatic tool changers</a> and so. In this respect, all the signals on the parallel port of the PC were already used, so I was in a dead end anyway.<br />
<br />
<br />
<h2 style="text-align: left;">
Stand-alone vs. interfaced controller?</h2>
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; text-align: right;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_2cB8sIHyHfas-VsjF0W2ACafk2LoqtM6_7qJNoGt5Djd-tXYl7IeBUdUR_gsnPYh34GJq0dmfNq-v0YQsaP089vWhB_vmN6mkl06ZKvHL8-nSbvk964g08nlooG2QYvJcZ7_Uwm7ZEIC/s1600/smoothie-web.png" imageanchor="1" style="clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_2cB8sIHyHfas-VsjF0W2ACafk2LoqtM6_7qJNoGt5Djd-tXYl7IeBUdUR_gsnPYh34GJq0dmfNq-v0YQsaP089vWhB_vmN6mkl06ZKvHL8-nSbvk964g08nlooG2QYvJcZ7_Uwm7ZEIC/s400/smoothie-web.png" width="147" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Smoothie web interface:<br />
certainly not for milling!</td></tr>
</tbody></table>
Smoothie comes with an embedded webserver, so as to be able to work untethered. But it never was an option to me, even for 3D printing: it sounds like I would be trying to control a caterpillar with a primitive gamepad (and without a screen -- unless you buy a really expensive one). Working blindly may be enough for a 3D printer, where you often simply upload a g-code file and leave it alone (which is a very reliable practice at least).<br />
<br />
So far, the LCD and rotary encoders that come with Marlin are just so efficient to fine tune and learn about the impact of tiny changes in the printing process.<br />
<br />
But milling jobs are way more complex to handle. The user often needs to check, calibrate and prepare the work, set axes and references. And doing so require a real interface. In this regards, even touchscreens are barely usable in my opinion.<br />
<br />
So I connected to the Smoothieboard via USB -- this is the blue cable in the first picture of this post, and I drive it from a full-featured CNC software.<br />
<br />
Yes, even though I really do not like unreliable USB links and I always 3D-print via my printer LCD interfaces and an SD card. But I hate even more Ethernet cables across my house, which is the other, more reliable and recommended option. Huh.<br />
<br />
<br />
<br />
<div>
<h2>
Which software to prepare and to control milling jobs?</h2>
</div>
<div>
There <a href="http://smoothieware.org/software">are many well made software</a> to run a milling machine. Actually, LinuxCNC would be a good one, or Mach3 on Windows. But they both want to handle the raw stepper signals also by themselves... hence the requirement for a parallel port. Huh. No way, we are in 2017!</div>
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhVm67YOKjaoMvnClYIvfWtPUTZGQAQ5gb2CP_XOtMj_fSg6EoJjtTIhmaXCbaXl_Baa5u6A_GRy7sf-Vm0B3u7c63ao2nX-qpZjh4cx_0L2xxwy9pk4eQ82CInq9jnjFVm2veSJq3RgjKr/s1600/chilipeppr.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="232" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhVm67YOKjaoMvnClYIvfWtPUTZGQAQ5gb2CP_XOtMj_fSg6EoJjtTIhmaXCbaXl_Baa5u6A_GRy7sf-Vm0B3u7c63ao2nX-qpZjh4cx_0L2xxwy9pk4eQ82CInq9jnjFVm2veSJq3RgjKr/s320/chilipeppr.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Chilipeppr is a web application to drive the CNC milling machine.<br />
It has an amazing list of features.</td></tr>
</tbody></table>
<br />
<a href="http://chilipeppr.com/">Chilipeppr</a> is an impressive CAM tool which runs... in your web browser! It even includes a very nice g-code debugging toolset! There are a few drawbacks though: it cannot be installed offline as it downloads every component from the internet at each start (so it will fail when the network is down!). It also was made initially for <a href="https://synthetos.myshopify.com/products/tinyg">TinyG</a> and GRBL, though it says it supports Smoothieware. Now, frankly, I could not have it talk correctly with my board even when it is configured in GRBL compatibility mode (which I suspect it does not very well, see below).<br />
<br />
Other web-based applications like <a href="https://cnc.js.org/">cncjs</a> or <a href="http://cncpro.co/">LaserWeb</a> are promising and very active, but I was not able to install it on the little "Pipo X8" running Windows 10 which I bought for the interface, and that I naively thought I could <a href="https://wiki.debian.org/InstallingDebianOn/PIPO/PIPO%20X8">upgrade it to Linux easily</a>. I think it boiled down to the many inter-dependencies, tons of ugly node.js stuff and my incompatibility with Windows in the first place. My bad, but I do not want to run a malware-ready OS anyhow soon :)<br />
<br />
Web-based CAM tools also rely on a small bridge for the link between the browser and the controlling board. It adds one too many software layer for me to feel safe: for reliable work, I like to reduce the stuff that gets in my (tool)path. But they are pretty, and LaserWeb was proven more than once to work <a href="https://plus.google.com/u/0/communities/115879488566665599508">very well with laser cutter</a>s and at high speed (with some initial issues with... Smoothieware!)<br />
<br />
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgnlEWevsIH-_uum6zpUJ8xfKMiSPqZxlSUNcwT3SrjwNWTVrHBEQFp42fXhRl1ho6D_K8V_PZn5o6C2xi54T1ds0e29HeOjF4vDWMiCpRFONje5vzLPyt2J0r-BBBK0nnMLqlYh07eu33a/s1600/bCNC.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="236" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgnlEWevsIH-_uum6zpUJ8xfKMiSPqZxlSUNcwT3SrjwNWTVrHBEQFp42fXhRl1ho6D_K8V_PZn5o6C2xi54T1ds0e29HeOjF4vDWMiCpRFONje5vzLPyt2J0r-BBBK0nnMLqlYh07eu33a/s320/bCNC.png" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><a href="https://github.com/vlachoudis/bCNC">bCNC</a> is a really nice piece of software to prepare, control<br />
and feed g-code to a CNC mill, e.g. for PCB milling.<br />
It even runs on a Raspberry Pi!</td></tr>
</tbody></table>
<br />
Eventually, I settled on a very nice CAM software named <a href="https://github.com/vlachoudis/bCNC">bCNC</a>.<br />
<br />
It is written in Python and it is small, well written, and very readable (read: hackable a lot!). The interface makes sense and it does not require megabytes of javascript and a huge browser to run either (as such, it will run fine on a Raspberry Pi for example).<br />
<br />
It really has many and nice features, including options that are not always present like leveling, i.e. probing at multiple points to interpolate and compensate the surface to mill (many 3D printer controllers have this also).<br />
<br />
bCNC is a really good choice, and even Smoothieware promote it. But let us see the issues now...<br />
<h2 style="text-align: left;">
Unexpected issues with Smoothieware for milling</h2>
OK, the hardware is fine. And the software is installed and running.<br />
<br />
Smoothieware configuration file has a promising "<a href="http://smoothieware.org/grbl-mode">grbl_mode true</a>" switch. To be honest, I am not completely sure what it does or does not. All the CAM "feeding" tools I tried (gcode senders) had specific issues with the board even with this mode. I read it was related to syntax and feedback information from the board to the controlling software, but it falls short in my opinion. <u>Update</u>: it might well better be called "<a href="https://plus.google.com/+ArthurWolf/posts/Berjz3VMnVQ">CNC mode</a>", as in the word of one of the author! This would explain that.<br />
<br />
So here are the main issues I need to solve to get me running at least as well as before with LinuxCNC.<br />
<h3 style="text-align: left;">
1a) Smoothieware has no "feed hold" M0 command? I cannot believe it!</h3>
This is a critical issue. It does not seem to support the very common and important <a href="http://smoothieware.org/supported-g-codes">M0 / feed hold</a> gcode command (vs. e.g. <a href="https://github.com/grbl/grbl/wiki">GRBL</a>). This is a <i>programmed pause</i>. It is just compulsory for manual operations, just like when you would switch filaments or need to clean the workspace or adjust something during the operation.<br />
<br />
This is critical for changing tools though!<br />
<div>
<br /></div>
For example, in bCNC like many other, a tool change is a procedure that embeds multiple gcode statements, and which embeds a fundamental M0 for pausing, so as to let the user actually change the end mill manually before resuming.<br />
<br />
Ignoring the pause will keep the existing tool and often ruin the job. On a 3D printer this may not be too dangerous, but on a mill it often break things. So, in this case, two separate blocks may be required and the second is sent only after the first one is "finished" (to be tested by the software). The second (i.e. resuming after the tool change) shall not be queued before the first one is done.<br />
<br />
I hope it is a temporary point of view, but the firmware developers keep on telling that it is the job of the feeding application. In the case of bCNC, it means deep and specific changes due to the way blocks of gcode are often prepared as a whole, and then sent for the driver to process them... Do they really ask that each and every software adjust to this <i>lack of</i> command?<br />
<h3 style="text-align: left;">
1b) Smoothieware has no user "pause"?</h3>
<div>
The board does not pause the movement either when you ask for it yourself during the milling job. It is probably harder to implement such unexpected pauses within the path planner component in Smoothieware, but we may not expect a fix anyhow early: "<a href="https://github.com/cncjs/cncjs/issues/94">If you want to pause you should simply stop sending gcode to smoothie</a>" -- er, what?!). </div>
<div>
<br /></div>
<div>
In any case, all commands that were already sent will be processed before you have a chance to stop something (non-standard codes like <a href="http://smoothieware.org/switch#stopping-smoothie">M600</a> still empty the queued commands before acting). E.g. the spindle will keep on moving even though you know you are going to hit a clamp... unless you cancel the whole job with the emergency red button! No chance you can pause, move the clamp away and resume. The results are more broken end mills or parts.</div>
<br />
Reciprocally, GRBL has a few explicit, certainly non-standard and weird commands like "!" (feed hold) and "~" (cycle start/resume). But these are welcomed addition, if not vital in some case. Version 1.1 even lets you pause in the middle of a movement, which is really great and saves a lot of time and mill bits. This really would be cool if it was enforced in Smoothie in GRBL compatibility mode as it is part of the expectations in my opinion.<br />
<h3 style="text-align: left;">
2) The super sticky alarm state</h3>
This is a very annoying, possibly major issue but I am still unsure where the problem is. For example, it occurs when a probing ends before making contact, and in other unexpected cases. This is a good behavior... but the user should be able to resume work after he has fixed the problem!<br />
<br />
In my case and so far, I found no other way than to reset the serial link, or even power-cycle the board (which most often ruins the current job).<br />
<br />
I want to be clear on this issue: the issue may be with bCNC, but since I found no one complaining with other firmware, and since bCNC driving GRBL does NOT have the issue, I think smoothieware does something one way or another, because of some specificity. Even Control-X (i.e. reset asked from software) will not reset the board either, neither does $X or M999 (<a href="https://github.com/LaserWeb/LaserWeb3/issues/176">specific</a>?). The communication is plain dead.<br />
<h3 style="text-align: left;">
3) The communications hang during mesh leveling (wait states)</h3>
It took me some time to figure it out, but the job was hanging during mesh leveling (probing multiple points to compensate for a non-level surface to mill). I had to add some %wait statements in bCNC for it to work (GRBL does not seem to require this). I submitted <a href="https://github.com/MoonCactus/bCNC/commit/ba5d4032f1a65fa32a9cdabd7e672c3862f64aac">this fix to bCNC</a> since it should not impact other firmware, it does not change a lot of code, and it may help other people. <u>Update</u>: see below the comments from the main developer regarding G0 and <a href="https://github.com/vlachoudis/bCNC/issues/143#issuecomment-300642937">this answer</a> by the author of GRBL himself.<br />
<br />
I know there is also a leveling procedure that comes bundled with the Smoothieware firmware, but I want to avoid investing in redundant knowledge, or board-specific behaviors or features. I also feel like I could contribute and be more productive for bCNC than for smoothieware: the mesh leveling in bCNC is certainly easier to modify and enrich in Python compared to modifying a C++ firmware to compile and upload on a constrained microcontroller! But board-specific changes in bCNC are anyhow to be avoided (e.g. to configure this embedded bed leveling specifically).<br />
<h3 style="text-align: left;">
4) Rapid G0 moves are sometimes slow</h3>
Smoothieware <a href="http://www.linuxcnc.org/docs/2.5/html/gcode/gcode.html#sec:G0">G0 "rapid moves"</a> are not necessarily rapid... they either rely on their own setting, or on some F speed that can be altered by other gcodes (may be other "linear (slow) moves" or probing). The common and ubiquitous interpretation is that G0 is fixed and shall use the maximum machine speeds. Sure, the g-code "norm" is a bit fuzzy, and furthermore when the 3D printing RepRap implementation introduced yet another variant to the <a href="https://en.wikipedia.org/wiki/G-code">NIST specifications</a>. But as CNC milling is concerned though, there is a better-defined set of behaviors, and G0 is well known.<br />
<br />
If you need details, the problem seems to be that G0 movement may be impacted by previous G1 g-code (<u>update</u>: it could have been only due to probing with G38.2, i.e. <a href="https://github.com/vlachoudis/bCNC/issues/143#issuecomment-300606047">a bug that was fixed</a> in between). It means/meant that jogging around may suddenly drop to 25mm/s because of a preliminary probing (which ought to be done very slowly). Since the possibly long jog move cannot be interrupted, be prepared to lose some time moving your spindle around like a turtle, unless you re-specify F for your G0 move.<br />
<br />
So far, the feedrate value had to be set again in the interface of bCNC each time, but it is too easy to forget. Moreover, it is very annoying with bCNC mesh leveling, as the "rapid moves" become as slow as the probing moves (fixed with point 3 above).<br />
<br />
<u>Update</u>: the main developer of Smoothieware <a href="https://github.com/vlachoudis/bCNC/issues/143#issuecomment-300094040">harshly disagrees on the issue</a>. He stands on his ground here and he states instead that GRBL and all others are wrong (but, imho, why then add a "GRBL compatibility mode"?). Put it short: in his opinion, all controlling software shall comply with their own interpretation.<br />
<br />
All in all, most of it boils down to how g-code is normalized, and also that Smoothie originally is a 3D printer firmware. Note also that this specific issue with G0 might be "fixable" with the <a href="http://smoothieware.org/g0">default_seek_rate</a> in the configuration of Smoothie, and that there was a bug in probing (it used G0 in the background and corrupted its value -- something that makes no sense in the usual interpretation). Set the default seek rate to your maximum machine speed and you will probably get a more compatible mode (but better set it to the slowest axis as it can still overshoot the value when moving on multiple axes at the same time -- another weird "feature").<br />
<h3 style="text-align: left;">
5) Spindle control</h3>
I was not able to control my spindle but I think I misconfigured something as many other <a href="https://github.com/Smoothieware/Smoothieware/issues/1103">could fix it</a> (M3+speed then M5). Handling the spindle manually as I was recommended initially is a no-go: it is both annoying and risky (I broke some more end mills).<br />
<h2 style="text-align: left;">
Is Smoothie actually ready for milling?</h2>
I certainly do not want to sound harsh: Smoothieware is a brilliant piece of software engineering, and it is open source, free to use. Anyone can contribute to it (or try to...). It really shines for 3D printing, and the documentation is outstanding. Many of you know I really liked and promoted it for 3D printing during the last years.<br />
<br />
But I feel like some important fixes need to be done before it becomes as friendly for CNC milling.<br />
<br />
I really did not expect these behaviors (or lack of), hence this post. If I had known beforehand, I would probably have used another board. Now, I cannot even simply wait and see because of the broken tool change procedure. But I feel like I switched too early in order to stay as productive at least as before.<br />
<h2 style="text-align: left;">
...when a dirt cheap Arduino Nano and a DB25 work enough?</h2>
I ended up checking the lastest GRBL first hand, with the highly skilled job you can see below: wiring a Arduino Nano directly to a DB25, which plugs into the existing stepper controller...<br />
<br />
Note: I need to give <a href="http://www.machinekit.io/">MachineKit</a> a try, based on a BeagleBone Black and a <a href="http://blog.machinekit.io/p/hardware-capes.html#Replicape">Replicape</a> shield (together they make a marvelous setup, and it brings a full-featured Linux to the deal).<br />
<br />
Back to GRBL on a dump Arduino Nano... I must admit they work for 3 axes to the point I cannot tell the difference with Smoothie or LinuxCNC.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjCjXYeBmKdBvvMTlZp1C5AJ50xebAUgcDHuZSw1-HrZjmOano-dPnXV4Syd2UkJ-BCinAZHb3wsw2ava4uVnnRzCY2DLIClSJQB-B1RymdhkSXYmj0z9ig3IV2WeNx6_zpqWEojluFzx33/s1600/GRBL_Arduino_Nano_DB25_CNC_1.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="360" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjCjXYeBmKdBvvMTlZp1C5AJ50xebAUgcDHuZSw1-HrZjmOano-dPnXV4Syd2UkJ-BCinAZHb3wsw2ava4uVnnRzCY2DLIClSJQB-B1RymdhkSXYmj0z9ig3IV2WeNx6_zpqWEojluFzx33/s640/GRBL_Arduino_Nano_DB25_CNC_1.jpg" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">A quick and dirty hack with an Arduino Nano, which runs <a href="http://www.instructables.com/id/GRBL-Pinout-Arduino-Nano-v30/">GRBL v1.1</a> (fully supported by bCNC).<br />
<span style="font-size: 12.8px;">When you already have the stepper drivers as here,</span> a $5 setup like this works so well<br />
that using a $100 Smoothieboard i<span style="font-size: 12.8px;">s kind of silly </span><span style="font-size: 12.8px;">for a CNC.</span></td></tr>
</tbody></table>
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; margin-left: 1em; text-align: right;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEizUT2C50CKvVgxL3HbzLd1iGEeSO74oeA0Lj5DKyH35hW-6ss10iBA0lmAoaq0FHRyOblvIoISyON6BFP4eoiomMSjfeOYWs-c1enS-wq2hPjhezRaC26XkqgBj874lj45J772oOogXMdh/s1600/3axis_grbl_nano_controller.jpg" imageanchor="1" style="clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" height="266" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEizUT2C50CKvVgxL3HbzLd1iGEeSO74oeA0Lj5DKyH35hW-6ss10iBA0lmAoaq0FHRyOblvIoISyON6BFP4eoiomMSjfeOYWs-c1enS-wq2hPjhezRaC26XkqgBj874lj45J772oOogXMdh/s320/3axis_grbl_nano_controller.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">This $30 GRBL all-in-one 3 axis controller will drive<br />
engravers and laser cutters. But you can get a much powerful<br />
setup at the same price with three <a href="https://www.banggood.com/TB6560-3A-CNC-Router-1-Axis-Driver-Board-Stepper-Motor-Drivers-p-921604.html?p=K70703705469201408A3">TB6560 3A drivers</a>.</td></tr>
</tbody></table>
I did not expect it, because I remember two years ago the impressive improvement after I ditched an Arduino-based <a href="http://reprap.org/wiki/Arduino_Mega_Pololu_Shield">RAMPS</a> which could barely move a CoreXY printer, and switched to a shiny $150 Smoothiebobard X5.<br />
<br />
Admittedly, I did not check how good the signal is here <a href="https://www.youtube.com/watch?v=8Jq-MAy8fnI">with a scope</a> (i.e. how large is the jitter?). But the sound is almost identical and speed and accelerations are identical... so it must be pretty OK.<br />
<br />
Moreover, I eventually can hold the job immediately, even <b>within</b> a long move (a really cool feature that was introduced with GRBL 1.1).<br />
<br />
Now, keep in mind that you still need the stepper drivers. They are included on the Smoothieboard (they are not really powerful though). But there are plenty to buy on the web for as low as <a href="https://www.banggood.com/search/tb6560-driver.html?p=K70703705469201408A3">$7 per axis</a>. So if you add a $5 Arduino Nano, then you are done, and you will run a flawless firmware that is extremely well supported by most CAM.<br />
<h2 style="text-align: left;">
Still... issues with GRBL on an Arduino!</h2>
When your need is only to drive a 3 axis CNC I would say: no drawbacks.<br />
<br />
I highly suggest going with an Arduino and GRBL 1.1 until Smoothieware is "fixed" for CNC milling and engraving. Now, if you already bought a Smoothieboard, then keep it for a better use, like driving a 3D printer. It has it all, it was designed for 3D printing, so it brings all the needed extra electronics to drive the stepper motors and the heated elements alike. This extra is lost money for a CNC.<br />
<div>
<br /></div>
In my case, however, GRBL on an Arduino is still a temporary solution.<br />
<br />
<b>GRBL is slow? </b>Take the worst case, which probably is laser engraving of rasterized hi-density images. With its large stream of "pixels", I would understand that an Arduino is really not a good idea. But still, I was told that the difference was not significant due to the highly optimized code in GRBL. Also, version 1.1 throws some very nice features in for laser engraving: what really counts is how much energy is absorbed by the target, hence the power needs to be lowered when the speed is reduced, e.g. because of the way sharp turns are planned due to inertia.<br />
<br />
<b>GRBL uses all the pins of an Arduino! </b>Yes, actually I will end up in need for more GPIO pins than what is left on an Arduino, i.e. mostly none!<br />
<br />
A short-term goal of mine is to add a <a href="https://plus.google.com/collection/QX47gB">XATCv04</a> tool changer (do go check it, there are tons of very smart ideas in this project!). But it only needs one pin and I could recycle one the unused "coolant enable" of GRBL as the author did.<br />
<br />
However I would like to drive a fourth axis (2 more signals: step and direction), and I would like to add more switches. Less than for 3D printing world, it is still useful to home the spindle at some time in the process, and avoid hitting the limits (which naturally triggers a serious alarm, contrary to 3D printers). And <i>this</i> requires more pins than an Arduino Nano provides.<br />
<b><br /></b> <b>GRBL on other Platforms: lots of options!</b><br />
<br />
There is an official port of GRBL to the <a href="https://github.com/gnea/grbl-Mega">Arduino Mega</a>, and it has tons of additional GPIO pins.<br />
<br />
But upgrading would then better also benefit from more memory, and more importantly a faster CPU (it is really pushed to its limits with GRBL). In this regard, there are already third-party ports of GRBL to the <a href="https://www.youtube.com/watch?v=5DBtbAYmfEE">STM32F ARM32</a> family for example (the "blue pills" are <a href="http://www.cnx-software.com/2016/05/17/bluepill-is-a-2-arduino-compatible-development-board-based-on-stmicro-stm32-mcu/">even cheaper</a> than a 8-bit Arduino, but they are much more powerful in every respect). There is also port to an uncommon but extremely interesting <a href="https://plus.google.com/+JeremieFrancois/posts/JxQxGhyaA5J">PSoC MCU</a> that still I need to put to use after one or two years...<br />
<br />
And eventually, there is even already a port of GRBL ... <a href="https://github.com/gnea/grbl-LPC">to the Smoothieboard</a>! Yep.<br />
<h2 style="text-align: left;">
Conclusion</h2>
Smoothieware (firmware) and the Smoothieboard (hardware) are straightforward for 3D printing.<br />
<br />
Ditch your old RAMPS and throw one in your existing setup and you are up and running better in no time. As I always need to tell pros and cons, my only regret when 3D printing with a smoothie board is the lack of a full-featured, low cost, non-networked user interface (I always need to tweak stuff while printing directly on/from the printer -- a remote web interface is cumbersome IMHO, and possibly unreliable unless you go with a network cable, huh). The official screens are costly compared to that of the feeble but functional Marlin/RAMPS.<br />
<br />
But as CNC milling is concerned, switching the boards is not enough. I naively thought that the "GRBL compatible" mode would make smoothieware behave like GRBL, but it does not.<br />
<br />
When asking, it is quite annoying that the authors always start arguing that Smoothieware implement better behaviors than GRBL (and all the other paradigms). The offered <i>GRBL compatibility mode</i> is a good idea but it is misleading. Moreover, this mode should simply be not impacted by a counter-productive point of view in my opinion: it would help make Smoothieware more compatible with existing software (and get a bigger share of the market!).<br />
<br />
<div style="text-align: center;">
<i><b>When switched to the provided "GRBL compatibility" mode,</b><b><br />why should it willingly behave differently than GRBL?</b></i></div>
<div style="text-align: center;">
<i><b>Whether the possible interpretations </b><b>are good or bad make no sense.</b></i></div>
<div style="text-align: center;">
<br /></div>
Nobody have complaints about the way Smoothieware does it for 3D printing. It handles g-code with no surprise, like most if not all other 3D printing firmwares.<br />
<br />
But in its current state, people will keep on having weird and unsolved issues when they try to use Smoothieware for driving their CNC. Each and every critic hits either a defensive or even an aggressive response from the team behing Smoothie. As such I am skeptical that <a href="http://oss-watch.ac.uk/resources/pullrequest">a pull request</a> would be accepted, that would try to make Smoothieware more compatible with GRBL in GRBL compatibility mode, how sad.<br />
<h3 style="text-align: left;">
What next?</h3>
I highly suspect that someone will end up forking a "rogue" version of Smoothieware just as to be able to implement these fixes himself and use his own non-cooperative CAM software suite. To be honest, I almost did, instead of trying to fix bCNC itself.<br />
<br />
But forking is not a good idea, when we look at the state of <a href="http://www.tridimake.com/2015/05/github-kills-marlin-which-branch-to.html#more">Marlin and its gazillion versions</a> in the 3D printing world. Still, the latter is so successful!<br />
<br />
Smoothieware is an opensource project and the team really promote open source (and their products btw), which are both good! But I suddenly realize that being an opensource project does not necessarily mean that it is fully open for third-party improvements nor to constructive criticism (I hope I am constructive despite what they say).<br />
<br />
To be honest, I already tried a couple of time to collaborate on very minor stuff, and either it was bluntly refused each time (e.g. make the whole project compatible with Eclipse IDE), or I raised an off-topic debate (as here, which eventually ended up in the public). As a developer, I would probably not spend time to try and contribute to Smoothieware. It would be easier in an alternate fork, or even another firmware (e.g. like I did for Marlin gcode core scheduling, or multi-line aliases, which were both accepted).<br />
<br />
Since I need no more than 3 axis for the moment, I will keep on using GRBL and bCNC for a while, may be until Smoothieware runs my mill in a smooth, unsurprising way just as it does for my 3D printers. Or, for some people with no controlling hardware yet, I should note that the plain old <a href="https://github.com/gnea/grbl-LPC">GRBL was eventually ported to the smoothieboard</a>. Weird at best, a bit saddening at worst :/<br />
<br /></div>
Jeremie Francoishttp://www.blogger.com/profile/02984201174566394892noreply@blogger.com7tag:blogger.com,1999:blog-3615478772815290200.post-47710134426781531032017-03-10T19:55:00.001+01:002017-04-21T17:57:54.738+02:00Low friction filament spool holder made in 3 minutes<div dir="ltr" style="text-align: left;" trbidi="on">
Here is a short post on yet another low-tech but functional tool (the last one was a <a href="http://www.tridimake.com/2014/08/home-made-filament-drier-box.html">dry box</a>).<br />
<br />
Give a maker a 3D printer and every problem is solved by 3D printing... A few years ago I started to re-realize that many problems are solved much better <i>without 3D printing</i>. At some time it was funny to see everything being 3D printable, including pipes, but how slow and inefficient it can be.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen="" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/c4tL7EktkgM/0.jpg" frameborder="0" height="266" src="https://www.youtube.com/embed/c4tL7EktkgM?feature=player_embedded" width="320"></iframe></div>
<br />
So here is a recent counter-example: I had to use a small, cheap but functional 3D printer recently (a sub $350 <a href="http://www.banggood.com/3D-Printer-Assembled-Me-Creator-Mini-Desktop-Kit-With-2004-Display-p-959232.html?p=K70703705469201408A3">Me Creator Mini</a>, a pretty good choice as an entry-level printer in my opinion). But it runs on 1.75mm filament and it lacked a compact, reliable low friction spool holder (the default is attached to the back of the printer, far from the side due to the electronics, and which is made of PVC pipe: the filament often jumps off the spool, which quickly fails).<br />
<br />
<a name='more'></a><br /><br />
I was both in a hurry and lazy, so I wanted a quick hassle-free solution.<br />
<h2 style="text-align: left;">
First idea: go find a design and 3D print it?</h2>
It was a long time I did not go to Thingiverse. When I do I have an "infinity" notification count on my own designs! I checked the existing designs, and... there are right now exactly 3,927 designs which are tagged "spool holder". By the way, there is even a super funky <a href="https://www.youtube.com/watch?v=DcY06NCV014">marble-powered one</a>.<br />
<br />
No way I will review thousands of designs until I find a "proper one". I do not want to print three of them to get one working (with possible additional problems with the printer I have at hand... like the very filament entanglements I want to fix).<br />
<br />
So, interestingly, no existing design suited me, my own <a href="http://www.thingiverse.com/thing:234040">spider spool holder</a> included.<br />
<h2 style="text-align: left;">
Second idea: no biggie, I design a new one and 3D print it?</h2>
Easy, <a href="http://www.tridimake.com/2014/09/how-to-use-openscad-tricks-and-tips-to.html">with Openscad</a>. But, doing so takes even more time! And that would make a 3,928th design on Thingiverse.<br />
<br />
Adding further steps or functionality between the idea and the realization is one of the best way to end with nothing. When I start designing something, all kinds of questions jumps at me. No way here, I need my spool holder (remark: I write this months later of course, but the idea to write about it jumped at me when I was doing it...).<br />
<h2 style="text-align: left;">
Final idea: make it crappy, and do not print it!</h2>
So here it is: a roller box that took me about 3 minutes to make. And it works very nicely with super low friction for the feeble filament driver of the printer (unlike my bulky one on the UM).<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhqzhd6JxreHjvNJysbwjqEZyDH6T2ckGzhvi7Mhca2NPaYQWplbNWKqkP45bHL0WlB3S98IZyxLa78yWI51e4fZBr7e8NCQpTqR6YLfkO6_3B_YnLYJJItTeEsFT3XAMzellK4NPeCNxZ8/s1600/20170115_1-plastic-anchor-box.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="241" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhqzhd6JxreHjvNJysbwjqEZyDH6T2ckGzhvi7Mhca2NPaYQWplbNWKqkP45bHL0WlB3S98IZyxLa78yWI51e4fZBr7e8NCQpTqR6YLfkO6_3B_YnLYJJItTeEsFT3XAMzellK4NPeCNxZ8/s320/20170115_1-plastic-anchor-box.jpg" width="320" /></a></div>
<br />
The box originally held an assortment of plastic anchors (<a href="http://www.naturalhandyman.com/iip/inffastener/infanchor/infanchor.html">large review here</a>). It looks like most of the "Parts Organizer" boxes.. The small hole I drilled, and filled with a piece of low-friction bowden tube was not useful in the end, as the thin filament never slips away of the spool.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg5khTP7wRN-IB2ltE6mcAXJXmQucKRrwf1JSymM2xJ_AVBBuFNMV8Pd0BUfklnXs-kcPJxg5Wo-G9gfDJgx2WK9ZAYb6R7RW2IbfblJIWORfGwuqB0RKbYtOLKW3tHMEOEy78O10IA4YMe/s1600/20170115_3-windscreen-metal-insert.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="180" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg5khTP7wRN-IB2ltE6mcAXJXmQucKRrwf1JSymM2xJ_AVBBuFNMV8Pd0BUfklnXs-kcPJxg5Wo-G9gfDJgx2WK9ZAYb6R7RW2IbfblJIWORfGwuqB0RKbYtOLKW3tHMEOEy78O10IA4YMe/s320/20170115_3-windscreen-metal-insert.jpg" width="320" /></a></div>
<br />
I used four super cheap V-grove roller bearings I bought on ebay years ago, with the intent to build a cheap fishing line-based CoreXY printer (see, e.g. <a href="https://www.youtube.com/watch?v=ZmjTTwpJ2Nc">this</a>) -- which I obviously never did.<br />
<br />
The groves were made with a grinder, faster and safer than with a cutter.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh9hxD3p4R7PWUm0398giOaMc1XBkyQGi2XD15mD4lvQjrpWE1BKjhO7h4-3z4LQcIeDXrsEBjSMQZACD1n6C4RN3faKj3FNrN8Xu-sFo2lkK_oogpQSgcNKQtZay7rejIwcVG2kxRcpRuJ/s1600/20170115_2-groves-and-v-bearings.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="190" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh9hxD3p4R7PWUm0398giOaMc1XBkyQGi2XD15mD4lvQjrpWE1BKjhO7h4-3z4LQcIeDXrsEBjSMQZACD1n6C4RN3faKj3FNrN8Xu-sFo2lkK_oogpQSgcNKQtZay7rejIwcVG2kxRcpRuJ/s320/20170115_2-groves-and-v-bearings.jpg" width="320" /></a></div>
<br />
You can add little pieces of tubing to keep the roller bearings in place, like above and below. Without V-shaped bearings you probably can get cheaper even, by using glued stacks of washers, that you enclose within a pair of bigger washers: the deal is to forbid the spool to drift aside. Friction on stainless steel with not be significantly higher than with bearings.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgU67rSou_tYUbUiAuBP2rvkcTGpdGbWILKiD3CrYbYXDjnOaEDpX2ElUoGqM80JRmCKnN47TB-d_3zTrGRhR1p-8uJQbcux9TshfbrhhKKSHTE8SLN9nsHlAiMhxmyO_4BeqSriox9FxNp/s1600/20170115_4-results.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="180" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgU67rSou_tYUbUiAuBP2rvkcTGpdGbWILKiD3CrYbYXDjnOaEDpX2ElUoGqM80JRmCKnN47TB-d_3zTrGRhR1p-8uJQbcux9TshfbrhhKKSHTE8SLN9nsHlAiMhxmyO_4BeqSriox9FxNp/s320/20170115_4-results.jpg" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_jp3b5Xez2w9d9pok7ynR_Ch2bSp6drh_KM_zMEhxbBs5TNRek3QIXojOlYhNrwiW9cGzkhs8DZcNJPAoJZqg0hUDZTm51nfLTysx9llXQyYGIoiO1E76BT9sFggWwIyDqRAiYiP0mvpd/s1600/20170115_5-result.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_jp3b5Xez2w9d9pok7ynR_Ch2bSp6drh_KM_zMEhxbBs5TNRek3QIXojOlYhNrwiW9cGzkhs8DZcNJPAoJZqg0hUDZTm51nfLTysx9llXQyYGIoiO1E76BT9sFggWwIyDqRAiYiP0mvpd/s320/20170115_5-result.jpg" width="278" /></a></div>
<br />
<div style="text-align: center;">
<span style="font-family: "helvetica neue" , "arial" , "helvetica" , sans-serif; font-size: x-small;">Note that the small outlet is useless when </span><span style="font-family: "helvetica neue" , "arial" , "helvetica" , sans-serif; font-size: x-small;">the whole is on a table,</span></div>
<div style="text-align: center;">
<span style="font-family: "helvetica neue" , "arial" , "helvetica" , sans-serif; font-size: x-small;">as it bends the filament too much. </span><span style="font-family: "helvetica neue" , "arial" , "helvetica" , sans-serif; font-size: x-small;">I have yet to see the filament<br />jump over the front pair of roller bearings.</span></div>
<br />
<br />
And as a bonus: I eventually made use of those nice, sturdy, shiny metal arms that I always collect on used windscreen wipers :)<br />
<br />
You get a short video <a href="https://www.youtube.com/watch?v=c4tL7EktkgM">here</a> (same as above).<br />
<br />
I now realize I spent much more time writing the post than making the stuff, so I hope you like it: all in all may be I could have 3D printed one... :D<br />
<br /></div>
Jeremie Francoishttp://www.blogger.com/profile/02984201174566394892noreply@blogger.com0tag:blogger.com,1999:blog-3615478772815290200.post-3112503295209805542017-03-01T17:42:00.001+01:002017-03-22T11:14:23.603+01:00Ultimaker to file patents... with dubious reasons<div dir="ltr" style="text-align: left;" trbidi="on">
Yes, this is no April fools' day: Ultimaker is <a href="https://ultimaker.com/en/blog/39119-company-update-ultimaker-files-first-patents">filing its first patents</a>. Wow. We have cheap 3D printers at home specifically because <a href="https://techcrunch.com/2016/05/15/how-expiring-patents-are-ushering-in-the-next-generation-of-3d-printing/">old patents</a> eventually ended up in the public domain. So: no lessons learnt?<br />
<br />
<div style="text-align: center;">
<span style="background-color: white; font-family: "univers" , "arial" , "helvetica neue" , "helvetica" , sans-serif;"><i>"The industrial additive manufacturing market has some strong players,</i></span></div>
<div style="text-align: center;">
<span style="background-color: white; font-family: "univers" , "arial" , "helvetica neue" , "helvetica" , sans-serif;"><i>some of whom are very proactive with patents. As such, we need to take</i></span></div>
<div style="text-align: center;">
<span style="background-color: white; font-family: "univers" , "arial" , "helvetica neue" , "helvetica" , sans-serif;"><i>extra measures to protect our intellectual property (IP)" </i><span style="font-size: x-small;"><strike>Makerbot?</strike> Ultimaker!</span></span></div>
<span style="font-size: x-small; text-align: center;"><br /></span>
<br />
<div style="text-align: justify;">
<span style="text-align: left;">I really have mixed feelings (<u>update D+2</u>: given the feedback on this article, I now have no more mixed feelings: makers <a href="https://plus.google.com/+JeremieFrancois/posts/BLDTbyJWB5o">will probably flee away from the brand</a>).</span><br />
<span style="text-align: left;"><br /></span>
<span style="text-align: left;">A lot of people say "it is how things are". But growing bigger is no excuse for playing the game: complying with the system is probably not a way to help fixing it. The bigger the company the more responsible it is of this stupid status quo.</span></div>
<br />
Do you remember BQ trying to patent stuff also? They reacted quickly and withdrew after the community outrage (see <a href="https://toms3d.org/2015/01/23/honest-review-the-bq-witbox-disclaimer/">Tom's disclaimer</a>).<br />
<br />
I hardly imagine the heated debates at Ultimaker headquarters on the matter. Sure, there are no real solution in the real world of intellectual property, and I understand that some thought they <a href="https://ultimaker.com/en/community/39121-ultimaker-files-its-first-patent?page=1&sort=#reply-173433"><i>had to file patents</i></a> at this point in the growth of the company.<br />
<br />
But what annoys me much is how they justify the move to the community. They invoke reasons to file patents that are dubious in my opinion. The call to a <a href="http://www.ipwatchdog.com/2008/11/24/defensive-patent-portfolio-no-help-against-patent-trolls/id=459/">defensive patent</a> portfolio, for example, neither has legal ground nor it works well (more on that after the break). But in any case, applying for a patent does not help or defend the community in any way. Heh, even the founder of Ultimaker himself <a href="http://www.whiteboardmag.com/how-3d-printer-manufacturer-ultimaker-thrives-thanks-to-open-innovation/">told so and years ago</a>.:<br />
<div style="text-align: center;">
<span style="font-family: "verdana" , sans-serif; font-size: x-small;"><br /></span></div>
<div style="text-align: center;">
<span style="font-family: "helvetica neue" , "arial" , "helvetica" , sans-serif;"><i>“If it weren’t for patents, 3D printers would have made it to consumers long before.</i></span><br />
<span style="font-family: "helvetica neue" , "arial" , "helvetica" , sans-serif;"><i>It’s only now, with important 3D printing patents expiring, that the technology flourishes.”</i></span><br />
<span style="font-family: "helvetica neue" , "arial" , "helvetica" , sans-serif; font-size: x-small;">Erik De Bruijn (founder of Ultimaker)</span><br />
<span style="font-family: "helvetica neue" , "arial" , "helvetica" , sans-serif;"><br /></span>
<span style="font-family: "helvetica neue" , "arial" , "helvetica" , sans-serif;"><i><span style="font-family: "helvetica neue" , "arial" , "helvetica" , sans-serif;">"In a Bid to Protect IP </span><span style="font-family: "helvetica neue" , "arial" , "helvetica" , sans-serif;">and Create More Freedom to Innovate</span><span style="font-family: "helvetica neue" , "arial" , "helvetica" , sans-serif;">,</span><br style="font-family: "Helvetica Neue", Arial, Helvetica, sans-serif;" /><span style="font-family: "helvetica neue" , "arial" , "helvetica" , sans-serif;">Ultimaker Announced their Decision to Invest in Defensive Patents"</span></i><br style="font-family: "Helvetica Neue", Arial, Helvetica, sans-serif;" /><span style="font-family: "helvetica neue" , "arial" , "helvetica" , sans-serif; font-size: x-small;">I hardly beleive they <a href="https://ultimaker.com/press/36-ultimaker-announces-defensive-patents">did write this</a>! Hey, They Even Capitalized Every Word :D</span></span><br />
<span style="font-family: "helvetica neue" , "arial" , "helvetica" , sans-serif;"><span style="font-family: "helvetica neue" , "arial" , "helvetica" , sans-serif; font-size: x-small;">Actually, patents may even <a href="http://www.tridimake.com/2014/05/the-businessman-and-maker.html">stop your innovation</a> as you have to stay within their protective bounds.</span></span></div>
<br />
I used to like the brand, but I recently started to be skeptical of the claims. So is Ultimaker heading <a href="http://www.tridimake.com/2014/06/do-not-buy-makerbot-3d-printers.html">the same ugly way as Makerbo</a>t, as I detailed in length in 2014? Do not read me wrong: I really do not think so at this point.<br />
<br />
But ... nobody can tell that it will never end the same way: there is simply no warranty. Trying to justify the move the way they do is wrong in my opinion and a step closer to a less friendly business. I thought a lot about it, both as a maker and as a businessman, and I do not like it.<br />
<br />
<br />
<a name='more'></a><br />
So after Makerbot went down the rabbit hole right into China, after BQ withdrew its claims on a Fibonacci extruder on the Witbox, here is Ultimaker move. But frankly, I am skeptical they will retract.<br />
<br />
They may have gone "too much" professional with this in my opinion and the move is obviously planed strategy at work (see the PR release again). We need to realize that the pioneering days are mostly over, as much as the time when the community helped Ultimaker survive and grow by doing the <a href="https://www.entrepreneur.com/article/58380">word-of-mouth marketing</a> in their place. Suddenly, it sounds as if its own, old community of makers and tinkerers count less than the new, huge, promising market share. I would certainly not go as far as saying they abandon us (it would be stupid to redo a Makerbot mistake), but times did change.<br />
<br />
Interestingly, some consider the brand with a heavy bias: they just "tell" that Ultimaker can proceed because it is not evil, and because it has good products. Just like Apple. Hey, the printers even are white ;) I got some bashing for what I say but I still need to read convincing non-biased arguments to change my mind.<br />
<br />
Faith is nonsense in the business. Many hackers in the former Makerbot community thought alike initially, and it did not end up very well.<br />
<h2 style="text-align: left;">
Why does a company patent stuff, what for?</h2>
But first, let me state all the options related to patents in my opinion, by "decreasing level of nastiness":<br />
<br />
1) <b>Patent for suing</b> (intellectual property = extorsion), the worst kind being "non-practicing entities" aka <a href="https://en.wikipedia.org/wiki/Patent_troll">patent trolls</a>, pure greed, pure evil.<br />
<br />
2) <b>Patent for blocking competition</b> (intellectual property = weapon). This should be as illegal as the previous strategy imho: you patent something to prevent the competitors to move on, including by refusing to licence the patent to them. The user pays a lot in the end. Apple plays at this level: is your stuff flat and round? You are in trouble because you are infringing their exclusive innovation.<br />
<div>
<br />
2.5) (update): <b>Patent to <a href="https://www.quora.com/What-are-the-advantages-that-a-company-receives-on-being-listed-on-a-stock-exchange">list on a stock exchange</a> or before selling</b> (so he pays more). This is a greedy neoliberal strategy, where IP does matter much as real added value, but more as a means to increase the <i>perceived value</i> of the company. Not really hacker-friendly thus.<br />
<br /></div>
3) <b>Patent for licencing (regular use)</b> (intellectual property = money, selling ideas instead, or in addition, to selling products). Still looks like greed, but a very common form of business. It was the original goal of patents so as to protect small inventors. But it did not work very long as such...<br />
<br />
4) <b>Patent to "protect the intellectual property"</b> (IP = protection). The idea to counter-sue is often theoretical. even really large portfolio of patents will not be a warranty, check e.g. Apple vs. Samsung. Ultimaker would not sue a maker. But as someone said, what if Prusa Research use this capacitive bed leveling? What if Zortax does? What if Stratasys does? Where is the line? So how Ultimaker could realistically counter-sue, say, 3D Systems with its large set of patents and long history of being aggressive/blocking in the field? Somehow like the <a href="https://en.wikipedia.org/wiki/Mutual_assured_destruction">MAD doctrine</a>: but we should realize that in the end, either everyone pays (for the bombs) or everyone dies (due to the bombs), and not only the players...<br />
<br />
5) or, 4b... <b>Patent to benefit from the above, while telling you do not like patents</b> (i.e. try to have people believe you are altruistic or good-willing at the same time), like Google... Ultimaker is here, right from point 9 below. I would trust them more if they did not "claim" that nothing changed and they will always be good guys (only, they start filing patents).<br />
Come on, nobody knows who buys who in the end and how the intellectual property is then handled... <i>Not being evil</i> is not legally binding either, as much as "faith" has no legal implications. And what if Ultimaker fails as a company? Or if the founders leave? No-one can say a patent troll will not buy it to sue everyone with their patents. Ultimaker should talk straight and say 4), 3) or possibly 2.5).<br />
<br />
6) <b>Patent and share within a group</b>. This is probably the best solution right now. Patent it either as a group or as a company, but make sure everyone signs a declaration that the members of the group will not sue each other. Looks idealistic? No, just check the <a href="http://www.openinventionnetwork.com/">Open Invention Network</a> for example, with Toyota, Asus and SpaceX among others. Something similar could be initiated by Ultimaker, and it would sound way closer to open source values than filing patents.<br />
<br />
7) <b>Patent and re-publish/license in the public domain</b>. There is sadly probably no legal ground to apply for a patent and to put it into the public domain with the goal that it is free to all and forever and nobody will sue you on top of it. An it costs money. "Public domain" is even not always recognized in court according to countries.<br />
<br />
8) <b>Do not patent, but rely on "prior art"</b>. Legally, a patent is invalid when it describes something already present on the market. So just make it and publish about it, as the community did for years. Sure, stupid US patent offices do not do their homework though, and they awards tons of invalid patents. As long as they would not share the penalties in the subsequent lawsuits, the system will cost also to the defendant. But do not be bought by the opposite argument: having a patent portfolio may not get out out of trouble anyway since you still you often have to go to court to counter-sue... The argument is very dubious to me. Some said, that using prior art to defend oneself means you need to be in court, which costs money. But, 1) applying for patents also costs money, and 2) once again, the very idea to hold a few patent to be able to fight back is naive. You usually need <i>lots of patents</i> to avoid being sued (and even, it does not always work see Apple vs Samsung). Is that what Ultimaker is goind to do?<br />
<br />
9) <b>Play clear of existing patents</b> (while contributing to prior art). It may not be simple, but they could try to avoid infringing genuine/risky/obvious patents filed by competitors. For example, heated chambers were subject to a patents but the "industrial reprap" beauties at <a href="http://kuehlingkuehling.de/">Kühling&Kühling</a> did not infringe the patent by incorporating the stepper motors within the enclosure. It sounds silly at first from the point of view of a maker, but as a business and legally speaking, it was smart and OK!<br />
Many others manage to make a living business without patents and within the limits, like <a href="https://www.alephobjects.com/">Aleph Objects</a> (immensely Open-Source), <a href="http://www.prusa3d.com/">Prusa Research</a> (here is a real maker from day one), <a href="https://www.bcn3dtechnologies.com/en/sigma-source-files/#break-intro">BCN3D</a> (another real Open-Source company with innovative printers), <a href="http://printrbot.com/tag/open-source/">printrbot</a> (really nice entry level but reliable printers) and many others. Or like Ultimaker was... until now. Note also that the last two are licensed under <a href="https://creativecommons.org/licenses/by-nc-sa/3.0/deed.en_US">CC-BY-NC</a> (i.e. technically not Open-Source).<br />
<br />
In my opinion not applying for any patent does work and is cheap. Admittedly, growing bigger and bigger puts you in the line of sight of even bigger companies, so you may feel you need protection. But playing the very game they played themselves for decades could be a riskier business even.<br />
<br />
I was told I was naive. I admit I am a bit of an idealist, but I really no not think I am naive (hopefully since helping startups writing about their IP is also part of my job, believe it or not!..)<br />
<br />
Why does a company patent something? Try to find any humanitarian or open source values at the <a href="http://www.wipo.int/sme/en/ip_business/importance/reasons.htm">world intellectual property organization</a> website. Hint: nothing interesting on the website, but no bullshit either, it is all about plain business. What is the benefit for others? None.<br />
<div style="text-align: center;">
<br /></div>
<div style="text-align: center;">
<span style="font-family: "helvetica neue" , "arial" , "helvetica" , sans-serif;">Patenting is not necessarily wrong per se, but it is</span></div>
<div style="text-align: center;">
<span style="font-family: "helvetica neue" , "arial" , "helvetica" , sans-serif;">an egocentric and sometimes greedy way of thinking and doing business.</span></div>
<div style="text-align: center;">
<span style="font-family: "helvetica neue" , "arial" , "helvetica" , sans-serif;">This is by essence far from the values of Open-Source.</span></div>
<br />
One way or another, filing patents is a means to try and protect its own intellectual "property", i.e. its own economic viability. Patents works mostly by reducing the freedom or even endangering the viability of others. It really does not fit well with the idea of Open-Source: do not be fooled by the company when it tells something else.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXhyxy0B6h9m1Qs4W_nrFCaNSA5LfHaRS_36U4URQV_p7VgCgLmYzzEIUDp0oY9RVg4IJhYB4lhDtsQbvN3NDTBuOej5PLUEdGCRTLyvs3TA9XGCPz7NEXBkuaVJJFZHE1rXUjrwG0SrjX/s1600/patent_wars.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXhyxy0B6h9m1Qs4W_nrFCaNSA5LfHaRS_36U4URQV_p7VgCgLmYzzEIUDp0oY9RVg4IJhYB4lhDtsQbvN3NDTBuOej5PLUEdGCRTLyvs3TA9XGCPz7NEXBkuaVJJFZHE1rXUjrwG0SrjX/s400/patent_wars.jpg" width="298" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Does Ultimaker really want to play the game like the others?</td></tr>
</tbody></table>
<br />
<br />
<h2 style="text-align: left;">
And... is Ultimaker eventually talking bullshit?</h2>
Back to the late news with Ultimaker: as a company, it slowly moves away from what it was imho.<br />
<br />
On one side I really like that they refused to get bought by bigger players (so far), that they hired open source developers (se Cura), or that they were open and managed to get paid back by a super friendly and active community. Many of us published many designs <a href="http://www.tridimake.com/2014/01/features-and-improvements-for-a-homemade-ultimaker.html">to improve an Ultimaker</a>. Some even made some money out of it, via the Ultimaker shop itself (like the old <a href="http://www.3ders.org/articles/20120531-a-story-behind-the-design-and-creation-of-ulticontroller.html">LCD panel by Bernhard Kubicek</a> or the Olsson additions).<br />
<span style="font-family: "helvetica neue" , "arial" , "helvetica" , sans-serif;"><br /></span>
<br />
<div style="text-align: center;">
<span style="background-color: white; font-family: "helvetica neue" , "arial" , "helvetica" , sans-serif;">If you’re an individual user or contributor,</span></div>
<div style="text-align: center;">
<span style="background-color: white; font-family: "helvetica neue" , "arial" , "helvetica" , sans-serif;">you don’t need to worry, as these patents will not affect you.</span></div>
<div style="text-align: center;">
<span style="font-size: x-small;">(from the official <a href="https://ultimaker.com/en/blog/39119-company-update-ultimaker-files-first-patents">press release</a>)</span></div>
<div style="text-align: center;">
<br /></div>
<div style="text-align: center;">
Oh, great! At least they will not sue me as a contributor! :)</div>
<br />
Ultimaker eventually managed to become a "serious business", and these are good news. Most if not all of us are pretty happy with it: it is justice, especially compared to <a href="http://www.tridimake.com/2014/06/do-not-buy-makerbot-3d-printers.html">Makerbot</a>. But they certainly no more behave as a bunch of makers, and this move does not go well with the ethics of open source either, as clearly stated by Rich <a href="https://plus.google.com/111190381678407996621/posts/3djHYQHgMb8">in a Google+ thread</a>.<br />
<br />
Here is what makes me feel the most nervous about: they hired professional public relation people, they raised their prices (the UM3 is almost perfect but just so expensive). But some people are raising eyebrows here and then (see e.g. some <a href="http://www.3dprintingforum.us/viewtopic.php?f=34&t=12&start=840#p8648">sneaky</a> little late moves). And they eventually file patents. The last time I heard this, it ended up very badly (and it keeps on being <a href="https://plus.google.com/u/0/+JeremieFrancois/posts/8og7HbfWwAh">more pitiful</a> with time - see below Ultimaker / Makerbot).<br />
<br />
There is simply no legal warranty at all that the next "Ultimaker Super Pro" will not be closed-source, or at least full of patents at this point. It is all "faith", but the factual behavior is that they are starting to apply for patents on their innovations, just as old-time nasty companies did. Period. Let us hope they will keep patenting only their own stuff.<br />
<br />
Seriously, go and read the press release if you did not already: at best it is dull or, say, "professional". At worst, they make it look like that "filing patents" is obvious and natural and it evens promotes open source ;) I hope they will avoid the next usual trap, which comes after polished/biased marketing. It may be time to follow a serious <a href="http://callingbullshit.org/FAQ.html">anti-bullshit course</a>.<br />
<br />
<b>Seriously, are they applying for patents to "protect the open community"? </b><br />
<br />
A company works to <a href="http://www.tridimake.com/2014/05/the-businessman-and-maker.html">make money and to pay its employees</a>. It has to, and I am perfectly OK with it.<br />
<br />
But I cannot help but <a href="https://ultimaker.com/en/blog/39119-company-update-ultimaker-files-first-patents">read the press release</a> as: "<i>we would better patent just in case</i>".<br />
Anyhow I would frankly better hear it straight, like this, and not without the additional highly counterproductive "<i>...but we will tell lots of reasons why it is better for you and the community</i>".<br />
Deep in me I fear it could sound like "<i>it is time we scrape a maximum of money out of this</i>". Being big and owning a large part of the market certainly attracts non-maker friendly people.<br />
<br />
When a company files patents, it is trying to protect its own intellectual property and its own economic viability, <i>and by definition I would not try to use or improve the patented "invention" if I was designing 3D printers as a business: that would simply be too risky!</i> Period. Patents are certainly not doing good to protect the community nor the makers at all. Just tell the truth, please. If you start telling lies, there is no end to the path.<br />
<br />
<div style="text-align: center;">
<span style="background-color: white; box-sizing: border-box; color: #565656; font-family: "trebuchet ms" , "helvetica" , sans-serif; font-size: 15px;">A chilling effect is, <em style="box-sizing: border-box;">“</em></span><span style="background-color: white; box-sizing: border-box; color: #565656; font-family: "trebuchet ms" , "helvetica" , sans-serif; font-size: 15px;"><em style="box-sizing: border-box;">the inhibition or discouragement of the legitimate exercise<br />of natural and legal rights by the threat of legal sanction.” (<a href="https://3dprintingindustry.com/news/aleph-objects-prusa-research-3d-printing-community-others-react-ultimaker-patent-application-107215/">ref</a>)</em></span></div>
<h2 style="text-align: left;">
So what about the patents in question?</h2>
<strike>I did not find details about the initial patent</strike> which seems related to bed leveling through capacitance (nice details <a href="https://ultimaker.com/en/community/23463-inside-the-ultimaker-3-day-6-active-leveling">here</a> ... and below!). I shall read about as it is available, to see how really "novel" it is but I hope they are not patenting it just because it was hard to get it reliable. Actually, I know well since I had written <a href="http://www.tridimake.com/2015/12/bed-leveling-tramming-sensors.html">a review</a> about various techniques, and since I spent a long time with an unusual force-sensitive resistor setup that ended up <a href="https://hackaday.com/tag/force-sensitive-resistor/">on hackaday</a> (without a patent).<br />
<br />
But just as with my setup, I would not be surprised that a maker here or there already made it before. I also highly suspect that Ultimaker's patent legalese makes it over-reaching (after all if a professional wrote it...).<br />
<br />
<u>Update</u>: Make your mind: here it is... err, just a contactless bed leveling? This sounds bad.<br />
<br />
<div style="text-align: right;">
<span style="color: purple; font-family: "verdana" , sans-serif; font-size: x-small;">“According the present invention a print bed levelling system of the type defined in the preamble is provided, wherein the print bed levelling system comprises a nozzle head assembly movably arranged with respect to a substantially flat print bed member, the nozzle head assembly comprising one or more nozzle bodies each having a nozzle end, and a contactless sensor member disposed at a print bed engagement end of the nozzle head assembly, wherein the contactless sensor member comprises a sensing surface in sensing engagement with the print bed member over a relative sensing range between a distal sensing position and a proximal sensing distance.”</span><br />
<span style="color: purple; font-family: "verdana" , sans-serif; font-size: x-small;">- Reference: NL2015361</span></div>
<div style="text-align: right;">
<br /></div>
<br />
If ever Ultimaker's patents keep on being filed and if they are over-reaching, I will no more promote the brand: they would have fallen in the greedy trap, and that would depart from the Open-Source ethics. Their printers are nice, but the business model that uses patents did too much harm already in the field for the last decades. Being big is not an excuse, nor being hard work. Putting PR sugar around the fact adds insult to injury in my opinion.<br />
<br />
What is sad is that they would have better talked about the need for patents when they were small imho. Small companies do need legal protection. Bigger ones mostly do silly things with patents and the economy. As they say, they could not afford it when they were small. But now that they have money, they play the same game as all bigger companies. They should choose point 6 in the list above, and lead a group of open cooperation, not file for they own private business/safety/whatever the talk.<br />
<h2 style="text-align: left;">
Big, serious, and with a patent portfolio. Sad usual business?</h2>
UM eventually grew on its own to a point it became a large, leading company in the 3D printer business. It is well deserved on one side. I remember times when the lead time was ridiculously long, and when non-EU customers had no distributors... That was a real pity because both the product and the stance were neat.<br />
<br />
Ultimaker promoted Open-Source values, in their way. There were a few hiccups though, such as files made with very expensive proprietary software (that no maker could really use), sometimes out of date, or incompatible. Or the choice of the "non-commercial" variant of the Creative Common licence, which is factually <a href="https://wiki.creativecommons.org/wiki/NonCommercial">not an Open-Source</a> licence, although a nice "intermediate" license in my opinion, though mostly unusable.<br />
<br />
Becoming "serious" probably brought in professionals in marketing, corporate look and feel, greed, and. Who knows they may end up hiring "invention harvesters" in the end as Makerbot did. All these employees are there to <b>improve sales</b> one way or another. Whatever they tell, their job are will not make better open source, nor "help" the community: wearing a tie never makes the job better. A better packaging only increase sales. They do their job I guess, but most of these people sound biased to me (to say the least). Patents are just an extension of this usual business, with the difference that they may not increase sales actually.<br />
<br />
<br />
<div style="text-align: left;">
<b>
Ultimakerbot?</b></div>
<div style="text-align: left;">
<b><span style="font-family: "helvetica neue" , "arial" , "helvetica" , sans-serif;"><br /></span></b></div>
<div style="text-align: center;">
<span style="font-family: "helvetica neue" , "arial" , "helvetica" , sans-serif; font-size: xx-small;">Five years ago [...] MakerBot was the darling of the<br />Open Source Hardware movement. MakerBot was the poster child of<br />a new economy where anyone could manufacture hardware, at scale,<br />and ship it to thousands of consumers around the world (<a href="http://hackaday.com/2016/04/28/the-makerbot-obituary/">ref</a>)</span></div>
<br />
Yes, Bre Pettis <a href="http://www.tridimake.com/2014/06/do-not-buy-makerbot-3d-printers.html">was also a zealous advocate</a> of Open Source before he changed his mind after his company, Makerbot, got bought for millions. He then argued that Open-Source was not a viable solution for a company, that Makerbot got ripped by competitors and it was losing money due to copycats. Innovation and efficiency was replaced by Marketing and bragging. His company was eventually outsourced to China. And nowadays it is a miserable catastrophic failure.<br />
<br />
Now, I am really sorry to realize there exists a parallel. I will certainly not say that UM is bound to the same fate (that would be a <a href="https://yourlogicalfallacyis.com/slippery-slope">fallacy</a>). But Erik De Bruijn, the founder of Ultimaker himself changed his mind also: check his <a href="http://www.whiteboardmag.com/how-3d-printer-manufacturer-ultimaker-thrives-thanks-to-open-innovation/">own words</a> <a href="http://www.whiteboardmag.com/how-3d-printer-manufacturer-ultimaker-thrives-thanks-to-open-innovation/">years ago</a>. Sure, Erik is not Bre, but I really would like to hear his own arguments to defend the new patent strategy, and to hear him say why and what changed. Oh, sorry, the official stance is that nothing changed at all. Huh.<br />
<br />
<h4 style="text-align: left;">
So?</h4>
I have no problem with people or companies changing their mind (it is even a sane attitude). And it is their right to move to closed source if ever they want at some point (the deal with Cura is more interesting as it is really Open-Source). Of course their latest move hurts the community, and Ultimaker does not resemble Makerbot: the latter was extremely arrogant and nasty in doing so, while the former is quite cautious (with reason).<br />
<br />
But I am quite uneasy when people or companies change their mind or their stance, <i>while they pretend they did not</i>. I would gladly see the opposite move than what Ultimaker chose to do. This is not a good sign at all. It sounds like dirty business.<br />
<br />
As far as I know, there are no shareholders at Ultimaker that only want to get richer whatever the way (even though this feeling may be shared among non-shareholders alike). It reduces the risks both for the company and for the community. Ultimaker may be large enough a company at this time (200+ people), with a clear sky ahead. So they might also resist being bought by bigger than them as they did already... in the short term, once again. Anyhow, I predict most of the "real makers" will quickly drift or flee away from the brand with their latest attitude.<br />
<div>
<br /></div>
I am not sure I want to spend time thinking about what the next step might be: filing more and more patents on each and every invention they can find or add to their printers? Progressively closing the sources of Cura while telling it is for our good?<br />
<br />
I would better <a href="http://www.tridimake.com/2014/05/the-businessman-and-maker.html">go and make something</a> instead.</div>
Jeremie Francoishttp://www.blogger.com/profile/02984201174566394892noreply@blogger.com0tag:blogger.com,1999:blog-3615478772815290200.post-30295788419315984262016-11-05T19:48:00.002+01:002016-11-05T21:55:52.900+01:00Filament switch: close up shots that highlights further the complexity of extruding plastics<div dir="ltr" style="text-align: left;" trbidi="on">
I stumbled upon this old picture while looking for another one. It shows tiny carbon fibers embedded in crystal-clear polycarbonate, that happened when I switched from CFPLA to a crystal-clear polycarbonate (hellish stuff to print btw). Looking at it a second time makes me realize how complex extrusion is (<a href="http://www.tridimake.com/2016/11/close-ups-of-extruded-filaments-transition.html">more</a> after the break).<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiDM00SZjJomX56OzgoTAIEmUkxdVt0LWLnxPU-k0jES6Td8BTw9s5RlCR52sELvTuQ6rCR8LlTVK9UQLvy4_NO7zYwWTm91egWz7OtmHa_Sbfwv0-vVY_3FMvbKrZFUjuDNvYiK4c1RC4q/s1600/filament_3D_printing_carbon_fibers_left_in_polycarbonate.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="452" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiDM00SZjJomX56OzgoTAIEmUkxdVt0LWLnxPU-k0jES6Td8BTw9s5RlCR52sELvTuQ6rCR8LlTVK9UQLvy4_NO7zYwWTm91egWz7OtmHa_Sbfwv0-vVY_3FMvbKrZFUjuDNvYiK4c1RC4q/s640/filament_3D_printing_carbon_fibers_left_in_polycarbonate.jpg" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">A microphotography that shows carbon fibers during a transition from CFPLA to polycarbonate.</td></tr>
</tbody></table>
<br />
<a name='more'></a><br />
<h3 style="text-align: left;">
Fluid mechanics during the transition of a 3D printing filament to another</h3>
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; margin-left: 1em; text-align: right;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEglfPw5XirCq2XQYIV-H0SqyMJ5pWcbtsV4LXsjXgiKraBrxAywzBb6lknoyqASr7f2x3pzyXV9NZwmSB84Wh3H-o_29HMvTJ6hv47I9XkoGHcP3jY_DdrfNPHnFg7A7wiMXtuGip6nY_KJ/s1600/close-up.jpg" imageanchor="1" style="clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" height="284" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEglfPw5XirCq2XQYIV-H0SqyMJ5pWcbtsV4LXsjXgiKraBrxAywzBb6lknoyqASr7f2x3pzyXV9NZwmSB84Wh3H-o_29HMvTJ6hv47I9XkoGHcP3jY_DdrfNPHnFg7A7wiMXtuGip6nY_KJ/s320/close-up.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Close up of the above: the carbon fibers are clearly visible.<br />
They are the last material to be cleared out of the nozzle.</td></tr>
</tbody></table>
The use of clear polycarbonate gives interesting clues about filament transition.<br />
<br />
Let me first say that I firmly believe it depends on the materials themselves (mostly viscosity), but also a lot on the internal <a href="http://www.tridimake.com/2016/06/3d-printing-nozzles-characteristics.html">shape of the nozzle</a>, and finally on the extrusion speed. Shear, backpressure, viscoelasticity and so all play a role. And when two different materials are mixed, you get a super tricky soup! :) Hence, polycarbonate introduces a high bias in the experiment, as much as starting with CFPLA.<br />
<div>
<br /></div>
But still... See the picture below: the black filament is being smoothly replaced from the <i>outside towards the inside!</i> That is, the polycarbonate first surrounds the existing black CFPLA by flowing on the outer of the nozzle first, and it then drags the remaining within. Weird!<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgN3QmEQHfGg387JbFgdu2I7Abj637NhfiG90JNYjdJWAzHTrdlRr-AJmk-w02wRe5P8qtJKfuRgAEvjd_Xre0O7ZC5kVzEbFQMqbcX9Hj7EythnYfMIg3S-FZoglidU5v_wxGtkjZ3-v-X/s1600/IMG_3191-CFPLA-to-PC.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="304" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgN3QmEQHfGg387JbFgdu2I7Abj637NhfiG90JNYjdJWAzHTrdlRr-AJmk-w02wRe5P8qtJKfuRgAEvjd_Xre0O7ZC5kVzEbFQMqbcX9Hj7EythnYfMIg3S-FZoglidU5v_wxGtkjZ3-v-X/s640/IMG_3191-CFPLA-to-PC.JPG" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Weirdly, the extruded polycarbonate replaced CFPLA from the outer towards the inner!</td></tr>
</tbody></table>
I would naively have expected it to be the other way: the new material would first be extruded "in the middle of" the existing one, and then it would purge the previous one by dragging it in an expanding cone-shaped thread. The last bits of black "ought" to be on the surface of the clear(ed) thread, not the opposite as above.<br />
<br />
My only guess for the above picture is that the polycarbonate in contact with the metal may flow better than the one which is surrounded by molten plastic (in the middle). So even though there is a larger friction on the internal walls of the nozzle, the resulting drag is lower than that of the additional viscosity due to the lower temperature in the middle of the molten filament?<br />
<br />
In the picture above I was pushing hard to squeeze the CFPLA faster out of the nozzle. No filaments are visible by the way. Reciprocally, in the first picture of the post, the extrusion rate was much slower, and the tiny carbon fibers are left behind as the last material to be dragged out.<br />
<br />
By the way, this is yet another interesting phenomenon: solid particles seems to be the last one to get out of the nozzle, and sometimes with a significant delay. It matches my impression that a significant additional length of the new material usually has to be extruded before I can trust that my nozzles are purged enough and clean from dirt.<br />
<br />
For some reason it reminds me how the heaviest grains of sand accumulate on the surface of a bucket when it gets shaken. Though the physics are probably quite different (i.e. particles vs. fluids).<br />
<h3 style="text-align: left;">
What about other materials? I have no clue.</h3>
Yet another picture below: I do like the "atomic" feeling of the following transition to an opaque flashy ABS (the picture is taken from this old review about <a href="http://www.tridimake.com/2012/12/3d-printing-plastic-filaments-kinds-and.html">various printable materials</a>).<br />
Even though it does not show the effect as much as with polycarbonate, we see patches of CFPLA on the surface -at least- of the ABS during the transition, which seems to match the first effect of this post (and not the previous one).<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgzRhzpUcf5hyLDhAHR5cPTOp1yENrJAh4k_V4P9Mah655_KRnkSP_45M3ZJiBPnSmIZQcZDmpXhZ7BxLDOS1Dky_JXmlSHGKDlgNvMisv45-tTiIi4hTqrcd9nW3ShGoxIJxBJd1g4P-Ii/s1600/IMG_2665CFPLA-to-ABS.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="425" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgzRhzpUcf5hyLDhAHR5cPTOp1yENrJAh4k_V4P9Mah655_KRnkSP_45M3ZJiBPnSmIZQcZDmpXhZ7BxLDOS1Dky_JXmlSHGKDlgNvMisv45-tTiIi4hTqrcd9nW3ShGoxIJxBJd1g4P-Ii/s640/IMG_2665CFPLA-to-ABS.JPG" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">CFPLA again to flashy ABS. Carbon fibers show up quite well and on the<br />
surface during the transition. It looks like the first picture on the post, not the latter.</td></tr>
</tbody></table>
<h3 style="text-align: left;">
So what? Is this just curiosity or are there ideas?</h3>
More experiments are certainly needed to get better clues of the physics behind. But this is more than just another "weird" post that shows that extrusion is a particularly complex process. The study of flow and forces and within fluids, namely <a href="https://en.wikipedia.org/wiki/Fluid_mechanics">fluid mechanics</a>, will keep me puzzled as now!<br />
<br />
Anyhow, dual extrusion printers often circumvent the issue by using a purge tower. This works fine because it ensures that enough material is being extruded (and lost) before it starts printing with the other material. There is a large room for optimization there though, depending on materials and how the switch is done. E.g. it could be beneficial to extrude more slowly or at different temperatures for the transition, etc.<br />
<br />
<br />
<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgQy_ZqJ9TvzddgJ46jrmTo-RyY53qU6MNfqTCIvAGAGhCYeCCXOpG9NqLVtWcCWCSCT94d_JFMDFwurLGFyyWgkxNzeEaH0D4lUOuvpYZVuYysOTWWgMJUn-AiitiQY6Xw6JkZQJCbsSZc/s1600/IMG_3168-cfpla-to-pc-overall.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgQy_ZqJ9TvzddgJ46jrmTo-RyY53qU6MNfqTCIvAGAGhCYeCCXOpG9NqLVtWcCWCSCT94d_JFMDFwurLGFyyWgkxNzeEaH0D4lUOuvpYZVuYysOTWWgMJUn-AiitiQY6Xw6JkZQJCbsSZc/s320/IMG_3168-cfpla-to-pc-overall.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Here is the original tiny sample in the palm of my hand.</td></tr>
</tbody></table>
<br />
<br />
<br /></div>
Jeremie Francoishttp://www.blogger.com/profile/02984201174566394892noreply@blogger.com0tag:blogger.com,1999:blog-3615478772815290200.post-57190265744602451302016-08-18T11:03:00.004+02:002016-08-18T20:27:21.119+02:00A huge and unique cross-cultural fablab in Europe!<div dir="ltr" style="text-align: left;" trbidi="on">
I was wondering what <a class="g-profile" href="https://plus.google.com/+FlorianHorsch/posts/bZjjNCzb9Gs" target="_blank">+Florian Horsch</a> was doing lately. If you are a reader of this blog and do not know already about this great person, you may remember him because he kindly invited me the <a href="http://www.fabcon-germany.com/en/homepage.html">Fabcon</a> conference for a speech about <a href="http://www.tridimake.com/2014/05/the-businessman-and-maker.html">the businessman and the maker</a> in Germany, 2014. I would have bet he was on a novel and useful project, but I did not expect it to be this big and humanist.<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg2fCs5chMKLgYuEiX3WqH6ZwVsgXteoAx2rosIvCh3tYBrXuq6ygTK3nDa33J8SDTnIexBl9yL3RD6wVGvalwp2OWosWHidOxJEU1kM83AfnY3tDGqUhbK9pvKUP1o9jfXQ2bkaGElWrvi/s1600/image2.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="360" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg2fCs5chMKLgYuEiX3WqH6ZwVsgXteoAx2rosIvCh3tYBrXuq6ygTK3nDa33J8SDTnIexBl9yL3RD6wVGvalwp2OWosWHidOxJEU1kM83AfnY3tDGqUhbK9pvKUP1o9jfXQ2bkaGElWrvi/s640/image2.JPG" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">One of the biggest European fablab (725m²), and most probably the most inter-cultural one!</td></tr>
</tbody></table>
<div>
<br />
<a name='more'></a><br /></div>
Here we know: he was busy with a cross-cultural NGO startup named <a href="http://soupandsocks.eu/">Soup and Socks</a> setting up a huge fablab in Norhern Greece, named habibi.works (<i>habibi</i> is one of my favorite word in Arabic, which means "close friend/brother" -- I am using my other best favorite to close this post!). Soup and socks is already helping migrants and refugees: "we act with people in need".<br />
<br />
Now this specific project of a fablab is unique it its own. Beside its size, its location is unexpected. You will find it in Northern Greece... 200 m "only" from a refugee camp. So it adds a bridge between cultures and populations to the already nice values of a fablab. This will make the place certainly even more creative!<br />
<br />
I consider it one of a few outstanding and practical ideas to try and connect so painfully named "heterogeneous populations" in order to reduce cultural and ethnics misconceptions ... and plain racism.<br />
<br />
Easy <a href="https://en.wikipedia.org/wiki/A_priori_and_a_posteriori">a-priori</a> made by who-does-not-want-to-tackle-the-whole-as-a-whole are the root of an increase in fascism all around the world right now, and obviously in Europe (this is weird since it knows too well about the danger of fascism...).<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhY1sAR_zPrtc_YnPeCDtv64SWQyW9VB6o1NtQSo_dnM64ux8YZozfinWmEd9BWE9IBSlmDS5SHiF4eqa6P6LxIucs4APZtniz79yvSQolmVw0ZzZgyMAhNrx-rtkLFGkdweyHGLjZoBXcw/s1600/Screenshot_20160818_095521.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="362" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhY1sAR_zPrtc_YnPeCDtv64SWQyW9VB6o1NtQSo_dnM64ux8YZozfinWmEd9BWE9IBSlmDS5SHiF4eqa6P6LxIucs4APZtniz79yvSQolmVw0ZzZgyMAhNrx-rtkLFGkdweyHGLjZoBXcw/s640/Screenshot_20160818_095521.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Europe, and the world is small. Borders are killing us all. Cooperation, education, respect is the key to a safe world.<br />
Greediness and aggressiveness trigger and fuel wars and so-called terrorism (which imho may only be despair).</td></tr>
</tbody></table>
Aggressive attitudes towards migrants and refugees, and even more generally towards the "other" do create wars, it kills people, it increases poverty worldwide, and it definitely makes a world less safe for everyone... Too many people naively believe on the opposite: closing borders and refusing to give help where help is needed is shooting one's (and the others') own foot in the long term.<br />
<br />
As our dead <a href="https://en.wikipedia.org/wiki/Coluche">Coluche</a> said decades ago, cynically as usual: "if you do not help and give them food they will come and eat in our plates". His humor was pretty spot on as usual. Some are even so desperate in our societies so tightly ruled by the richest that they also <a href="http://www.tridimake.com/2015/01/sad-day-for-intelligence-and-respect.html#more" target="_blank">use Kalashnikovs</a> to try and have their voice heard (even though the message is inarticulate, and overall a pity).<br />
<br />
Back to habibi.works fablab. Beyond direct needed help, which is being given by many NGOs, the project reminds me of the few remote villages in Italy that <a href="http://www.aljazeera.com/indepth/inpictures/2016/04/refugee-settlement-programs-save-dying-italian-villages-160421113908416.html">willingly called and welcomed migrants</a> and refugees for the benefit of everyone years ago. Economical integration is as important as tolerance, if not more. Both are heart-warming stories and pretty smart ideas made real.<br />
<br />
Now, I cannot imagine the difficulties the habibi.works team went through, digging its path through legal stuff, through misconceptions, locally and globally. They certainly did not count their time and energy to get up to this point. Just being able to open it is a milestone in humanism in my opinion, because it certainly helped everyone to get a better view and respect of each other, that the main media seldom give (not to cite many toxic and short-sighted politicians...). It gives hopes and skills to the migrants also, in the first place.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen="" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/KpftcTMNQ_w/0.jpg" frameborder="0" height="266" src="https://www.youtube.com/embed/KpftcTMNQ_w?feature=player_embedded" width="320"></iframe></div>
<div class="separator" style="clear: both; text-align: center;">
<span style="font-size: x-small;">Check also <a href="https://www.google.com/maps/@39.610737,20.9051382,3a,75y,90t/data=!3m8!1e1!3m6!1s-0-c64AOdDZY%2FV7RIwJfXI3I%2FAAAAAAAAAAo%2Ftvf0AaZO4u0-6ce1dmot-9fdo7vqxDeMwCLIB!2e4!3e12!6s%2F%2Flh4.googleusercontent.com%2F-0-c64AOdDZY%2FV7RIwJfXI3I%2FAAAAAAAAAAo%2Ftvf0AaZO4u0-6ce1dmot-9fdo7vqxDeMwCLIB%2Fno%2Fphoto.jpg!7i8704!8i4352">this dynamic, 360 degree view</a> of the inside!</span></div>
<br />
Obviously, as a non-profit organisation, Soup and Socks is welcoming funding.<br />
<br />
It is not to open the fablab: as it <a href="https://soupandsocks.eu/habibi-works-coming-soon/">happens right now</a>. Both migrants and local people are already on-board, they already want to build projects, they want to attend workshops. Funding is actually needed to keep the running costs covered: as far as I could read, this is less than $1500, which is certainly not a lot for the size of the project (Soup and Socks is no huge NGO where money sometimes sadly "leaks" all everywhere). For example, the campaign is backed by Indiegogo's social branch, namely <a href="https://www.generosity.com/education-fundraising/habibi-works-a-fablab-of-freedom">generosity.com</a> where no commission applies, but donations are of course welcome directly and with different means like paypal <a href="https://soupandsocks.eu/donate/">here</a>.<br />
<br />
I want to stress it out: projects like these are for the benefit of everyone, well beyond the village of Katsikas, beyond Greece, and even beyond Europe. States should spend more money on collaborating actions to "address today's most pressing social challenges" (as stated by the 258 year-old charity videos from <a href="https://www.youtube.com/watch?v=qOP2V_np2c0">The RSA</a>). Instead, we spend millions on building fences, and on sending people back to a place they flee away, whatever the reason.<br />
<br />
Seriously, nobody wants to leave his own house and family, to go and cause trouble abroad... unless he is a fascist or he greedily wants the oil of his brother, seeding long-range and long-term trouble all around, up to his own place in the end.<br />
<br />
In two words: <i>Yallah habibi</i> :)<br />
<div>
<br /></div>
</div>
Jeremie Francoishttp://www.blogger.com/profile/02984201174566394892noreply@blogger.com0tag:blogger.com,1999:blog-3615478772815290200.post-55240536355016237192016-06-02T02:22:00.005+02:002016-06-02T21:24:04.021+02:003D printing nozzle characteristics<div dir="ltr" style="text-align: left;" trbidi="on">
<h2 style="text-align: left;">
Nozzle shapes and nozzle materials</h2>
Obviously the nozzle diameter is one of the major parameters when 3D printing. But you may have wondered about the many nozzle <i>shapes</i> that are available on the market. Some brands have preferred shapes. And, even though will not have a drastic impact on the print, they may be significant and worth a post.<br />
<br />
<h3 style="text-align: left;">
Overall length of the nozzle?</h3>
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEirmQwNzGh3BnCqtcQe2rLy7thmjPN3um8tD35BKUpkq87y_MxiQWtDVKOcaQtGIxg7sPztvyBBKq8eyutG-Vse1bsuAZdBDXhOGsr9Zyv3XtHoYZUt9wKsTmcQemoL0tCX5Q5vEUrYvTqs/s1600/makerbot_vs_ultimaker_nozzle.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="165" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEirmQwNzGh3BnCqtcQe2rLy7thmjPN3um8tD35BKUpkq87y_MxiQWtDVKOcaQtGIxg7sPztvyBBKq8eyutG-Vse1bsuAZdBDXhOGsr9Zyv3XtHoYZUt9wKsTmcQemoL0tCX5Q5vEUrYvTqs/s320/makerbot_vs_ultimaker_nozzle.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Marketbot vs Ultimaker nozzles.<br />
Both are quite long, <span style="font-size: 12.8px;">but the former </span><span style="font-size: 12.8px;">has a</span><br />
<span style="font-size: 12.8px;">bigger </span><span style="font-size: 12.8px;">flat ring </span><span style="font-size: 12.8px;">around the nozzle hole.</span></td></tr>
</tbody></table>
In my opinion, long nozzles are more convenient for cleaning, and they let more cooling air flow around.<br />
<br />
Shorter nozzles reduce heat loss a bit and they probably give a better control and reading of the temperature (remember: the sensor is on the heating block, not on the output).<br />
They could arguably help to reduce the overall length of the hot end, so they reduce could positioning error slightly. And they may spare a few grams... But this is marginal and for the most hard core players: they will not help make a bad design better!<br />
<br />
<a name='more'></a><br />
<br />
I suspect shorter nozzles are more popular nowadays not because of the intrinsic value to the user, but mostly because they use less material for the manufacturers!<br />
<h3 style="text-align: left;">
With or without a flat ring around the throat?</h3>
This characteristic has a bigger impact than the length in my opinion.<br />
<br />
"Pointy heads" like the latest Ultimaker 2 nozzles reduce the unwanted heat transfer to already deposited material, as the surface in contact is smaller. And, just like the longer nozzles, they offer a better view on what is going on. Now, the thinner and the more fragile: crashing hardly the hot end on the print surface may deform the nozzle beyond repair.<br />
<br />
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg0RPIHyXc-gPJYEX-7mQwSGkMM7qDzatmjjP9xPaQ3RXnZKu4tl4_cI3BK814s74Mja0yl-ulxFSOOP92oG32KLO0JRf8GC8wmPoBxNHge_fHEetUftX4rS5s7zJegFf-ShNzjPpth0xFX/s1600/protoparadigm_trace_cross_section.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="274" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg0RPIHyXc-gPJYEX-7mQwSGkMM7qDzatmjjP9xPaQ3RXnZKu4tl4_cI3BK814s74Mja0yl-ulxFSOOP92oG32KLO0JRf8GC8wmPoBxNHge_fHEetUftX4rS5s7zJegFf-ShNzjPpth0xFX/s320/protoparadigm_trace_cross_section.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Flat outer ring around the nozzle (in gray) let you print<br />
larger than the nozzle diameter! (source: an interesting<br />
<a href="http://www.protoparadigm.com/news-updates/filament-tolerances-and-print-quality/">protoparadigm analysis</a> on filament tolerances).</td></tr>
</tbody></table>
I usually prefer flattened heads though, like that of the Makerbot above, or as shown on the left: they allows fatter threads, as they get squeezed in between the nozzle and the previous layers.<br />
For the same reason, they withstand better abusive flows (e.g. to get a sturdier part, but I mean 102 or 103% extruded rate, not more!).<br />
<br />
And while they drag more existing material around, flattened ends tend to "clean" existing blobs of plastics better than pointy nozzles.<br />
<br />
The main drawback is that they transfer more heat to the already deposited material. For tricky parts like a very small tower, they do have a negative impact without <a href="http://www.tridimake.com/2016/05/3d-printing-cooling-with-air-pump-aquarium.html">proper cooling</a>. Better activate so-called Z-hop or "retracted" cooling in between layers, instead of staying in contact while trying at the same time to give more time for the layer to cool down (so-called "minimum layer time")!<br />
<br />
So without a flat ring on the end, you need a well tuned setup and a very repeatable positioning. Even a slight over-extrusion will give dirty prints, like furrows in the layers.<br />
<br />
Overall, I recommend nozzle shapes without a flat outer ring only for small diameters (e.g. <a href="http://www.tridimake.com/2013/05/3d-printing-with-smaller-nozzle-diameter.html">less than 0.4 mm</a>) and for high quality prints. Most of the time, a significant flat end is both better and sturdier in my opinion.<br />
<br />
<br />
<h3 style="text-align: left;">
Size markings</h3>
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhGNhR_onrfcxfbbhg0Ukbd3VZp-LNvADJs9dFDAEaay6oeAwuS0dB47KfOyMRW26vEbEa7uYK1IsUqGzu194e71tqpQFTwm3l9qxARoc0ZvTKJGrhHKqcOLb_-SstcS-jkqKzmazeVSOcB/s1600/2016-06-01-224418.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhGNhR_onrfcxfbbhg0Ukbd3VZp-LNvADJs9dFDAEaay6oeAwuS0dB47KfOyMRW26vEbEa7uYK1IsUqGzu194e71tqpQFTwm3l9qxARoc0ZvTKJGrhHKqcOLb_-SstcS-jkqKzmazeVSOcB/s320/2016-06-01-224418.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Explicit, useful embossed size of the nozzle (0.8mm).<br />
I think this recognizable shape was introduced by E3D,<br />
but I suspect <span style="font-size: 12.8px;">the main motive was to spare material!</span></td></tr>
</tbody></table>
As soon as you have different nozzles, having a way to identify them precisely is a must, unless you manage to keep them on separate boxes (but now, what is the size of this nozzle on that spare printer I did not use for months?).<br />
<br />
And even it is somehow possible to guess the size with the naked eye and some practice... and when the nozzle is clear. It is impossible when it was left with plastic in or around it (the usual end result of a print unless you <a href="http://www.tridimake.com/2012/10/clean-hotend-and-nozzle.html">clean it</a> thoroughly).<br />
<br />
Some manufacturers use cryptographic dots (huh), some have explicit sizes (which I like better), but in any case more of them are doing it.<br />
<br />
Now, when you do not have any markings on your existing nozzle, just make them yourself with a small file on the side: one mark for each 0.1 mm for example.<br />
<br />
<h3 style="text-align: left;">
The inside shape</h3>
<div>
Here again there are different strategies, but no definitive answer in my opinion.<br />
<br />
I only would recommend to stay away from uselessly thin conduits like that on markerbots below: they uselessly increase the friction due to the viscosity of the material, especially at low temperature.<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhV3pRaKc0wqDSHli2icCQqcvpg216Adurin61ULQy1gJdoh7p_kgVhfMvQj24jKVoHhFNKBRQ9CiedXsM04otTfr01BsdNi3XYhl5P_uETxPNEKnfBl4NMtyS8Ozb0wjaAhsnnYYpjwbbO/s1600/nozzle-cutaways-labeled.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="361" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhV3pRaKc0wqDSHli2icCQqcvpg216Adurin61ULQy1gJdoh7p_kgVhfMvQj24jKVoHhFNKBRQ9CiedXsM04otTfr01BsdNi3XYhl5P_uETxPNEKnfBl4NMtyS8Ozb0wjaAhsnnYYpjwbbO/s640/nozzle-cutaways-labeled.jpg" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Comparison of the inside of 3 nozzle shapes, from <a href="http://www.jerrill.com/blog/2013/04/whats-in-a-nozzle/">Jerril.com</a>. Stay away from uselessly thin and long cavities!</td></tr>
</tbody></table>
Too short terminal throats like that of the middle nozzle above are no good either. The filament should better stay "straight" for some distance before getting out (3 or 4 times the diameter of the nozzle). Else it bends once out, which is annoying when priming.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi2y5OxtgCgUtna7JOE7ogl5JXkgHWkYOPlboRK8Bi8RyztBCfi3ObB9WUfSveHCPI105q1ZIOHWu45eM293U5iYdWBEu51Y8LSrLMgujzyP3lwrIMOcdoco9FcahdFi7Yqyu66Xkbsom9k/s1600/1mm_nozzle.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi2y5OxtgCgUtna7JOE7ogl5JXkgHWkYOPlboRK8Bi8RyztBCfi3ObB9WUfSveHCPI105q1ZIOHWu45eM293U5iYdWBEu51Y8LSrLMgujzyP3lwrIMOcdoco9FcahdFi7Yqyu66Xkbsom9k/s1600/1mm_nozzle.jpg" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Priming a funny <a href="http://www.tridimake.com/2013/07/extremely-fat-extrusion-with-1-mm-nozzle.html">1.1mm homemade fat nozzle</a>, made out of a round head nut.<br />
The conduit is usually too short with such nuts, which tend to bend the filament mid-air.</td></tr>
</tbody></table>
Also, really too short and the the nozzle is weakened: it may deform or blow under the extruding pressure. For this reason, making nozzles out of blind nuts never gave me satisfactory results: manufacturers do not leave enough material to drill nicely through the top of their nuts...<br />
<br />
<a href="https://plus.google.com/114722716901025057698/about">Ryan Carlyle</a> raised another property, the <i>interior taper angle,</i> which may be very hard to know from the outside. Let me quote him from the comments of this post: "[...] a steeper drill taper between the full-bore section and throat decreases extrusion back-pressure and improves reliability. For example, E3D recently switched from two 120 degree bits in a stepped profile to a single steep taper drill bit. Makerbot made that switch years ago. (Molten polymers are <a href="https://en.wikipedia.org/wiki/Viscoelasticity">viscoelastic</a> and don't like to change diameter and linear velocity fast)". I suspect that a <a href="http://www.tridimake.com/2013/04/rollerstruder-filament-feeder-driver.html">proper extruder</a> will generate enough pressure to overcome this viscosity, but in any case when you need to know about chemistry and material properties, Ryan is extremely knowledgeable!<br />
<br />
<h2 style="text-align: left;">
Materials</h2>
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjGnlWdz-b2Zw2edbXcnfWoc9TgS8dnXuKPakPow33kjR5yuNL-ghtAWfTWKLw3jxzHjX0TTLLF4fsn-zRY23PNffUg-j2HqQ78tTe_Kn6XrkZGyD78Kdtz9c52rF9dB9FefuGlgNx3DjBQ/s1600/1mmNozzle.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjGnlWdz-b2Zw2edbXcnfWoc9TgS8dnXuKPakPow33kjR5yuNL-ghtAWfTWKLw3jxzHjX0TTLLF4fsn-zRY23PNffUg-j2HqQ78tTe_Kn6XrkZGyD78Kdtz9c52rF9dB9FefuGlgNx3DjBQ/s200/1mmNozzle.jpg" width="200" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">A 1 mm nozzle, made out of<br />
a 6mm brass threaded rod</td></tr>
</tbody></table>
Nozzles were originally made out of brass, a nice material to work with at home (see my thoughts about <a href="http://www.tridimake.com/2014/03/thoughts-and-hints-around-hot-ends.html">hot ends</a>).<br />
<br />
At some time, a few "single body" were available (integrated heating block + nozzles), mostly to get rid of any possible leak. They were often all aluminum because of the heating requirements, but this material is just too soft as a nozzle: after a crash on the bed, the nozzle will deform and it is quite impossible to bring it back into shape.<br />
<br />
More nozzles are produced out of stainless steel nowadays. This is not because they print better but because they wear out slowly compared to brass, as shown in this <a href="http://e3d-online.com/is-carbon-killing-your-nozzle">detailed analysis by E3D</a>.<br />
<br />
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; text-align: right;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhF13FJzI8HlDnSyjFYHEFpIx-2LiMqbeP_I1zvkp3IVjHUWNljZX57X9h_SbiWNZgeryoXe2gve0W4nzRb_AAe2fnH6dyq6X5SFrqoU5KrUU1890ENKDYxRcpYoOjWneQNQ6cPT19vXVJT/s1600/HeadOnComparison.jpg" imageanchor="1" style="clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" height="171" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhF13FJzI8HlDnSyjFYHEFpIx-2LiMqbeP_I1zvkp3IVjHUWNljZX57X9h_SbiWNZgeryoXe2gve0W4nzRb_AAe2fnH6dyq6X5SFrqoU5KrUU1890ENKDYxRcpYoOjWneQNQ6cPT19vXVJT/s200/HeadOnComparison.jpg" width="200" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Head-on comparison of brass<br />
and stainless steel nozzle subjected<br />
to abrasive filament (<a href="http://e3d-online.com/is-carbon-killing-your-nozzle">E3D</a>)</td></tr>
</tbody></table>
A noticeable effect remains to be proven here but I would think that, as a better thermal insulator, stainless steel probably keeps the flowing core closer to the heater block temperature and independently of the changing and active cooling conditions around it. Reciprocally it will conduct the heater block heat less than plated brass for example...<br />
<br />
Stainless steel is obviously recommended for abrasive filaments, like carbon-fiber, chalk- or metal- loaded <a href="http://www.tridimake.com/2014/07/3D-printing-material-for-artists-bronze-wood-chalk.html">special polymers</a>. Interestingly, the 4-5 Kg of Protopasta CFPLA that went though my nozzles did not wear any of my nozzles. This may be due to a lower content of carbon than that of other brands (given this <a href="https://plus.google.com/+JeremieFrancois/posts/KkfjTxa1MMn">comment</a>).<br />
<br />
<br />
<h2 style="text-align: left;">
Brands names vs. cheap stuff?</h2>
<br />
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhpYRkfZLdGatBI-JeyvoJVvq4qAjy5qnP4UaspkPn8I2JZ2OjTzN-fqpl2vRRbct59AoCZQX2ayRswxTciCelpv07v33dNtOmZW7BdP7NqB2TCJCuNVGJfx7Ot_QY2j0Q6Lkz9SF2_NtBO/s1600/2016-06-01-224453.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhpYRkfZLdGatBI-JeyvoJVvq4qAjy5qnP4UaspkPn8I2JZ2OjTzN-fqpl2vRRbct59AoCZQX2ayRswxTciCelpv07v33dNtOmZW7BdP7NqB2TCJCuNVGJfx7Ot_QY2j0Q6Lkz9SF2_NtBO/s320/2016-06-01-224453.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">The quality of this 0.8 mm Chinese nozzle is<br />
pretty decent for such a price (<a href="http://rover.ebay.com/rover/1/711-53200-19255-0/1?icep_ff3=2&pub=5575160029&toolid=10001&campid=5337834253&customid=&icep_item=291751131663&ipn=psmain&icep_vectorid=229466&kwid=902099&mtid=824&kw=lg">$1.59</a> on ebay!)</td></tr>
</tbody></table>
I used to make my own nozzles, and I tried many commercial ones (not all of them obviously, and some like the <a href="http://www.dura-gem.com/blog-1/">dura-gem nozzle</a> are really interesting).<br />
<br />
I recently bought a few $1.59 stainless steel nozzles from ebay to give them a try (0.24, 0.4 and 0.8 mm)... And I must admit that they are good enough to the point I will probably never make my own again (hey, it was years ago, when a lack of choice and of competition kept prices much higher!).<br />
<br />
But I still have a few comments and recommendations...<br />
<br />
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjfPo00KilnPudohMxhlZvGNJjdIlNub6ogGQjqm6LO-6sa4NCYhYGzI0nNF6HzUPjUMwSY1ijBmkclwbgRsmGj6VG0gncsmrOhmiQN5bRe22D-CUmSAZMc-4QsFZg28nBFVnys5B3yHZZt/s1600/2016-06-01-224534.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjfPo00KilnPudohMxhlZvGNJjdIlNub6ogGQjqm6LO-6sa4NCYhYGzI0nNF6HzUPjUMwSY1ijBmkclwbgRsmGj6VG0gncsmrOhmiQN5bRe22D-CUmSAZMc-4QsFZg28nBFVnys5B3yHZZt/s320/2016-06-01-224534.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">The inside is not well polished. No biggie at this stage where<br />
the <span style="font-size: 12.8px;">filament is fully molten (not much friction to be feared).</span><br />
This would certainly not be good for a barrel though!</td></tr>
</tbody></table>
First, the inside is not well polished, as you can see on the picture on the right: this is no surprise as it is a costly part of the process... PLA sticks well to stainless steel, contrary to most other materials. Would <a href="http://www.tridimake.com/2014/03/thoughts-and-hints-around-hot-ends.html">the barrel</a> be so badly polished it would be a major no-go (the barrel is where the heat melts the filament, and where most of the friction occurs).<br />
<br />
But I do not think non-polished nozzles are a problem. The filament is fully molten at this stage and the drilled hole is much larger than the throat diameter. Interestingly some manufacturers offer 1.75 and 3mm filament-specific nozzle variants, but I doubt it matters a lot: molten 1.75mm is the same as molten 3mm for a given nozzle output. (it may not be so obvious though given the interior taper angle we talked above).<br />
<br />
To stay safe and given poor polishing, I would still recommend to buy the "3mm-filament nozzles" even when your printer uses 1.75 mm filaments. Admittedly, it may ooze a bit more as the "magma" chamber is larger... please tell me if you compare the two!<br />
<br />
<br />
Back to the cheap nozzle: more annoyingly, the outer flat ring is far from being smooth! As shown on the picture below, this $1.59 is certainly do not compare to a perfect high-end $21 hardened steel E3D nozzle... no surprise again, quality comes at a price!<br />
<br />
Even such tiny artifacts on the outer flat ring can be seen on fine prints. Also, the initial extruded plastic bends as soon as it it out when extruding in mid-air, because some tiny speck slows it sideways. As a consequence it often loops back on the nozzle itself, which is dirty when we are priming specifically to have a clean start! Interestingly, it does not happen that much on this specific nozzle, probably because of the chamfer they added on the inside (may be to reduce this problem cheaply!?)<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEja0O7ggyn0LkVjlWXFXeR6-yMvr_PVRPr36gta-rmOPVbkqU3rHHhNgKIO_vdNPmYma1ypekRuNDnSthlg1ErY3-fXiV2Lw3Ndb5ze08ndsWYDI30lksndKuiyJOxzxPY_STt4ZkQqQLFJ/s1600/2016-06-01-230706.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEja0O7ggyn0LkVjlWXFXeR6-yMvr_PVRPr36gta-rmOPVbkqU3rHHhNgKIO_vdNPmYma1ypekRuNDnSthlg1ErY3-fXiV2Lw3Ndb5ze08ndsWYDI30lksndKuiyJOxzxPY_STt4ZkQqQLFJ/s320/2016-06-01-230706.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">The tip is ugly though. The nozzle throat itself is OK (was it "cowardly" chamfered?!).<br />
But the defects of the flat ring <span style="font-size: 12.8px;">produce slight but visible artifacts on the </span><span style="font-size: 12.8px;">printed surfaces,<br />and they are</span><span style="font-size: 12.8px;"> annoying when priming </span>as the filament bends back on itself or onto the nozzle.</td></tr>
</tbody></table>
<br />
All in all it is a bargain at this price. Moreover it can be <a href="http://www.tridimake.com/2014/05/the-businessman-and-maker.html">improved at home</a> with some polishing (either with a polishing stone or with extremely fine sanded paper, and very gentle pressure).<br />
I just will have to be very cautious to keep it perfectly flat as any angle here will have a large impact when the filament tends to flow in an <a href="https://en.wikipedia.org/wiki/Anisotropy">anisotropic</a> way. The best way to proceed would probably be to mount the nozzle on a longer threaded tube.<br />
<br />
<br />
<br />
<br />
<br /></div>
</div>
Jeremie Francoishttp://www.blogger.com/profile/02984201174566394892noreply@blogger.com2tag:blogger.com,1999:blog-3615478772815290200.post-74053303025892519572016-05-27T13:27:00.003+02:002016-05-27T16:59:05.926+02:00PC crash: back to a working state in 5 minutes!<div dir="ltr" style="text-align: left;" trbidi="on">
For the last 15 years, both my hardware and system upgrades always evolved AROUND my work, <b>and not the opposite</b>! The overwhelming majority of configuration files, preferences and application shortcuts survive through both system software and hardware upgrades for decades... when you are running Linux.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjwXimM0bjJ_40MykLLCZx7MCHm_72cRbBTSjSgYFhIFLQayh-19LS25aVvdSgF3Cm3MTr3-AEuKX_K-yqENjdJii1IPh2ZJ0UVbjJfBakjWhY5_KxUT_ou7wls3WR7HncOt4tVFfPhGg1o/s1600/hardware_change_on_linux_is_too_easy.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img alt="linux beats them all - crashed my pc had urgent work to do moved 2 hard drives took me 5 minutes back to work" border="0" height="360" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjwXimM0bjJ_40MykLLCZx7MCHm_72cRbBTSjSgYFhIFLQayh-19LS25aVvdSgF3Cm3MTr3-AEuKX_K-yqENjdJii1IPh2ZJ0UVbjJfBakjWhY5_KxUT_ou7wls3WR7HncOt4tVFfPhGg1o/s640/hardware_change_on_linux_is_too_easy.jpg" title="linux efficiency with hardware" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Linux is never putting its foot in the door. Focus on your work, it even keeps your preferences and settings.</td></tr>
</tbody></table>
Yesterday night my motherboard died without warning (hopefully it is not my high end i7 CPU!). I had work in process to deliver, and some of it was not synchronized with my remote servers yet.<br />
No biggie! I brought my 4-year old old Core2 duo Desktop back from the dust in the garage, I plugged my hard drives into it, and I booted.<br />
<br />
Bang, back to work in 5 minutes in the exact same state. Linux is so useful and so efficient!<br />
<br />
So why is it so easy to change your computer on Linux without impacting any of your own data and preferences?<br />
<div>
<br /></div>
<br />
<a name='more'></a><br />
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjFC0tDdLF25iNiHQWjP3MQukks1LZVjpJA8EhYpdYhJzaVy-7Rf1Id-U9MjsMz4xX4j_Y88s9AzSw18bpNL5gRO2Rs-un0afIpvfRE-wnz6RR2GeqQP-vM6P-SSNcWC-CpPvbRl_-5-yV3/s1600/Windows_Vs_Mac_Vs_Linux.jpeg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="298" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjFC0tDdLF25iNiHQWjP3MQukks1LZVjpJA8EhYpdYhJzaVy-7Rf1Id-U9MjsMz4xX4j_Y88s9AzSw18bpNL5gRO2Rs-un0afIpvfRE-wnz6RR2GeqQP-vM6P-SSNcWC-CpPvbRl_-5-yV3/s320/Windows_Vs_Mac_Vs_Linux.jpeg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Via <a href="http://itsfoss.com/10-funny-jokes-pictures-windows-mac-linux/">itsfoss.com</a> (who is the author?)</td></tr>
</tbody></table>
In comparison, reinstalling windows (prior to Windows10?) would probably take between 1 and 5 hours, and then you need to re-configure it most of it if not all. The funniest was at a time when a virus could slip from the internet in even before you had a chance to upgrade and install an anti-virus, so the hole is secured. So ridiculous!<br />
<br />
And reinstalling a Mac... Well, who really re-installs a Mac? One buy a new one ;)<br />
<br />
I have just checked: the old PC I am typing on right now is in fact 5+ year old, as the production of its CPU stopped in 2011. It just plain runs, I compile my C++ project, I use the latest Chrome browser and I use Jetbrains PHP IDE just as yesterday. It is almost boring (and quite slower for these tasks!)<br />
<div>
<br /></div>
Actually I admit I like how people react in awe when I tell them how easy it is to bring my work to a new PC running Linux... Buy, copy your home folder, add a few missing and safe applications with two clicks and a few keystrokes and start working.<br />
<ul style="text-align: left;">
<li>First, Linux is not "locked" onto the PC you bought. Windows and MacOS are deeply attached to the very hardware they were installed on, so that when you change your computer you need to pay again for a licence instead of re-using the same drive on the new computer (<u>update</u>: Windows10 seems much better in this regard -- I must admit I stopped counting some time ago and I need to try this last one, check the comments below). They say it is for security reasons, but they simply want your money in the first place.</li>
</ul>
<ul style="text-align: left;">
<li>Linux checks for all the hardware and each time it boots. This is incredible since it still boots faster than the other systems. It also supports an amazing variety of plug and play hardware out of the box, without the need for additional and sometimes conflicting drivers. As such, Linux makes no "definitive" choice when it is being installed. Now, MacOS does it well here since you mostly have no choice of hardware anyway.</li>
</ul>
<ul style="text-align: left;">
<li>All of this makes it backward-compatible to older machines, as in my case here! No other bloated and locked OS would allow this. And when you might succeed, your PC would feel sluggish which is just not my case (Linux does nothing when you do nothing, and writing a post in a browser for a blog is just considered doing nothing for a well-optimized OS).</li>
</ul>
<ul style="text-align: left;">
<li>Eventually, and more importantly even, your data is in YOUR folder and only in your folder. It is not fragmented everywhere in the system or on the cloud. When the system goes down, your data is still in YOUR hands. This includes almost everything, from application settings and preferences to wifi network passwords. Even when fully re-installing a Linux, you will need only a few "apt-get install the_application" and you feel at home with the_application, just as before. In fact, your home is better on a separate hard drive, but you could move it even remotely without any impact on the system, or even on a USB drive: it will not prevent nor complain about your choice. It is your own data, it is not under the control of the operating system, and it is even less under the control of a 3rd party company. MacOS switched to a Unix kernel with appropriate user separation a while ago so it might be quite good here, in addition to Apple owning all your stuff remotely ;) It will not be as transparent as Linux by the very nature of Macintosh own self-esteem (check, e.g. "without using itunes" on Google which spits out 45M results!).</li>
</ul>
<br />
So upgrading or downgrading the hardware and the system has usually no impact on your work, your files, your network configuration, your preferences and even the configuration of the system.<br />
<br />
Think about it the next time you have a hardware failure, or even when you simply buy a new machine. Wouldn't it be cool to feel back <i>at home</i> immediately? An application is missing? Just apt-get install it and you're productive again, even with your settings, shortcuts and your very own "last opened files" in the menu. Try to beat this!<br />
<h2 style="text-align: left;">
Pros and cons of Linux vs Windows or MacOS imho.</h2>
If you really want to hear my point, keep on reading...<br />
<br />
One of the increasing advantages of Linux today is security. There are no trojans and more importantly even, it is safe from the <a href="http://us.norton.com/yoursecurityresource/detail.jsp?aid=rise_in_ransomware">increasingly dangerous ransomware</a>.<br />
Note that scarewares are even funnier: they ask you for money or they say they infect you...<br />
<br />
How to deal with it? Just ditch this unsafe crap and move to Mac OS or, better imho, to Linux.<br />
<br />
I switched our parents a decade ago. Honestly, they do as much and they complain as much as when they were on Windows! But my own life got much better since! No more headache, no more fear they install something nasty. In fact they probably do not even know about being root so they cannot screws the machine themselves. In the worst case I can even <a href="http://www.oz4.us/2015/10/linux-restricted-tunneling-handling.html">control they PC, securely and from anywhere</a>, wherever they are. I only check or upgrade their PC once a year or so. Using Ubuntu <a href="https://wiki.ubuntu.com/LTS">LTS versions</a> is very convenient: the release from 2014 will live until 2021. And still, I can upgrade without expecting any trouble.<br />
<br />
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; margin-left: 1em; text-align: right;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiy9s8FbujAVJ97qosAEjN7PpjG8dL-vVTa24vjAAhv39dU8YFYtQueDtYojxBxW975FPzVSUJsFP7bwfNtoXEAODV8zanZ5pxycfnmPtG_raFmFRWrf4xiqYjXy-CRCUECvHtaS3EnjPPu/s1600/upgrades_Windows_Vs_Mac_Vs_Linux.jpg" imageanchor="1" style="clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" height="195" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiy9s8FbujAVJ97qosAEjN7PpjG8dL-vVTa24vjAAhv39dU8YFYtQueDtYojxBxW975FPzVSUJsFP7bwfNtoXEAODV8zanZ5pxycfnmPtG_raFmFRWrf4xiqYjXy-CRCUECvHtaS3EnjPPu/s320/upgrades_Windows_Vs_Mac_Vs_Linux.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">By Christiann MacAuley at <a href="http://stickycomics.com/">stickycomics.com</a></td></tr>
</tbody></table>
On Windows I no more recommend anything else than open-source software, or sometimes old and reliable freeware. Actually even the opens-sourced <a href="https://notepad-plus-plus.org/">Notepad++</a> managed to beat Ultraedit (pleaaase stop using the pitiful incompetent notepad!). People shall better use extreme caution with new shareware or freeware, because they are to be considered loaded with invisible trojans or even nastier ransomware (unless you consider the latter as "in-app purchase"!).<br />
<br />
In the end, it is a pity because if you need to use open source software on Windows, you would better switch to Linux in the first place...<br />
<br />
As for me, I sometimes work with Windows for clients, but they run exclusively on <a href="https://www.virtualbox.org/wiki/Screenshots">virtual machines</a>. It is so convenient because each of my client work has its own instance of Windows. I can have multiple variants of Windows on my Linux machine(s). Theses systems are just plain single big files when seen from Linux: so I can copy, duplicate, move or backup them just as easily as with files, and move them even from one PC to another (virtual one). When an old software no more exists on recent Windows, I can keep an old version just for it as a simple file (e.g. a 2GB file is largely enough for Windows XP!).<br />
<h3 style="text-align: left;">
Multi-tasking is much more efficient on Linux</h3>
Now as a programmer, Linux gives me an extreme gain in productivity with a real shell, highly reactive, non-invasive and fully controllable multitasking.<br />
<br />
Sure, Windows is multitasking in its way: it does a lot of work in the background while it tells you it is idle.<br />
<br />
And MacOS is also multi-tasked in its own way: it keeps popping up stuff in front of your eye to tell you what it is doing (or not). Oh, and for a multi-tasking OS, well, you have only one menu... for the currently active application! How stupid when you have multiple applications, and more over large or multiple monitors: the active application may be far away from its menu. Miles of mouse movements just to get to the menu and realize it is not the active application! Also, you have to learn many key by heart on a non conventional keyboard (e.g. where is the damn <a href="http://www.computerhope.com/jargon/b/backquot.htm">back-quote</a> on an outrageously expensive Mac keyboard?). I do not call this intuitive at all.<br />
<h3 style="text-align: left;">
Stability concerns on Linux? Fear no more (well, almost)</h3>
For long, stability was the most controversial issue with linux, but it tends to be non-existent nowadays. E.g. my older PC had a NVDIA video cards while my new one was ATI. After rebooting, the screen resolution was set back to the ugly "safe mode". But it took me probably a half of the 5 minutes to fix it -- I just had to run the official corresponding driver again. This is no more as painful as it was 10 years ago :) And Windows has so much trouble by itself that no one can decently say that Linux is less stable than Windows nowadays.<br />
<br />
Even with deeply encrypted hard drives, upgrades are easy. The latter is quite important since I can throw, store or lose old drives and nobody can read them anyway. And in case of trouble, the online community is incredible. Just keep a second, possibly extremely obsolete linux at hand, so you can browse and get the info for the other PC. Oh, everyone has a smartphone nowadays.<br />
<h3 style="text-align: left;">
Market: just an inertia?</h3>
Interestingly, Linux owns the market both for the entry-level hardware (e.g. Rapsberry Pi or other $20 machines, most of the Internet Of Things to come, almost all routers and wifi boxes, and so). No-one else fits here. Linux also owns a large share of the smartphones via Android. It owns most of the internet servers and routers. It finally it also owns all of the supercomputing market...<br />
<br />
As for users, I really think that Windows is there only because it was there for ages. I hear that things may change with Windows 10, and I still have to check by myself. But it has no merit and it did so wrong for so long that it became a pile of gigantic unstable crap. This, even though Microsoft invented many interesting features (e.g. the "Start" menu is among them, which they ditched, then put back...).<br />
<br />
Mac OS is OK-ish to me. I stole most of its features and did not invent a lot more than just well-done marketing. And it sucks a lot of your money for sure since they have the monopoly and will not let other deal with them easily. Many people are OK with that, so why not. I guess many also fear that Linux is too hacky for them, and they want something that works out of the box (which it does since you have no big choice of the box). Also there are those who want a good looking, stylish, but exceedingly standardized object (functionally-wise also). I often redirect them to the <a href="https://en.wikipedia.org/wiki/Stockholm_syndrome">Stockholm Syndrom</a> wikipedia page.<br />
<h2 style="text-align: left;">
Why use a proprietary OS for free software and services?</h2>
The only major trouble with Linux is that once a while people keep on sending you very proprietary files or calls for events, specifically because they are using themselves proprietary software that do not want them to keep their money. However, enterprise slowly switch to opensource tools like <a href="https://www.odoo.com/">odoo</a> ERP or <a href="https://owncloud.org/">owncloud</a>. I helped some and they like it: they get recent stuff, that works transparently across platforms and hardware updates, and they get more options for free... while they keep it entirely under control. Good.<br />
<br />
Sure, there are a few software that are still better on Windows, like Adobe Photoshop or Premiere and many CAD programs (SolidWorks, Catia, and some like Mach3 much more than LinuxCNC). But the opposite is true: many linux software exist that are not so well integrated on windows, especially from programmers. Also more and more software are cross-platform, <a href="http://www.pcworld.com/article/2896797/steam-hits-1000-linux-games-days-after-valves-big-steam-machine-reveal.html">even top notch games</a>.<br />
<br />
Interestingly, I still have to find a single piece of software that exists on MacOS that I would miss on Linux though, and please, no, do not tell me about XCode. So here it is, aficionados: tell me I and will have a look!<br />
<br />
Anyhow, in the age of <a href="https://www.google.fr/url?sa=t&rct=j&q=&esrc=s&source=web&cd=3&cad=rja&uact=8&ved=0ahUKEwia-JPFjPrMAhXHfRoKHWp8ACgQFggpMAI&url=https%3A%2F%2Fen.wikipedia.org%2Fwiki%2FWeb_application&usg=AFQjCNGqrETinQUF9cKLteEFuxMLeHdcww&sig2=Ed0xPtRl3tJoh0lFBfEk4Q">webapps</a> that run in browsers, no OS is really interesting <i>per se.</i> Linux requires less resources to do the same job as others here, so it will probably get more and more shares with time, mostly driven by mobile devices. Making hardware with Linux costs less and is more efficient as the Linux core is very well made and modular. See how all the Chinese tablets run on Android?<br />
It is cheaper and without a loss of features and of quality... I see no reason to complain.<br />
<h3 style="text-align: left;">
Conclusion</h3>
Many people say that switching to Linux is annoying because it differs from Windows or from Mac.<br />
<br />
Hell, sure it is! And this is an incredible chance in my opinion!</div>
Jeremie Francoishttp://www.blogger.com/profile/02984201174566394892noreply@blogger.com0tag:blogger.com,1999:blog-3615478772815290200.post-5747817219585750352016-05-18T22:20:00.002+02:002017-08-22T08:38:12.625+02:00Cooling 3D prints with an aquarium pump<div dir="ltr" style="text-align: left;" trbidi="on">
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; margin-right: 1em; text-align: left;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgAoCoskI6CVkhWIpf3BZvzbdmI8vniUns4kfqS81Z9sXazU5FHMQbtqAgcOcX-CXFydfJmJHF5puUWbsCg1SIL1Pdyz9NiBTAw88P58UpREPUlx6zh-s4H7vFpWV61F-X0MM9LcQxHoJAR/s1600/air_cooling.jpg" imageanchor="1" style="clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgAoCoskI6CVkhWIpf3BZvzbdmI8vniUns4kfqS81Z9sXazU5FHMQbtqAgcOcX-CXFydfJmJHF5puUWbsCg1SIL1Pdyz9NiBTAw88P58UpREPUlx6zh-s4H7vFpWV61F-X0MM9LcQxHoJAR/s400/air_cooling.jpg" width="251" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">3D printing cooled with an aquarium pump!<br />
It works well and it cannot be quieter. T<span style="font-size: 12.8px;">he pump is bulky,</span><br />
<span style="font-size: 12.8px;">but the overall is a very compact hot end.</span><br />
<span style="font-size: 12.8px;">(the above was a preliminary experiment)</span></td></tr>
</tbody></table>
Interestingly, while this trick is not new, very few people seem to use it. For years I had an air pump on a shelf for this purpose. Only recently did I use it, and I really like it better than fan on the hot end.<br />
<br />
The good thing is that aquarium pumps do build some pressure in order to pump air down into water. No regular radial or axial fan can do this, they only move air around. Do not get me wrong: regular fans works well, but the smaller the fan the noisier and the shorter its lifespan. And they are bulky anyhow and obstruct the view.<br />
<br />
Actually, I printed almost years without fans attached to the hot end at all. Instead, I used a large, powerful and silent 120mm PC fan on the printer chassis. It blows a lot of air on the whole part, which is often even better, but it fails to cool down tiny towers or islands when the hot end never move aside (flowing air is very lazy and will not reach tortuous parts). Also, the big fan blows air only from one direction, which shows up on opposite sides.<br />
<br />
So I still needed air again on the head....<br />
<br />
<br />
<br />
<a name='more'></a>By the way, cooling is an absolute must for long bridges, and even though I always try to design my parts to avoid bridges, there are times where it is suboptimal without local cooling.<br />
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen="" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/jfAxOG8FGa0/0.jpg" frameborder="0" height="266" src="https://www.youtube.com/embed/jfAxOG8FGa0?feature=player_embedded" width="320"></iframe></div>
<div style="text-align: center;">
<span style="font-size: x-small;">3D printing in air. One key point for efficient bridging</span></div>
<div style="text-align: center;">
<span style="font-size: x-small;">is to have fast and local cooling (by <a href="https://plus.google.com/114505261653802471003/posts">Erik Cederberg</a>).</span><br />
<span style="font-size: x-small;">In real life, the part should better be printed upside down!</span></div>
<br />
I had bought myself a costly <a href="http://www.amazon.com/Tetra-26075-Whisper-Aquarium-150-Gallon/dp/B000V7KM32">Whisper AP150</a> for this purpose, which is a branded, solid and extremely quiet pump made for aquariums. Sadly, it only runs 110VAC and we are 220VAC here... So I hacked it with a simple power diode (i.e. it gets half waves of 220VAC)... Make sure <a href="https://plus.google.com/+JeremieFrancois/posts/CtoGtyuxuQb">to understand though</a>: the signal is no more sinusoidal and it would probably break many devices. However I checked that this pump had no sensitive components (see at the end of the post). And it does get hot even on long prints. Now, the efficiency is probably halved, or worse...<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen="" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/-GztUQNRGyc/0.jpg" frameborder="0" height="266" src="https://www.youtube.com/embed/-GztUQNRGyc?feature=player_embedded" width="320"></iframe></div>
<div style="text-align: center;">
<span style="font-size: x-small;">My aquarium pump brings ambient air via </span><span style="font-size: x-small;">a latex tube,</span></div>
<div style="text-align: center;">
<span style="font-size: x-small;">down on the freshly deposited plastic. It works well!</span></div>
<h3 style="text-align: left;">
<span style="font-size: small; font-weight: normal;">As you can see in the video, the significant pressure I get from these pumps allows me to use a very soft latex tube, as it will stay open up to the head: no worry that it gets pinched by its own weight when the head moves around when air gets pumped into it. Also since it is very flexible it will obviously not restrict the movement of the head (regular thick plastic</span><span style="font-size: small; font-weight: normal;"> </span><span style="font-size: small; font-weight: normal;">aquarium</span><span style="font-size: small; font-weight: normal;"> tubing would be very wrong here).</span></h3>
<h3 style="text-align: left;">
How did I make the copper nozzle?</h3>
I used copper because I had no other suitable metallic tube. The best choice would be very thin stainless steel tubing, as it would not suck heat from the nearby hot end like copper. Reciprocally, copper is an easy material to shape as you can see below.<br />
<br />
<span id="goog_1118946803"></span><span id="goog_1118946804"></span><br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhzF5AAj4uaU2G-EP4j_8g0QcJ3bKNzEKxa_90DS74z9MFWBZg2Tyc94hr9lESn5auMKRlvfwIndSs4tSj2joO_h4e02qvqjfnlnlOz-tiWftkKCP7DQb01nj8uhVCov0KXayfW6UMESARr/s1600/IMG_1168.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhzF5AAj4uaU2G-EP4j_8g0QcJ3bKNzEKxa_90DS74z9MFWBZg2Tyc94hr9lESn5auMKRlvfwIndSs4tSj2joO_h4e02qvqjfnlnlOz-tiWftkKCP7DQb01nj8uhVCov0KXayfW6UMESARr/s320/IMG_1168.JPG" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Copper tubes are easily bent (even more when heated).<br />
Better insert something so the tube does not flatten too much,<br />
some even fill the tube with sand before bending it.</td></tr>
</tbody></table>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh9D2wK6_h1Q86Y_gWa8aoUhNXAqZ2Bov5ROqSjB5aed-vyw8eXdK0EV75Gc-E8F-cnKZa2hvcEVdTAxgT4-VZnvz82BtYT_bn26HkabuWJJhTohp7O9vzefwoAWT_3otg_o8OqIO8pTq_D/s1600/IMG_1171.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh9D2wK6_h1Q86Y_gWa8aoUhNXAqZ2Bov5ROqSjB5aed-vyw8eXdK0EV75Gc-E8F-cnKZa2hvcEVdTAxgT4-VZnvz82BtYT_bn26HkabuWJJhTohp7O9vzefwoAWT_3otg_o8OqIO8pTq_D/s320/IMG_1171.JPG" width="262" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">I used this loop of thick stainless steel wire<br />
to keep <span style="font-size: 12.8px;">the mouth wide open</span></td></tr>
</tbody></table>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgMmq0CoNCKGw5oT-z-dRJ7gG1L1driWKa8GM4TID1y9HkvzAy_JQatEYnsx3eJ1dy8dUdj347qYMxBGBckA8tA8JrBArjV01IWYHbREj57uOlQ9a6ZrwJfsmFyKKvQqYfQTI81wrBOW06F/s1600/IMG_1172.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgMmq0CoNCKGw5oT-z-dRJ7gG1L1driWKa8GM4TID1y9HkvzAy_JQatEYnsx3eJ1dy8dUdj347qYMxBGBckA8tA8JrBArjV01IWYHbREj57uOlQ9a6ZrwJfsmFyKKvQqYfQTI81wrBOW06F/s320/IMG_1172.JPG" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">And a secondary piece. It is important so that<br />
I can crush the middle later without closing the two gaps.</td></tr>
</tbody></table>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgsO0tYwAiObio1ccsABPoIhBtm7y6rPy7Lund5IMxsd_b5a6evMlhyc83BBth-w2NAibP80R5yAiHv3ZXF6XIEU_R7HyhYpk6NOYeW8pD-zXr5Opsxv9fWJeZC5U5ZPrfEt23d9I37cA21/s1600/IMG_1176.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgsO0tYwAiObio1ccsABPoIhBtm7y6rPy7Lund5IMxsd_b5a6evMlhyc83BBth-w2NAibP80R5yAiHv3ZXF6XIEU_R7HyhYpk6NOYeW8pD-zXr5Opsxv9fWJeZC5U5ZPrfEt23d9I37cA21/s320/IMG_1176.JPG" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Heating it makes it softer, which makes it easy to deform at will.</td></tr>
</tbody></table>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj9lhDQh84G1DvtMTlXICAjS2vLQc_Cs551lhdPHbgQwKJdco6ak4k36LHiMnrd6AXgL1jQDsCJnBWKU3Ls6pkr9v0rX6ZGy3BdMlXku4139noA60sZAgMC8hG8_qTKl0TFNfe9KVWYScCT/s1600/IMG_1177.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj9lhDQh84G1DvtMTlXICAjS2vLQc_Cs551lhdPHbgQwKJdco6ak4k36LHiMnrd6AXgL1jQDsCJnBWKU3Ls6pkr9v0rX6ZGy3BdMlXku4139noA60sZAgMC8hG8_qTKl0TFNfe9KVWYScCT/s320/IMG_1177.JPG" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Using a hammer to widen the opening.</td></tr>
</tbody></table>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPfQVGq8acCUcfasGChVWWDp19Tfo1TY9QevacTG2LFJmtkH4zRRoDDm8lx_eytsqpELmqPE6G0e3IxYt50UHQAPxfBlTzHWT6h9ASWsihWbBTtYgd32bB35PxFSlmUjlfFzwQok8x1Ch1/s1600/IMG_1179.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPfQVGq8acCUcfasGChVWWDp19Tfo1TY9QevacTG2LFJmtkH4zRRoDDm8lx_eytsqpELmqPE6G0e3IxYt50UHQAPxfBlTzHWT6h9ASWsihWbBTtYgd32bB35PxFSlmUjlfFzwQok8x1Ch1/s320/IMG_1179.JPG" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">And closing the middle section. <span style="font-size: 12.8px;">I do not want to cool the nozzle</span><br />
<span style="font-size: 12.8px;">itself, </span><span style="font-size: 12.8px;">but only to have powerful flows of fresh air around it.</span></td></tr>
</tbody></table>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiUNEvajIs1M4c9Q1VPSA3whTD0lOn2AjG4KETOOsVvwNuorkNDNg96xdUqyJPT3pDVDcFYLZFsJriAIvFBkdhv8_XQse4x29t-DzTIg_PeuTyoBxQ8d0sZmOkRsRwSLcg0XCmMZxrhycAq/s1600/IMG_1180.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiUNEvajIs1M4c9Q1VPSA3whTD0lOn2AjG4KETOOsVvwNuorkNDNg96xdUqyJPT3pDVDcFYLZFsJriAIvFBkdhv8_XQse4x29t-DzTIg_PeuTyoBxQ8d0sZmOkRsRwSLcg0XCmMZxrhycAq/s320/IMG_1180.JPG" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">This is how it looks before I remove the wire loop.</td></tr>
</tbody></table>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh6z8lX3pXmH5k6jpkzpkkAtvYBl44KGTiUJk7It2C0H_bsipvujQDmTT1Bjyt4sEzI89-3MZyY1TFp4ANdya5igakBnM1Pg_C6IXflgeVvAUxhOn7cw88_X9pafkqxorQlbDjKIXVBiPKe/s1600/IMG_1185.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh6z8lX3pXmH5k6jpkzpkkAtvYBl44KGTiUJk7It2C0H_bsipvujQDmTT1Bjyt4sEzI89-3MZyY1TFp4ANdya5igakBnM1Pg_C6IXflgeVvAUxhOn7cw88_X9pafkqxorQlbDjKIXVBiPKe/s320/IMG_1185.JPG" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">And the almost final mouth, with the two lateral openings.</td></tr>
</tbody></table>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhE1jy9CNMGbY2bOFk9g0KXKF1OwraKlaFU6Pekya4DCEhCPEW_j96KYezO191_N9C_8Pf4mL_IoxwemQmD1hKAdccYkwW85uDevi4zoYVW3wVC5UaXUHwdy7ysGoFsoVMi2IcPQ6fs63xn/s1600/IMG_1189.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhE1jy9CNMGbY2bOFk9g0KXKF1OwraKlaFU6Pekya4DCEhCPEW_j96KYezO191_N9C_8Pf4mL_IoxwemQmD1hKAdccYkwW85uDevi4zoYVW3wVC5UaXUHwdy7ysGoFsoVMi2IcPQ6fs63xn/s320/IMG_1189.JPG" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Once polished.</td></tr>
</tbody></table>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: right;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhUijnCqkL0y30cMG6hdOHyL6mG7m81D7shSSCWuy2pXg8Ka1PPTyaVHQzCIE8hNBpenm4OPzwmWLUBDSOb408KlNhQ0DcqT6H2z4Eli6G38HnjCvo5PQ4TzQqxWueQQALKU1GUjmZYCX8j/s1600/latex_tube.jpg" imageanchor="1" style="clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhUijnCqkL0y30cMG6hdOHyL6mG7m81D7shSSCWuy2pXg8Ka1PPTyaVHQzCIE8hNBpenm4OPzwmWLUBDSOb408KlNhQ0DcqT6H2z4Eli6G38HnjCvo5PQ4TzQqxWueQQALKU1GUjmZYCX8j/s320/latex_tube.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Latex tubes are cheap, very flexible and easy to connect.<br />
They would collapse without air pressure (e.g. regular fans).<br />
One drawback is they become brittle with heat, so double<br />check that the copper tube does not touch the nozzle!</td></tr>
</tbody></table>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhKwPjmQjo9_HwXaT6wpk6U6X1Y9XO7iYxgr5NodVClnxR2vGPnX8Nl0yofgwUaVIWr5hxq3RDsJW3Ky2c0Ept2MU3zKHDglexSn41V-taNi9Y-sp2U6PIVEbEOt_og3DjPP2R4L7IGFCkw/s1600/IMG_1197.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhKwPjmQjo9_HwXaT6wpk6U6X1Y9XO7iYxgr5NodVClnxR2vGPnX8Nl0yofgwUaVIWr5hxq3RDsJW3Ky2c0Ept2MU3zKHDglexSn41V-taNi9Y-sp2U6PIVEbEOt_og3DjPP2R4L7IGFCkw/s320/IMG_1197.JPG" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">The end result, which is screwed directly between to fins of the heat sink <a href="http://www.tridimake.com/2014/03/thoughts-and-hints-around-hot-ends.html">hot end</a>.<br />
Nylon washers keeps the tube airtight. Using two screws would prevent the tube <span style="font-size: 12.8px;">from</span><br />
<span style="font-size: 12.8px;">swiveling </span><span style="font-size: 12.8px;">when the bottom hits unwanted plastic blobs. </span><span style="font-size: 12.8px;">Also, that end of the tube</span><br />
<span style="font-size: 12.8px;">shall not get </span><span style="font-size: 12.8px;">in contact </span><span style="font-size: 12.8px;">with </span><span style="font-size: 12.8px;">the nozzle or it will act as a heat sink!</span><br />
<span style="font-size: 12.8px;">I also ended up filing the mouths so </span><span style="font-size: 12.8px;">the powerful flows</span><span style="font-size: 12.8px;"> are less horizontal</span></td></tr>
</tbody></table>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiEjPbV_60vSkLueQzKLdf5q25wsmGufKCoGfCrdRycfYoNPgk1lcBFKYIpRUMmuOYriNSZhC0LLMBPR4DHt9JtBnYXjuscKb19wnl5BxJCGs9gW_-Wqvf4qW1c5zUNT7GUdZi7NLQloA-n/s1600/IMG_1222b-ultimaker-aquarium-pump-cooling-cfpa-hiquality.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiEjPbV_60vSkLueQzKLdf5q25wsmGufKCoGfCrdRycfYoNPgk1lcBFKYIpRUMmuOYriNSZhC0LLMBPR4DHt9JtBnYXjuscKb19wnl5BxJCGs9gW_-Wqvf4qW1c5zUNT7GUdZi7NLQloA-n/s640/IMG_1222b-ultimaker-aquarium-pump-cooling-cfpa-hiquality.jpg" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">An action shot! Printing CFPLA at 210°, 75mm/s, 25 mm layer height and 0.4mm nozzle.<br />
The setup works very well, especially for trickier prints than this, with little towering islands..</td></tr>
</tbody></table>
<br />
Here is another setup, which shows <a href="http://www.thingiverse.com/thing:1752200">the support</a> John O'Shaughnessy made for his tube. It screws conveniently on the fan of his delta printer. By the way, he used an old trick: you can fill the tube with salt to avoid pinching it when you bend it. I found that heating it gives the same result. In any case, pinching the output is even a good thing to achieve a <a href="https://en.wikipedia.org/wiki/Venturi_effect">venturi/blowing effect</a>.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNbJONKyA2GMs4a4qHiEfqx-cix1p13O5dffDJphvazL0sT7tK7PkvQDKDZB-wiuGBbqn1rSdYp1OVTa2e1xfYLztL2PWDXohWtXXdNGaTZArp2vQUn7nvOf3znX2mPFPX9ri0XnVSTfyn/s1600/Geeetech_G2S_Pro_Layer_Cooling_Tube_Holder_by_JohnOCFII.jpeg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="241" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNbJONKyA2GMs4a4qHiEfqx-cix1p13O5dffDJphvazL0sT7tK7PkvQDKDZB-wiuGBbqn1rSdYp1OVTa2e1xfYLztL2PWDXohWtXXdNGaTZArp2vQUn7nvOf3znX2mPFPX9ri0XnVSTfyn/s400/Geeetech_G2S_Pro_Layer_Cooling_Tube_Holder_by_JohnOCFII.jpeg" width="400" /></a></div>
<br />
<br />
<br />
<h3 style="text-align: left;">
By the way, what is inside an air pump? How does it work?</h3>
I opened it, you bet! And it is deceptively simple. There is only a transformer, which is opened on one side. It acts as an alternating electro-magnet which push-pulls two levers. The latter move only by a few millimeters to fill and empty rubber pouches on two valves. Since they runs at 50Hz or 60Hz according to your country it represents a lot of air -- where 60Hz will give you a slightly better throughput ;)<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh20OsjpBznkWJ6cNXbIblqrATQ8BHvVFK_Jk7cUElViyfAC7ufukzfZ57KvJ-UY6Pxlb66Ye73qeM8y2MsgtLuvqA4NeH2f5-vpGpjnLUi0QswNu_tnWK51-2tN-tuo8VsKQ2wb7WLm1kJ/s1600/air_pump_internal_stuff_howto.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="253" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh20OsjpBznkWJ6cNXbIblqrATQ8BHvVFK_Jk7cUElViyfAC7ufukzfZ57KvJ-UY6Pxlb66Ye73qeM8y2MsgtLuvqA4NeH2f5-vpGpjnLUi0QswNu_tnWK51-2tN-tuo8VsKQ2wb7WLm1kJ/s320/air_pump_internal_stuff_howto.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="font-size: 12.8px;">Inside of an aquarium air pump (Whisper AP150).<br />
This is only an electromagnet which relies on the alternative mains!</td></tr>
</tbody></table>
<br />
Also, some make their own pumps of course. Thy most often rely on regular motors, which are probably noisier and less efficient or durable than the industrial pumps, but they can be made to work very well. And, they are homemade, which <a href="http://www.tridimake.com/2014/05/the-businessman-and-maker.html">does not mean it is crappy</a> :)<br />
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen="" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/uQBwRc52UEM/0.jpg" frameborder="0" height="266" src="https://www.youtube.com/embed/uQBwRc52UEM?feature=player_embedded" width="320"></iframe></div>
<div style="text-align: center;">
<span style="font-size: x-small;">Home made air pump with a regular motor, very nice howto and result.</span></div>
<br />
<h3 style="text-align: left;">
So what is next?</h3>
<div style="text-align: right;">
</div>
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgeyDrHKIrU-itsdFQzBgL7A1kdB2oHN5PyXZLBUuiLoUUBHq7mDiQ5alOxE9mUkogHm7_3sxEokqoEVRq4n0bFvOMLtX2AqDKPR7idhKb9AbsCb6_kTk3Yty6fKbzghmSmhp-PAoYRtADv/s1600/air_pump.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="133" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgeyDrHKIrU-itsdFQzBgL7A1kdB2oHN5PyXZLBUuiLoUUBHq7mDiQ5alOxE9mUkogHm7_3sxEokqoEVRq4n0bFvOMLtX2AqDKPR7idhKb9AbsCb6_kTk3Yty6fKbzghmSmhp-PAoYRtADv/s200/air_pump.jpg" width="200" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><span style="font-size: 12.8px;">A $12, <a href="http://rover.ebay.com/rover/1/711-53200-19255-0/1?icep_ff3=9&pub=5575160029&toolid=10001&campid=5337834253&customid=&icep_uq=5W+220V-240V+Twin+Outlet+Air+Pump+Aquarium+Fish+Tank+Pond+Oxygen+Oxygenation&icep_sellerId=&icep_ex_kw=&icep_sortBy=12&icep_catId=&icep_minPrice=&icep_maxPrice=&ipn=psmain&icep_vectorid=229466&kwid=902099&mtid=824&kw=lg">dual outlet air pump</a>,</span><br />
<span style="font-size: 12.8px;">1.5L/min (verified myself).</span></td></tr>
</tbody></table>
Since it is working better than I expected, I bought the dual outlet pump on the right (so cheap: <a href="http://rover.ebay.com/rover/1/711-53200-19255-0/1?icep_ff3=9&pub=5575160029&toolid=10001&campid=5337834253&customid=&icep_uq=5W+220V-240V+Twin+Outlet+Air+Pump+Aquarium+Fish+Tank+Pond+Oxygen+Oxygenation&icep_sellerId=&icep_ex_kw=&icep_sortBy=12&icep_catId=&icep_minPrice=&icep_maxPrice=&ipn=psmain&icep_vectorid=229466&kwid=902099&mtid=824&kw=lg">$12 shipped on ebay</a>). I was first disappointed by the throughput until I noticed the little magic button on the back! Switching it doubled the throughput ... and also probably doubled the noise (is still OK though). I checked it by myself and emptied a 1.5L bottle in about 50 seconds with one outlet. This is certainly not the claimed 4L/min but it is still decent compared to my previous "real brand" one.<br />
<br />
The pressure seems even higher, so it may be better for very focused air cooling (I am unsure is it worth though).<br />
<br />
I also need to add either a switch to stop or start the air flow (<u>update</u>: check this excellent <a href="http://www.sgabolab.com/p/blog-page_63.html">maker</a>), or, better a <a href="https://www.google.fr/url?sa=t&rct=j&q=&esrc=s&source=web&cd=3&cad=rja&uact=8&ved=0ahUKEwi8xsv758vSAhUElxoKHXVBBTQQFggkMAI&url=https%3A%2F%2Fen.wikipedia.org%2Fwiki%2FPulse-width_modulation&usg=AFQjCNHNjcqTrZR8421Rwla6yo8uezVb1w&sig2=xEOoXmBatW7IYErMcpGEIQ">PWM regulation</a> to set the amount of air as with the default fans.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; margin-right: 1em; text-align: left;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgOoVNp7utIc5TxZBBVoQ4BFoMjUMZjANakEL9SEFUCmt_zx_XFg6-P5PHS66J0DWYj_ABvuWjuKU8dplfjVBvkt-Q5rmCn8DzmNrTtgZYju4vXNrtmTXF_GSiCSMFL-9U1aF7b3VXf_rDG/s1600/smaller_copper.jpg" imageanchor="1" style="clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgOoVNp7utIc5TxZBBVoQ4BFoMjUMZjANakEL9SEFUCmt_zx_XFg6-P5PHS66J0DWYj_ABvuWjuKU8dplfjVBvkt-Q5rmCn8DzmNrTtgZYju4vXNrtmTXF_GSiCSMFL-9U1aF7b3VXf_rDG/s200/smaller_copper.jpg" width="199" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Todo: less weight, wider mouth?</td></tr>
</tbody></table>
Also, I wanted to give it a try: not only to cool the immediately deposited thread of plastic, but also to try and cool down the hot end itself without having to revert to water cooling. This way I would get rid of the annoyingly noisy and failure-prone but nonetheless compulsory little fan on the hot end heat sink (more on that <a href="http://www.tridimake.com/2014/03/thoughts-and-hints-around-hot-ends.html">here</a> by the way).<br />
<br />
Finally, my existing tube is uselessly long (hence uselessly heavy), and the mouth could be wider to cool a larger portion, to trade pressure with surface. So my next iteration will probably be based on a shorter and thinner tube, like the one on the left.<br />
<br />
Another possible issue is how well copper conducts heat, especially if it touches the nozzle (it becomes very counter productive then as it will heat the air befores it gets out). In this regard, so-called "capillary" tubes like these <a href="https://rover.ebay.com/rover/1/711-53200-19255-0/1?ff3=4&toolid=11800&pub=5575160029&campid=5337834253&mpre=http%3A%2F%2Fwww.ebay.com%2Fitm%2F304-Stainless-Steel-Capillary-Tube-Tool-OD-6mm-x-4mm-ID-Length-250mm-%2F182639681540%3Fepid%3D1076425390%26hash%3Ditem2a862c6004%3Ag%3ASI0AAOSw3YJZUh1b">cheap ones on ebay</a> are probably something to try.<br />
<br />
<br />
<br />
<br />
<br /></div>
Jeremie Francoishttp://www.blogger.com/profile/02984201174566394892noreply@blogger.com1tag:blogger.com,1999:blog-3615478772815290200.post-88476171052379874532016-04-18T17:26:00.000+02:002018-01-22T09:23:57.288+01:00Being a contractor or a full-time employee?<div dir="ltr" style="text-align: left;" trbidi="on">
<h3 style="text-align: left;">
Working as a contractor <i>versus</i> regular employment?</h3>
I regularly see the fear about working as a contractor. Lately I was part of a discussion that started like: could it be risky for any subsequent 9-to-5 career? I strongly disagree: being a contractor is interestingly a warranty for me to find again a new job in case I fail as a contractor! In my opinion, it will indeed <i>help</i> most careers, as I an employer I would favor people that took the risk to try, whether they were successful or not. Contracting both provides and requires skills at the same time, more than any regular 9-to-5 job.<br />
<div>
<br /></div>
I feel like I can handle all sorts of professional blows, like being fired. And first of all, well, I will not be fired as long as I am my own boss! This is because I feel each day insured by varied and evolving professional experiences together with a growing professional network.<br />
<br />
Here is a post about how I ended up as being a very happy contractor, after having been a state employee, a full time engineer in a small family-owned company, then in a stock-valued much larger company, then a CEO and a CTO in a start-up (<a href="https://en.wikipedia.org/wiki/List_of_corporate_titles">silly names</a>), and a very well-paid part-time employee in a startup... before I flew on my own in the naked simplicity of a contractor in a cooperative, with no mess.<br />
<br />
<i>Disclaimer:</i> my experience is all in the so-called "new" technologies, but it may still help beyond.<br />
<a name='more'></a><br />
My very nature is to keep on doing things I did not before. Call it curiosity, I do not know, but I do know it is very useful both for my work and for my pleasure. This is not optimally lucrative, as I do not stop much to try and <a href="http://www.tridimake.com/2014/05/the-businessman-and-maker.html">monetize</a> what I can do, e.g. with products of my own. But I join the two ends while I manage to fulfill my hobbies to a good extent (days are certainly too short to achieve that completely).<br />
<br />
When I am asked the main difference between work and hobby, I do not say that work is paid, but that work has to be delivered. Hobbies can be put on hold indefinitely, which is a pity by the way!<br />
<a href="http://www.tridimake.com/2016/04/3d-printing-sponsorship-hired-and-fired-just-as-usual.html">Sponsorship</a> is probably a very good thing that can happen to a contractor, but here again it may end up eating all your other hobbies. As for me, I would not like it for long periods, and I would highly favor co-operation (i.e. help to develop a product at no cost or so, and a client sells it, with royalties).<br />
<h2 style="text-align: left;">
Things to know and value about being a contractor (in my opinion)</h2>
Here are the main points I would stress out. They come for my years of being a happy contractor and I would be glad whenever someone finds a few ideas or avoids a pitfall thanks to this post.<br />
<h3>
Check and assess your professional network first!</h3>
I would say that you must know if, when and where <i>you may help companies you already know</i>. I was already working for a decade in my city before I switched to being self-employed. I had a lot of contacts with tens of companies with my former start-up and before that, with my former jobs. It made me confident both about their needs and about my relationship with bosses and employees alike.<br />
<br />
I cannot say how incredibly useful to have been on both sides of the fence and to understand all points of view. This includes: state employee "vs" private sector, bosses "vs" employees, small businesses "vs" large ones and so, which are all fake. The cursor, as always is in the middle of all this.<br />
<br />
In fact I started my contractor work securely with a 3-month long pre-defined contract for a known client. I had a second one afterwards for an independent and friend of mine. It was much easier as it was for people and companies I used to work for or with formerly, so I did not have to feel the pressure to prove something.<br />
<br />
For this same reason, I would say that moving to a new town is extremely harmful if it matches the time where you decide to be a contractor. Unless you are a really god marketing guy and know how to sell your work (I just do not, I let my former clients be my advocates!).<br />
<br />
Working for remote clients becomes increasingly easy when your own clients tell about your good work to within their own network. Interestingly, I even once worked for a client I never ever saw (that was for a prototype of a payment terminal based on an embedded linux and a barcode scanner).<br />
<h3>
Don't be uselessly secretive: competition or cooperation?</h3>
Most startups are paranoids. They think others would steal their "intellectual property", but they do not realize they are exactly alike: their founders spent years ahead on they own idea and they have no time to steal the idea. And major companies will crush you whatever you do, unless you target the sky (as too many do, only to realize how much chance plays a role in the end).<br />
<br />
I have the same attitude towards work as a contractor: I know a (few) contractors who may do some specific work that I could possibly do also (most notably, image analysis, since I no more do web development).<br />
<br />
But I talk and I consider them as resources more than competitors, i.e. people I could work with. Many start ups and companies do not think about it. Some do, and I work with them, mostly by contracting their R&D under and <a href="https://en.wikipedia.org/wiki/Non-disclosure_agreement">NDA</a>, so they do not have to hire me full time.<br />
<br />
Some projects are just too big for one single contractor anyway. We even answer together to one complex proposal and we are friendly to each other. When I have no time for such a job, I would handle it to him. I guess he would most probably do the same to me. Once again: know the others and do to others as you would have them do to you, it is a win/win.<br />
<br />
Now, I have many skills that he does not have, so I can work on stuff that he would not like nor can work on, and reciprocally. This is easier to handle than to consider he may be eating parts of "my" market. Good for him when he gets an interesting job :)<br />
<h3 style="text-align: left;">
Be curious and be well aware of your skills</h3>
You need to be very conscious of your existing skills, and what you like to learn. Be as knowledgeable as you can, because it will help you know what you want, and it will give confidence to your clients that if something happens during the work, you will know how to deal with it, or where to seek outside help.<br />
<br />
I also had work experiences that proved I could also develop software products on my own if I had no contracts, but I never took the time since!<br />
<br />
Obviously it also depends on your skills and existing network. If you are part of a large aerospace company and you design satellite positioning software, it may be harder to work as a stand-alone contractor... If you are a web developer, you will have to fight harder with competitors, and it will be harder to keep only a few clients as I do.<br />
<br />
If I had to give only one advice to parents, it would be this one: teach insatiable curiosity to your kids and you are done with education. OK, you get the picture, respect to the others, to the nature and to self, or the joy to achieve a good result is as important. But curiosity pays so much :)<br />
<div>
<blockquote class="tr_bq">
<span style="font-family: "verdana" , sans-serif;"><i>“Study hard what interests you the most in the most undisciplined, irreverent and original manner possible.”</i> ― <a href="https://en.wikipedia.org/wiki/Richard_Feynman">Richard Feynman</a></span></blockquote>
In fact, curiosity gave me an interesting result: I often suggest contents or features that my client and myself like better, for the benefit of all. I also have to postpone interesting works for months because I have too many right now and need a rest :)</div>
<h3 style="text-align: left;">
Be opportunistic, and pragmatic. Let things happen: future is unpredictable!</h3>
As I often say, contractors are not companies, at all. Actually, even very small companies are better opportunistic or they die. Business plans and market/prospective analysis are mostly to buy investors.<br />
<br />
As an example, a colleague and friend of mine tried Angular JS, earlier than others and out of curiosity. He became one of the first google certified expert of this technology, and he is now <a href="http://www.methotic.com/formation-angularjs">teaching it</a> all over France and beyond all year long. He did not even come to our cooperative with this job in mind, and he certainly can work on something else.<br />
<br />
We all see opportunities one time or another. I would say it even becomes easy to provoke some with time. Reciprocally, who knows what the future is for independent contractors in new technologies?<br />
<br />
I have no clue for myself. As long as it is something I still like, I am fine with it. It may be bee keeper, who knows (I have yet to wait to see them come and populate the box though).<br />
<br />
Seriously, who knows what the world will be in 2 years? Admittedly, there are some amazing skills that date back to centuries and which will not change anytime soon. Non-technological jobs are less prone to changes, but so few jobs are not force-fed with technology nowadays!<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen="" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/C0dkDEcQMdA/0.jpg" frameborder="0" height="266" src="https://www.youtube.com/embed/C0dkDEcQMdA?feature=player_embedded" width="320"></iframe></div>
<div style="text-align: center;">
<span style="font-size: x-small;">I must admit a few jobs are unlikely to change in the near future.</span></div>
<div style="text-align: center;">
<span style="font-size: x-small;">(the making of a violin, a must see for all makers)</span></div>
<br />
<br />
<h3 style="text-align: left;">
Money is a wrong way to measure your happiness</h3>
I do not consider money as a good indicator, even though it is all around us. Keeping a so-so job in the same company for years always end in never-ending wage disputes between employees and chiefs. And when the company collapses, so many have money income as the first and prominent way to select their next job.<br />
<br />
I love my work, and there is just no money that can buy this. Working on your own may or may not pay a lot. I guess it may be a pain, and sometimes I admit I hardly sleep.<br />
<br />
But I get in touch with more and more clients ... and possible future employers! I see more opportunities than with a single long term contract with a single employee. I prove my value to would-be employers by my work as a contractor. Hence, being a contractor may also simply be a temporary situation and very efficient way to find a better job in the end, because the employee and the employer already know about the other and the work to do.<br />
<h3 style="text-align: left;">
Still, obviously be cautious about your income requirement.</h3>
So far, I never accepted lucrative but uninteresting work. I even did not have to look for clients since my start as a contractor... I would ask to be paid more, but my family needs are small, I managed to pay my house with my former well-paid jobs as an employee, my other half has a steady job and I have some money saved in case I become a useless moron. Actually I even check my bank balance only every two months may be (boo)!<br />
<br />
If ever I cannot get more interesting work, I could first try to try to raise my price on less interesting ones. Or I would apply to "senior" positions here of there, or as a regular developer in a startup. But I hope I would also accept any work, including non-qualified one if I have to. Now, I used to work hard at school without having this idea in mind, but I am glad I have many diplomas. In this respect, France is a place where your scholarship follows you everywhere you go, and it is a great injustice to self-made men.<br />
<br />
Now, I talk about safety... Regular so-called "permanent" jobs are going to be something of the past. An average career nowadays goes through multiple jobs, because companies go bankrupt, because you get fired one way or another. E.g. the office closes and you are asked to move far from your place, family and kids. Or a nasty boss gives you only boring jobs so you go by yourself...<br />
Being a regular employee is less and less a professional safety, with the additional "risk" of being stuck on narrow profiles. This in turn may be a problem when looking for another job, while in my case, I could probably apply on a dozen of profiles with proof of past experience, so I feel much more confident than ever if I had to find a new job.<br />
<h3>
Know and learn how to say no.</h3>
With time, I more and more often say no. It is one of the hardest part of being a contractor. Know yourself, and realize that every work is not always good to catch. Example: each year, more people come to me with fuzzy ideas of undefined products. I used to spend time with them to refine it into something that could become a product, that I could work on. Now I consider that if the guy does not know what he wants beforehand, then there is no time for me to waste. The making will keep on changing also ("oh, actually it would better be blue", then "I talked to X and he says it would better be red"). Actually, I could better be paid to <i>help him shape his fuzzy idea</i> into something usable. And even then I would unlikely be the one to make it anyhow.<br />
<br />
No. It is very hard to say no as a contractor, especially when you put money in the balance.<br />
I still have much trouble saying no, and I end up overwhelmed with work. Well, at least it is interesting work :)<br />
<h3 style="text-align: left;">
Establishing boundaries between work and play?</h3>
<div>
All humans are alike at some extent: we all have a large panel of capabilities and experience. Some are useful at work, some are not... and reciprocally. E.g. when I started playing with 3D printers and embedded electronics it was just for fun. But I soon realized it may be useful at work also.<br />
<br />
At the same time, writing Palm, Java Mobile, Android applications, web sites and PHP APIs was becoming less interesting. Recently I even realized that linux server administration no more talks to me. Great! It means more time to learn and use something else. So I just shifted my work so it embeds electronics, and I started doing so on my hobby time. By the way, shifting your focus is much more difficult to achieve as a full-time permanent employee with a pre-defined work contract.<br />
<br /></div>
<div>
What I do love is to mix all knowledge. Fences are sterilizing in my opinion. Sure, I almost never stop working at 5, partly because my work is my hobby or the opposite, and partly because I cannot stand not being able to succeed. Let me put it clearly: this is not necessarily a good thing. Now, I have no kids, my wife is very nice and I love my work. All this helps immensely for my job, even though I should go on a ride more often... I easily keep on working through the night to get things done, and until the delivery suits the client and its own clients. In my case, the pay itself often comes afterwards. One usual client even asks me <i>afterwards</i> how long I really spent on it, and he gives more than what what planned, this is amazing.</div>
<div>
<div>
<br /></div>
<div>
I do not get it when people say "work" ought to be separated from "hobby". Sure, when your work is not enjoyable, then I agree it shall not bleed on your hobbies, obviously.<br />
But if you like it why shouldn't you? I get it from the other side: if your work is bad, it may be a good reason to try something else.<br />
<blockquote class="tr_bq">
<span style="font-family: "verdana" , sans-serif;"><i>“Human spirit is the ability to face the uncertainty of the future with curiosity and optimism. It is the belief that problems can be solved, differences resolved. It is a type of confidence. And it is fragile. It can be blackened by fear, and superstition.”</i> ― <a href="https://en.wikipedia.org/wiki/Bernard_Beckett">Bernard Beckett</a></span></blockquote>
It mostly boils down to fear of change, and actual costs regarding need and family.<br />
Now, I just saw so many computer engineers stay late at work while complaining that their work sucks at the same time... so it bleeds on they families and hobbies anyhow. Being a contractor means choosing what to do: better do what you like in the first place, then!</div>
</div>
<h3 style="text-align: left;">
Working as a contractor from within the comfort of a cooperative</h3>
Also, an excellent but unknown idea is to go, find and work from within a <a href="https://en.wikipedia.org/wiki/Cooperative">cooperative of contractors</a>.<br />
<br />
I am part of <a href="http://www.crealead.com/">Crealead</a>, which is a long-standing network of co-workers, a rich and heterogeneous group of independent contractors within a shared and unique legal entity (180 of us right now, with a cumulated income of 3.5M€ last year). Activities range from passive energy experts, to house architects, software experts, photographs, designers... There, I certainly do not feel alone: we are able to help an teach each other, to have breakfasts, talks and restaurants altogether, and obviously to respond to bigger projects and needs when we feel like so. We also pay ten experienced employees for the paper and accounting work, which is something that would just kill me as a stand-alone contractor. I hate that, and they like their own jobs, the world is well made.<br />
<br />
Here again it is a win-win for my clients: I spend 90% of my time working exclusively on my added-value, and I still can be as "pro" as it is possible regarding the legal and administrative work. Then, obviously, we pay ourselves independently with the money we bring in (and here is the trick: with the exact same status as a regular employee -- so I could benefit full social welfare and even unemployment benefit if/when I decide to quit, anytime). Five to ten percent of the income goes to pay the full-time employees, the longer you stay, the lower you pay.<br />
<br />
Did I say such cooperatives are a democratically controlled business? I do have one vote, which is as much as the president of the cooperative and any of the numerous colleagues on the board. It does not depend on the number of share I have (which is the regular mostly broken <a href="https://en.wikipedia.org/wiki/Plutocracy">plutocracy</a>). So if my boss does something bad, we just fire him.<br />
<br />
Obviously, you will understand that I cannot recommend enough to try and start within a cooperative if you want to be on your own, but without being alone.<br />
<h2>
Uncertainty: shall I say yes? Can I make it?</h2>
This is a state of mind. When I want to try a new skill, then I try it, either on hobby time, as a free bonus for a client, or within a contract.<br />
<br />
Actually, I regularly tell it in advance: <i>"I think I can do it, but I never did it yet as a formal job: </i><i>as a client, are you trusting me enough for me to try here?"</i><br />
<blockquote class="tr_bq">
<span style="font-family: "verdana" , sans-serif;"><i>“If somebody offers you an amazing opportunity but you are not sure you can do it, say yes – then learn how to do it later!”</i> ― <a href="https://en.wikipedia.org/wiki/Richard_Branson">Richard Branson</a></span></blockquote>
Sometimes, I go as far as to cut the bill in half... Most of my colleagues tell me it is no good business. I do get their point: the client does not care whether you know or not, he just wants and pays for the results. So he could pay the same as if you knew how to do it before you start.<br />
<br />
Now, I talk straight to my clients, it is much easier to handle than remembering what you may be hiding to one but not to the other and so. They know I also keep an interested eye on their product or give a hand to their team, and almost all of them come back to me after a contract, so I need only a few regular clients. The reciprocal is that they are smart enough not to abuse from my good will: I would stop working for them and switch to another task or another client. I just never worked twice for an annoying client (fool me once...)<br />
<br />
I do not care that much for business actually. I never was refused for job proposal that require skills I do not have yet and even though I say so... Trust is everything. Obviously, it goes the other way: I would not foolishly answer to a call that is out of my reach, or out of motivation. This would mean hours of pain, which I already have with regular projects, sometimes (the real world of embedded electronics is way more troublesome than software).<br />
<br />
Now, once I tried something new for a contract, I decide whether I add it to my explicit portfolio or no. In any case I will have more skills and to recycle than ever. Which gives me more opportunities to get more interesting jobs. Win again for everyone. For example, I proposed only once to 3D print an object. It is too time consuming, especially when the client wants to spare money by <a href="http://www.tridimake.com/2014/09/how-to-use-openscad-tricks-and-tips-to.html">learning how to designing</a> the object himself. Even paying by time and not material is something I will no more do.<br />
<h2 style="text-align: left;">
Do I need to apply for grants or get funded?</h2>
It may or may not be a good idea. Some countries may probably be as bureaucratic as France, most probably in Europe.<br />
<br />
When you need money, sure it's a good idea to apply for a grant, and there really are some useful ones. Say, when it is the regular grant you are given after losing a job in place of the unemployment benefits, it is also quite easy to handle, and very often totally worth the deal (actually looking for a job is just like building a new business!). I did it twice actually.<br />
<br />
But some grants, are probably not worth though, especially for startups with big ideas. This is specially true for individuals working at home and with no hardware needs, or with already some sort of income.<br />
<br />
Why? Because looking for, applying to, and reporting to the state and agencies may become a full time job. Really, e.g. one client of mine probably spends 80% of his time looking and handling these grants. He is very successful as the founder and head of a 10 person-company, but it is a game that needs to played fully or not... Half way means you will not tick the marks and be refused. Also it sometimes becomes local politics, when your papers need to be on top of the pile, not counting due dats and so...<br />
<br />
I even know two small businesses which killed themselves because they had drown in JEI, CIR, AFT, AFC... grants and labels I know too well with my former startup and my existing clients.<br />
<br />
Most notably, I had a former and early client who was rich enough to start on his own as he always did before (I remember him writing a check of 10K€ before I even started working on his prototype, wow!). Then a "business developer" (my former associate.......) urged him into grants and labels. It totally ruined his motivation and eventually killed his project. Originally, he was able to focus and move very fast. When he got registered in the "business innovation center", he soon got pissed off by the sheer and repetitive work, meetings and paperwork he had to do (business plans, executive summaries and so)... in order to justify grants he did not need! Then came the smartphones which made his very smart and useful project obsolete (he did know he had to move swiftly).<br />
<br />
Now obviously, your mileage may vary. The example I give is the worst scenario I know about. It was also specifically counter productive because it was a startup with a unique innovative product.<br />
Once again, this is NOT to say a grant is bad, but to say that some come with a heavy and exceedingly annoying counterpart. Nothing is free ;)<br />
<h2 style="text-align: left;">
For companies, hiring contractors instead of employees is often better. Let them know it!</h2>
What is interesting is that it is easier and easier for me to refuse politely a full-time job, and to explain that it is often more interesting for them to hire me as a contractor. Also, an external on-demand support is easier to manage than a risky long-time employment (especially in France where you cannot fire people easily, even if they are willing to go, or they lose most of their social welfare!). This is often how I help existing teams, including in the long term.<br />
<br />
Most companies will not have enough food to keep me happy all the time on a full time job... which means I would have also to work on less interesting stuff because my boss asks me so and I could not refuse. Bigger companies have fuzzy projects, which often are killed without prior notice. Startup often go bankrupts before their product is out or successful. As a contractor I just help, but I am not part of the business strategy, nor of the failure if any!<br />
<br />
I did sometimes accept a short-term job -- my most notable experience in this regard was one month in Doha for a client who had to hire me for a partnership with the Qatar Foundation, how could I refuse such an experience? But I politely refused both proposals to work in the long term.<br />
<h3 style="text-align: left;">
Transparency pays a lot</h3>
What is even more interesting is how transparency pays.<br />
<br />
I usually tell my clients everything: because it creates a win-win and trusted context, and I never have to remember lies. I never ever will say again "I am unavailable abroad" when I am on well-deserved holidays. And when I accept a proposal, then it means the stuff appeals to me and I will work better and harder to get it done. When I say no, I explain why, and they like it.<br />
<br />
And here is my point: it becomes increasingly easier to find work and contract when you already showed you did good (and most often not expensive) work as a contractor. It is easier when your skills and your experience are rich, and they are necessarily richer than that of a full time long-term employee in a single company.<br />
<br />
Asking for a moderate pay is also an excellent, and justified way imho, to keep your existing clients and to work on interesting contracts. In turns, it means you do not have to look for more work all the time.<br />
<br />
And eventually, I am back to the beginning of this post: it becomes incredibly easier to ask for part-time jobs, without feeling like someone who does not want to work.<br />
<br />
As a "senior" I realize how difficult it is to ask for a part-time job, without raising an eyebrow. Having contracted with the company formerly is a proof that you are no lazy guy. It is even easier when they ask you to join.<br />
<br />
Part-time jobs are probably a huge win for personal life, but I personally still favor contractor mid/short-term projects, because I like the idea to be free (in reality it is not that easy, but if a huge opportunity happens, I just get it -- like an unplanned holiday without jeopardizing the pre-defined and constant number of holidays that my wife has).<br />
<br />
I also contract for long term, sparse, external support, mostly leveraging research and optimization issues for startups (I never do more than 2, as they are often exhausting as you end-up doing all sort of support). Startups frenzy is weird, but they often give you shares to cut their price... Even though I often do not care, it may prove to be lucrative one day.<br />
<h2 style="text-align: left;">
Opportunities are everywhere to the non-conforming!</h2>
<div>
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhcZZKyHcm65-sLXWz9m7n0dK_kxQKmOLE87KX1mSQ71KUoNlu1w8Y4_W9ZfR5lX-SFv_RTjuoHQeYVvJEmBB0st8s-1T8xEmqigITlTpOrgRrCkWL3dyQNMxBhNGb3xfW7qZlN-xVvcw1E/s1600/xkcd_standards.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="181" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhcZZKyHcm65-sLXWz9m7n0dK_kxQKmOLE87KX1mSQ71KUoNlu1w8Y4_W9ZfR5lX-SFv_RTjuoHQeYVvJEmBB0st8s-1T8xEmqigITlTpOrgRrCkWL3dyQNMxBhNGb3xfW7qZlN-xVvcw1E/s320/xkcd_standards.png" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><a href="https://xkcd.com/927/">XKCD</a> - The trouble trying to conform with standards...</td></tr>
</tbody></table>
Being curious also means being non-conforming in my opinion: technologically, nothing is sacred.<br />
<br />
Of course, standards and norms are there for a purpose, and often a very good one. Sometimes they are just part of the contract.<br />
<br />
But most programmers' habits and rambling about each OS is plain counter-productive for the client. E.g. I love linux and I almost can't stand windows as a user. But I practice both as a pro. I even like .NET while I like bash scripts. Or I don't like Arduinos that much, but they have an immense value and I praise them as they made my work easier and helped me be where I am now. The client wants a PIC instead? No problem it is a chance for me.<br />
<br />
Unbounded curiosity helps me suggest uncommon but affordable and efficient <a href="http://tapsearch.com/therationale-journal/id37.html">bottom-to-top solutions</a>. Top-down solutions are becoming increasingly costly and inefficient for many business (btw. you can check <a href="http://www.tridimake.com/2014/11/suspicious-3d-printing-trends-reports.html">my motivated view</a> about crappy "high-level strategically analyzed reports"). You buy an expensive product for more expensive support and longer delays.<br />
<br />
With the social media diktat nowadays, more and more clients are becoming open-minded and pragmatic. For example, a while ago, a long-running company asked me to write an Arduino library for their products, so not only they deploy solutions far more quickly for their own clients, but they also can sell their formerly purely industrial products to hobbyists worldwide. They like it, I like it, and no big client would have provided them with such a "non-conforming" solution.<br />
<br />
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; text-align: center;"><tbody>
<tr><td><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhev3Nt1m7IbbKjFbIP1thzxhE98LpSgim-6zoxszx7G8AM089vtTdbqfkk3JauYhxOujydnSKL1oSYt0nALv2SFhywPnVDPS9pOxSKMni3KYqeidX6bhygoOvHOE9Ax9_YGjMTOJmZRuup/s1600/dmx_controller_tecrd.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="185" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhev3Nt1m7IbbKjFbIP1thzxhE98LpSgim-6zoxszx7G8AM089vtTdbqfkk3JauYhxOujydnSKL1oSYt0nALv2SFhywPnVDPS9pOxSKMni3KYqeidX6bhygoOvHOE9Ax9_YGjMTOJmZRuup/s320/dmx_controller_tecrd.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="font-size: 12.8px;">Yet another cool project; a low cost DMX controller<br />
for a laser at IRSTEA, a public research institute.</td></tr>
</tbody></table>
Actually it is becoming increasingly easy to suggest solutions based on a low cost Raspberry Pi or an Arduino, even to national research institutes. I did it without much trouble: low cost hardware, quicker support than others, and old client of mine as a referee... see the importance of the network? Years later, they are happy enough to pay and extend the deal for two more years. How cool is that?<br />
<br />
I can think of so many applications on the embedded world, which I must admit is one thriving market right now.<br />
<br />
<br />
<h2 style="text-align: left;">
Being laid off after a long job in the same company...</h2>
Interestingly, I regularly see some of my former colleagues at Palm.<br />
<br />
Palm then became PalmSource, then Access, than Intel, then ... nothing! The local office is closing and a bunch of well-qualified and very well-paid specialists are suddenly thrown on the small market in a moderately small city. They probably earned twice as much as me and they were so much used to earn more and more for 15 year that the reality may be a shock for many, who got used to comfortable wages. They kept on working <i>grosso modo</i> on the same job with the same people while I feel I lived 3 or 4 more times and met hundreds of people in between. I would certainly not trade my place right now with them.<br />
<br />
On my side, I could call quite a few companies I was looking for a "regular" job, with a significant chance to get something quickly. I also know enough of the market, product design processes and sub-contractors to go and create a startup with "easy / low risk" products, that I could make on my own and/or propose as a joint-venture to existing clients. May be I will try again one day.<br />
<br />
For now, not requiring large wages is well-compensated by working on interesting projects only, without spending more than a couple of months on them each time. Talk also about "consideration" or being "part of the boat" and so. I have more self-esteem when my clients keeps on asking for more contracts, when they recommend me to others, when my former colleagues look at me with wishes in the eye, than within a large company that talk corporate values and bullshit when the ultimate goal is foremost to fulfill shareholder needs (i.e. money -- they just do not care about you and your work as an employee long as the share price rises, or if they know when to sell before it falls).<br />
<br />
And I do not fear the future because I need no forecast, I just like to move and to adapt.<br />
<h2 style="text-align: left;">
Freedom, at last!</h2>
First, I would say that I am lucky. Everything that drove me to this place proved to be useful for my status. <br />
<br />
One and a half year back, my desktop was that of a regular software engineer (OK, and slightly a 3D printer maker). Now it happens to be that of an electronic mad scientist, with power supplies, oscilloscope and soldering station right below my big screen. But I still like both jobs, and I even managed to do both at the same time. It is time consuming, but so it gives so big a satisfaction to hold a real prototype in your hand instead of yet another software release!<br />
<br />
Funnily, some clients think I came from electronics, and they ask me with doubt if I would accept to do some software for them as they feel I could help. Reciprocally, some are puzzled to see how I am surrounded with hundreds of little component drawers, steppers, 3D printers while I only designed algorithms for them.<br />
<br />
Some are puzzled that I love philosophy and cognitive sciences so much, or that I will not miss a chance to play with machine learning algorithms (my PhD in sensor fusion, heuristics and automatic diagnosis was achieved mostly out of curiosity at the time). May be I invested a lot at school but I loved learning and it was not that painful.<br />
<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgfi8DH3mf-QUexXmDX99bfy6QaaUvXcGcrYUbzhXF5_2a6gSXxxwKapNFQzIS95f3JmTIj4I2dmA-U-AUaId4Z959WRJFTu0otGrA6jbOPRC7lB6SqmyEfJjcr1Ar2tgDW76hHCvg7deOx/s1600/DSC02912-Iceland-2015.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="300" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgfi8DH3mf-QUexXmDX99bfy6QaaUvXcGcrYUbzhXF5_2a6gSXxxwKapNFQzIS95f3JmTIj4I2dmA-U-AUaId4Z959WRJFTu0otGrA6jbOPRC7lB6SqmyEfJjcr1Ar2tgDW76hHCvg7deOx/s400/DSC02912-Iceland-2015.jpg" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">A one-month camping trip to Iceland on a motorbike?<br />
Certainly, my boss is fully OK with that :)<br />
I will not care much about money as long as I do not miss such rare opportunities.</td></tr>
</tbody></table>
Now and as a final note, I just plainly love being harshly cold and wet for weeks on camping, riding an enduro bike in the depth of frozen Iceland rivers. Sure I have 3D printed gears on my handle bar together with a few robust homemade weatherproof USB power supplies. But we only have one life.<br />
<br />
<div>
And interestingly, <i>I certainly do not feel ashamed</i> to enjoy plotting curves of <a href="http://onlinelibrary.wiley.com/doi/10.1111/1467-8659.1310049/abstract">class C²</a> while driving on a wet trail with my bike towards <a href="https://www.google.fr/search?q=Landmannalaugar&source=lnms&tbm=isch&sa=X&ved=0ahUKEwj_hsn-uZjMAhVDKywKHRdvDBAQ_AUIBygB&biw=1487&bih=1250">Landmannalaugar</a>. Why should I be ashamed? Because some dislike their own job up to the point they say it pollutes their hobbies or free time?<br />
<br />
I am quite glad it is not my case :)</div>
</div>
</div>
Jeremie Francoishttp://www.blogger.com/profile/02984201174566394892noreply@blogger.com0tag:blogger.com,1999:blog-3615478772815290200.post-91889981406074672112016-04-15T12:08:00.003+02:002016-04-17T18:45:31.069+02:003D printing sponsorship: getting hired and getting fired ... as with any other job? :(<div dir="ltr" style="text-align: left;" trbidi="on">
<h3 style="text-align: left;">
A blow to Octoprint and to the 3D printing community? May be not.</h3>
This short post is triggered by the recent lay off of Gina Häußge by BQ, its sponsor and maker of some opensource 3D printers (notably the <a href="http://richrap.blogspot.fr/2016/01/building-and-using-bq-hephestos-version.html">witbox and hephestos</a>). And by the fact she goes with a few others, more recently hired, well-known people like Thomas Sanladerer (a well known high-quality educational <a href="http://toms3d.org/">video blogger</a> on youtube) or <a href="http://www.silberkind.de/">Nils Hitze</a> (currently an evangelist for rent, and a pillar in the largest 3D printing community on <a href="https://plus.google.com/communities/117814474100552114108">Google Plus</a>). The are part of a massive lay off, so it shall not be felt as specifically related to individuals or to the open source movement (in my opinion).<br />
<br />
But why does it matter to the average 3D printer user? Easy one: Gina is the founder and main developer of <a href="http://octoprint.org/">Octoprint</a>, a "<a href="http://makezine.com/2014/12/09/interview-with-octoprints-gina-hausge/">baby monitor for 3D printers</a>", or more technically a massively popular and very useful software which runs on a Raspberry Pi and which lets you remotely control 3D printers. It can be used on BQ 3D printers as other brands, and many companies even ship it with their own printers (when they are not just stealing it!).<br />
<br />
No more sponsorship equals less features and less maintenance.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg6Xb45BOjfuGQOxvlt5ATobh6DdRmwgGLaZFE7s64mzQbmOMW8CfM_DDbfuKJaCX4VzzSeffRLE61kZelOvIT5PlLG1W1FD_fB1TOr_YBkSXLM492chcUWVl76WYAH4v5VkctnK-gCDwwu/s1600/octoprint-screenshot-controls.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="368" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg6Xb45BOjfuGQOxvlt5ATobh6DdRmwgGLaZFE7s64mzQbmOMW8CfM_DDbfuKJaCX4VzzSeffRLE61kZelOvIT5PlLG1W1FD_fB1TOr_YBkSXLM492chcUWVl76WYAH4v5VkctnK-gCDwwu/s640/octoprint-screenshot-controls.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><a href="http://octoprint.org/">Octoprint</a> is a milestone in usability as a remote control, just like <a href="https://ultimaker.com/en/products/cura-software">Cura</a> simplified slicing 3D models.<br />
Both are free and open-sourced, initially made by smart developers on their free time,<br />
and who later got sponsored for keeping on doing their good work.<br />
(hey I realize only now they were printing one of <a href="http://www.thingiverse.com/thing:25501">my early designs</a> in 2012 for this action shot!)</td></tr>
</tbody></table>
<br />
<a name='more'></a><br />
<br />
I have to agree with a comment in a post I relayed from her on <a href="https://plus.google.com/u/0/+JeremieFrancois/posts/SaVFEA244Yr">Google Plus</a> though: whatever the reason and whatever the outcome, BQ, the company which hired and sponsored the former three people, still deserves respect for being - or having been - one of the very few companies which did feed open source developers and invested large amounts of money to provide knowledge and education to the mass. Check <a href="http://diwo.bq.com/en/">this section</a> of BQ website to get an idea.<br />
<br />
This talks to me further, because for some time I was in touch to do the same work as Nils and Tom for France. At the time I declined the offer, mostly because I practice DIY (do-it-yourself) much more than DIWO (do-it-with-others: <a href="https://www.youtube.com/watch?v=nbeOPJj-kcE">empathy vs. sympathy</a>?). Also, my existing work is already so interesting, without a need to travel to school all across France and talk with institutions... So I feel lucky somehow. Most probably, like Richard Horne from <a href="http://richrap.blogspot.fr/">Richrap</a>, I have other sources of income (but I am by no mean as productive or useful to the community as him: how he manages to be prolific and have a regular job at the same time puzzles me).<br />
<br />
The reason BQ fired Nils, Tom and Gina is unclear. Given this Spanish <a href="http://www.laizquierdadiario.com/ERE-encubierto-en-la-tecnologica-espanola-BQ">newspaper article</a>, I understand a lot of employees may be laid off because the company does not meet hyper-capitalists' growth expectations (this is absolutely not restricted to people working for the community). The way people get fired seems to be nasty. The company experienced a huge growth (mostly as an initial smartphone reseller and maker), from 4 million euros of revenues in 2010 to more than <a href="https://en.wikipedia.org/wiki/Mundo_Reader">200 million euros</a> in 2014. It certainly goes with management difficulties, re-organization and internal or external greed and ego. Who decides what and why is probably as unclear as who is responsible in the existing social turmoil. I do not know and actually this is not the topic here.<br />
<div style="text-align: right;">
</div>
<h3>
The people that got fired?</h3>
<br />
One thing is sure: it is a pity for the individuals who were already paying with their time to promote 3D printing. It is even more of a pity as they resigned from their former, and probably more lucrative positions, and switched to an esoteric but passionate new job.<br />
<br />
Regular companies and regular job contracts just come to an end one day or another. Sponsorship is no exception.<br />
<br />
Like Gina <a href="https://plus.google.com/u/0/+OctoprintOrg/posts/5m53jf6cdme">puts it clearly</a>, it may be hard or impossible for her to keep on by working on Octoprint only on evenings or week ends as she did before. Especially when we realize how major features were made possible only with a full-time sponsorship.<br />
<h3 style="text-align: left;">
Sponsorship as a win-win business strategy?</h3>
In my opinion, the overall sponsorship is a real benefit to the community anyhow, one way or another. Let me be clear though: in this case, the additional profits to be expected by firing these people will be totally insignificant for such a large company as BQ, but as I said, they go along many others so it is probably not personal. Anyhow, Octoprint certainly gained a higher momentum. With sponsoring, Thomas and Nils could also invest more time than with their former hobby, by getting financial support to help even further hundreds of thousand if not millions of users worldwide. This is probably no more the case for them.<br />
<br />
For the company itself, <i>having sponsored</i> an open source project and evangelists is no economic failure in my opinion... unless the company destroys the positive image it acquired with it. BQ is a Spanish company that nobody heard of outside of spain in the 3DP community before that (just because of the exclusive language for example). They did a great job in the last years regarding outreach indeed (remember the <a href="http://www.bq.com/fr/ciclop">Ciclop 3D scanner</a>? or the popular Zowi robot -- itself a successful derivative of an <a href="http://www.thingiverse.com/thing:43708">earlier third-party work</a>).<br />
<br />
I am not sure what benefit BQ will keep here, as it is too early to tell. I only hope that would-be investors and business "angels" always keep in mind the extreme counter-example of Makerbot, which business and image was destroyed by switching from an open-source model to a fully and <a href="http://www.tridimake.com/2014/06/do-not-buy-makerbot-3d-printers.html">nasty, counter-productive closed source model</a>... precisely because of the takeover by Stratasys, a massive and vastly profitable company! Moderation is a good thing, and too much greed is killing us all as usual. So I really hope that no forthcoming take over is responsible for the laying off of "non productive" people... in the eye of the stock holder.<br />
<h3 style="text-align: left;">
So? Is open innovation and humanism incompatible with real business?</h3>
Certainly not. Let me give examples...<br />
<br />
Ultimaker was an early advocate by paying David Braam for <a href="https://ultimaker.com/en/products/cura-software">Cura</a>'s development, and it still holds as far as I know. The printer itself is largely open, and it helped building a large and very strong enthusiast community of makers and "helpers".<br />
<br />
A few companies like LulzBot keep on their <a href="https://www.lulzbot.com/community">amazing open stance</a>: not only their products are perfectly open, but the business itself is transparent, and even up to preliminary <a href="http://devel.lulzbot.com/">research documentation</a> (how noble!).. And they still make money. Less known companies like <a href="https://www.bcn3dtechnologies.com/en/">BCN</a> make and sell rare but open-source hardware: the <a href="https://www.youtube.com/watch?v=O9ck7tCz7AU">BCN3D</a> is a functional dual-head opensource printer - uncommon because it is not easy to achieve reliability with more than one head (most companies which tried it retracted afterwards).<br />
<br />
I certainly forget a lot more companies doing open-innovation, like <a href="https://beeverycreative.com/3d-printing-in-education/">BeeVeryCreative</a> or <a href="http://printrbot.com/education/">Printrbot</a> which have educational programs in their portfolios in addition to their own printers. Or <a href="http://e3d-online.com/">E3D-online</a> that keep on making well-document and well-justified products, from their <a href="http://www.tridimake.com/2014/08/e3d-v6-hot-end.html">E3D hot end</a> and with their BigBox 3D printer. This may not be direct sponsoring, and "non commercial" <a href="http://www.disruptivemagazine.com/features/driven-open-source">creative commons</a> licences may not all be "open source" or "open hardware" <a href="http://www.oshwa.org/2014/05/21/cc-oshw/">technically speaking</a>, but it is part of a more open business than regular companies that try actively to protect their intellectual property and do not contribute to the community at all, or worse, that fear and try to control user feedback.<br />
<br />
Anyhow, let us just I hope that all of such companies are <i>enough</i> profitable for their investors to keep on... Else skeptics will draw lines too easily. The balance between profit, open and closed world is neither all black or all white though and I already talked and wrote about it in an older post (<a href="http://www.tridimake.com/2014/05/the-businessman-and-maker.html">the maker and the businessman</a>).<br />
<h3 style="text-align: left;">
Patreon for octoprint: a viable and independent solution?</h3>
Let us just hope the wheel turns and people like Nils, Tom and Gina find new and interesting sponsorship or regular jobs. Feel free to get in touch if you are an employer reading me and I will relay the offer.<br />
<br />
As for Octoprint, <b>we simply need to keep this essential and unique tool alive</b>. Interestingly, I am not using Octoprint myself regularly, for obscure reasons (may be: not enough room under my printers, modified LCD menus and firmwares, always at home when printing?).<br />
<br />
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhMh2iz4YO584XI9qW_S7k1DtrLh8MPfFDqpOcuN5PlqnlP5QaGSc_RWA4wH8Nwhunn92DJrrKpHJgSAX0GXdAXKrSd0__WPIlW0joOFj3Zfm7nUqCj5_64Wc1Y0oOTLjd7FFuaYnuTlmbe/s1600/patreon_octoprint.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="231" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhMh2iz4YO584XI9qW_S7k1DtrLh8MPfFDqpOcuN5PlqnlP5QaGSc_RWA4wH8Nwhunn92DJrrKpHJgSAX0GXdAXKrSd0__WPIlW0joOFj3Zfm7nUqCj5_64Wc1Y0oOTLjd7FFuaYnuTlmbe/s320/patreon_octoprint.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><a href="https://www.patreon.com/foosel?ty=h">Patreon</a> is a crowd-funding service, that provides<br />
recurring funding for many artists and creators.</td></tr>
</tbody></table>
Let me know if I am wrong, but I know no real alternative software. Actually, the crowd-funded <a href="http://printtopeer.io/">printopeer</a> shall be mentioned here (check this <a href="https://www.youtube.com/watch?v=VXIws_v1fS8">good review</a> ... made by by the very same Thomas Sanladerer that got fired!). Also, <a href="http://www.pronterface.com/">pronterface</a> is enough for the hard core users (I like it in some case), but it is not meant to be as user friendly and feature-packed as Octoprint. The latter goes as far as to have web-based webcam viewing and automatic timelapse made while you are printing.<br />
<br />
Among any other regular sponsoring Gina is willing to accept, direct sponsoring may not be unrealistic. Say, with as low as $1 a month <a href="https://www.patreon.com/foosel?ty=h">on Patreon</a>, it looks like she could get a living when/if more people contribute to the already existing 142 "patrons" (as of today 15 april 2016).<br />
<br />
Now, at $3 you even get an interesting foot in the door, by voting on the upcoming features. Compare this to well known commercial products like the $150 <a href="http://makezine.com/2015/12/10/review-150-simplify3d-software-worth-it-for-some/">Simplify 3D</a> licence that many bought and like (not saying it is not worth -- but I will not buy it when good open source solutions exists). I am just putting things in perspective: this price amounts to a 4-year long equivalent right to vote for the features you wish, and anyhow unlimited free use of Octoprint and its upgrades.<br />
<br />
Now even if $150 seems far-fetched to some, here is another point of comparison: most of us know how horrible and unreliable it is to print with a USB tethered laptop. As soon as I tried an LCD screen and card reader I never went back except for <a href="http://www.tridimake.com/2015/05/github-kills-marlin-which-branch-to.html#more">debugging the firmware</a>.<br />
<br />
<b>But if ever you do not have an LCD controller already, then Octoprint is probably a must. Period. </b>Seriously: even the cheapest reprap LCD at a Chinese online reseller costs about $12. And $12 is one year of sponsoring at $1/month on Patreon for her. So whenever you have a $35 spare Rapsberry Pi in a drawer (everyone has one, right? many other hardware will run octoprint btw), then please just give the LCD money to Gina instead, and <a href="http://octoprint.org/download/">install Octoprint</a> on the Pi. It is as easy as with the stock distribution, and it is well documented.<br />
<br />
Octoprint gives you much more than an LCD screen with a remote control. It is why it was sponsored by a company in the first place: BQ with Octoprint was as smart as Ultimaker with Cura. The main difference is that Cura is no more the only 3D printer slicer now ... and that Ultimaker is still sponsoring it! Octoprint has no alternative, and it is no more sponsored.<br />
<br />
<br />
<span style="font-size: x-small;"><br /></span>
<span style="font-size: x-small;">As usual, please let me know what I missed and where I am approximate. I hope I have more time in the next days to publish. I also wish I could afford more time on our fully forthcoming open-source printer, meant to be as easy to use as possible, but with unusual features in addition. My "other" feeding work is sucking my time. I cannot decently complain about it anyway, but I get the picture quite clearly how sponsorship is such a good thing to move faster.</span></div>
Jeremie Francoishttp://www.blogger.com/profile/02984201174566394892noreply@blogger.com0tag:blogger.com,1999:blog-3615478772815290200.post-72285202866319782632015-12-19T23:20:00.002+01:002017-09-07T11:44:32.584+02:00Tribed: a fully automatic bed leveling and tool height adjustment, with FSR and 3 Z screws<div dir="ltr" style="text-align: left;" trbidi="on">
This post is the continuation of my <a href="http://www.tridimake.com/2015/12/bed-leveling-tramming-sensors.html">preliminary analysis</a> regarding bed tramming and automatic tool height adjustment. So far I never made the step to redo my bed, even though it was on my <a href="http://www.tridimake.com/2014/01/features-and-improvements-for-a-homemade-ultimaker.html">wish list</a> for years. Now it is a reality :)<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen="" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/lTeF73TdQvk/0.jpg" frameborder="0" height="266" src="https://www.youtube.com/embed/lTeF73TdQvk?feature=player_embedded" width="320"></iframe></div>
<div style="text-align: center;">
<span style="font-size: x-small;">Early testing of the complete setup : starting with a properly calibrated bed,</span></div>
<div style="text-align: center;">
<span style="font-size: x-small;">corrupting it manually, </span><span style="font-size: x-small;">and letting the system auto-calibrate it again.</span><br />
<span style="font-size: x-small;">A faster / realistic movement is <a href="http://www.tridimake.com/2015/12/tribed-fully-automatic-bed-leveling-and-z-offset-adjustment.html">here</a>, since speed was not a concern above.</span></div>
<br />
So why now? A few months ago, someone came and talked to me about his wish to design a new, open source, user-friendly printer for the prosumer market. Please <a href="http://www.tridimake.com/2015/10/preliminary-expectations-and-design.html">check this</a> as <i>your</i> opinion counts!<br />
<br />
All in all, it was an excellent reason to realize my idea of a fully automatic bed leveling. And since the new printer will also be opensource, here is the work, design and my analysis. How nice: not only I was given the possibility, but I was <i>asked</i> to do so!<br />
<br />
As said, this improvement is part of a longer effort towards a user-friendly printer, for more reliability and less manual tweaking. My Ultimaker itself may eventually be ditched one day. Huh. No, I am joking. Well.. unless the new one is really is obviously better... Damn, that's exactly what it is all about :/<br />
<br />
<a name='more'></a><br />
<h2 style="text-align: left;">
Automatic bed leveling and tool height compensation</h2>
Specifically, the idea is to combine bed leveling (aka tramming), and tool Z offset (automatic calibration of the tool height). The latter is important as we plan to offer multiple heads and an automatic tool changer (my next work). Nobody wants to deal with the corresponding offsets that needs to be set to less than a tenth of millimeter to avoid havoc. You can read my <a href="http://www.tridimake.com/2015/12/bed-leveling-tramming-sensors.html">preliminary analysis</a> there, but here are the main goals for the combined bed leveling + tool height calibration system:<br />
<br />
<ul style="text-align: left;">
<li>automatic bed tramming - bed should be level after calibration, with no user interaction</li>
<li>automatic Z offset calibration - i.e. according to the mounted tool (various length)</li>
<li><a href="https://www.google.fr/url?sa=t&rct=j&q=&esrc=s&source=web&cd=5&cad=rja&uact=8&ved=0ahUKEwi808LHv-jJAhWGWxoKHSkQAF8QFgg2MAQ&url=https%3A%2F%2Fen.wikipedia.org%2Fwiki%2FRepeatability&usg=AFQjCNHUqsW7p6CeuESO_1KfaSfGnS-wDA&sig2=fxy_RWsOOp6rthopVbzK9A">repeatability</a> - two successive calibrations should give the same result.</li>
<li>real accuracy - vs. software <i>compensation</i> of imperfect bed calibration</li>
<li>simplicity - reduce mechanical risks due to wear or backlash</li>
<li>compatibility with heated bed and 3D printer designs whenever possible</li>
</ul>
<br />
<div>
<div>
</div>
</div>
<div>
Secondary, but nonetheless important items are:</div>
<div>
<ul style="text-align: left;">
<li>small weight - less inertia for better speeds and overall print quality</li>
<li>small footprint - reduce impact on the printable volume and surface</li>
<li>minimal cabling - mostly, tools should not carry duplicated sensors</li>
<li>steadiness of the bed - no bed vibration including at high speed (springs?)</li>
<li>low impact on the firmware</li>
</ul>
<div>
Given prior analysis, I settled on a fully revised heated platform, with 3 embedded FSR force sensitive sensors, 3 independent Z screws, and some modified software.<br />
<h2 style="text-align: left;">
Interesting (temporary?) options left out</h2>
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhFA7sYK_MG2GdjgI23kXGh_32sfGBSzo4gMIJsgqnlvGYXIRBkpEjF6sCy4WvT_1KyUNC3-HsdlHaDIV0Rsn-sQczdAIoPsX_K_q5zlYUfaBjoagLzhICa1SaizKdy1bBomYIyWhovOBPL/s1600/15mm+linear+actuators.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhFA7sYK_MG2GdjgI23kXGh_32sfGBSzo4gMIJsgqnlvGYXIRBkpEjF6sCy4WvT_1KyUNC3-HsdlHaDIV0Rsn-sQczdAIoPsX_K_q5zlYUfaBjoagLzhICa1SaizKdy1bBomYIyWhovOBPL/s200/15mm+linear+actuators.jpg" width="200" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><span style="font-size: 12.8px;">The tiny low cost <a href="http://www.ebay.com/sch/i.html?_from=R40&_trksid=p2047675.m570.l1313.TR0.TRC0.H0.Xmini+linear+actuator+15+mm.TRS0&_nkw=mini+linear+actuator+15+mm&_sacat=0">15mm linear actuators</a></span><br />
<span style="font-size: 12.8px;">I'd use if I had to tram a cantilever bed.</span></td></tr>
</tbody></table>
Using a regular cantilever bed with 2 small-range actuators could do the job. But I tend to dislike such "hanging beds" as they eventually wear out and leave room for vertical free play. Well, unless the whole thing is supersized (which, in this case is not really <a href="https://en.wikipedia.org/wiki/Overengineering">over-engineering</a>, but just pricey).<br />
<br />
<br />
For example, the bed of my old Ultimaker could be shaken vertically by a few millimeters at the end, and I was never able to fix that with the existing design. For some time I thought about adding a second slave Z screw on the front side just to prevent this sloppiness. Better add another one and fully control the 3 "corners" of the bed.<br />
<br />
<br />
<br />
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgBb-q2HBxYEMvyb_Ob-F5ReRDPj83eztMetuOSumG3ksGeuh7eai0dcI9kJa-TyfbxwmlUBtpxQy3SOfiMkvp3Dbc4L5S_xFh0WranZt04ASJqMzYxS2_j1aoIakzbog2teFqpfBovZkGB/s1600/FSR_groove_mount.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgBb-q2HBxYEMvyb_Ob-F5ReRDPj83eztMetuOSumG3ksGeuh7eai0dcI9kJa-TyfbxwmlUBtpxQy3SOfiMkvp3Dbc4L5S_xFh0WranZt04ASJqMzYxS2_j1aoIakzbog2teFqpfBovZkGB/s320/FSR_groove_mount.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Rediscovering what is done <span style="font-size: 12.8px;">already</span><span style="font-size: 12.8px;">: </span><span style="font-size: 12.8px;">FSR groove mount </span><a href="http://www.thingiverse.com/thing:386146" style="font-size: 12.8px;">by edlep</a><span style="font-size: 12.8px;">.</span><br />
I would try to use a load cell instead, for a sturdier mechanical<br />
attachment (but heavy and more complex to interface).</td></tr>
</tbody></table>
For some time I thought about putting the pressure sensors on the tool holder itself. The head itself would then know when it hits the bed.<br />
<br />
Three-point bed attachments would still be required for the actual tramming, and a cable to be run from the tool holder to the firmware.<br />
This idea is not yet fully out of my mind because it is elegant, and it may be even more reliable than embedded sensors in the bed. And I found someone who did it, so it may not be stupid ;)<br />
<br />
<br />
<br />
<br />
Still, I first want to check my current solution. I suspect that the mechanical joint at the head may then be somehow fragile with FSR that cannot be squeezed too much (some floating must be left, necessarily). It may create vibrations during high speed printing or milling for example. In this regard, a metallic <a href="https://en.wikipedia.org/wiki/Load_cell">load cell</a> could be a better choice than FSR, but it is sensibly heavier also and more complex to interface due to its <a href="https://en.wikipedia.org/wiki/Wheatstone_bridge">wheatstone bridge</a>.<br />
<br />
Now for regular single head printers, I really like the idea: it is both simple and probably efficient, so go with it and tell me ;)</div>
<h2 style="text-align: left;">
Hardware choices and requirements</h2>
Overall the improvement required significant additional hardware:<br />
<ul>
<li>of course, three FSR sensors and a new bed gantry...</li>
</ul>
<br />
<ul style="text-align: left;"><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhBKA9OovA2JfPna7Ram7q1FKJJsABH7xmWq17ENWr02nGnTwPL1_BDJvXYdPmsDnWtHqJ45eVNPS9N6J20B9KrYbcpSYW0O9soQxPckk_JNAB6hyf-ct5zwpo4rOTKpbKLgWLtVb4nJsUQ/s1600/IMG_4584-bottom-plate-with-FSR-sensor-Z-screw-and-nut.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="229" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhBKA9OovA2JfPna7Ram7q1FKJJsABH7xmWq17ENWr02nGnTwPL1_BDJvXYdPmsDnWtHqJ45eVNPS9N6J20B9KrYbcpSYW0O9soQxPckk_JNAB6hyf-ct5zwpo4rOTKpbKLgWLtVb4nJsUQ/s320/IMG_4584-bottom-plate-with-FSR-sensor-Z-screw-and-nut.JPG" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">An FSR sensor on the bottom plate of the bed (the tail goes below the bed).<br />
The corresponding nut is linked to the plate with a 3D printed join,<br />
aluminum tube towards the other links (in a triangular setup),<br />
and glued to the bottom of the bed with high temperature silicone.</td></tr>
</tbody></table>
</ul>
<div class="separator" style="clear: both; text-align: center;">
</div>
<ul style="text-align: left;">
<li>due to the two additional steppers, I added a 3 axis CNC shield slave (running a firmware of my own, not GRBL). There are now 3 of them for Z in place of a single one one.</li>
</ul>
<ul style="text-align: left;">
<li>so... 3 Z screws instead of one. By laziness, I bought Nema17 steppers pre-equipped with Z screws (just to test initially). At least there is no more Z elasticity as with those common aluminum couplers (oldham are better but not cheap), and the screws were still straight enough for no noticeable wobble. I used the worst one for the background center "free" screw.</li>
</ul>
<ul><table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; text-align: right;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg4A8TnT4VhEMcLLJPDPQxavdhpCdJs-IXDGQRq2ElOWTRKJJfyzj5NopSnsTrcDmSYeN1T-Uoi3LhaXfHxL6i3hCNo98hqhlIXL8nyk3BB-ckrcYHoS85f1TaZ807KWGS6rDur1tUTBa7o/s1600/nema_17_linear_stepper_motor_linear_actuator_motor_with_lead_screw.jpg" imageanchor="1" style="clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" height="187" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg4A8TnT4VhEMcLLJPDPQxavdhpCdJs-IXDGQRq2ElOWTRKJJfyzj5NopSnsTrcDmSYeN1T-Uoi3LhaXfHxL6i3hCNo98hqhlIXL8nyk3BB-ckrcYHoS85f1TaZ807KWGS6rDur1tUTBa7o/s320/nema_17_linear_stepper_motor_linear_actuator_motor_with_lead_screw.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Basic all-in one stepper motors with lead screw (surprisingly good)<br />
At least I avoid low quality aluminum flex shaft couplers!</td></tr>
</tbody></table>
<li>a few easily designed and 3D-printed holders for the top front roller bearings, and two for the bottom steppers. I should relocate them under the bottom plate of the printer as done the third stepper (I re-used the existing holes of my Ultimaker original). The top of the screw of this stepper is left "free" so as to to over-constrain the 3 Z screws (this is a common error when people want to constrain everything. The front two screws are already doing the job nicely).</li>
</ul>
<br />
<ul>
</ul>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgefbjTCl1jw_MseFjbts5LoY-_KjyUohj4UTL6JvNeqA2iikYzf0HoyMwo8zTc70IRZJH1Ay5w9Z8RPSKwtJHKxaI7u0D1LIPZFQDoJE3TVZPJNq2fB30hEfAh_zqMwrWUwN8VYgS8t8qf/s1600/tribed-top-and-bottom-z-screw-with-nema.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="297" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgefbjTCl1jw_MseFjbts5LoY-_KjyUohj4UTL6JvNeqA2iikYzf0HoyMwo8zTc70IRZJH1Ay5w9Z8RPSKwtJHKxaI7u0D1LIPZFQDoJE3TVZPJNq2fB30hEfAh_zqMwrWUwN8VYgS8t8qf/s400/tribed-top-and-bottom-z-screw-with-nema.jpg" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Bottom and top 3D-printed parts. Both are temporary, since the stepper should<br />
eventually be relocated under the wooden bottom (like the regular Ultimaker Z),<br />
and the top part should not protrude like this. No printable area is lost,<br />
as my <a href="http://www.tridimake.com/2014/01/features-and-improvements-for-a-homemade-ultimaker.html">banana block</a> is already hitting the end stop in this configuration.</td></tr>
</tbody></table>
<ul>
<li>you may have noticed the small arduino pro mini on the bottom of the printer. It is dedicated to the FSR filtering, so that they behave as regular hardware end stops for the CNC slave. Initially I wanted to make sure they acted reliably and independently of the main controllers, but timings seem to indicate it could be computed by the slave or even the main board for less hardware.</li>
</ul>
<h3 style="text-align: left;">
Tricky points</h3>
Time will tell but I know that both guiding and driving with a lead screw is somehow "impolite" to most engineers -- but I am pragmatic: it seems to work quite well with only three Z screws that do both jobs. The bed does not move at all. Milling may add lateral wear to the nuts though, but we have here very cheap Chinese stuff so they can be improved also.<br />
<br />
Wear. This is yet to test... For this reason, part of this post may then get updated without much notice, and as usual, any feedback is welcome, so feel free to criticize!<br />
<br />
A major trouble came with how to insert and fix the 3 pressure sensors to the bed, without impacting the surface area, without exposing them directly to heat (the bed shall be able to go up to 150°C), and more importantly.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen="" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/YwEfrEuktZ4/0.jpg" frameborder="0" height="266" src="https://www.youtube.com/embed/YwEfrEuktZ4?feature=player_embedded" width="320"></iframe></div>
<div style="text-align: center;">
<span style="font-size: x-small;">These show how sensitive the FSR force-senstive-resistors can be, after heavy filtering.</span></div>
<div style="text-align: center;">
<span style="font-size: x-small;">I did not keep this seemingly fine setting though, as it generates too many "false positive" signals.</span></div>
<div style="text-align: center;">
<span style="font-size: x-small;">So I had to ask for more pressure before they trigger. Some room for improvement is left !</span></div>
<br />
More importantly even, I had troube figuring out how not to overload the sensors because of the bed weight (PCB heater + aluminum plate + glass plate). Resting the bed directly on the FSR transmitted also all kind of vibrations which triggered them too easily unless I asked for excessive/risky pressure (the nozzle could break the glass, no good).<br />
<br />
My best idea was to use neoprene, that protrude largely around the FSR sensors. This way the bed is well maintained laterally, it will not transmit its heat to the FSR, its weight is well supported, but it still transmits very well the slightest pressures. And neoprene does not melt like thermoplastics (I would not recommend to print these parts!).<br />
<br />
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjlwSYRY5xyzAgbK3aUEiD2w7HNjsABDyvHfiRMvpJC-RJERJQVxBPI0JHKT9qFTgXT8Mutu4fcAa6QgsvHvQ5NGSC9Ge-4fz6xOEMW00Ia-7r7FzogS11S9uSZB3KqX42jC2-yVj864Yp_/s1600/IMG_9547-neoprene-with-FSR-filters-out-noise.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="213" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjlwSYRY5xyzAgbK3aUEiD2w7HNjsABDyvHfiRMvpJC-RJERJQVxBPI0JHKT9qFTgXT8Mutu4fcAa6QgsvHvQ5NGSC9Ge-4fz6xOEMW00Ia-7r7FzogS11S9uSZB3KqX42jC2-yVj864Yp_/s320/IMG_9547-neoprene-with-FSR-filters-out-noise.JPG" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Neoprene is just excellent as a heat-resistant spacer, as a <a href="https://en.wikipedia.org/wiki/Shock_absorber">shock absorber</a>,<br />
and as a weight relief. It filters most of the mechanical noise, but it transmits<br />
nicely the pressure from the nozzle on the top plate to the FSR.</td></tr>
</tbody></table>
Electrically, using the convenient internal 10K pull-ups of the Pro mini was not wise, as it sent the signals in a tiny dynamic range, which was prone to trigger false positive. I had to use external resistors (not difficult but it means specific electronics...). <i><a href="https://en.wikipedia.org/wiki/False_positives_and_false_negatives">False positives</a></i> are when the sensor triggers abusively (e.g. when the bed brakes hardly while it goes down, due to interia). They just ruins the very first idea of user-friendliness!<br />
<div>
<br /></div>
Also, the CNC slave is used to drive 3 stepper drivers. All in all we have 1 X, 1 Y, 3 Z screws and 1 for each extruder. With our minimum of two heads by default, it means 7 steppers and most 3D printer boards cannot handle so many motors. As long as we do not design our own electronics, which we may better do in the end, we had to use a slave controller, and this sucks. The good news is that it only controls the Z during calibration (see below my trick with "transparent mode").<br />
<h3 style="text-align: left;">
Software requirements</h3>
There were also some software modifications:<br />
<ul style="text-align: left;">
<li>I modified Marlin to activate the third Arduino Mega serial port 3 (soldered a connector on the board). It links to the CNC shield slave (on an arduino Uno). I wrote a small protocol to control the slave from Marlin, and I added corresponding custom menus in the LCD too.</li>
</ul>
<ul style="text-align: left;">
<li>I wrote a basic but fully custom stepper driver for the CNC shield, named "bunchosteps". It should not have been compulsory as GRBL is a very nice piece of software and does its job. The problem is that it was made with "only" CNC control in mind, notably with the "fatal" endstops and asynchronous operations and look ahead (block-based segmentation of the commands). It took me too much time to tailor it to my needs so I rewrote my own simpler version. It is also low-level (non-Arduino) code, based on fast interrupts so as to achieve fully controllable smooth Z movements with acceleration and brake (you'll see the effet in the introductory video), but it also handle direct interrupts, common 3Z movement, and most of the calibration (complex interaction with the pseudo-endstops), thanks to a pseudo g-code interpreter fed via the serial link. For me it was much simpler to write one from scratch and deal with it overall.</li>
</ul>
The sources are posted on my <a href="https://github.com/MoonCactus?tab=repositories">github account</a>, but they are mostly proofs of concepts, still in evolution. So better ask me before you clone or you fork them, and use with care! I need to polish the FSR filtering, but I see Johann Roscholl already has <a href="https://github.com/JohnSL/FSR_Endstop">posted such source code</a> also (check the page! I realize a lot work was done there already).<br />
<br /></div>
<div>
I should at least post the low-level Serial3 support for Marlin as it may help others. I still am unsure whether I rewrote something existing, but I really was not able to active it in the existing state of Marlin.<br />
<br />
<h2 style="text-align: left;">
How it works</h2>
<h3 style="text-align: left;">
Bed leveling</h3>
Tramming is triggered by a specific "tribed" menu.<br />
<br />
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; margin-left: 1em; text-align: right;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgyMztTxGCEWVWHxOhAQPucXQJS6ShBKe9OBMx6q6KUSE8tm2_3QkwJ6toU1D4wQlJjeOQ9kgrO4ZbcbotW5Z6USl4TEcA5qQdbWqUiEACBzJY6Cf-PPEO2MDSDpX-xdqxvSSvx_88tQQn2/s1600/tribed-bed-components.JPG" imageanchor="1" style="clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgyMztTxGCEWVWHxOhAQPucXQJS6ShBKe9OBMx6q6KUSE8tm2_3QkwJ6toU1D4wQlJjeOQ9kgrO4ZbcbotW5Z6USl4TEcA5qQdbWqUiEACBzJY6Cf-PPEO2MDSDpX-xdqxvSSvx_88tQQn2/s320/tribed-bed-components.JPG" width="213" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">The bed components.</td></tr>
</tbody></table>
It is a mix of XY moves (done by the master), and Z1,2,3 and combined Z (done by the slave). The procedure is simple : lower the bed (to avoid crashing in it), do a regular XY calibration (find origin), move back to center, home the entire bed (to have an average point of reference). Lower again slightly (assuming the bed is not skewed more than this value), then move sequentially over each of the FSR sensors, raise the entire bed until it triggers the sensor. Lower the bed again, but only by a few millimeters, then raise only the corresponding Z to "home" the axis (this is where the calibration really occurs). Rinse and repeat.<br />
<br />
The origin of the first axis is not changed, as it is used a the unique reference. Only the second and third axes are modified to that eventually the zero matches expectation.<br />
<br />
As usual any homing is done in two passes: a fast seek up, slight lowering, and a second, slower seek up. The deal is never to move too fast to crash the head on the bed. The first homing is faster and less precise, the second moves a shorter distance but is much more precise (just because it is easier to stop at once when breaking due to a lower inertia).<br />
<br />
This is just how it is done on existing printers and CNC machines: it is also why there is this weird "bounce" when homing.<br />
<br />
<br />
<h3 style="text-align: left;">
Homing and post calibration: transparent mode!</h3>
Once calibration is done (moving the 3 Z axes independently with the slave), all the remaining operations can be done by the master.<br />
<br />
The nice little trick I found is to switch the slave to "transparent mode", where it acts as a multiplexer to the stepper signal emitted by the main controller board: I literally redirected into the slave hardware interrupts the "step" and "direction" signals that I took from the empty Z pololu socket on the main board!<br />
<br />
So the slave gets the pulse quickly from the master and passes them as soon as possible (a few nanoseconds), unchanged, to its own 3 stepper drivers.<br />
<br />
The benefit is great: I can drive my Z just like before, as if I had only one Z screw. But I can also set them separately by switching the slave in calibration mode first!<br />
<br />
My goal here is to ditch the obsolete RAMPS + Marlin and easily switch to a more powerful and promising board like the <a href="http://smoothieware.org/smoothieboard">Smoothieboard</a> or the <a href="http://www.thing-printer.com/product/replicape/">Replicape</a>. I plan to do in a near future, so the less I have to tweak the main firmare, the better. Seriously, I spend already too much time just on enabling the third serial port in Marlin for my Ultimaker RAMPS... The old AVR is at its end of life for driving fast 3D printers, and even more when it comes to additional sensors and hacking. Times are for ARM32 boards.<br />
<h3 style="text-align: left;">
Flashing the slave</h3>
As a final trick, I added a menu entry in my "tribed" section so that I can shut off the serial link between the RAMPS and the slave. This way I can flash or talk to the slave directly without conflicts. This was a huge time saver. In between, I have tweaked Marlin g-code interpreter so that orders are sent to the slave when I prefix them with S3 (this stands for Serial3). So "S3 g120" will ask the slave to do a homing. Yes, this is no g-code, sorry ;)<br />
<h2 style="text-align: left;">
Notes and conclusion</h2>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiAQOWp9fmhqGgqlNQTKAnX0n-nvGwsmoeUqCPvszQGQhIcjDOcONECYh_rlB1S79JNB_hjG2AbB2FjzMuRI8E67SZG764Xhh2r8tizD90MMKiDDrKUS3VgiQ9FgI-knLqhBqbbFaiiBLfC/s1600/the-tribed-final-setup-hardware-bed-calibration.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiAQOWp9fmhqGgqlNQTKAnX0n-nvGwsmoeUqCPvszQGQhIcjDOcONECYh_rlB1S79JNB_hjG2AbB2FjzMuRI8E67SZG764Xhh2r8tizD90MMKiDDrKUS3VgiQ9FgI-knLqhBqbbFaiiBLfC/s640/the-tribed-final-setup-hardware-bed-calibration.JPG" width="587" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">The overall is pretty clean imho: the bed is much thinner, so I also maximize the printing volume.<br />
The two vertical Z screws in the front lost no horizontal printing area - Full win :)<br />
<span style="font-size: 12.8px;">(OK, the short cable and the arduino mini should be fixed, and the two steppers<br />in the front should go to the underside, just as the one in the background is)</span></td></tr>
</tbody></table>
<h3 style="text-align: left;">
Achievements</h3>
<br />
<ul style="text-align: left;">
<li>this 3Z-bed works well, as intended, even though there are still rare few false positive to fix during calibration. I can print straight out of a badly configured bed without having to tune anything</li>
<li>this setup accepts any bed thickness and any tool height. I can change my nozzle and even the entire printer head and simply run another calibration, the new tool length is taken into account automatically. Even if a complete bed tramming is slow, it is not required often, unless I change the bed components and it ends not perfectly level for some reason.</li>
<li>we really have a hardware calibration, not software compensation of the hardware defaults</li>
<li>not really expensive (it costs less than the high-quality hardware that would be required to avoid the need for any calibration in my opinion)</li>
<li>it is compatible with heated bed (the sensors are safe, not exposed to external accidents)</li>
<li>it looks cool! My ultimaker looks empty :)</li>
</ul>
<br />
<h3 style="text-align: left;">
Improvements? Of course!</h3>
Optimization and testing is not only possible, but compulsory.<br />
<ul>
<li>tramming requires more than one pass, because the distance between the FSR sensors and the Z nuts is not null. It creates a pivotal point, and fixing one Z impacts all other settings, so a subsequent pass is usually necessary</li>
<li>in the video above, 3 passes were required to go below significant changes. Actually by simply moving the calibration offsets as close as possible to their respective Z nuts, only two passes are now required. A third one fixes nothing visible, so it makes the whole faster.</li>
<li>may be I could also scan first to get the offsets, solve the equation and fix in second pass</li>
<li>better, with some trigonometry, I think should be able to reduce it to one single pass.</li>
<li>I should also simply stop the calibration as soon as no more "fix" is required. This is useful because once the bed is properly calibrated, it should stay so unless major events happens</li>
<li>once stable, I could also increase the Z speed. The thing is to make sure not to trigger the FSR when the bed brakes, which I should be able to do as no detection is expected when the bed moves down! Still, some vibration may be transmitted to the FSR when moving fast (it was just so frustrating before I used neoprene spacers as shock absorbers).</li>
</ul>
And finally, more importantly for our project and in order to reduce the total cost of the machine, I think I should move to hardware multiplexing of the Z, so as to avoid the need for an overly complex CNC slave. But this requires a specific hardware board, which I should take into account (honesty, I think it will be beneficial).<br />
<br />
Oh, and of course, a lot of real world testing to verify the options were sound and efficient.<br />
<br />
And now, I can switch to something else: designing an automatic tool changer!<br />
<h2 style="text-align: left;">
Addendum: the reprap way -- making it cheaper</h2>
<div class="separator" style="clear: both; text-align: center;">
</div>
<h3 style="text-align: left;">
Motors and drivers</h3>
Since there are 3 motors to drive the Z, and since it does not need to move fast (unless may be for Z-hopping), I think it may be possible to trade the NEMA 17 and CNC shield for 3 of these little $5 stepper motors found on ebay.<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEju1MdpzvrzFbaveePc1CxgKyowUWiBU1qtg988al96WkDlUz9KOGizao017-fdbXj31K1lQWf91Ziz-eKAjWa_Ze8BWdjY86ekLVh7dO5g1wlOr_t66CCT9XUJB1iGkd_ZI9VExNekkcso/s1600/low_cost_stepper_and_driver.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="182" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEju1MdpzvrzFbaveePc1CxgKyowUWiBU1qtg988al96WkDlUz9KOGizao017-fdbXj31K1lQWf91Ziz-eKAjWa_Ze8BWdjY86ekLVh7dO5g1wlOr_t66CCT9XUJB1iGkd_ZI9VExNekkcso/s320/low_cost_stepper_and_driver.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">5$ stepper driver with UNL2003 driver. Could three of them drive the bed?</td></tr>
</tbody></table>
<br />
<h3 style="text-align: left;">
Alternate force-sensitive sensors</h3>
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; text-align: right;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghZW7lUG7S2gCJ3fDtvunBVdGSN12_t_tpub91_SDGR0cc2cY5hCt49lpbRywe0BPAJL48FGGoDXufccdgH6ZsrNpANz61sL8MjK_ZoIpKELtMr4g1HnoIor3WGHvaols-kpTOayAfQDjB/s1600/conductive_foam.jpg" imageanchor="1" style="clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghZW7lUG7S2gCJ3fDtvunBVdGSN12_t_tpub91_SDGR0cc2cY5hCt49lpbRywe0BPAJL48FGGoDXufccdgH6ZsrNpANz61sL8MjK_ZoIpKELtMr4g1HnoIor3WGHvaols-kpTOayAfQDjB/s1600/conductive_foam.jpg" style="cursor: move;" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">A very cheap pressure sensor!</td></tr>
</tbody></table>
Unsurprisingly, there also a few ways to replace the efficient, robust, but $10 intersil FSR sensors.<br />
<br />
I am not telling here about on/off contacts as they are trivial to make but they are harder to tune. The deluxe version would be to use more durable conductive rubber, as used in gamepads or TV remote controller. The cheaper would be bare cables criss-crossed on top of each other with a tiny air gap made by "just enough" foam spacers. Probably not very reliable.<br />
<br />
More interestingly, you can make your own basic pressure sensitive sensor using antistatic/conductive foam (static dissipative foam), like the one often used to protect the pins of electronic chips (well, when your seller is serious - or you can buy some very cheap on ebay). There are tons of howtos on the web (ex. <a href="http://www.instructables.com/id/DIY-Force-Sensitive-Resistor-FSR/">this</a> or <a href="http://www.todayifoundout.com/index.php/2010/01/how-to-make-a-ridiculously-cheap-analog-pressure-sensor/">that</a>). The deal is just to insert two wires in it, or here, put a slice of conductive foam between two conductive plate: here, the bottom may be the common steel plate, and the top made of cooking aluminium foil, or bare wire in zig-zag. The resistance depends on the distance between the two, it may just have to be calibrated.<br />
<br />
Another idea would be to use (ideally partially) <a href="http://www.shieldextrading.net/">conductive textiles</a>. Even though it is harder to find R.F shielding textiles nowadays to recycle, it can be found online. Not sure how expensive it would be though... I would make a sandwich with a very thin or porous non-conductive intermediate layer, like coarsely woven non-conductive fabric. This way, the the two conductive layers would not tough by default and, when you use <i>partially</i> conductive textile, the more you press the lower the resistance. This makes life easier to set triggering thresholds. Oh -- just found someone who <a href="http://www.instructables.com/id/Pressure-Sensor-Matrix/">made it</a> into an interesting touch-sensitive matrix.<br />
<br />
You could also sew your own "conductive textile" by using <a href="https://en.wikipedia.org/wiki/Nichrome">nichrome wire</a>, an interesting material to use in many projects. For some time it was used to make heated beds, before PCBs and silicone heaters became common online -- an option I forgot to talk about about in my obsolete <a href="http://www.tridimake.com/2012/10/homemade-heated-bed.html">heated bed</a> (... failures).<br />
<br />
<br />
<br />
<br />
<br />
<i>Note: this work was partly sponsored, as part as a former attempt to create an opensource printer. Please do comment and give your opinion! Since the printer will be fully open, the community could benefit from the result reciprocally, if it is worth -- and we share the thing as with this post. It would be a pity that I do something stupid and miss an interesting point or feature.</i><br />
<br />
<div>
<i>Note2: tribed, tri-bed or tridibed... I did not spend enough time on chosing a good name, but since <a href="https://hackaday.com/2016/01/31/tribed-3d-printer-configuration-doesnt-ever-need-to-be-leveled/">hackaday</a> linked to this page and its title before I had a chance to change it, let me keep it now ;)</i></div>
</div>
</div>
Jeremie Francoishttp://www.blogger.com/profile/02984201174566394892noreply@blogger.com1tag:blogger.com,1999:blog-3615478772815290200.post-11137066959632380612015-12-18T14:32:00.001+01:002016-03-18T20:10:59.121+01:00Sensors and issues for automatic bed leveling and height adjustment<div dir="ltr" style="text-align: left;" trbidi="on">
My printer eventually has a fully automatic and hardware bed leveling (aka tramming), and bed height (aka Z-offset). Yes, it now handles any tool height without any user action, in addition to a long-wished automatic leveling of the bed.<br />
This is part of preliminary studies for a <a href="http://www.tridimake.com/2015/10/preliminary-expectations-and-design.html">prosumer open-source printer</a>, for which you are more than welcome to give your opinion! The entire bed structure was entirely revamped, as one important point in my <a href="http://www.tridimake.com/2014/01/features-and-improvements-for-a-homemade-ultimaker.html">former wish list</a>.<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjLZNwabr9jdaNIyx9zUt89USLAD4KpijYKVx1VJlTrM-JG1vOiQSx0HkWW7XQGHU6XBBlUchmzbznFF81gufAnvq2Sc-qc244fEC1WhBYhUdigEzxkT2JIgPH6YT2XL0CYJ-GtgGPF_y33/s1600/IMG_9551-tribed-front.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="250" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjLZNwabr9jdaNIyx9zUt89USLAD4KpijYKVx1VJlTrM-JG1vOiQSx0HkWW7XQGHU6XBBlUchmzbznFF81gufAnvq2Sc-qc244fEC1WhBYhUdigEzxkT2JIgPH6YT2XL0CYJ-GtgGPF_y33/s640/IMG_9551-tribed-front.JPG" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Revised heated bed with automatic tramming and tool height compensation.</td></tr>
</tbody></table>
Since I wanted to document both the new bed but also <i>why</i> I wanted it this way, this first post addresses usual sensors and strategies used to deal with the bed calibration. The deal is to make a bed level and to start printing at a proper height, and there are many ways to do so, but not as conveniently as I wanted (which will be documented in a subsequent post). <a href="http://www.tridimake.com/2015/12/tribed-fully-automatic-bed-leveling-and-z-offset-adjustment.html">The second post</a> will show more precisely what and how I did it.<br />
<br />
<br />
<a name='more'></a><h2 style="text-align: left;">
3D printers need a fine, flat, level bed... or they fail.</h2>
A precise bed level is just plain compulsory. As listed in the <a href="http://reprap.org/wiki/Leveling_the_Print_Bed">corresponding section</a> in reprap.org, a wrong bed leveling may result in<br />
<ul style="text-align: left;">
<li>The initial layer is not sticking to the bed.</li>
<li>The initial layer isn't complete; parts of the print just don't get laid down.</li>
<li>The head scrapes the bed in some spots (you probably worked this one out for yourself).</li>
<li>Plastic gathers around the head during printing of the first or second layer.</li>
<li>When printing the second layer the print head is picking up the first layer</li>
</ul>
There is no hope to print properly with a skewed surface. Not only the first deposited layer must be parallel to the bed surface, but it must also be squashed "just enough" to keep the part stuck on the bed for the duration of the print. Also, the initial layer height must be known precisely for the correct amount of plastic to be deposited (most of us guess the value -- a safe bet with experience).<br />
<br />
<i>Side note</i>: other factors may pop the initial layer off the bed. Most thermoplastics contract when they cool down. Old-school Polycarbonate is hellish in this respect, when ABS and Nylon can be difficult. You need both a bed which is well-calibrated and heated, and often use <a href="http://www.tridimake.com/2014/01/how-to-3d-print-nylon-and-trimmer-line.html">additional glue or special material</a> to keep the deposited plastic stuck on the bed for the duration of the print.<br />
<h2 style="text-align: left;">
The problem with bed tramming</h2>
Manual bed tramming is time consuming at best, and difficult at worst. Most of us often overlook the calibration, by considering it was done weeks or month ago and it did not change... But not all printers are equal here. For example, I probably can drag my sturdy printer here and there without trouble, when most of the entry-level repraps do require a calibration again.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen="" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/ED1Gxvw2Rmw/0.jpg" frameborder="0" height="266" src="https://www.youtube.com/embed/ED1Gxvw2Rmw?feature=player_embedded" width="320"></iframe></div>
<div style="text-align: center;">
<span style="font-size: x-small;">A tutorial on bed leveling by Tomas Sanladerer</span></div>
<div style="text-align: center;">
<span style="font-size: x-small;">(<a href="https://www.youtube.com/channel/UCb8Rde3uRL1ohROUVg46h1A">his channel</a> is full of such wise videos)</span></div>
<div>
<span style="font-size: x-small;"><br /></span></div>
A rule of thumb is that cheaper printers need more regular maintenance, even though some get software compensation nowadays. The reciprocal is <a href="http://www.tridimake.com/2014/06/do-not-buy-makerbot-3d-printers.html">not always true</a>, though.<br />
<br />
Anyhow, bed leveling is just not something that can be overlooked to get easy and nice prints. And probably all printers need to be calibrated regularly, soon or later, manually or automatically.<br />
<br />
Another fundamental issue is that each time you change something to the head or to the nozzle, a new "zero bed height" must be set. This value is the initial bed distance, not the bed level. A large unwanted offset may kill your plate or your gantry when the nozzle crashes into the bed during homing, but tiny difference as small as 0.1 mm are often enough enough to degrade significantly a print. The latter happens when your new nozzle height changed just because tiny bits of plastic were left in the thread, or because it was not tightened to the exact same force as the former.<br />
<br />
Now, obviously, when you change the complete head, a new bed height has to be set, even though the bed leveling <i>should</i> still be OK -- the bed height is not.<br />
<br />
All in all, the difficulty to properly calibrate them, and keep them calibrated is a major reason why printers are not as mainstream as the <a href="http://www.tridimake.com/2013/04/what-cannot-be-3d-printed.html">hype likes to tell</a>.<br />
<h2 style="text-align: left;">
Common bed leveling mechanisms</h2>
You may want to skip this small <i>state of the art</i> if you already know this, before I talk about my implementation.<br />
<br />
Historically, beds were first adjusted manually via screws and springs: the user moves the head over the bed at different places, check the gap and tune the screw so that the nozzle almost touches the bed. The goal is to leave a few tenths of millimeters. One classic trick is to sliding a sheet of paper between the two. Note that leaving any gap is arguable, but I understand that nobody wants the zero to be a real contact for security reasons. Leaving a safe tiny gap ensures that the nozzle never gets dragged on the bed accidentally. I do it also, but then the gap which is left must be taken into account for the first layer thickness in the object slicer. It would be better that the slicers sets this value, and not that we set the value in the slicer... Anyway.<br />
<h3 style="text-align: left;">
First, better use a flat/planar bed!</h3>
I made an assumption here. I consider my bed to be a perfect flat, and this is mostly why I am using a <a href="http://www.tridimake.com/2012/10/homemade-heated-bed.html">glass on top of an aluminum bed</a>. Having a perfectly flat bed is important, as nothing else than a complete probing may compensate a bent or a deformed beds. Given many height values, the firmware can compute and correct the 3D model in real time, so as to compensate for the surface irregularities -- we will see that again later.<br />
<br />
As a side note, delta printers are beasts of their own: since the gantry provide no natural movement in the X-Y plane, a multi-point calibration is often required (<a href="https://www.youtube.com/watch?v=L9URtv2LqKc">check it</a> with Marcus Littwin -- the author of <a href="http://www.repetier.com/">Repetier</a>, a slicer and firmware).<br />
<h3 style="text-align: left;">
Manual bed leveling.</h3>
Bed flatness and bed leveling are two different things. You may have a flat bed (aka. a plane), but it may not be parallel to the X-Y movement of your head, which is our main subject here. Historically, bed leveling was done via a few mechanical systems.<br />
<ul style="text-align: left;">
<li>4 manual screws pull the bed down, and springs pushes it up. For example, the original Ultimaker had such a 4-point bed leveling , and I still see new printers arriving on the market with this very wrong design. Hey, a plane is well defined by 3 points, not 4! In fact, the fourth screw will always go against the 3 others... and in the worst case, you may even bend your bed surface if it is elastic enough (and then, no way you can print correctly).</li>
<li>3 manual screws: this is the minimum you ought to have on a "modern" printer. And indeed, it is the most common system to level a bed. Actually, it may also be enough if your hardware is sturdy (or even expensive), or when the printer is not dragged here and there, when it is not subject to highly variable temperatures, and when your tool set does not change.</li>
</ul>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjBaC6V9ZW3ZlSrUH1RKhI7y1PbpIK5Rl_g8Oa0vobIqWruy_Hd86Ab4NRL5X6U46ydttVbAN4rWDF4CKo6_qsNvRzK45wkBMQZ4jMium56dI4exVaMxK45SCqxZ5JjnFtUK8nFPlWxiM9W/s1600/hotbed_final.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="266" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjBaC6V9ZW3ZlSrUH1RKhI7y1PbpIK5Rl_g8Oa0vobIqWruy_Hd86Ab4NRL5X6U46ydttVbAN4rWDF4CKo6_qsNvRzK45wkBMQZ4jMium56dI4exVaMxK45SCqxZ5JjnFtUK8nFPlWxiM9W/s400/hotbed_final.jpg" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">My <a href="http://www.tridimake.com/2012/10/homemade-heated-bed.html">former heated bed</a> used a central elastic pivot point (made of half a squash ball), where<br />
the front pair of screws pulled the bed downwards while the third one is fixed (<span style="font-size: 12.8px;">not seen).</span></td></tr>
</tbody></table>
<ul style="text-align: left;">
<li>A smart semi-automatic bed leveling was made for the <a href="http://kuehlingkuehling.de/2013/05/01/wondering-how-the-semi-automatic-print-bed-leveling-works-video/">Kuehling & Kuehling</a> printer. In this design, the nozzle pushes the bed down to compress the springs to a known height, and only then thumbscrews are used to lock the height (note that the thumbscrews could be activated automatically themselves).</li>
<li>A similar idea was done by Scottbee and <a href="http://hackaday.com/2014/04/15/automated-bed-leveling-for-3d-printers-is-now-solved/">featured in hackaday</a>, as a fully automated system. Sadly, I did not hear much about this system. But the idea is there.</li>
</ul>
<h3 style="text-align: left;">
Automatic and semi automatic bed leveling</h3>
<div>
Next came printers with heads equipped with a sensor to record (aka to "probe") the bed by moving closer enough so the sensor triggers.</div>
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen="" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/1eNz1l56H5E/0.jpg" frameborder="0" height="266" src="https://www.youtube.com/embed/1eNz1l56H5E?feature=player_embedded" width="320"></iframe></div>
<div class="separator" style="clear: both; text-align: center;">
<span style="font-size: x-small;">Contact probing and flatness compensation on a delta printer</span></div>
<div class="separator" style="clear: both; text-align: center;">
<span style="font-size: x-small;">by the legendary Johann Rocholl, on his mini Kossel</span></div>
<div>
<br />
<ul style="text-align: left;">
<li><i>Contact probes</i> were first tested, where a microswitch or an infrared barrier is indirectly activated when the probe gets in contact with the bed. The problem is that either the probe or the nozzle must be in contact with the bed, and not both for obvious reasons. Hence, a <a href="https://youtu.be/mcVIJf90OtM?t=373">servo motor</a> or a a <a href="https://www.youtube.com/watch?v=ErxfshCtd88">solenoid</a>, is often used to <i>deploy</i> and <i>retract</i> the sensor, so that it protrudes below the nozzle during the calibration.</li>
</ul>
By knowing the "constant" difference in height between the probe and the nozzle (so called "Z offset"), the firmware knows how far and unlevel the bed it. The tricky part here is "constant", which may not be so constant as we will see in a minute.<br />
<ul style="text-align: left;">
<li><i>Contact-less probes</i> are often better, not only because they no more require a heavy, complex and often unreliable mechanical deployment system, but also because they are immune to wear (like infra-red diodes or <a href="https://en.wikipedia.org/wiki/Hall_effect_sensor">hall-effect sensors</a>), or even to dirt (like <a href="http://diy3dprinting.blogspot.fr/2015/03/how-to-use-inductive-distance-sensor.html">inductive sensor</a>, as commonly used on dirty CNC machines). They are also lighter than contact probes and need less cabling (no need to move the probe in and out of the way).</li>
</ul>
</div>
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen="" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/3xqdr11gRkw/0.jpg" frameborder="0" height="266" src="https://www.youtube.com/embed/3xqdr11gRkw?feature=player_embedded" width="320"></iframe></div>
<div style="text-align: center;">
<span style="font-size: x-small;">Contact-less inductive sensor: a howto and an example.</span></div>
<div>
<br /></div>
<div>
However, inductive sensors require a close metallic bed to trigger and they may be subject to electromagnetic noise. Infrared or hall effect sensors precision is often poor: the triggering distance is not reliable enough. This also depends on the price and sensor you can afford of course.</div>
<div>
<br />
<i>Note</i>: many if not all firmwares already support probing, with or without automatic retraction. In case of Marlin you have to tweak the configuration somehow and recompile the firmware, which may get tricky (just to get the <a href="http://www.tridimake.com/2015/05/github-kills-marlin-which-branch-to.html#more">correct branch</a>...). More advanced features are also supported such as the "matrix probing" (probing is done in many poinst so as to correct non-planar beds -- which proves to be extremely useful for Delta printers when their arms are not perfectly identical).<br />
<br />
Now, probes that are attached to the head will add weight to the head. This is detrimental to speed or quality as more inertia is more trouble. Even fixed probes like inductive sensors are often bulky: they may reduce the number of objects that can be printed serially on a bed, since the head need to move around formerly printed parts without knocking them down.<br />
<br /></div>
<h2 style="text-align: left;">
Z-offset: an issue with the usual bed leveling systems</h2>
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5urPfYaJILw0dNHhl3kw9Eui2Z2pI90NMW5RAyf4aw8nVKqlnuNzV58uwYlREfFonUFODRAbGb9HJLLJ-i6WHd8giUG9xDyDVNTQEFHw7rJzB1jTw8jVLcpLnVMppPRqSFmdM_LMeracB/s1600/32279_ATC_under_lrg.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="212" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5urPfYaJILw0dNHhl3kw9Eui2Z2pI90NMW5RAyf4aw8nVKqlnuNzV58uwYlREfFonUFODRAbGb9HJLLJ-i6WHd8giUG9xDyDVNTQEFHw7rJzB1jTw8jVLcpLnVMppPRqSFmdM_LMeracB/s320/32279_ATC_under_lrg.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">A professional <a href="https://www.youtube.com/watch?v=unsQ9i-nBNc&feature=youtu.be">tool changer</a> (<a href="http://www.tormach.com/upgrades_tts_atc.html">ref</a>.).<br />
See how no tool ends at the same height?</td></tr>
</tbody></table>
In any case, two problems remain with the above systems. Even when the bed is level, two other factor may impact the print.<br />
<br />
<ul style="text-align: left;">
<li>heat expansion: when the bed heats, it often expands a bit vertically, especially when it embeds an aluminum plate (which I would recommend to homogenize the heat). Without a sensor, most existing systems will not take this into account, so they better be set <i>after</i> the bed is hot.</li>
</ul>
<ul style="text-align: left;">
<li>reciprocally, helping calibrate the tool height is something almost always forgotten in the 3D printer world as for now! But the distance to the bed also changes each time a nozzle or a complete head is changed (possibly for dual heads, but also for <a href="https://youtu.be/O9ck7tCz7AU?t=77">manual head changes</a>). Each tool has its own "Z offset".</li>
</ul>
<br />
<div>
<h3 style="text-align: left;">
A remark on dual head setups</h3>
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; text-align: center;"><tbody>
<tr><td><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEil3_idBRkB97J9Eqvfc00wksjPNOUgWPC99BICpEvmIz2zEPqbFZ5YOij8PCLxNuInuFkposkQMNCJzG-mjfP-Mr86zHlwIDpayJXX-_rFbawczaSg924OuaiXZEd6J1kPgtbKgzDdTxx-/s1600/BCN3D-2015-10-17+09.07.42.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="180" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEil3_idBRkB97J9Eqvfc00wksjPNOUgWPC99BICpEvmIz2zEPqbFZ5YOij8PCLxNuInuFkposkQMNCJzG-mjfP-Mr86zHlwIDpayJXX-_rFbawczaSg924OuaiXZEd6J1kPgtbKgzDdTxx-/s320/BCN3D-2015-10-17+09.07.42.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="font-size: 12.8px;">The excellent BCN3D dual head setup I discovered as<br />
a moderator at the <a href="http://3dprintshow.com/paris-2015/">3D Print Show Paris 2015</a></td></tr>
</tbody></table>
All in all, manual alignment of the heads is both difficult and extremely non user-friendly, to a point it took years for printer manufacturers to propose reliable dual head systems. In fact even single-headed printers require regular re-calibration, possibly each week or month at best as said by the Kuehling brothers (and even though their printers are really good pieces of engineering -- not low cost repraps).<br />
<br />
Back to dual heads: say, if the nozzles are not exactly aligned, or if one oozes a bit before it cools down, then it will kick the part being printed by the other nozzle. Vertical alignment of the nozzle outputs must be achieved to less than a thenth of millimeter. Manually, it is almost impossible without some help from the design itself (e.g. sliding the entire barrel up and down in an Ultimaker or in a Kraken is quite hard).<br />
<br />
Designers now often dissociate the heads to reduce the problem drastically, as shown above in the <a href="https://www.bcn3dtechnologies.com/en/catalog/bcn3d-sigma">BCN3D</a> printer for example. But the head nozzles still need extremely careful vertical adjustment, just as with more or less usual multi-nozzle hot ends.<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-LcWaCSlRBrlO14T43Fg7JTtsLDzFHP4qHKpVF1vv77VUTkOtxIJ1ECsB5zwdgZ2lxcpJzpKrhUZ2p12sd511LQbUx19dLm-RCPiVttBK27XoDCbJWeDpqyp1eXMrQEZJBi0QCMn-cld1/s1600/kraken1.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="234" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-LcWaCSlRBrlO14T43Fg7JTtsLDzFHP4qHKpVF1vv77VUTkOtxIJ1ECsB5zwdgZ2lxcpJzpKrhUZ2p12sd511LQbUx19dLm-RCPiVttBK27XoDCbJWeDpqyp1eXMrQEZJBi0QCMn-cld1/s320/kraken1.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">The <a href="http://e3d-online.com/The-Kraken">Kraken</a> by E3D. Four hot ends to align perfectly!</td></tr>
</tbody></table>
<br /></div>
<h3 style="text-align: left;">
In deeper trouble now: forthcoming tool changers!</h3>
<div>
Automatic tool changers are devices that let the machine change its tool without any user action, most often within the job.</div>
<div>
<br /></div>
<div>
Some high-level CNC milling machines featured tool changers for years already. The need was high for these, because a single work session requires many different tools (e.g. milling a path on a PCB with a V-bit, then drilling the holes with different diameters).<br />
<br />
But nowadays, the need to 3D print with different material is also becoming important, and soon compulsory. So 3D printers will soon requires tool changers aswell.</div>
<div>
<br /></div>
<div>
A very few people already tackled the subject. Most notably to me, the prolific Markus Seidt (aka wokbrenner or foehnsturm) did this oustanding <a href="https://www.youtube.com/watch?v=_iODxWwQyzE">combined printer/polishing</a> machine:</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen="" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/unsQ9i-nBNc/0.jpg" frameborder="0" height="266" src="https://www.youtube.com/embed/unsQ9i-nBNc?feature=player_embedded" width="320"></iframe></div>
<div style="text-align: center;">
<span style="font-size: x-small;">An outstanding <i>automatic</i> tool changer for an Ultimaker by <a href="https://www.youtube.com/channel/UCrH7e5fBWaI5Bn2leb4tmGg">Markus Seidt</a>.</span></div>
<div style="text-align: center;">
<span style="font-size: x-small;">This is one of the earliest designs for a 3D printer and it relies on magnets.</span></div>
<div>
<br /></div>
The so-called tool "Z-offset" is most probably computed once, manually, and then given to the machine so it adapts the height according to the tool in use. It is somehow easier when the tools are the same as above, and when the tool holder grabs the heads is a very repeatable way.<br />
<h2 style="text-align: left;">
Bed adjustments with sensors <i>on</i> the bed.</h2>
The other major option is not to carry the sensor on the head, but to keep it in on the bed. This results in less visible/moving cabling, and less weight to carry (both are a good thing).<br />
<br />
On CNC milling machines, a contact switch is usually placed on the bed, and the head is then lowered until it touches the probe. Often electric conductivity is used for a very high precision (check this small <a href="http://www.instructables.com/id/Mach3-Zero-Probe-Tool/">instructable</a> for example, or see the video below).<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen="" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/AfuDsyX3dSY/0.jpg" frameborder="0" height="266" src="https://www.youtube.com/embed/AfuDsyX3dSY?feature=player_embedded" width="320"></iframe></div>
<div class="separator" style="clear: both; text-align: center;">
<span style="font-size: x-small;">Zeroing a CNC with a probe (and and <i>electric</i> contact)</span></div>
<br />
<i>But these are still all manual operations</i>: forgetting them, or failing to do it properly will break the bits and ruin the work. The damage is lower on a 3D printer compared to a CNC mill, but it still means failed prints and wasted time, and angry users.<br />
<br />
Zeroing a CNC is often achieved by sensing an electric contact. On a 3D printer though, the milling bit, the printer nozzle, or the bed itself may not be conductive -- or more exactly no electric path can be made from the nozzle back to the bed. The electic contact probe could be made with a reliable microswitch, but it would gather dust, oozed plastic, and it will be a problem very quickly if it is left in place.<br />
<h2 style="text-align: left;">
Automatic bed leveling with permanent sensors inside the bed</h2>
Manual procedures may help with automatic tool changer only when each of the tools are pre-calibrated <i>and</i> the mechanical tool holder is very repeatable (and better not mix the toolset).<br />
<br />
Finally, locking a tool in place is hard to achieve without tiny and non-repeatable errors, which in turn leads to irregular heights or lack of precision. On CNC mills, it is probably even impossible to adjust the drill bits properly as the smaller ones can be swallowed completely in the <a href="https://en.wikipedia.org/wiki/Collet">collet chuck</a>.<br />
<br />
No... the real deal would be to detect the exact time when any tool that gets lowered gets in contact with the bed, because we would not only be able to tram the bed nicely, but also to compute the proper Z offset for the tool.<br />
<br />
We have seen that relying on electric contact of the nozzle on the bed is possible only with bare aluminum beds and conductive hot ends. Moreover, a 3D printer heating cartridge is often driven with PWM, which generates a lot of electric noise and may pollute an electric signal.<br />
<br />
And anyhow, our bed may be coated or covered with a glass plate, so it is not conductive. Period.<br />
<br />
So far, I have never seen someone using retractile sensors on the bed itself, where a servo motor would slide or pop sensors in the corner of the bed for the head to go a touch them. I guess it would be much too complex to get something reliable (and I am not even considering the complexity).<br />
<br />
Could we sacrifice a small surface of the bed, with protruding sensors? Why not... but it gets impractical as soon as the bed can be removed (a desirable feature). And the sensors probably get exposed too much, especially with a heated nozzle moving around.<br />
<br />
Or again, may be the head could move out of the bed to probe a fixed sensor (only to compute the tool height). But sacrificing any part of the printable surface for calibration is a pity.<br />
<h3 style="text-align: left;">
So... could sensors be embedded in the bed, or <i>under</i> the bed instead?</h3>
Yes. And there are different options, like having a magnetic field sensor under the bed, and a magnet glued close to the nozzle. Now, for the same reasons as above, I tend to favor mechanical contacts over distant field sensors, as the formers leave no fuzziness on the measure.<br />
<br />
So what kind of sensors? The most interesting to me are pressure-sensitive ones. They can "feel" when the nozzle enters in contact with the bed, i.e. when it starts pushing it down. Of course the sensor need to be fast to react, and sensitive enough to get the signal before the nozzle breaks anything...<br />
<br />
Sensitive <a href="https://en.wikipedia.org/wiki/Load_cell">load cells</a> may be an option, even though their signal is slightly more complex to analyse and they require amplification and proper calibration. For bed leveling, most of the load cells are also probably unsuitable because of their bulkiness and weight range. Still, <a href="http://airtripper.com/1338/airtripper-extruder-filament-force-sensor-introduction/">Airtripper</a>, as an another and early hacker god, used some to experiment with filament force sensors<br />
<br />
<a href="https://en.wikipedia.org/wiki/Piezoelectric_sensor">Piezoelectric sensors</a> are also an option. These generate (high) voltages when squeezed, but they only react to changes in pressure (i.e. they at zero volt under a static load). A good read about the pros and cons of piezo sensors for bed leveling can be found in <a href="http://forums.reprap.org/read.php?1,635075,page=1">this thread</a>.<br />
<br />
So far and in my opinion, a promising kind of sensors are FSR: <a href="http://www.interlinkelectronics.com/FSR402.php">Force Sensitive Resistors.</a> As they name suggests, they are resistors that change with the applied pressure. Their main drawback is their price, unless you make them <a href="http://www.instructables.com/id/DIY-Force-Sensitive-Resistor-FSR/">by yourself</a> (easy, but I suspect the foam may wear out quickly as it is not intended to be squashed repeatedly contrary to FSRs).<br />
<br />
And... without much surprise, a few people already tried FSR to help with the bed calibration on a 3D printer. The video below shows them used on a delta printer. The FSR are the 3 round sensors placed just below the glass plate.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen="" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/HcnhCNh2Ln4/0.jpg" frameborder="0" height="266" src="https://www.youtube.com/embed/HcnhCNh2Ln4?feature=player_embedded" width="320"></iframe></div>
<div style="text-align: center;">
<span style="font-size: x-small;">Unsurprinsingly, Johan Kossel again:</span></div>
<div style="text-align: center;">
<span style="font-size: x-small;">bed calibration using force sensitive resistors.</span></div>
<br />
<br />
FSR are also what we used, and the complete setup will be documented in depth in the second part of this post.<br />
<h2 style="text-align: left;">
Conclusion</h2>
Bed tramming and tool height detection... lots of options, eh?<br />
<br />
But in any case, I am sure that automatic probing will soon become a must for user-friendly machines (for 3D printers as much as for CNC mills).<br />
<br />
As for now there are four main options:<br />
<ul style="text-align: left;">
<li>tram the bed manually, with springs and screws</li>
<li>probe a static bed and compensate with the software (deform the printed object accordingly)</li>
<li>design an extremely sturdy printer that need only calibration once before it is sold (costly)</li>
<li>automatically tram the bed with help of an automatic probing, and 3 actuators</li>
</ul>
Only the last option solves both problems at once, which is very important as soon as the printer's heads can be changed. And 3D printers with tool changers are a near and very expected future in my opinion.<br />
<br />
Time to switch to <a href="http://www.tridimake.com/2015/12/tribed-fully-automatic-bed-leveling-and-z-offset-adjustment.html">my own bed</a> ;)<br />
<h3 style="text-align: left;">
<div style="font-size: medium; font-weight: normal;">
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj43jYtMItga7Dc82brzyJf_J93Ldjfvwl8b_Di9Hiky9uOYvELEpxO3n06uds7CIPeZhIZ8z3_b_lFZEBNEw7dY1kY6_k8WYSi-_KuqmWsNWUiyhx4NpeoBftVWdGxR4wsf7KiZ-xxxUtR/s1600/IMG_4579.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="260" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj43jYtMItga7Dc82brzyJf_J93Ldjfvwl8b_Di9Hiky9uOYvELEpxO3n06uds7CIPeZhIZ8z3_b_lFZEBNEw7dY1kY6_k8WYSi-_KuqmWsNWUiyhx4NpeoBftVWdGxR4wsf7KiZ-xxxUtR/s640/IMG_4579.JPG" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">A Force Sensing Resistor (FSR) on a hidden plate in the bed. Its resistance varies with pressure.<br />
It is used here for an automatic 3D printer bed leveling system (and, yes, my plate is rusty).</td></tr>
</tbody></table>
</div>
</h3>
<br />
<br />
<br /></div>
Jeremie Francoishttp://www.blogger.com/profile/02984201174566394892noreply@blogger.com0tag:blogger.com,1999:blog-3615478772815290200.post-31062408793998962072015-10-30T09:16:00.001+01:002017-05-11T20:24:58.987+02:00Preliminary expectations and design options for a prosumer, fully opensource 3D printer. Your opinion matters!<div dir="ltr" style="text-align: left;" trbidi="on">
<div dir="ltr" style="text-align: left;" trbidi="on">
<h3 style="text-align: left;">
Call for feedback: designing an opensource, prosumer-grade 3D printer</h3>
(<i><u>update 2017</u></i>: this project is no more alive, sorry!)<br />
<br />
We are currently designing a 3D printer for advanced, serious, or professional usage.</div>
<br />
The main target is reliability. The price tag is secondary, but we expect it to be $3 to 5K.
Would you help us with this short survey?
Being open source, the preferences of the community is very valuable to us, and we think it may be a win-win strategy.<br />
<br />
<u>Update</u>: as an example of a forthcoming growing list of publication, here is an <a href="http://www.tridimake.com/2015/12/tribed-fully-automatic-bed-leveling-and-z-offset-adjustment.html">automatic bed leveling and head height adjustment</a>.<br />
<br />
Please feel free to <a href="https://jeremiefrancois.typeform.com/to/xbuY9S">share the link</a>, every opinion counts: https://jeremiefrancois.typeform.com/to/xbuY9S<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://jeremiefrancois.typeform.com/to/xbuY9S" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="625" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg0cqycucPP8tUz_AGzX3LnbZx3-bFKWClrYxbTqfS5t22DwQXzWfY7gy2YoT79n8PfAc_jsJJjD6MaZz6_ykefwKVuO1hr8V2z4U7ukPXPZuc3MH_IKk64fmnDWdGENIcgSJfuLqXzZhs3/s640/prosumer_3D_printer_design.png" width="640" /></a></div>
<br /></div>
Jeremie Francoishttp://www.blogger.com/profile/02984201174566394892noreply@blogger.com0tag:blogger.com,1999:blog-3615478772815290200.post-2131790821760797242015-10-02T14:07:00.002+02:002015-10-26T19:23:44.093+01:00"It is better for your safety that we are opaque" (Volkswagate)<div dir="ltr" style="text-align: left;" trbidi="on">
<div class="tG QF" style="background-color: white; color: #404040; font-family: Roboto, arial, sans-serif; font-size: 13px; line-height: 16.5455px; position: absolute; width: 0px;">
<br /></div>
<div class="tG QF" style="background-color: white; color: #404040; font-family: Roboto, arial, sans-serif; font-size: 13px; line-height: 16.5455px; position: absolute; width: 0px;">
<br /></div>
<div class="tG QF" style="background-color: white; color: #404040; font-family: Roboto, arial, sans-serif; font-size: 13px; line-height: 16.5455px; position: absolute; width: 0px;">
<br /></div>
<div class="tG QF" style="background-color: white; color: #404040; font-family: Roboto, arial, sans-serif; font-size: 13px; line-height: 16.5455px; position: absolute; width: 0px;">
<br /></div>
<div class="tG QF" style="background-color: white; color: #404040; font-family: Roboto, arial, sans-serif; font-size: 13px; line-height: 16.5455px; position: absolute; width: 0px;">
<br /></div>
<div class="tG QF" style="background-color: white; color: #404040; font-family: Roboto, arial, sans-serif; font-size: 13px; line-height: 16.5455px; position: absolute; width: 0px;">
<br /></div>
<div class="tG QF" style="background-color: white; color: #404040; font-family: Roboto, arial, sans-serif; font-size: 13px; line-height: 16.5455px; position: absolute; width: 0px;">
</div>
<h2 style="background-color: white; color: #404040; font-family: Roboto, arial, sans-serif; font-size: 13px; line-height: 16.5455px; text-align: left;">
<span style="line-height: 16.5455px;">"It is better for your safety that we are opaque"</span></h2>
<div class="Ct" style="background-color: white; color: #404040; font-family: Roboto, arial, sans-serif; font-size: 13px; line-height: 16.5455px;">
<span style="line-height: 16.5455px;">I just read </span><a href="http://www.bbc.com/news/technology-34338646" style="line-height: 16.5455px;">an article</a><span style="line-height: 16.5455px;"> on the BBC related to Volkswagen and the "(...) argument for stopping people fiddling with those systems, because if you don't know what you are doing - or even worse do know and have malicious intent - you could create genuine safety issues."</span></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="Ct" style="background-color: white; color: #404040; font-family: Roboto, arial, sans-serif; font-size: 13px; line-height: 16.5455px;">
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg3R4PX5YkFgqsIb0PN3Sv8WIkejpRJz0zNzwwxhc_7sad5WgsaDzmxgv23nUnxHx_sZwwZLrBZIezs2ziReMqtRkDUN5rP6brnIwyqBDVsny5UF3T08g0OoupFzvuRpQbqSrqTg92cwOYC/s1600/volkswagen_complete_idiot.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg3R4PX5YkFgqsIb0PN3Sv8WIkejpRJz0zNzwwxhc_7sad5WgsaDzmxgv23nUnxHx_sZwwZLrBZIezs2ziReMqtRkDUN5rP6brnIwyqBDVsny5UF3T08g0OoupFzvuRpQbqSrqTg92cwOYC/s320/volkswagen_complete_idiot.jpg" width="240" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><i>Volkswagen in 1969</i><i style="font-size: 12.8px;"> by <a href="https://en.wikipedia.org/wiki/John_Muir_(engineer)">John Muir</a></i><i><br />But are we still complete idiots?</i></td></tr>
</tbody></table>
<span style="line-height: 16.5455px;">This post not only relate to Volkswagen, but to any big company using proprietary stuff and saying it is good for you. You can replace "car" with any non-open piece of software or hardware alike. Transparency is just so hard to depreciate, especially when you are talking to your own customers.</span></div>
<div class="Ct" style="background-color: white; color: #404040; font-family: Roboto, arial, sans-serif; font-size: 13px; line-height: 16.5455px;">
<a name='more'></a><br /></div>
<h3 style="background-color: white; color: #404040; font-family: Roboto, arial, sans-serif; font-size: 13px; line-height: 16.5455px; text-align: left;">
<span style="line-height: 16.5455px;">Here we go: "If we give access to our source code, our cars will risk more hacking".</span></h3>
<div class="Ct" style="background-color: white; color: #404040; font-family: Roboto, arial, sans-serif; font-size: 13px; line-height: 16.5455px;">
<span style="line-height: 16.5455px;">Yes and no. Manufacturers just fail to understand that </span><span style="line-height: 16.5455px;">their cars will eventually be hacked, be it open or not.</span></div>
<div class="Ct" style="background-color: white; color: #404040; font-family: Roboto, arial, sans-serif; font-size: 13px; line-height: 16.5455px;">
<span style="line-height: 16.5455px;">Actually i</span>t already happened (e.g. some <a href="http://www.wired.com/2015/07/hackers-remotely-kill-jeep-highway/">fatal hacks</a>). Hackers need no source code. There are thousands of people that will try to reverse-engineer their protocols, soon or later.</div>
<div class="Ct" style="background-color: white; color: #404040; font-family: Roboto, arial, sans-serif; font-size: 13px; line-height: 16.5455px;">
<br /></div>
<div class="Ct" style="background-color: white;">
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; margin-left: 1em; text-align: right;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjGWgzcyXJ03l64_JZxJQwGFrGmv-D050CtSgaV469jzYzT8buAMyyazSq4u3eVyRP7HBzFeG3WJRKtksesojjPGnM30mPGJ-XInHy86XwqNMsJnHndNgH1f2DvNbaEp9EyiJBreojOoHDe/s1600/software-security-vulnerabilities-and-physical-security-17-728.jpg" imageanchor="1" style="clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjGWgzcyXJ03l64_JZxJQwGFrGmv-D050CtSgaV469jzYzT8buAMyyazSq4u3eVyRP7HBzFeG3WJRKtksesojjPGnM30mPGJ-XInHy86XwqNMsJnHndNgH1f2DvNbaEp9EyiJBreojOoHDe/s320/software-security-vulnerabilities-and-physical-security-17-728.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><i>Security through obscurity is a business fallacy.</i></td></tr>
</tbody></table>
<span style="color: #404040; font-family: Roboto, arial, sans-serif;"><span style="font-size: 13px; line-height: 16.5455px;">Is Linux more often hacked than windows? Yes, obviously. Now is it less secure? <a href="http://www.pcworld.com/article/202452/why_linux_is_more_secure_than_windows.html">Certainly not</a>. </span></span><span style="color: #404040; font-family: Roboto, arial, sans-serif; font-size: 13px; line-height: 16.5455px;">This is simply the consequence of two strategies regarding openess and transparency. The car makers are no software makers: they say closeness is necessary for the user security. I am sure that even Microsoft no more says that (funny one: "</span><span style="background-color: transparent; font-size: 13px; line-height: 16.5455px;"><span style="color: #404040; font-family: Roboto, arial, sans-serif;"><a href="https://github.com/Microsoft">Open source, from Microsoft with love</a>" on github!).</span></span></div>
<div class="Ct" style="background-color: white; color: #404040; font-family: Roboto, arial, sans-serif; font-size: 13px; line-height: 16.5455px;">
<br /></div>
<div class="Ct" style="background-color: white; color: #404040; font-family: Roboto, arial, sans-serif; font-size: 13px; line-height: 16.5455px;">
<span style="line-height: 16.5455px;">Moreover, </span><span style="line-height: 16.5455px;">their fear of security-related hacks is revealing for me: it is <i>fueled by their lack of confidence in their own capabilities to secure their cars and their software</i>. This is exactly where third party experts should be in, and this is what they refuse to do, citing... security reasons?!</span><br />
<span style="line-height: 16.5455px;"><br /></span>
<span style="line-height: 16.5455px;">Many sensitive software are open sourced. Actually they are enough secure that the vast majority of the worldwide internet is heavily relying on open sourced components (<a href="https://en.wikipedia.org/wiki/LAMP_(software_bundle)">linux, apache, mysql, php</a> to name a few).</span></div>
<div class="Ct" style="background-color: white; color: #404040; font-family: Roboto, arial, sans-serif; font-size: 13px; line-height: 16.5455px;">
<span style="line-height: 16.5455px;"><br /></span></div>
<div class="Ct" style="background-color: white; color: #404040; font-family: Roboto, arial, sans-serif; font-size: 13px; line-height: 16.5455px;">
<span style="line-height: 16.5455px;">By the way, their stance denies the possibility that someone fixes their mistake for free and for the benefit of everyone, including them. And when they try to fix flaws, they do not always do it properly either (Jeep sent <a href="http://www.bbc.com/news/technology-34156598">USB sticks</a> via the postman, giving even more food and means to hackers).</span></div>
<div class="Ct" style="background-color: white; color: #404040; font-family: Roboto, arial, sans-serif; font-size: 13px; line-height: 16.5455px;">
<span style="line-height: 16.5455px;"><br /></span></div>
<div class="Ct" style="background-color: white; color: #404040; font-family: Roboto, arial, sans-serif; font-size: 13px; line-height: 16.5455px;">
<span style="line-height: 16.5455px;">So when the source code is not available, they should do a better job at protecting their cars at the very minimum. We are now driving computers </span><span style="line-height: 16.5455px;">which requires essential </span><a href="http://blog.fcanorthamerica.com/2015/07/22/unhacking-the-hacked-jeep/" style="line-height: 16.5455px;">firmware updates</a><span style="line-height: 16.5455px;">. But car manufacturers are like the vast majority of the industrial companies that are switching to the "internet of things": they do not seem to consider software security before they release their software. And here, the "computer" can kill you!</span></div>
<div>
<br /></div>
<h3 style="background-color: white; color: #404040; font-family: Roboto, arial, sans-serif; font-size: 13px; line-height: 16.5455px; text-align: left;">
Again: "if we open the source code, someone who tampers with it may crash his car"</h3>
<div class="Ct" style="background-color: white; color: #404040; font-family: Roboto, arial, sans-serif; font-size: 13px; line-height: 16.5455px;">
<span style="line-height: 16.5455px;">So what? Come on, that would be a problem for the user himself, and for third-party controllers if any. </span><span style="line-height: 16.5455px;">Who would sue Microsoft because his pirated version of Windows crashed his hard drive?! </span><span style="line-height: 16.5455px;">Who ever installs </span><a href="http://www.techradar.com/news/phone-and-communications/mobile-phones/cyanogenmod-from-android-modding-to-the-mainstream-1214261" style="line-height: 16.5455px;">Cyanogen Mod</a><span style="line-height: 16.5455px;"> </span><span style="line-height: 16.5455px;">on a phone makes the manufacturer not responsible of any quirk that happens to the phone.</span></div>
<div class="Ct" style="background-color: white; color: #404040; font-family: Roboto, arial, sans-serif; font-size: 13px; line-height: 16.5455px;">
<div>
<span style="line-height: 16.5455px;"><br /></span>
<span style="line-height: 16.5455px;"><br /></span>
<span style="line-height: 16.5455px;"><br /></span></div>
</div>
<div class="Ct" style="background-color: white;">
<span style="color: #404040; font-family: Roboto, arial, sans-serif;"><span style="font-size: 13px; line-height: 16.5455px;">You just need to know that you may void the warranty of your product in doing so. They genuinely can say they cannot be held responsible when your firmware does not come from them! </span></span><span style="color: #404040; font-family: Roboto, arial, sans-serif; font-size: 13px; line-height: 16.5455px;">Do they really think they would be held liable in justice by someone who hacked his airbag and who ends in a tree? Or while texting?</span></div>
<div class="Ct" style="background-color: white; color: #404040; font-family: Roboto, arial, sans-serif; font-size: 13px; line-height: 16.5455px;">
<span style="line-height: 16.5455px;"><br /></span></div>
<div class="Ct" style="background-color: white; color: #404040; font-family: Roboto, arial, sans-serif; font-size: 13px; line-height: 16.5455px;">
<span style="line-height: 16.5455px;">And if/when a user installs unconfirmed third-party car firmware, *he* is the one to blame when something goes wrong with it. Think about getting a <a href="https://en.wikipedia.org/wiki/Trojan_horse_(computing)">trojan</a> by downloading some dubious freeware!</span></div>
<div class="Ct" style="background-color: white; color: #404040; font-family: Roboto, arial, sans-serif; font-size: 13px; line-height: 16.5455px;">
<br /></div>
<h3 style="background-color: white; color: #404040; font-family: Roboto, arial, sans-serif; font-size: 13px; line-height: 16.5455px; text-align: left;">
Just comply by the law. This is not their business!</h3>
<div class="Ct" style="background-color: white; color: #404040; font-family: Roboto, arial, sans-serif; font-size: 13px; line-height: 16.5455px;">
<span style="line-height: 16.5455px;">What they fail to see is that </span><span style="color: #404040; font-family: Roboto, arial, sans-serif;"><span style="line-height: 16.5455px;">tampering with the car firmware still means that you have to comply to the law. Not doing so means a big fine when you are discovered. And it is not necessarily the car manufacturer business to check if you stick by the law. This is the job of other people, and controls can be preventive or <i>post-mortem</i> (according to the state policy -- another topic).</span></span></div>
<div class="Ct" style="background-color: white; color: #404040; font-family: Roboto, arial, sans-serif; font-size: 13px; line-height: 16.5455px;">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh3MQb7wOjKbVNcuQLXbSsPh7gmntPWcjS3cpoKEWfo9itMgRgsi8109iJsc0VLcjrwLZQnuU8XohO4aKk1NjPD2UOYi-z5mjfDusbX59SmkbTYi932nMqsLPiUKqfeekqZCS03PkWxyuoU/s1600/compliance.gif" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh3MQb7wOjKbVNcuQLXbSsPh7gmntPWcjS3cpoKEWfo9itMgRgsi8109iJsc0VLcjrwLZQnuU8XohO4aKk1NjPD2UOYi-z5mjfDusbX59SmkbTYi932nMqsLPiUKqfeekqZCS03PkWxyuoU/s640/compliance.gif" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Comply with the law! - Dilbert</td></tr>
</tbody></table>
<div class="Ct" style="background-color: white; color: #404040; font-family: Roboto, arial, sans-serif; font-size: 13px; line-height: 16.5455px;">
<span style="line-height: 16.5455px;">Actually people are already hacking their hardware. Some mount unsuitable tires, while other just pour the wrong gas in the engine! Do they complain to the manufacturer?</span></div>
<div class="Ct" style="background-color: white; color: #404040; font-family: Roboto, arial, sans-serif; font-size: 13px; line-height: 16.5455px;">
<span style="line-height: 16.5455px;"></span><br />
<span style="line-height: 16.5455px;"></span></div>
<div class="Ct" style="background-color: white; color: #404040; font-family: Roboto, arial, sans-serif; font-size: 13px; line-height: 16.5455px;">
<span style="line-height: 16.5455px;">The car manufacturers could just tell "here are the only firmwares we certify" and use real digital certificates on it. And if they really were willing to cooperate they could embed pieces of codes from third parties in their own releases. They <a href="http://www.businessinsider.com/1-million-hack-chrome-2012-2?IR=T">could even pay</a> hackers for discovering security flaws, as more and more companies do in the software industry.</span></div>
<div class="Ct" style="background-color: white; color: #404040; font-family: Roboto, arial, sans-serif; font-size: 13px; line-height: 16.5455px;">
<span style="line-height: 16.5455px;"></span><br />
<span style="line-height: 16.5455px;"></span></div>
<div class="Ct" style="background-color: white; color: #404040; font-family: Roboto, arial, sans-serif; font-size: 13px; line-height: 16.5455px;">
<span style="line-height: 16.5455px;">Now, well, they tell us it would be illegal to hack their firmware, while they are illegally hacking it in the first place to circumvent the laws, how cynical!</span></div>
<div class="Ct" style="background-color: white; color: #404040; font-family: Roboto, arial, sans-serif; font-size: 13px; line-height: 16.5455px;">
<br /></div>
<h3 style="background-color: white; color: #404040; font-family: Roboto, arial, sans-serif; font-size: 13px; line-height: 16.5455px; text-align: left;">
The funnier is that they ask that <span style="line-height: 16.5455px;">we trust them ... for our own security!</span></h3>
<div class="Ct" style="background-color: white; color: #404040; font-family: Roboto, arial, sans-serif; font-size: 13px; line-height: 16.5455px;">
<span style="line-height: 16.5455px;">Seriously?! Hey they just cheated on everyone for years, without much regard to our health (nor to the highly regarded </span><span style="line-height: 16.5455px;"><i>reputation</i> of </span><span style="line-height: 16.5455px;">German manufacturing). What for? Raw, stupid short-term profit. What I do think is they </span><span style="line-height: 16.5455px;">would have sold us cardboard boxes if it was legal.</span><br />
<span style="line-height: 16.5455px;"><br /></span>
<span style="line-height: 16.5455px;">This is the time when *they* should be transparent and try to repair the incredible damage they have done consciously. No, instead they keep asking for confidence without letting any one see the inside?</span><br />
<span style="line-height: 16.5455px;"><br /></span>
<span style="line-height: 16.5455px;">Speaking of transparency... they could get insight from Henry J. Heinz that made the first <i>transparent</i> tomato ketchup bottles, and who helped making the first health laws and quality controls a reality... while helping his own business! </span><span style="line-height: 16.5455px;">Yes, car manufacturers could learn from century-old tomato ketchup producers, check it here: </span><a href="http://www.theellisschool.org/page/Default?pk=29093" style="line-height: 16.5455px;">Concerned citizen or clever capitalism</a><span style="line-height: 16.5455px;">? But they try to escape the law, instead of using it for a better business.</span><br />
<br /></div>
<h3 style="background-color: white; color: #404040; font-family: Roboto, arial, sans-serif; font-size: 13px; line-height: 16.5455px; text-align: left;">
Double speech, public relations, marketing and bullshit again.</h3>
<div class="Ct" style="background-color: white;">
<div style="color: #404040; font-family: Roboto, arial, sans-serif; font-size: 13px; line-height: 16.5455px;">
<span style="line-height: 16.5455px;">This is just double speech, while they are in an inexcusable situation. It reminds me of Monsanto that was arguing that their GMO seeds are sterile because of safety reasons while they were saying they were totally safe at the same time. </span></div>
<div style="color: #404040; font-family: Roboto, arial, sans-serif; font-size: 13px; line-height: 16.5455px;">
<br /></div>
<div style="color: #404040; font-family: Roboto, arial, sans-serif; font-size: 13px; line-height: 16.5455px;">
<a href="https://en.wikipedia.org/wiki/Security_through_obscurity">Security through obscurity</a> is insufficient, and naïve at best. And security through minority is not available when you sell millions of cars. </div>
</div>
<div class="Ct" style="background-color: white; color: #404040; font-family: Roboto, arial, sans-serif; font-size: 13px; line-height: 16.5455px;">
<br />
<br />
<div class="Ct" style="-webkit-text-stroke-width: 0px; background-color: white; color: #404040; font-family: Roboto, arial, sans-serif; font-size: 13px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 16.5455px; orphans: auto; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 1; word-spacing: 0px;">
</div>
<br />
<div class="Ct" style="-webkit-text-stroke-width: 0px; background-color: white; color: #404040; font-family: Roboto, arial, sans-serif; font-size: 13px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 16.5455px; orphans: auto; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 1; word-spacing: 0px;">
<div style="margin: 0px;">
<span style="line-height: 16.5455px;">Hey I better go and check that my old Transporter isn't made of cardboard actually. At least there is almost no electronics in it.</span></div>
</div>
</div>
</div>
Jeremie Francoishttp://www.blogger.com/profile/02984201174566394892noreply@blogger.com0tag:blogger.com,1999:blog-3615478772815290200.post-1691160310270298502015-05-16T16:27:00.003+02:002016-09-26T11:01:28.703+02:00<div dir="ltr" style="text-align: left;" trbidi="on">
<h3 style="text-align: left;">
Messy code, branches with a lack of guidelines and comments are killing Marlin!</h3>
<i>Marlin no more exists as a single, readable, common branch!</i><br />
<br />
Where shall I go now?<br />
<br />
In a previous post, I described a tiny contribution I made to the 3D printer firmware <a href="http://reprap.org/wiki/Marlin">Marlin</a>. The deal was to help with the calibration of a Delta printer thanks to a manual Z-probe (calibration really is the drawback of Delta printers, due to their weird geometry as compared to easier <a href="http://reprap.org/wiki/Mechanical_arrangement">cartesian X-Y bots</a> like the usual printers). It was <a href="http://www.tridimake.com/2015/01/github-howto-contribution-submit-patches.html">already painful</a> for such a small, one-time improvement to the code source, and given the invested time, I tried to make it broader by implementing multi-line comments (and to learn about git by the way).<br />
http://www.dailymotion.com/video/x2gp98t_hal-fixing-a-light-bulb_fun<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjmK9VDZb9NY5C1j9wum-bMQ4O6CdNi0SwBeLV9xcQeoWQJeObkJXckzhKEVWZ1PobELFoeuR4rtBPgexuDnHb7ho6LYdVkuhEvsJHwgfDs4iKadpYXzv9Jo4krjhfarSkYaLOXO0RGVtOC/s1600/hal_fixing_a_lightbulb_t0XHtgJ.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjmK9VDZb9NY5C1j9wum-bMQ4O6CdNi0SwBeLV9xcQeoWQJeObkJXckzhKEVWZ1PobELFoeuR4rtBPgexuDnHb7ho6LYdVkuhEvsJHwgfDs4iKadpYXzv9Jo4krjhfarSkYaLOXO0RGVtOC/s1600/hal_fixing_a_lightbulb_t0XHtgJ.gif" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<span style="font-size: x-small;">This is how I feel when I want to code something in Marlin!</span></div>
<div class="separator" style="clear: both; text-align: center;">
<span style="font-size: x-small;">(<a href="http://www.dailymotion.com/video/x2gp98t">Malcom in the Middle</a>, fixing a light bulb)</span></div>
<br />
So I worked in <i>mainstream Marlin. </i>My idea was that it could benefit to existing variants of Marlin as well, when they decide to get changes from the "official" parent. But it does not work so well in reality.<br />
<br />
<b>This experience unveiled another, deeper, issue related to the many Marlin variants</b>, and I think it is due to the fundamental way github works, in addition to <a href="http://justinhileman.info/article/changing-history/">git own complexity</a>. In my opinion, Marlin is just dying because of this, together with the limits of the Arduino platform.<br />
<br />
<br />
<a name='more'></a><br />
<br />
In fact, shortly after my pull request was included, the basic support for Z-probes was removed from Marlin (the M700 - M702 gcode height probing commands were gone! -- I was there at the wrong time I guess).<br />
<br />
May be it was changed in a way I could not find it anymore (I do not think so)... Or it was too experimental (since M7xx commands seem not to be well defined). Or someone removed it by mistake. Or it was considered too obsolete a procedure.<br />
<br />
IMHO it is still straightforward to assess the height of three point by use of a removable push-button on a socket that is hand-placed below the nozzle at three points on the bed. Actually, I do not want to add complexity or to hack to my printer with retracting probes, nor to add weight to my head (even though there are <a href="https://www.youtube.com/watch?v=1eNz1l56H5E">interesting hacks</a> of course).<br />
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen="" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/1eNz1l56H5E/0.jpg" frameborder="0" height="266" src="https://www.youtube.com/embed/1eNz1l56H5E?feature=player_embedded" width="320"></iframe></div>
<div style="text-align: center;">
<span style="font-size: x-small;">Clever but complex retractable automatic Z-probe,</span></div>
<div style="text-align: center;">
<span style="font-size: x-small;">with multiple test points on a Delta (</span><a href="https://github.com/jcrocholl/Marlin" style="font-size: small;">Johann Rocholl</a><span style="font-size: x-small;">)</span></div>
<div>
<br /></div>
<div>
Anyhow here is the problem: unless I try and modify Marlin again so it stays compatible with my use of "discarded" G-code manual probing commands, I would have to change my hardware.</div>
<div>
<br /></div>
<div>
In my post you may have seen that any contribution to a project hosted on git hub requires a new branch to be created and a parent branch to be chosen.</div>
<div>
<br /></div>
<div>
This is where a bigger problem occurs in my opinion.</div>
<br />
<h3 style="text-align: left;">
Down with Marlin (variants)?</h3>
First, do not get me wrong: Marlin is vital. Marlin was a huge step forward and it is still the most widely free and open source software for driving low cost 3D printers. I do use it on all of my three 3D printers.<br />
<br />
But in my opinion, Marlin no more exists as a single, readable, common branch. And it may be doomed.<br />
<br />
First, it is already bloated by so many different electronics and hardware setup that it is barely readable. It looks like Marlin death is slowly approaching because of the new hardware it tries to support further.<br />
<br />
Then and thus, there are myriads of branches, including some that are alive and made by well-know pillars of 3D printing, such as Richard Horne (see <a href="https://github.com/RichRap/MARLIN_FIRMWARE_for_3DR_V2">this branch</a> tweaked for his 3DR v2 Delta printer), or the <a href="https://github.com/jcrocholl/Marlin">older deltabot</a> branch by Johann Rocholl (arguably a father of most Delta printers). Sure, Ultimaker sponsored Erik Zalm when he took over Sprinter. This gave evidence about the <a href="https://github.com/MarlinFirmware/Marlin"><i>main</i> branch</a>, which is a beacon in the whole mess but which is not enough sadly.<br />
<br />
Indeed, the main branch no more looks like a definitive reference for wilder children or hardware configurations. There are tons of variants, and I am not even speaking of older variations on older branches like <a href="https://github.com/kliment/Sprinter">Sprinter</a>, nor the parallel rise of <a href="http://reprap.org/wiki/List_of_Firmware">other firmware</a> (which may be the only possible outcome in the long term). This really is not the fault of the tool, but it helps spreading the disease by not requiring developers to stick to correct guidelines (like, please: comments and minimal documentation on what to find where and why).<br />
<br />
Even very knowledgeable people like Anthony Morris (aka ThantiK) ask for help about <a href="https://plus.google.com/+AnthonyMorris/posts/Vy4VDaGgQ6G">which Marlin variant</a> to use for a specific hardware, and there is no clear answer. Or it sounds like "better make the hardware according to the firmware you chose".<br />
<br />
I cannot make my mind either about the branch to use, which is live, which is stable, which I can trust, which I shall contribute to, which suits my need... And this is even more of a serious problem when features are dropped without notice from the <i>main</i> branch!<br />
<br />
<h3 style="text-align: left;">
My options right now...</h3>
<b>1)</b> I would love to keep on using the mainline, and even to adapt my own needs or even my hardware so it reflects what Marlin supports nowadays (unhappy though). Since M700 are gone and I did not want to make my hardware more complex, I had to revert to manual <a href="http://airtripper.com/1799/marlin-firmware-home-offset-guide-using-g-code-m206/">M206</a> to set the offsets on the origins. But this is unbearable (I have to "send" the g-code with guessed values with an external software like <a href="http://www.pronterface.com/">pronterface</a>: back to prehistory! I hate tethered printers).<br />
I definitely could write some more software to fix my burden in main Marlin, but I am not sure I can be confident that Marlin will still be compatible with my hardware in a few releases, which kills my motivation to contribute to it (especially due to git + github tiring procedures imho). And would I like to spend half and hours and days of reviews to have my specific need included in next Marlin?<br />
<br />
<b>2)</b> So I could just stop trying, and live on my own branch, as many do. Then I could try to contribute to mainline on regular occasions. It is probably the common strategy among many developers. But it is a pity as I would just create one more pseudo-active branch, and it would eventually divert so much from mainline with time that it will no more be possible to merge the two (as I do not intend to work a lot on it, not even to keep it up to date with the upstream). There are just so many dead branches of Marlin already on github that adding one is not wise.<br />
<br />
<b>3)</b> Or I can use my own Marlin branch and stop worrying at all about other hardware and other branches. Trying to support all hardware in a single branch is cool, but time proved nonetheless that it resulted in many wild forks that defeated the intention!<br />
<br />
<b>4)</b> Further, I could even <i>get rid</i> of all existing support for the hardware I do not own! I considered this nasty until I thought about how more productive I would be with a clean source to work with! There are just too many #defines in the existing configuration.h, for hundreds of variants of hardware, that it is unreadable and very tricky to submit anything safely back to the main branch anyway.<br />
<br />
<b>5)</b> I could give <a href="http://reprap.org/wiki/List_of_Firmware">other firmware</a> a try, like <a href="https://github.com/repetier/Repetier-Firmware">Repetier</a>. But it means dropping all help I could provide to the main community. And it does not solve another raising issue: the <a href="http://www.reprap.org/wiki/RAMPS_1.4">RAMPS electronic</a> environment is so much limited by the tiny Arduino Mega that I consider it to be at the end of its life...<br />
<br />
<b>6)</b> So... I may better forget about Marlin and Arduino alike! May be it is time to have a clean start with <a href="http://smoothieware.org/">Smoothieware</a> on my old but powerful <a href="http://reprap.org/wiki/R2C2_RepRap_Electronics">R2C2</a> ARM board instead (32 bits, 100MHz). This would be a big change, but a larger environment and a faster CPU would give real room for real improvements. It could also be a chance to get rid of most of the mess at the source code.<br />
<br />
<br />
<h3 style="text-align: left;">
The Arduino is dying as a 3D printer firmware controller. ARM is the future!</h3>
<br />
Switching to ARM is a good thing, and more people are considering the move to be the next major step in 3D printing (see <a href="https://www.youtube.com/watch?v=vsu_vAKvRO0">Thomas Sanladerer's review</a> of the Smoothieboard for example). It gives some air for improvements, and I hope it is well written as a new start. In my opinion, a recent firmware would benefit a lot by relying on an object-oriented paradigm and on hardware abstraction layers via compulsory interfaces, pure virtual methods, etc.<br />
<br />
Most 3D printer firmware for ARM processors are still based on the original <a href="http://dank.bengler.no/-/page/show/5470_grbl?ref=checkpoint">GRBL G-code interpreter</a>, just like Marlin is. I will have to look at the source code of GRBL also, it seems ubiquitous! I did not look at the source code of any new firmware yet, but I sincerely hope they ensure that any subsequent software development does comply with real and safe standards, contrary to Marlin which is full of ugly tricks and unsafe shortcuts (OK, they might have been considered compulsory because of the limited power of the Arduino, the Arduino IDE, and the anarchy induced by github imho!).<br />
<br />
And still, I find it hard to conclude I should better move to an ARM board! It requires some physical and hardware changes to my existing printer. <i>My goal was only to try and improve the calibration procedure for my current Marlin / RAMPS setup.</i> What a pity!<br />
<br />
I just cannot make my mind... Someone should write a post with the different branches, their activity, state and compatibility.<br />
<br />
(Uplate to make it clear that my rant is not against github really, but just a point of view on the state of Marlin - and I praise applaud the evelopers that have the energy to contribute to it regularly! )<br />
<br /></div>
Jeremie Francoishttp://www.blogger.com/profile/02984201174566394892noreply@blogger.com0tag:blogger.com,1999:blog-3615478772815290200.post-6395401792684836122015-04-21T11:24:00.001+02:002015-05-27T18:07:00.429+02:00Headlines again... 3D printing guns, a passion?<div dir="ltr" style="text-align: left;" trbidi="on">
<h3 style="text-align: left;">
Headlines again: 3D printing yet another part of a gun. So what?</h3>
Please <a href="https://wtvox.com/2015/03/3d-printed-gun-that-can-fire-hundreds-of-rounds/">Cody</a>, yes, you the guy with big <strike>stainless-steel</strike> thermoplastic bollocks, please, now I want new stuff, like 3D printing bazookas, ammo or landmines!<br />
<div>
<br /></div>
I already tackled the subject it in <a href="http://www.tridimake.com/2013/04/what-cannot-be-3d-printed.html">this older post</a> but telling that a 3D printer is probably not the best tool to use is not even my point here. Using a 3D printer to print more guns is no surprise, but I wish headlines focus more on noble usage like <a href="http://enablingthefuture.org/tag/3d-printed-prosthetics/">e-NABLE prosthetics</a>. It is an excellent project, where volunteers 3D print free upper-limb prosthetics, like artificial hands for others. If your printer is idle, you should go and read about them!<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgZ_8oDqxsOqYLzjxblzdsf5n6QGLVMsEB5CJFnXgPrsN95_sCUrdOzoHeB_rYtWn6ObDMrRMFlyqB79AAh4hVdsSWZ88T9vmmXr1bMoIIQA454WHr2ImcY3KJqsfKSPgSqHDNo0pV_rWuU/s1600/e-nable-3D-printed-prosthetics.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="202" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgZ_8oDqxsOqYLzjxblzdsf5n6QGLVMsEB5CJFnXgPrsN95_sCUrdOzoHeB_rYtWn6ObDMrRMFlyqB79AAh4hVdsSWZ88T9vmmXr1bMoIIQA454WHr2ImcY3KJqsfKSPgSqHDNo0pV_rWuU/s1600/e-nable-3D-printed-prosthetics.jpg" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><a href="http://enablingthefuture.org/about/">E-NABLE</a>: is this not a better use for 3D printing, according to you?</td></tr>
</tbody></table>
This way we have people printing tools that may harm people, while other people do repair them. Nice absurd world.<br />
<br />
Here is my point for once: why do the words <i>gun</i> and <i>freedom</i> have to be put in the same sentence almost each time pro-gunners start to argue? What the heck?<br />
<br />
<a name='more'></a><br />
<br />
Say, I never felt my <i>freedom</i> is harmed by the <i>lack of</i> firearms in the hands of citizens around me, including in my own hands. Europe has a long tradition on relying exclusively on the authorities to ensure both the freedom and protection of citizens. And any personal bypassing of the law is ... well, illegal.<br />
<br />
But that is just <i>my own opinion</i>: guns are physically linked to violence, one way or another.<br />
<h3 style="text-align: left;">
I expect better arguments from pro-gunners when they want me to change my mind!</h3>
Let me re-state it: why do zealots feel the urgent need to justify themselves and feel like I say that all gun <i>owners</i> are stupid? I only consider stupid the law that allows any one to own a gun <i>and to carry it in public</i>. I never said the opinions of others are wrong, and it includes those of gun owners or lovers. Now what happens at home is just personal business and a matter of education.<br />
<br />
What really bugs me hard are the wrong arguments that are too often put forward. I like to argue, and I can be wrong, or fail to understand. But I need proofs, actual real statistics, science, sociology. No low-level bullshit motivated by some passion.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEggX50-UJqpUNBd_80NPmlQJyHomdX_0uCttuIZ6Ngahff_3hUbJWUMaL8b1H4I66g7OiQ_wLbdyOGWMCl6YztBgI84SQnYHMnYHqjvppMxwfMxkaFf6bAClFJydlX0RpQLIWyL70IJDale/s1600/Humor-CalvinyHobbes-Leer-Ingls.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="204" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEggX50-UJqpUNBd_80NPmlQJyHomdX_0uCttuIZ6Ngahff_3hUbJWUMaL8b1H4I66g7OiQ_wLbdyOGWMCl6YztBgI84SQnYHMnYHqjvppMxwfMxkaFf6bAClFJydlX0RpQLIWyL70IJDale/s1600/Humor-CalvinyHobbes-Leer-Ingls.jpg" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Education is harder than passion. Guts and feelings are just not enough (Calvin & Hobbes of course)</td></tr>
</tbody></table>
My biggest complaint are falsified arguments used to "counteract" gun-skeptics, or out-of-scope arguments like "cars are killing more". Hey, life kills at 100% rate - so what? By the way, even that argument seems to be wrong. Check, e.g. <i>The Economist</i>: "<a href="http://www.economist.com/news/united-states/21638140-gun-now-more-likely-kill-you-car-bangers-v-bullets">A gun is now more likely to kill you than a car is</a>". Well... in the USA of course!<br />
<br />
Most often people revert to individual cases where a gun would have "avoided" a problem (usually a shooting, how ironic!). It may be true indeed, but I believe in more scientific methods such as <i>statistics. </i>Individual counter-examples do not make the rule. They lead nowhere and sterilize the debate. Headlines are crap. Real studies rules.<br />
<br />
Inductive reasoning is to make broad generalizations from specific observations, and it may be plain wrong: <i>"Harold is a grandfather. Harold is bald. Therefore, all grandfathers are bald."</i> (from <a href="http://www.livescience.com/21569-deduction-vs-induction.html">livescience</a>, a nice read on the scientific method).<br />
<br />
But more than half of the population keep on using such individual statements to argue, never to try and get a bigger non-passionate picture.<br />
<br />
See, when a raper is caught, nobody asks for all men to be sterilized! But that's as much as a scientific reasoning for me as the <a href="http://www.theguardian.com/world/2013/apr/02/nra-unveils-plan-armed-guards">NRA saying that there should be armed guards in schools</a> to shoot down armed students (i.e. "save lives"?). Actually, they would better close schools then, and bingo, 100% guaranteed no more homicide at school!<br />
<br />
<h3 style="text-align: left;">
So? A weapon is a weapon. And a weapon adds surrouding danger.</h3>
Of course, there are fundamentally different views at play here. But once again, it did not say that shooting cans is not funny. And I can play paintball or laser quest games to fire at each other and have fun (I did).<br />
<br />
But a real weapon is a real weapon. I would keep saying what I say, even for people that print knives with their 3D printer: not that interesting at best once done, and in any case dangerous when they they are carried in public. Who decides who may carry a gun? Who is the "good guy" and who is the "bad guy"? Seriously, if bad guys carry guns as much as good guys do, nothing gets solved, but "collateral damage" occurs invariably. Oh, what a funky name to say "innocent people deaths".<br />
<br />
<h3 style="text-align: left;">
Is world is safer without guns in the public. I do think so, but...</h3>
As for me, I am still glad and I feel safer that no one but hunters own a gun here in France (and most of Europe). Unsurprisingly, the latter do account for so many "accidents" in the south of France, namely <a href="http://www.oncfs.gouv.fr/Chasser-dans-les-regles-ru18/Bilan-des-accidents-de-chasse-2013-2014-news1715">16 deaths in 2014</a> (which is sounds so many, how stupid).<br />
<br />
Technically and factually, a gun is a dangerous tool that allows any small kid or idiot to kill someone, and it happens just more often where guns are <i>legal to carry in public</i>, and to some extent also when <i>owning a gun</i> is made easy (see below for my moderation). A weapon may kill. No weapon cannot kill, period. More weapons around is more deaths, be it guns, knives or fists. The more you know there are many weapons around, the more you get nervous and you are prone to be aggressive with your own.<br />
<br />
Carrying guns in public creates a risky social environment, to the point the police often fires and kills <a href="http://www.mintpressnews.com/video-33-police-officers-fire-600-bullets-car-knowing-contained-hostage-killing/197948/">suspects and innocents</a> way too easily and without solving anything in the long term. Compare to EU countries, like England where the police <a href="http://www.pri.org/stories/2014-08-18/how-many-times-british-cops-fired-guns-all-last-year-3">fired 3 rounds in 2012</a> (killing no-one). British citizens are around 100 times less likely to be shot <i>by a police officer</i> than Americans!<br />
<br />
Sorry but I do not buy it when a two century old rule that initially was meant to allow citizens to <a href="http://sandiegofreepress.org/2013/01/a-cultural-comparison-gun-violence-in-the-us-and-europe-part-1/">protect the state</a> against foreign "hostile" countries is now considered to be a <i>private affair</i> by so many.<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhebKEuCE0WKVDsZyxzutAJuZzx1KS1-CtB2hjJYFicTp8lJVQNYcd2u0GFYASlxQazO77pAviTKKkyHxf7Clq4VqJcktVAAaOaD1M3L9zjw5F0pGMEBYs_3VctcVf6xolHNYx0RBlI8Xh1/s1600/shooting.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="265" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhebKEuCE0WKVDsZyxzutAJuZzx1KS1-CtB2hjJYFicTp8lJVQNYcd2u0GFYASlxQazO77pAviTKKkyHxf7Clq4VqJcktVAAaOaD1M3L9zjw5F0pGMEBYs_3VctcVf6xolHNYx0RBlI8Xh1/s1600/shooting.jpg" width="400" /></a></div>
<br />
<br />
<h3 style="text-align: left;">
Free education beats free guns!</h3>
Back to Europe: and still, Great Britain is even considered more dangerous than the northern European countries.<br />
<br />
Anyhow, there are countries where it may be somehow easy to <i>own a gun</i>, but it is simply forbidden to carry it <i>in public</i>. Beside some psychopath who kills a lot once in a decade the average casualty is very small. Why? Because people are just well educated and laws prevent them from carrying guns everywhere (which in turn makes everyone want to carry and use one for <a href="http://www.businessinsider.com/gun-deaths-in-florida-increased-with-stand-your-ground-2014-2?IR=T">self-defense</a>: how ridiculous!).<br />
Say, when Switzerland is probably <a href="http://en.wikipedia.org/wiki/Gun_politics_in_Switzerland">ranked first for gun ownership</a> because of their special constitution, there are only 5 deaths for 1M people, while there are 30 in the USA (check the stats <a href="http://en.wikipedia.org/wiki/List_of_countries_by_firearm-related_death_rate">here</a>).<br />
<br />
<div dir="rtl" style="text-align: right;">
<span style="color: #3f4549; font-family: 'Helvetica Neue', arial, sans-serif; line-height: 21px;"><i style="font-size: 15px;">I was hoping that by the time we arrived here, we would have stopped trying to prevent things being banned, & moved to actually preventing people wanting to kill. You know, through being sensible and rational. But I guess I was wrong.</i><span style="font-size: x-small;"> - Nigel tolley in the <a href="https://wtvox.com/2015/03/3d-printed-gun-that-can-fire-hundreds-of-rounds/">original post</a>.</span></span></div>
<br />
Once again it all boils down to a better, good and free education for everyone in my opinion. It always works better than any gun or knife in the long term and even laws related to weapon ownership. A person who needs to fight <i>to make his point</i> is a psychopath to me, and gun owners are often tempted by the same kind of argument: better kill your neighbor before he kills you.<br />
Sorry, I just feel better when the risk that anyone kills someone is simply negligible simply because there are no such weapons all everywhere. Just try peace for once, and it works better than casting war everywhere.<br />
<br />
Now for sure, printing gun parts is going to be a lot more dangerous in countries were the remaining parts are readily available, or where you can buy ammo in a supermarket, and this is where laws are important. I feel glad to be in a place where it is illegal. Both the <i>freedom</i> and the <i>safety</i> it warranties for me each day is a joy :)<br />
<br />
You can check and compare your country policy regarding firearms on this <a href="http://en.wikipedia.org/wiki/Overview_of_gun_laws_by_nation">wikipedia page</a>.<br />
There I learnt that I could get a 5-year jail term in Germany just because I own a nunchaku. And I definitely would not have bet that Poland had the lowest rate of gun onwership in Europe!<br />
<br />
Facts, not fiction nor passion. Do not get me wrong.</div>
Jeremie Francoishttp://www.blogger.com/profile/02984201174566394892noreply@blogger.com0tag:blogger.com,1999:blog-3615478772815290200.post-87081283786318859892015-04-05T23:59:00.004+02:002020-09-18T20:39:16.471+02:003D printer survival kit: a comprehensive set of 3D printer tools and tips.<div dir="ltr" style="text-align: left;" trbidi="on">
<br />
<h2 style="text-align: left;">
Survival kit: tools for the 3D printers</h2>
<br />
This post started as early as September 2013, and it eventually ends here, may 2015! At least, you can be sure I heavily made my opinion and I have feedback on the tools I list here.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgc451WAckCO9FpbaZ57piUPxean65YJAgvhDU7BaUw02BAAeibGnU0sQHTXODslbU8H53NSAkrDK_BXyciydw1ae-_6kfEvV8Rxwu6ehS80JBU45ABBg4E6VQ-pPioHna8sbQraNf9mQlB/s1600/all_in_one_ultimaker_ready-for-travel.jpg" style="margin-left: auto; margin-right: auto;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgc451WAckCO9FpbaZ57piUPxean65YJAgvhDU7BaUw02BAAeibGnU0sQHTXODslbU8H53NSAkrDK_BXyciydw1ae-_6kfEvV8Rxwu6ehS80JBU45ABBg4E6VQ-pPioHna8sbQraNf9mQlB/s1600/all_in_one_ultimaker_ready-for-travel.jpg" width="334" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">All included, a nicely packed Ultimaker 100% ready for travel.</td></tr>
</tbody></table>
I keep nearly all my tools in a dedicated box, that matches well the bottom of my printer. You will read in this post about each of the tools, slightly sorted in different categories and even though some tools are used for multiple tasks.<br />
<br />
I attached a note after each of the items, where 5/5 is a must in my opinion, and 0/5 a luxury or a useless tools. Of course there are no 0/5 in my box as I want only a (comfortable) survival kit in the end. <a href="http://www.tridimake.com/2015/04/3d-printer-tools-survival-kit.html">Read more...</a><br />
<br />
<br />
<a name='more'></a><br />
<br />
<h3>
Hot end</h3>
<b>Telfon tape (3/5)</b> is mostly interesting when assembling the hot end, in order to seal it against PLA leaks. But take care, as teflon is no good above 250°C. When assembled tightly and with quality stuff, no seal really is needed. The initial brown liquid will eventually seal it completely. I still keep a small roll of Teflon (bought for plumbing affairs), according to the hot ends I swap and filament I print.<br />
<div>
<br /></div>
<div>
<b>One large roll of Kapton (2/5).</b> Everyone knows that this very special adhesive band is used on the bed to improve adhesion of the first layers. In this case a large roll is better (50+ mm). Extra large rolls (150mm) are interesting but too large to keep within reach. In fact I never use Kapton on my bed, mostly because mine is <a href="http://www.tridimake.com/2012/10/homemade-heated-bed.html">heated</a> and I use glue (see below). Kapton gets torn soon or later and it is annoying to replace.<br />
<br />
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; text-align: center;"><tbody>
<tr><td><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhq4iyoqB3vP4i-i8gkQrwzmDKSKY2fDCzKSDY7-0zvF2vckqzRqeucxijxrG47kSdq_oE9VHEn4H-AxJXAKT_HxoY-1knrea-F8-tlmsRmzVFAQ4xCPrw7NUuvG-SAuRArhmtFn-me_CVR/s1600/2015-02-06+08.37.16-kapton-koptan.jpg" style="margin-left: auto; margin-right: auto;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhq4iyoqB3vP4i-i8gkQrwzmDKSKY2fDCzKSDY7-0zvF2vckqzRqeucxijxrG47kSdq_oE9VHEn4H-AxJXAKT_HxoY-1knrea-F8-tlmsRmzVFAQ4xCPrw7NUuvG-SAuRArhmtFn-me_CVR/s1600/2015-02-06+08.37.16-kapton-koptan.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="font-size: 12.8px;">Bought Kapton, but got Koptan! Bad quality. But this size<br />
is perfect to insulate the hot end (and your fingers).</td></tr>
</tbody></table>
After more than one year using it, I find Kapton is most suited to insulate the hot end: it keeps the temperature stable even when fans start blowing toward it. And it gives me time to retract my fingers before I burn myself (compared to raw aluminum that conduct heat much faster!).<br />
It also prevents the leaked goo to end on your parts!<br />
<br />
For this purpose, I found that a <b>thinner roll of Kapton (4/5)</b> that is only 10mm-15mm wide makes life much easier than a large one.<br />
Anyhow, beware of cheap Kapton that does not stick well (sometimes sold as knock-off "Koptan"!).<br />
<br />
Note that some people embed the hot end nicely with better and thicker material such as <b>glass-insulated tape (4/5)</b>, but it becomes cumbersome to swap nozzles or hot ends afterwards, so it may be good if you never change them.</div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<h3 style="text-align: left;">
Before printing and calibration</h3>
<b>A basic lighter (5/5)</b> is a must. I use it very often to "round" the head of the filament before I run it through the hot end. This is the easiest way to make it thin enough, but also to prevent inside damage to the bowden tube when it has sharp "snapped" edges (PLA may strip <a href="http://www.tridimake.com/2013/05/no-slipping-no-grinding-not-always-good.html">thin bands of PTFE</a>, that will block your nozzle badly). A <b>blowtorch (2/5)</b> is so powerful that it melts the filament instantly, and then burns you when you flatten/burr it with bare hands. A lighter gives enough time to get the proper viscosity. Sure, the best tool here is a hot air rework/soldering station as you can set the exact temperature target, but it is totally bulky.<br />
<br />
<br />
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhXviqznO7Me1BzWANG04UUswLDPwN8AmjOdjlBHpTfFbDTEHYKsSld_T5BbZtbPKm0fQ7ZTXcSEeZ5gNorIysFrDnSORPU2yhN1KA9znRDbLYuGAXWiNqBAuBslAY4RMzkp63tcug5i99X/s1600/hot-end-cleanup.jpg" style="margin-left: auto; margin-right: auto;"><img border="0" height="208" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhXviqznO7Me1BzWANG04UUswLDPwN8AmjOdjlBHpTfFbDTEHYKsSld_T5BbZtbPKm0fQ7ZTXcSEeZ5gNorIysFrDnSORPU2yhN1KA9znRDbLYuGAXWiNqBAuBslAY4RMzkp63tcug5i99X/s1600/hot-end-cleanup.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Nozzle cleanup with pieces of ABS (<a href="http://bukobot.com/nozzle-cleaning">whosawhatsis</a>)</td></tr>
</tbody></table>
Note that a lighter also helps shape hooks on the fly, e.g. to prevent your bowden tube from rubbing against the printer, to release strain on cables and so. PLA snaps a bit too easily in this regard, favor ABS.<br />
<div>
<br /></div>
<div>
To clean the head, I do not recommend <b>thin wire (2/5)</b> as it may ruin the nozzle (check the proper size <a href="http://en.wikipedia.org/wiki/American_wire_gauge">here</a>). It helps only when you nozzle is completely clogged with hard carbon. Always keeping a cheap piece of nylon <b><a href="http://www.tridimake.com/2013/04/3D-printing-with-cheap-trimmer-line.html">trimming line</a> (5/5)</b> is the real best way to "fish" PLA/ABS dirt out of the nozzle.<br />
<br />
A big <b>rounded nail (2/5) </b>very rarely helps to push the other way (it depends on your hot end, check my old <a href="http://www.tridimake.com/2012/10/clean-hotend-and-nozzle.html">post on the matter</a>). With <a href="http://www.tridimake.com/2014/03/thoughts-and-hints-around-hot-ends.html">my metal hots ends</a> I no more have such problems.</div>
<div>
<br /></div>
A small <b>flask of alcohol (3/5) </b>to clean the bed -- no need to try beer (0/5). Actually, I often prefer almost undiluted <b>dish washing soap (4/5)</b>. Rinse and repeat until you get a thicker foam on the bed, which means no trace of grease subsists. I do it rarely, as liquid glue is so efficient, unless I want to wash it off to revert to a pristine (sanded) glass bed for the neatest PLA prints.<br />
<br />
Some people use a lot of <b>blue painter tape (3/5)</b> to improve bed adhesion, but I don't like it as it needs to be changed often, and it leaves tiny bits of fibers in the bottom of the prints.<br />
<br />
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhLv0__sNCGof-3-n7fd5VwKSnFAPLzjsEFTmwv6dOmgRIj2Kjx_xuH_emAe5G0ON6ouZZlXFNhRt4kPiQhbXjGHx8VF6Yo9qN2kt49YAgmgmLLltZbIL3vXvGd-LqzRC-PdgEJiyHrUfI3/s1600/IMG_2696-glue-alcool-superglue.JPG" style="margin-left: auto; margin-right: auto;"><img border="0" height="192" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhLv0__sNCGof-3-n7fd5VwKSnFAPLzjsEFTmwv6dOmgRIj2Kjx_xuH_emAe5G0ON6ouZZlXFNhRt4kPiQhbXjGHx8VF6Yo9qN2kt49YAgmgmLLltZbIL3vXvGd-LqzRC-PdgEJiyHrUfI3/s1600/IMG_2696-glue-alcool-superglue.JPG" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><span style="font-size: 12.8px;">I would go in bed with my </span><a href="http://www.tridimake.com/2014/01/how-to-3d-print-nylon-and-trimmer-line.html" style="font-size: 12.8px;">liquid glue</a><span style="font-size: 12.8px;"> :)</span><br />
<span style="font-size: 12.8px;">Cyanoacrylate is only for extreme fixes on the fly.<br />Alcohol mat not be better than thick soap though.</span></td></tr>
</tbody></table>
Solvent-free <b>liquid glue (5/5)</b> is the killer in my opinion. I really was using this exclusively and consistently for almost two years now. I often add a bit of water to dilute the liquid glue further, even when <a href="http://www.tridimake.com/2014/01/how-to-3d-print-nylon-and-trimmer-line.html">printing annoying Nylon</a>.<br />
<br />
Comparatively, I do not recommend <b>glue sticks (3/5)</b>, as they leave annoying blobs of glue that need to be watered/flattened afterwards.<br />
<br />
I do not like <b>sprayed glue (2/5)</b>, as it is not economical, nor ecological, and the mechanical parts will eventually collect some glue also (very bad!). Still OK when you can detach your bed (but still not really economical imho).<br />
<br />
<div>
<b>Automotive thickness gauges (1/5)</b> are useful only if you feel the need to know exactly how much gap you left between your nozzle and the bed. Actually I have a pretty reliable idea of "how much" by the eye and enough experience I guess.</div>
<div>
<br />
And, oh, <b>a pen or marker and sticker notes (4/5)</b> is very helpful. It is often needed to write down and remember settings and comments for the many filament kinds you may own. Once properly tuned, I re-write them in a private wiki page. But a marker or a small pen is always useful, just to give your email or website to someone (by the way, I also attached a small <a href="http://www.thingiverse.com/thing:218913">small box</a> to hold a few visit cards).<br />
<br />
<br /></div>
<h3 style="text-align: left;">
During printing</h3>
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjTrsQmrixtEsrBNTkOaQNqyNh0dLrcibxnr4GXAVL4OXooNWoinhH3EHp0ZqAmIqy2fvxiJevrzr1m9vlsOdynTDXfOtYjkB4Ymj9n_K-WGX22C_UnbP4NkKU3xTWvquUIfvVc3Wzu7WjA/s1600/IMG_2701-powerful_ligth_and_magnifier.JPG" style="margin-left: auto; margin-right: auto;"><img border="0" height="197" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjTrsQmrixtEsrBNTkOaQNqyNh0dLrcibxnr4GXAVL4OXooNWoinhH3EHp0ZqAmIqy2fvxiJevrzr1m9vlsOdynTDXfOtYjkB4Ymj9n_K-WGX22C_UnbP4NkKU3xTWvquUIfvVc3Wzu7WjA/s1600/IMG_2701-powerful_ligth_and_magnifier.JPG" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Powerful light source and powerful magnifier are a must.</td></tr>
</tbody></table>
A <b>magnifier glass (5/5)</b>, preferably with a high power is a must to check your prints. Keep it small, or print your own handle, as you will not always have the space around the head to check the the deposited layers.<br />
<br />
Together with a spot, or less bulky <b>powerful light torch (4/5)</b>, a magnifier is an invaluable tool to learn and fine tune your printer. As you can see on the left and below, I use a high end x12 microscopic lens for digital camera (overkill), and a 3D printed handle made out of flexible PLA. This way I can stick the magnifier and get the proper angle to check the first layers, while illuminating the print from the other side (for the maximum light reflection).<br />
<div>
<br />
<br />
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; margin-left: 1em; text-align: right;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjpBXihmLC2rlEtXI_VYZNdGlGvGoV16coS3zWls6Q6uGpI_ENXv1oNVIXr1-1XyBmcqNmhe02D0zcnCsZHujqYCsT0qh0cdR9URZ5QWmxp6z-I4_Rguvud55XfelLM041Ti4NsQ4klHRi-/s1600/magnifier-3D-printer.jpg" style="clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" height="145" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjpBXihmLC2rlEtXI_VYZNdGlGvGoV16coS3zWls6Q6uGpI_ENXv1oNVIXr1-1XyBmcqNmhe02D0zcnCsZHujqYCsT0qh0cdR9URZ5QWmxp6z-I4_Rguvud55XfelLM041Ti4NsQ4klHRi-/s1600/magnifier-3D-printer.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Here is the self-made handle for my high-quality magnifier.</td></tr>
</tbody></table>
My use of <b>super glue (4/5)</b>, aka cyanoacrylate, is mostly restricted to "hot fix" stubborn warping. It also helps to repair cracked printer parts on last resort like a small gear (in which case it becomes compulsory if you have no spare!).</div>
<div>
<div>
<br />
I really miss <b>strong paper towel (4/5)</b> when I forget it, as I very often I wipe the head with it, before I start printing directly on it. Then I slide the paper with the head toward the actual start of the print while pulling any ooze away.</div>
<div>
</div>
<br />
Long and <b>flat tweezers (2/5)</b> are useful to grab those damn little screws that fell in the darkest corners of the printer. Some use it to grab the oozed filament, though I had been doing it with my bare fingers without burning myself for years (OK, almost never burnt myself -- check kapton above).<br />
<br />
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhYaJ6TZ9M6gPRgaFAxGokU8LlMRwE6dyxxhdzJzr8moIoZ8TcsrpsuW6-sZufe0_HDAoJqmP7W6KjaXXBKUr81VHXNcYvryH86HrUSff6RSLfxAJIrrpDLwdqeL4L15AtUuDDCw9HOw4Vz/s1600/2014-08-21+15.04.41-MiserableFailure-Curling-Wrapping.jpg" style="margin-left: auto; margin-right: auto;"><img border="0" height="154" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhYaJ6TZ9M6gPRgaFAxGokU8LlMRwE6dyxxhdzJzr8moIoZ8TcsrpsuW6-sZufe0_HDAoJqmP7W6KjaXXBKUr81VHXNcYvryH86HrUSff6RSLfxAJIrrpDLwdqeL4L15AtUuDDCw9HOw4Vz/s1600/2014-08-21+15.04.41-MiserableFailure-Curling-Wrapping.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Miserable failure at trying to print impossible Polycarbonate...<br />
The clamp is useless, but the long flat piece of aluminum helps<br />
against warping and to maintain a flat top during tricky prints.</td></tr>
</tbody></table>
Possibly <b>a clamp (1/5)</b> to fight warping as shown on the left. But when you revert to this, your print is probably ruined anyhow! It may help to secure a cable but it is bulky.<br />
<br />
A <b>long, flat aluminum tab (4/5)</b>, to help cooling corners quickly, especially when you have no "local" fan as I have. It is always weird to me how efficient it is. I gave it some curve to help me keep the top part of a tricky print flat and cooler. Generally unused until you need it!<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br /></div>
<h3 style="text-align: left;">
Removal of printed parts and post-processing</h3>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjFB1oS8MHFmsK82zoUD10_G4FvyQrDsPgz7R-6OY2UX_5gDLAFWi9ldQ2uJ4t7wzy36GEulwURVk7VVR_Z3ClsDn7gAFIQjLy1Cv-BElQnLiuN4U8xjGRuEAS0mOitutmIJFlHxl_t1UZj/s1600/IMG_0603-deluxe-removal.JPG" style="margin-left: auto; margin-right: auto;"><img border="0" height="216" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjFB1oS8MHFmsK82zoUD10_G4FvyQrDsPgz7R-6OY2UX_5gDLAFWi9ldQ2uJ4t7wzy36GEulwURVk7VVR_Z3ClsDn7gAFIQjLy1Cv-BElQnLiuN4U8xjGRuEAS0mOitutmIJFlHxl_t1UZj/s1600/IMG_0603-deluxe-removal.JPG" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Deluxe cheese knife as a removal tool (overkill), and a blade holder as a scraper (see text).<br />
Much better and safer than any naked cutter blade.</td></tr>
</tbody></table>
Large <b>flat knife (2/5)</b> to use as a lever, or, better, a <b>wide scalpel holder (4/5)</b> to help removing the stuck prints off the bed. But better dose the glue appropriately (no need for PLA!). The wide blade is also very useful to remove dried or dirty glue off the bed.<br />
<br />
Use of sharp cutting tools is compulsory at one moment or another. The best are definitely <b>scalpels (5/5)</b> in my opinion, with one curved blade and another with a thin and straight one. They cost nothing on ebay, and there are sets of 10 blades of many shapes.</div><div dir="ltr" style="text-align: left;" trbidi="on"><br />
Scalpels are also useful to remove specks of plastics that remains on the bed, without removing too much glue.</div><div dir="ltr" style="text-align: left;" trbidi="on"><br /></div><div dir="ltr" style="text-align: left;" trbidi="on">
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgFgQNgezm7P-72tIePnyKG7EGKKMQ-QeXbxHLsXzYuCio4AAjNFk-aG2t8d6ijvnLznx6Iuz9si4jNR6H7_CmlR5it6mb5I4wcJCDDFOiXBNQil2ldOoq7LNnOhGczjeiNTetA8GxE1ADB/s1600/2014-01-24+20.18.14-1.jpg" style="margin-left: auto; margin-right: auto;"><img border="0" height="212" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgFgQNgezm7P-72tIePnyKG7EGKKMQ-QeXbxHLsXzYuCio4AAjNFk-aG2t8d6ijvnLznx6Iuz9si4jNR6H7_CmlR5it6mb5I4wcJCDDFOiXBNQil2ldOoq7LNnOhGczjeiNTetA8GxE1ADB/s1600/2014-01-24+20.18.14-1.jpg" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Three tools for three different deburring jobs. Using the proper tool is a joy in itself.<br />
I do not like <a href="http://en.wikipedia.org/wiki/X-Acto">X-Acto knives</a> because they are bulkier (and more expensive).<br />
Most "snap-off blade" utility knives are both dangerous and inefficient in my opinion.</td></tr>
</tbody></table>
<br /><div dir="ltr" trbidi="on">Still, a proper but cheap <b>deburring tool (2/5)</b> is a weird tool with a freely rotating head, but it does a faster, smoother and pretty job when it can be used.</div><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEitDdeOGQP3roRLCfZG3M1kYXv_Hv0rb4n1tEBJXsNEGJyP3OsQDs4zdS7W53VTgtFIvIv9cmS8lYoxic8IoDQ673cyMAzwK4AP89pNeMjpd0QxQURwB-P3PFU2GY5aRmtU24CUhNTqEOKn/s2085/deburring_tool.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="576" data-original-width="2085" height="174" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEitDdeOGQP3roRLCfZG3M1kYXv_Hv0rb4n1tEBJXsNEGJyP3OsQDs4zdS7W53VTgtFIvIv9cmS8lYoxic8IoDQ673cyMAzwK4AP89pNeMjpd0QxQURwB-P3PFU2GY5aRmtU24CUhNTqEOKn/w633-h174/deburring_tool.jpg" width="633" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">Deburring tool ($5 or so)<br /></td></tr></tbody></table><div class="separator" style="clear: both; text-align: center;"><br /></div><div class="separator" style="clear: both; text-align: center;"><br /></div>
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; margin-left: 1em; text-align: right;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjZDKsWY7IKvTDu3ytTcQCdlYs2U6FEHmKiakgvzjYZ9_jBS_WUpmfBEpTPwGFWq9lZe66hmVMYtlmKHqWgSD4c7oiE8qeGLJiFOgILPqh-NbxgA5ReYyGdR357y1m3IByTHtrZu8ypqfmf/s1600/IMG_2693-chamfer-tools.JPG" style="clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjZDKsWY7IKvTDu3ytTcQCdlYs2U6FEHmKiakgvzjYZ9_jBS_WUpmfBEpTPwGFWq9lZe66hmVMYtlmKHqWgSD4c7oiE8qeGLJiFOgILPqh-NbxgA5ReYyGdR357y1m3IByTHtrZu8ypqfmf/s1600/IMG_2693-chamfer-tools.JPG" width="141" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Three ways to chamfer,<br />
but the right one is useless.</td></tr>
</tbody></table></div><div dir="ltr" style="text-align: left;" trbidi="on">A <b>manual drill (4/5)</b>, which handle you can print yourself. Or, a more expensive <b>reamer (1/5)</b>, that will suit many more sizes. Better get one long and thin one to have a very sharp angle and make almost non-conic holes. There are also bigger tools to <b>chamfer holes (2/5)</b>, like the big one on the right. They are are useful, but you may want to check for 45° chamfer wood end mill, as they will use less space in the toolbox.</div><div dir="ltr" style="text-align: left;" trbidi="on">
<br />
In any case, I think that manual tools let you do a much cleaner job compared to power tools when dealing with thermoplastics.<br />
<br />
<br />
Of course, you will probably want also to have <b>some taps (3/5)</b> and corresponding drill bits. Now, most of the time it may be done with the help of a regular long screw and fast forward-reverse movements.<br />
<br />
<br />
A set of <b>good set of small files (3/5)</b> are really useful. Some can be found very cheap on ebay (e.g. <a href="https://rover.ebay.com/rover/1/711-53200-19255-0/1?ff3=4&toolid=11800&pub=5575160029&campid=5337834253&mpre=http%3A%2F%2Fwww.ebay.com%2Fitm%2F121948184468">$1.76 here</a>!), and still give good results as the ones below. They are very useful for printed joins when you need a tight tolerance.<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgjJCPSJOsH6qFoytV8sqbIdFzR-zw35KoEIsufAeonAXWEzjVrqPrYF6oijSamzhmeVXgd4_D9o8y8O9xYxqTOR9ismTEGKxdbwZLMrc7hdMDaSSdMbMjP6rINOG3-LSb1ZrsfT3ndbTnw/s1600/IMG_2689-files.JPG" style="margin-left: auto; margin-right: auto;"><img border="0" height="244" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgjJCPSJOsH6qFoytV8sqbIdFzR-zw35KoEIsufAeonAXWEzjVrqPrYF6oijSamzhmeVXgd4_D9o8y8O9xYxqTOR9ismTEGKxdbwZLMrc7hdMDaSSdMbMjP6rINOG3-LSb1ZrsfT3ndbTnw/s1600/IMG_2689-files.JPG" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Very useful <a href="https://rover.ebay.com/rover/1/711-53200-19255-0/1?ff3=4&toolid=11800&pub=5575160029&campid=5337834253&mpre=http%3A%2F%2Fwww.ebay.com%2Fitm%2F121948184468">tiny files</a>. A round one and a flat ones are a must to post-process tight joins.</td></tr>
</tbody></table>
<br />
<br />
<br />
<br />
<br />
<h3 style="text-align: left;">
Assembling, mechanical tools and 3D printer maintenance</h3>
<div>
<br /></div>
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEip6rpim_f-HiCcJtjuvbGvmSjwdVWxXNBLEFntx7sgmEfiSgHIy6RU2amiV9FLJ99oJS-iU3nYduJUGSIUKNqHS2j91elbyh-SXq8fQPqHU2ZtwiF61JYC2hWtY9oI5YkewD4y_6oNFAwO/s1600/IMG_2688-small-and-useful.JPG" style="margin-left: auto; margin-right: auto;"><img border="0" height="196" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEip6rpim_f-HiCcJtjuvbGvmSjwdVWxXNBLEFntx7sgmEfiSgHIy6RU2amiV9FLJ99oJS-iU3nYduJUGSIUKNqHS2j91elbyh-SXq8fQPqHU2ZtwiF61JYC2hWtY9oI5YkewD4y_6oNFAwO/s1600/IMG_2688-small-and-useful.JPG" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Small and useful multi-tool wrench. It cuts Nylon safely.<br />
This one is not very comfortable in my hand though.</td></tr>
</tbody></table>
A tiny <b>pair of pliers (3/5)</b> is a must have, and it helps also to snap or cut filaments more easily than anything else (think about Nylon: you cannot break it, and using a scalpel is out of question imho).<br />
<br />
<br />
A set of hex keys (M8 is used in many printers, mostly because of the <a href="http://www.tridimake.com/2013/03/which-hobbed-bolt-for-filament-feeder.html">filament driver bolt</a>). Actually a tiny <b>adujstable wrench (2/5)</b> would be very useful to replace a bunch of 8, 10, 12 flat wrenches, but I did not get anyone good enough so far (crappy sloppy ones from ebay).<br />
<br />
<br />
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhINlYxLpZu1zbah1KyFa2vwFcmlW-R6Ozd9L3qhNR2hMYrP7pRizBfKFFVFitXo8JBY6J33S0D9StJ7GrDqyzXnaXHejMEvi3Udy0x-_EiFBNmMYvxbayNnQwU3wPY3-VZJojMh7Xrfes3/s1600/IMG_2695-M3.JPG" style="margin-left: auto; margin-right: auto;"><img border="0" height="175" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhINlYxLpZu1zbah1KyFa2vwFcmlW-R6Ozd9L3qhNR2hMYrP7pRizBfKFFVFitXo8JBY6J33S0D9StJ7GrDqyzXnaXHejMEvi3Udy0x-_EiFBNmMYvxbayNnQwU3wPY3-VZJojMh7Xrfes3/s1600/IMG_2695-M3.JPG" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">M3 everyday tools. Well, the nut holder on top is bulky even<br />
though I shortened it, I often use my <a href="http://www.thingiverse.com/thing:44118">nut calumet</a> instead.</td></tr>
</tbody></table>
A high quality set of <b>hex screwdriver (5/5)</b>. Actually, I better recommend a multitool that can hide long bits within the handle, so it takes less place in the box and has more than one size.<br />
<br />
<br />
<b>Pulley allen hex key (5/5)</b>, that are rarely used but that are compulsory to secure your pulleys on the axis.<br />
<div>
<br />
<br />
My <b>nut calumet (4/5)</b>, as it helps tremendously on the UMO for the rod caps and the nuts within the stock hotend fan... As you can <a href="http://www.thingiverse.com/thing:44118">print it</a> it costs nothing and takes no place for what it brings.<br />
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; text-align: center;"><tbody>
<tr><td><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEha9mkYEZNknlW2Mf6pXRTy9LdbZ3I1Jq539HpkQ7VLqwgj9aHi7ibTTSmOx2O5ds3Ya8pTrfhZDiLSiKDFuruf7rvolCZ7AAEylB2QIqFPmOI5-atDtqeVsC4PrVoG8UBe7ahxyankrPz0/s1600/IMG_2694-wrenches.JPG" style="margin-left: auto; margin-right: auto;"><img border="0" height="242" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEha9mkYEZNknlW2Mf6pXRTy9LdbZ3I1Jq539HpkQ7VLqwgj9aHi7ibTTSmOx2O5ds3Ya8pTrfhZDiLSiKDFuruf7rvolCZ7AAEylB2QIqFPmOI5-atDtqeVsC4PrVoG8UBe7ahxyankrPz0/s1600/IMG_2694-wrenches.JPG" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="font-size: 12.8px;">The top wrench was "widened" specifically for the heater block.<br />
This way I can remove it without burning myself.<br />
BTW, the small adjustable wrench is too bulky,<br />
but the cheap ones I tried so far proved to be too cheap.</td></tr>
</tbody></table>
<br />
<br />
<div>
Light/liquid grease for the rods and bearings. <b>Sewing machine oil (5/5)</b> is the simplest and best oil for a 3D printer. <b>Teflon sprays (2/5)</b> are "cleaner" but they do not last enough in my opinion. <b>Thick grease (3/5)</b> is a bad idea, even though they may be used nicely for the Z axis (and only there, please!).<br />
<br />
<br /></div>
<div>
A very small <b>flat screwdriver (?/5)</b> will help you tune the tiny potentiometer on some Pololu drivers. Some people recommend ceramic (non-conductive) screwdrivers, but I find it works as well with a regular one. It may become a must only if you want to fiddle with the stepper power (e.g. to try and print faster).</div>
<br />
<br />
<br />
<br />
<br />
<br />
<br /></div>
<div>
<h3>
Spare parts</h3>
Miscellaneous <b>electric ties (4/5)</b>: small ones keep the electric cabling tidy, and large ones help routing the bigger cable and bowden tubes to the head. Some of them can be adjusted and re-opened, which is very convenient for the latter case. I always have some at hand. I often use scratch-like ties.<br />
<b></b><br />
<b></b>
<b>Spare gears (3/5)</b> for the filament driver (though they they eventually break at the worst moment).<br />
<br />
One more <b>stepper driver (1/5)</b> and <b>RAMPS board (1/5)</b> if you really want to make sure you can print when you want to print.<br />
<br />
One <b>power supply block (2/5)</b>, as it breaks more often than expected.<br />
<br />
Some <b>spare bowden tube (3/5)</b>, that I prefer in a larger diameter (see my post)<br />
<br />
Obviously a proper <b>set of spare nuts, washers, springs (4/5)</b> for your printers. I also bought a comprehensive set of M3 stainless steel nuts to assemble my designs, as they are also the ones used to assemble the printer itself.<br />
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiB1me2Kebh2JeJiBEgncQWwEhKGl4A6bLNCp36kHQs9Dp6YuZX3UGNuZtk3Ok1fgz-iLXvb62MwMhg6m_nNdr-dLHAsBG7Vhrf28lRoDOK22ukvzoZHqhzjaWdvpYMmsRDO5q4j8wcpGaW/s1600/IMG_2699-misc-stuff.JPG" style="margin-left: auto; margin-right: auto;"><img border="0" height="435" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiB1me2Kebh2JeJiBEgncQWwEhKGl4A6bLNCp36kHQs9Dp6YuZX3UGNuZtk3Ok1fgz-iLXvb62MwMhg6m_nNdr-dLHAsBG7Vhrf28lRoDOK22ukvzoZHqhzjaWdvpYMmsRDO5q4j8wcpGaW/s1600/IMG_2699-misc-stuff.JPG" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">More tools and spare parts. I printed the small box for the set of screws, nuts and washer.<br />
I usually also have a spare filament driver and almost one full hot end, but this is luxury.<br />
The zip-ties and piece of nylon are very really useful though.</td></tr>
</tbody></table>
<br /></div>
<h3 style="text-align: left;">
</h3>
<br />
<br />
<br />
<br />
<h3>
</h3>
<h3>
</h3>
<h3>
</h3>
<h3>
</h3>
<h3>
</h3>
<h3>
</h3>
<h3>
</h3>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<br />
<br />
<br />
<br />
<h3 style="text-align: left;">
Conclusion</h3>
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiwuBLTxJQKC45o5RipsKqslsh4H6ckPb4Qho_ZvYcV5FTj8PT6F-7a1llJg4aRFOQYejLGSQMr55KWwUp1G2TJi1IcQAUwAW1aSdNcyOEFCrMoiV1R4Pk0THvrP2HXpGwEGg1obCUTZHmU/s1600/IMG_7098-Something-useful-I-carry-with-me-3D-printed.jpg" style="margin-left: auto; margin-right: auto;"><img border="0" height="215" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiwuBLTxJQKC45o5RipsKqslsh4H6ckPb4Qho_ZvYcV5FTj8PT6F-7a1llJg4aRFOQYejLGSQMr55KWwUp1G2TJi1IcQAUwAW1aSdNcyOEFCrMoiV1R4Pk0THvrP2HXpGwEGg1obCUTZHmU/s1600/IMG_7098-Something-useful-I-carry-with-me-3D-printed.jpg" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Not useful, but you always need to show what can be done (rod end, nylon hub)<br />
It is tiny enough to be kept with the tools, so you always have it handy.</td></tr>
</tbody></table>
<br />
<br />
<br />
<br />
And always... I keep a carefully selected set of tiny but high quality <b>printed samples (4/5)</b> to brag about. In my case, my printer is probably enough as many parts were already <a href="http://www.tridimake.com/2014/01/features-and-improvements-for-a-homemade-ultimaker.html">re-designed</a>.<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-Ku8FqwAtxAzIffvHMsxELLdd2AEGmx4L7SmQNOFJUhHSK6qDQcxRTmArbvhRtoKyouuwHEpGWlywo4kEd74f7G1Xw2XsJmKtcgKh3Lf1ihMl631oRy7OdaCKd8vCDHNhxlFiACeAWSqH/s1600/IMG_2705-box-in-UM.JPG" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="213" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-Ku8FqwAtxAzIffvHMsxELLdd2AEGmx4L7SmQNOFJUhHSK6qDQcxRTmArbvhRtoKyouuwHEpGWlywo4kEd74f7G1Xw2XsJmKtcgKh3Lf1ihMl631oRy7OdaCKd8vCDHNhxlFiACeAWSqH/s1600/IMG_2705-box-in-UM.JPG" width="320" /></a><br />
<br />
<br />
The <b>tool/dirt box (5/5)</b> itself: it holds all the tools, and in my case it fits nicely the bottom of my Ultimaker, so it makes it very easy to drag around in only one piece (given that I also moved my power supply <a href="http://www.tridimake.com/2012/10/homemade-heated-bed.html">beneath</a> the frame).<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
Also, I eventually bought some tools twice. Now I have one set specifically for my 3D printer work. I realized more than once that I had left THE required tool/fix at home just when I needed it badly on a trip with my printer to a friend or to a client. The worst was when I did not have the spring for the level of my filament feeder (I had to revert to electric ties... and it worked! At least I had electric ties).<br />
<div>
<br />
A good set of tools really helps with 3D printers. Good tools help not only to fix problems more efficiently, but also to clean prints better than with the too common "basic" household stuff. What is nice is that the proper tool for the proper job is not necessarily expensive nowadays: most of these here were bought on ebay or at the local shop for a few bucks.<br />
<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgFMxQVrV32rrKCRL1KZMsAas0Ut_CTpoM4skgqQwgxvGN190_64YRtsJpXKCt0mO5psfkBE7qkzObqqe7U2CXjFuGtygDPSQUl1mzHOi4x8ZJ2dZymu4K2fidhvi3HKJH2T62B9rzsB3hl/s1600/IMG_4389-glue-scalpel.JPG" style="margin-left: auto; margin-right: auto;"><img border="0" height="523" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgFMxQVrV32rrKCRL1KZMsAas0Ut_CTpoM4skgqQwgxvGN190_64YRtsJpXKCt0mO5psfkBE7qkzObqqe7U2CXjFuGtygDPSQUl1mzHOi4x8ZJ2dZymu4K2fidhvi3HKJH2T62B9rzsB3hl/s1600/IMG_4389-glue-scalpel.JPG" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Nicely removing a Nylon object on a glued bed<br />
with the help of a scalpel, equipped with a s<span style="font-size: 12.8px;">traight blade.</span></td></tr>
</tbody></table>
<br />
<br /></div>
</div>
Jeremie Francoishttp://www.blogger.com/profile/02984201174566394892noreply@blogger.com1tag:blogger.com,1999:blog-3615478772815290200.post-64196980100956844552015-03-30T11:21:00.000+02:002015-05-14T21:01:54.957+02:00CNC fail? 3D printed design blows my ears instead of the dust<div dir="ltr" style="text-align: left;" trbidi="on">
I bought a well-built Chinese CNC machine last year, namely a 4 axis CNC3040Z-DQ router/engraver, for about €1000 (as far as I remember).<br />
<br />
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgfWGBqirj0enqStAYUgF4CjsC2TmIo7LdNAwcO_Wi3NMDmRJyJfXxoB04-TzbQpimrDCuGOpaMtyVxojWdkGVKrytSBQvCVQ1vXyBdchSc59SC-k55dwu87kg5jUi5IO6u6Yc-GFyF3b6R/s1600/IMG_4394-tridimake-CNC-3040Z-DQ-Milling-PCB-20150302.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="265" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgfWGBqirj0enqStAYUgF4CjsC2TmIo7LdNAwcO_Wi3NMDmRJyJfXxoB04-TzbQpimrDCuGOpaMtyVxojWdkGVKrytSBQvCVQ1vXyBdchSc59SC-k55dwu87kg5jUi5IO6u6Yc-GFyF3b6R/s1600/IMG_4394-tridimake-CNC-3040Z-DQ-Milling-PCB-20150302.JPG" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Milling a PCB with a low cost CNC router/engraver controlled by LinuxCNC.</td></tr>
</tbody></table>
My initial need was to "etch" electronics PCB boards at home, to get rid of so called proto- and perf boards. This machine is overkill for the job, but I do not regret my purchase since it can do much more than PCB milling...<br />
<div>
<br /></div>
But only recently did I spend enough time to use it. Even though the reliability and consistency of a CNC milling machine is way better than that of a 3D printer, the whole process is cumbersome. It takes a lot of time to get used to the software, which is a decade behind the ergonomics of more intuitive <a href="http://www.tridimake.com/2012/10/the-software-side-of-view.html">3D printing software</a>. Worst, the controlling software like <a href="http://www.linuxcnc.org/">linuxCNC</a> or Mach3 still require a parallel port and a special real-time distribution of linux. Both are a real pain because you need a dedicated and obsolete machine just to drive the CNC. Recent projects like <a href="https://github.com/grbl/grbl">GRBL</a> are knocking at the door though, as an alternative to parallel port hardware: they rely on Arduinos, but are limited by the power of this platform. ARM-based boards are more promising, especially for fast machines, or when you have more than 3 axis of freedom (e.g. see <a href="http://en.wikipedia.org/wiki/Six_degrees_of_freedom">6DoF</a>)<br />
<br />
Note: I may write more about CNC machining at home, its software and process in other posts. But I start here with a quick, funny, and miserable failure of mine, that was meant to be an improvement in the first place. And, well, it mixes printing and milling so it is a good transition.<br />
<br />
<br />
<a name='more'></a><br />
<br />
<h3 style="text-align: left;">
And who thought a 3D printer was dirty?</h3>
<br />
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; text-align: left;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiYEATnjrthSdwGt9dKOoxjgnvkLh2tt9zdKogEnaLfg0MvrS2rbRuByJ4GLLu9tlKRVYtqqj_JxUN3I4dc8DeBGN3QNQwI5sKSS5IrBHMx_vLrq1oEMifBCjOROtURPiRmd33Xwvl2vahw/s1600/IMG_4665.JPG" imageanchor="1" style="clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiYEATnjrthSdwGt9dKOoxjgnvkLh2tt9zdKogEnaLfg0MvrS2rbRuByJ4GLLu9tlKRVYtqqj_JxUN3I4dc8DeBGN3QNQwI5sKSS5IrBHMx_vLrq1oEMifBCjOROtURPiRmd33Xwvl2vahw/s1600/IMG_4665.JPG" width="245" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">A 3D printer is tremendously useful<br />
for such a design. But it does not mean<br />
the design is functional!</td></tr>
</tbody></table>
As a <a href="http://en.wikipedia.org/wiki/Machining">subtractive manufacturing</a>, a CNC milling machine is way dirtier than a 3D printer. The latter only generates lots of strings and bits of plastic, but they are well contained in the bottom of semi-enclosed printers like the Ultimaker Original (the second version homes to the bottom, which is annoying in this regard imho!).<br />
<br />
Reciprocally, CNCs generate an outstanding amount of <i>dust</i>, composed of very fine particles that easily fly and float in the air. Contrary to 3D printers, no way you can clean up <i>after</i> a job, it must be done <i>during</i> the milling process. The high speed spinning end mill throws the dust all around contrary to a mostly static 3D printer nozzle.<br />
<br />
Moreover, raw PCB boards are often made of toxic epoxy: I do not want to inhale that dust at all. So even though a vacuum cleaner is the minimum you want to use, it still may not block the fine dust and may only throw them even farther in the room (in this regard, I was told about HEPA-grade filters).<br />
<br />
<br />
<br />
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhZ3JzM_wRailHOni576JRRuDLMOU_nOZ8JmSBuNs6UprCdNNg5AFz2AweLxILTcCtS956Xg-vguEDkcDmhSqe_Gd1Y8pP8BZG7b44zlHJJOqnL-_wr_2Gej6sf2VS759Ren_aQLGNpGjSM/s1600/IMG_8345-CNC-vacuum-cleaner-hose-dangerous.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="212" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhZ3JzM_wRailHOni576JRRuDLMOU_nOZ8JmSBuNs6UprCdNNg5AFz2AweLxILTcCtS956Xg-vguEDkcDmhSqe_Gd1Y8pP8BZG7b44zlHJJOqnL-_wr_2Gej6sf2VS759Ren_aQLGNpGjSM/s1600/IMG_8345-CNC-vacuum-cleaner-hose-dangerous.JPG" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">The unsafe, boring and tiring way (hence triply unsafe!).<br />
Keep your fingers away and never ever<br />
touch the drill bit while it rotates!</td></tr>
</tbody></table>
Anyhow, it is both tiring, cumbersome and dangerous to stay and hold a hose close to the milling bit. The 20.000 RPM spinning bit would probably shatter at the very moment something unexpected touches it. The end bit may be small, but its kinetic energy is huge, and without eyes I would not be able to hack anymore...<br />
<br />
So I soon started to think about a design to hold the hose for me, so I could step back from the job (and, well, work on something less boring, like staring at a 3D printer -- additive processes are way more interesting imho!)<br />
<br />
<br />
<br />
<br />
<br />
<br />
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXnMycyltKGd6qE3QNJVEyDRY6siROrJBLE_Ss8IWLGwpf-LdoxKZRZx0n5GZhSRCzRanh7pRoJsdKoqbC34KPJzJZqtj_tGIBTGcUkQK8k2MnBtQ7dLHqzrEfNlJDjwjZRkPJ97nmO8C8/s1600/magnetic-cnc-head-Andy-Shrimpton.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="194" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXnMycyltKGd6qE3QNJVEyDRY6siROrJBLE_Ss8IWLGwpf-LdoxKZRZx0n5GZhSRCzRanh7pRoJsdKoqbC34KPJzJZqtj_tGIBTGcUkQK8k2MnBtQ7dLHqzrEfNlJDjwjZRkPJ97nmO8C8/s1600/magnetic-cnc-head-Andy-Shrimpton.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">A milled CNC extraction head, held by magnets (<a href="https://youtu.be/VfpWo8LrGmo?t=752">video</a>),<br />
and what looks like a hollowed broom below!<br />
(this is a really smart design by Andy Shrimpton)</td></tr>
</tbody></table>
<br />
Of course, many designs already exists to hold a vacuum hose close to the end mill.<br />
<br />
Some of them even are made with the CNC, like the smart one on the right (milled from polycarbonate).<br />
<br />
But there are also many designs that are 3D printed, for more "complex" shapes (complexity is no goal of course, but a 3D printer allows "non-flat" shapes at least), such as duck-shaped adapters for existing vacuum hoses which are bolted on the CNC head.<br />
<br />
<br />
<br />
<br />
<h3 style="text-align: left;">
3D printing a "too smart" end, to suck up the dust of the CNC end mill ?</h3>
<br />
I just find it terribly hard for me to recycle ideas and designs stuff when I think I can do it myself, especially when I think I can improve on existing devices.<br />
<br />
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="clear: left; float: left; margin-bottom: 1em; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjrtb-Dg7srPUW26ShsYSbWf-PYZwK0rN9mqW17n4EDVxfGJWxcR5rXvkyqCZ6zxsddiq3hfWGo6z8-a3pC5EOlgECKEkHJ-fUOCd02mueKvWQVNvOBUsILD5oH8f8q_Ua6mlWCUgq4bI6G/s1600/openscad-cnc-vortex-head.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="251" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjrtb-Dg7srPUW26ShsYSbWf-PYZwK0rN9mqW17n4EDVxfGJWxcR5rXvkyqCZ6zxsddiq3hfWGo6z8-a3pC5EOlgECKEkHJ-fUOCd02mueKvWQVNvOBUsILD5oH8f8q_Ua6mlWCUgq4bI6G/s1600/openscad-cnc-vortex-head.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">A swirling vacuum head with internal<br />
angled fins. Owning both a 3D printer<br />
and a CNC is such a killer combo!</td></tr>
</tbody></table>
So after a few hours of <a href="http://www.tridimake.com/2014/09/how-to-use-openscad-tricks-and-tips-to.html">designing in Openscad</a>, I came to what I though would be a good idea: a "swirling sucking end". My goal was eventually to create a swirling air movement all around the mill bit, in order to suck the dust up and into the vacuum cleaner. The printed adapter would screw on the CNC spindle and stay somehow far from the milled material (the drill bit can plunge into it for about 3 cm, no way I could extend the adapter downwards -- and the chuck must remain accessible).<br />
<br />
This is why the design on the left features some angled fins around the CNC chuck, that would eventually help to create a vortex down to the milled board and around the end mill...<br />
<br />
<br />
<br />
<b>A word of caution on using 3D printed parts for a CNC (again)</b><br />
<br />
Making anything that will sit close to a CNC must be done carefully again.<br />
<br />
Once again, for safety, you certainly do not want a 3D printed part to crack or break and it hits the end mill in the middle of a job. You would get the whole thrown in the air randomly with the metallic bit. This is why I chose the material carefully for the job (here I used black PET (Colorfab XT) as a tough material, but I could probably better switch to <a href="http://www.tridimake.com/2014/01/how-to-3d-print-nylon-and-trimmer-line.html">Nylon</a>). Carbon-fiber reinforced filament are no option, as is way too stiff, hence it breaks without prior deformation.<br />
<br />
Specifically, I do not trust 3D <a href="http://www.tridimake.com/2012/12/3d-printing-plastic-filaments-kinds-and.html">printed thermoplastics</a> as much as milled materials. Even milled thick thermoplastic sheets would give a stronger object because the material is more homogeneous than with layers that may have bonding issues.<br />
<div>
<br /></div>
<div>
<br /></div>
<div>
<b>So? Did it work?</b></div>
<br />
Alas, not only this sucker is a pure failure as a vortex-inducer but all the powerful vacuum energy seemed to be converted into an unbearable resonant noise!<br />
<br />
This thing just sucks nothing but it blows my ears. This damned design probably exceeds 120dB, and the weaved resonant frequencies as it stops are really unbearable!<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen="" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/L1YT9tA_Nno/0.jpg" frameborder="0" height="266" src="http://www.youtube.com/embed/L1YT9tA_Nno?feature=player_embedded" width="320"></iframe></div>
<div style="text-align: center;">
<span style="font-size: x-small;">Here is it (video): a better vacuum sucking head? Not at all!</span></div>
<div style="text-align: center;">
<span style="font-size: x-small;">Warning: extremely noisy, check your audio volume first!</span></div>
<div style="text-align: center;">
<span style="font-size: x-small;">This thing just sucks nothing, but it blew my ears.</span></div>
<br />
<h3 style="text-align: left;">
Conclusion: failure gives experience...</h3>
It teaches me five good lessons:<br />
<br />
<ol style="text-align: left;">
<li>(even painful) fun is always hidden behind where you do not expect it</li>
<li>Field testing is the only way to check that a design works!</li>
<li>Reciprocally I should learn more about fluid mechanics theory</li>
<li><a href="http://en.wikipedia.org/wiki/KISS_principle">KISS</a> (keep it simple, stupid): now I will retry without the small angled fans</li>
<li>Always better protect myself, not only for the eye, but now also for the ear!</li>
</ol>
<u><i>Update</i></u>:: ...and a 6th lesson: never draw conclusions too early! The major source of noise actually came from the blue tube in relation to the adapter to the larger vacuum tube. Plugging the larger vacuum hose directly makes it much quieter (but still inefficient).<br />
<br />
<br />
So now... I will retire deep in a cave for a few hours, to design something else while I heal my ears.<br />
<div>
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjo7kI2klluRS_qFSeJ-MZGBJS4-4dTR0a5hYqk2pwmX8jXtOD8vUPYMp15o1uPGSfjc9pcTvQ3Gb-jwOpBKWE7i1oP3_9eqqVUQWNIEnTO7SjKsqMYAunFWrHgYeAqpYDwfwxWNZRS44Qm/s1600/growth-mindset.gif" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjo7kI2klluRS_qFSeJ-MZGBJS4-4dTR0a5hYqk2pwmX8jXtOD8vUPYMp15o1uPGSfjc9pcTvQ3Gb-jwOpBKWE7i1oP3_9eqqVUQWNIEnTO7SjKsqMYAunFWrHgYeAqpYDwfwxWNZRS44Qm/s1600/growth-mindset.gif" width="470" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">I deeply think that failure is a good opportunity<br />
(discover! as in this nice post about <a href="http://blog.norsecorp.com/2014/09/18/revealing-the-awesome-truth-about-hackers/">hackers/makers</a>)<br />
(<a href="http://blog.dyslexicadvantage.org/2014/10/08/growth-mindsets-and-dyslexia-dr-carol-dweck-roundtable-free-online-1014/">illustration</a> by Carol Dweck and Nigel Holmes)</td></tr>
</tbody></table>
<div>
<br /></div>
</div>
Jeremie Francoishttp://www.blogger.com/profile/02984201174566394892noreply@blogger.com0tag:blogger.com,1999:blog-3615478772815290200.post-4391011704474274762015-01-27T01:25:00.001+01:002018-04-13T11:25:04.804+02:00Contributing to projects hosted on github: a step by step howto, and an illustration with Marlin (3D printer firmware).<div dir="ltr" style="text-align: left;" trbidi="on">
<h2 style="text-align: left;">
Git is powerful... and very painful the first time! / Github contribution howto / Tweaking Marlin for better 3D printer menus.</h2>
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgn8IXWzfVDVbuqIRpK_-BYuLsiGUto3AzEJC8P0ZgI7sXS_yC-jbmrmeSSScdORFZbDEzjLEgYT5nvfGvI3AxYS2Wa2mHJBYyMXrv_M8gZ2DbX_atDsq_aSMC-V_3Q6VNyvsrhBoyjjotp/s1600/git-hell.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="375" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgn8IXWzfVDVbuqIRpK_-BYuLsiGUto3AzEJC8P0ZgI7sXS_yC-jbmrmeSSScdORFZbDEzjLEgYT5nvfGvI3AxYS2Wa2mHJBYyMXrv_M8gZ2DbX_atDsq_aSMC-V_3Q6VNyvsrhBoyjjotp/s1600/git-hell.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Git mess, only partially resumed by <a href="http://blog.osteele.com/posts/2008/05/my-git-workflow/">Oliver Steele</a>.<br />
Indeed, the <i>upstream</i> higher repository is not shown here,<br />
as seen on this other bigger, clean and <a href="http://ndpsoftware.com/git-cheatsheet.html">useful cheat sheet</a>.</td></tr>
</tbody></table>
I eventually wrote a feature to fix something that annoyed me for years: allow <a href="https://github.com/MarlinFirmware/Marlin/pull/1423">multi-line commands</a> in the LCD menus of Marlin, a very well known firmware for 3D printer.<br />
<br />
I needed it for my Delta printer: these printer do require precise calibration, often with a sequence of <a href="http://reprap.org/wiki/G-code">gcode commands</a> (check the end of this post for more and why I wanted these to be in my menus and not as initialization files on all my SD cards nor on a PC over a USB cable).<br />
<br />
Now, Marlin is hosted on <a href="https://github.com/">github</a>, a community front end to many other open source projects. Actually, the <a href="https://github.com/torvalds/linux">linux kernel</a> itself is developed with <span style="font-family: "courier new" , "courier" , monospace;">git</span> so it works, for sure.<br />
<br />
I often tried to use github, but I never went past a simple <span style="font-family: "courier new" , "courier" , monospace;">git clone</span> of a repository. It was still better than to download a zip archive, because you can easily get the new stuff with a <span style="font-family: "courier new" , "courier" , monospace;">git pull</span>. But here and partially out of curiosity, I wanted to try and <i>contribute</i> to a project at the source.<br />
<br />
Now... what a huge and painful procedure just to give a hand! Seriously, it is mind boggling how much crap and megabytes need to be handled just to help and submit a few dozen f*king lines of code to an opensource project hosted on github. This is too bad since I am sure many programmers would be glad to give a hand to project they stumble upon (like me, often), but without this need to become administrators of complex and shared projects themselves!<br />
<div>
<br /></div>
<div>
This article is all about posting and contributing to a project hosted on github. You'll get the calibration g-code line I used at the end of the post if you really ask yourself.</div>
<div>
<a name='more'></a><a href="http://www.garyrobinson.net/2014/10/git-in-two-minutes-for-a-solo-developer.html">This short introduction</a> may be a good start, i.e. using git as a solo developer without a "mother" project that you have no right on it. But we want here to contribute to someone else's project.</div>
<div>
<br /></div>
Almost all github existing projects rely on the <i>fork and pull model</i>. Else, you probably know better than me when you are allowed to work directly in the repository of others ;)<br />
<br />
So the deal is that <span style="font-family: "courier new" , "courier" , monospace;">git</span> requires you to make yourself a full copy of the project, both remotely and locally. Then you work locally, you commit locally, then again remotely, and then tell the project maintainer that your copy has a change that may be interesting to them. Powerful, but convoluted for sure as it also means you need to get the changes from their own project that also moves on in between.<br />
<br />
Anyway git and github are painful enough for me to record the full procedure here, and hopefully once for all. It may help some old school developers as me, and may be it would let them contribute more easily to open source projects hosted on github.<br />
<br />
If this post is <a href="https://en.wikipedia.org/wiki/Wikipedia:Too_long;_didn%27t_read">TL;DR</a>, you may like this small and raw <a href="http://rogerdudler.github.io/git-guide/">graphical resume</a> instead.<br />
<br />
<h3 style="text-align: left;">
Initial setup: create your own version of the original repository</h3>
OK. For now you want to use your browser at https://github.com/<br />
<br />
1) You first need (to create) a github account (not that much painful so far, but it already gets annoying haha)<br />
<br />
2) Then go to the github <i>repository</i> you want to work with.<br />
<br />
For Marlin, the main one seems to be https://github.com/MarlinFirmware/Marlin.git<br />
<br />
You will see that there are tons of secondary variants made by tons of people so make sure you are working on the "right" one. Now, this is really annoying to me when your goal as here is just to try to submit a piece of code to the "original" authors. And no, you have to create your own repository first!<br />
<br />
This just due to the way github works: as a matter of fact we have to create <i>yet another</i> version of Marlin!<br />
<br />
3) Now, still in the web page, click and fork the official Marlin repository (it will create copy in <i>your</i> account... and add to the mess for newcomers!).<br />
<br />
4) Make sure to rename this copy to a meaningful name. Be it for you or for others, it will prove very valuable! Just click on the tiny almost hidden "project settings" icon in the bottom right margin (see below), then rename your project.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgsy-bR2WfCiOpnag7_AOvJCp-Jsf1b_S-jXjJRk1ymyptS9tbNWPZQ3e7b38rJJJWMOvQ3pDlKK_6tpHWshTSEUD0b3MCCLbaMrQnXB95QwxGVABmHEYN6Klmr_3IctR5B3KD_qg1bE7_8/s1600/github-rename.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="449" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgsy-bR2WfCiOpnag7_AOvJCp-Jsf1b_S-jXjJRk1ymyptS9tbNWPZQ3e7b38rJJJWMOvQ3pDlKK_6tpHWshTSEUD0b3MCCLbaMrQnXB95QwxGVABmHEYN6Klmr_3IctR5B3KD_qg1bE7_8/s1600/github-rename.jpg" width="640" /></a></div>
<br />
Now get back to your main project page by clicking on the name of the repository, then copy the content of the small box in the bottom right margin, labeled "<span class="text-emphasized" style="box-sizing: border-box; color: #333333; font-family: "helvetica" , "arial" , "freesans" , "clean" , sans-serif , "segoe ui emoji" , "segoe ui symbol"; font-size: 11px; font-weight: bold; line-height: 1.1;">HTTPS</span><span style="background-color: white; color: #999999; font-family: "helvetica" , "arial" , "freesans" , "clean" , sans-serif , "segoe ui emoji" , "segoe ui symbol"; font-size: 11px; line-height: 1.1;"> </span><span style="background-color: white; color: #999999; font-family: "helvetica" , "arial" , "freesans" , "clean" , sans-serif , "segoe ui emoji" , "segoe ui symbol"; font-size: 11px; line-height: 1.1;">clone URL</span>". This is your repository URL, its ID card in a way.<br />
<br />
5) Now back to the console!<br />
<br />
<b>WARNING</b>! You may want to use your public SSH keys to log in (so that you are safe and do not have to provide your login all the time). In this case, do NOT use the above link, but tweak it to this syntax instead:<br />
<span style="font-family: "courier new" , "courier" , monospace;"> git clone git@github.com:MoonCactus/Marlin-JFR-features.git</span><br />
<br />
Else, to use other means to identify yourself on github, you may use the copied URL as is:<br />
<span style="font-family: "courier new" , "courier" , monospace;"> git clone https://github.com/MoonCactus/Marlin-JFR-features.git</span><br />
<br />
Of course you want to specify your own repository, not the one you forked from.<br />
Also, make sure you are using <span style="font-family: "courier new" , "courier" , monospace;">https</span> and not <span style="font-family: "courier new" , "courier" , monospace;">http</span> or will will make your life harder later on.<br />
<br />
<br />
<h3 style="text-align: left;">
Now you can code... (but the pain is still to come!)</h3>
Now the funniest part: start coding and hacking your stuff around... Oh you did already, didn't you?<br />
<br />
And you though about committing your changes to git afterwards, right?<br />
<br />
In fact, I use a comparison tool like <a href="http://meldmerge.org/">meld</a> to re-incorporate my changes to a <i>forked</i> repository after I usually start working "just to try" on a <i>cloned</i> repository. There should be one single command to switch from the latter to the former... Alas, do not forget: Git was first, and only then came the source code... ;)<br />
<br />
Now, it is time to submit your changes, and here it becomes annoying again.<br />
<br />
<h3 style="text-align: left;">
Commit your changes... multiple times and all everywhere ;)</h3>
When you are done and want to save/store/submit/commit your changes, you have different commands to issue (no way it will never be as dead simple as a dumb <span style="font-family: "courier new" , "courier" , monospace;">cvs commit</span>!).<br />
<br />
<br />
<ul style="text-align: left;">
<li><span style="font-family: "courier new" , "courier" , monospace;">git status</span> -- a useful command to check the state of your repository</li>
</ul>
<br />
E.g. here it tells me I modified three files in the project:<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> On branch Development</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> Your branch is up-to-date with 'origin/Development'.</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> Changes not staged for commit:</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> (use "git add <file>..." to update what will be committed)</file></span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> (use "git checkout -- <file>..." to discard changes in working directory)</file></span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> modified: Marlin/Marlin.h</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> modified: Marlin/Marlin_main.cpp</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> modified: Marlin/ultralcd.cpp</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> no changes added to commit (use "git add" and/or "git commit -a")</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"></span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"></span>
<br />
<div>
<ul style="text-align: left;">
<li><span style="font-family: "courier new" , "courier" , monospace;">git add</span><span style="font-family: inherit;"> </span>-- Tell it you changed something (!)</li>
</ul>
</div>
<div>
You first need to <i>commit</i> your changes <i>locally</i> with a git add followed by the name of files that changed (listed above):</div>
<div>
<br /></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> cd Marlin</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> git add Marlin.h Marlin_main.cpp ultralcd.cpp</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"><br /></span></div>
<div>
<ul style="text-align: left;">
<li><span style="font-family: "courier new" , "courier" , monospace;">git commit</span> -- Now tell it to record that you changed something, still <i>locally</i> (!)</li>
</ul>
</div>
<div>
In fact you may merge the add + commit commands by typing <span style="font-family: "courier new" , "courier" , monospace;">git commit -a</span> instead.</div>
<div>
<br /></div>
<div>
But no, it will not be uploaded yet. It may be useful though, so that you can work with a local history and you can work offline. But that is nonetheless more steps to the whole procedure (what the heck is then the need for an index and a <span style="font-family: "courier new" , "courier" , monospace;">git add</span> really?). Anyway here it goes:</div>
<div>
<br /></div>
<div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> git commit</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> [Development dd301be] <b>Added suport for multiline G-code commands in the</b></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"><b> LCD menus</b></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> 3 files changed, 43 insertions(+), 4 deletions(-)</span></div>
</div>
<div>
<div>
<br /></div>
<div>
As you seen it asked for a message related to the changes. Better write something useful because it will show in the history, and it helps you <i>reverting</i> to an older revision of the project when you screw it all, and it helps anyway to understand what you did months ago!</div>
</div>
<div>
<br /></div>
<div>
<ul>
<li><span style="font-family: "courier new" , "courier" , monospace;">git push</span> -- At last, send it to your repository!</li>
</ul>
</div>
<div>
Hooray? oh no, not at all!</div>
<div>
<br /></div>
<div>
First, it will ask for some more obscure options. Better do the following once <i>before</i> you push your changes:</div>
<div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> git config --global push.default matching</span></div>
<div>
<br /></div>
</div>
<div>
Then again:</div>
<div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> git push</span></div>
</div>
<div>
<br /></div>
<div>
But now it asks for your github credentials. Here I typed them manually:</div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> Username for 'https://github.com': <b>MoonCactus</b></span></div>
<div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> Password for 'https://MoonCactus@github.com': <b>XXXXX</b></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> Counting objects: 6, done.</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> Delta compression using up to 8 threads.</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> Compressing objects: 100% (6/6), done.</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> Writing objects: 100% (6/6), 1.22 KiB | 0 bytes/s, done.</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> Total 6 (delta 5), reused 0 (delta 0)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> To https://github.com/MoonCactus/Marlin-JFR-features.git</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> 865ca0e..dd301be Development -> Development</span></div>
</div>
<div>
<br /></div>
<div>
At least it worked! My remote repository on github is now updated with my local changes. But how do I get the remote changes from the original repository, and further, how do I tell them I added a feature to Marlin?</div>
<div>
<br /></div>
<h3 style="text-align: left;">
Credentials and github</h3>
<div>
Don't we just want to submit one patch and not to administrate repositories? No way...</div>
<div>
<br /></div>
<div>
As we have seen, <span style="font-family: "courier new" , "courier" , monospace;">git push</span> asks for your credentials (login and password). And it is more likely we will be making changes and submitting them more than once.</div>
<div>
<br /></div>
<div>
To avoid having to type it all the time, you may check the many options given in this <a href="http://stackoverflow.com/questions/6565357/git-push-requires-username-and-password">post</a>.</div>
<div>
If you are using a desktop PC and use an encrypted user directory, then you may take the risk to store your password in your <span style="font-family: "courier new" , "courier" , monospace;">~/.netrc</span> special file (I have no clue on windows, sorry there!).</div>
<div>
But you would better go the safe way and upload your public SSH keys to github. This way it stops asking and you stay "fully" secure.</div>
<div>
<br /></div>
<div>
You can do that here on the web:</div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">github / edit profile / SSH keys </span>(aka https://github.com/settings/ssh)</div>
<div>
<br /></div>
<div>
There you can add your own "*.pub" SSH key. Check <a href="https://help.github.com/articles/generating-ssh-keys/">this help</a> if you need more about SSH keys, or if you want github to generate some for you because you do not have some already (this is not recommended imho).</div>
<div>
<br /></div>
<div>
Then, check you are OK when <span style="font-family: "courier new" , "courier" , monospace;">ssh -T git@github.com</span> no more asks for your login.</div>
<div>
<br /></div>
<div>
But still... for SSH login to work, you must have cloned your project NOT with the given https repository link, but the following way instead. Else you are <a href="http://stackoverflow.com/a/11958103/2638860">screwed</a> and need to download the project all over again, by using:</div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">git clone git@github.com:MoonCactus/Marlin-JFR-features.git</span></div>
<div>
<br /></div>
<div>
Did I say git was just plain painful to set for newcomers? Well, at least you can first commit your existing changes in the "htpps style" by providing your login to the <span style="font-family: "courier new" , "courier" , monospace;">git push</span>, then delete the local project and re-clone the project as just above.</div>
<div>
<br /></div>
<div>
So once done you can check your local and remote projects are synced:</div>
<div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> git status</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> On branch Development</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> Your branch is up-to-date with 'origin/Development'.</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> <b>nothing to commit</b>, working directory clean</span></div>
</div>
<div>
<br /></div>
<div>
And git push should no more ask your ccredentials</div>
<div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> git push</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> Everything up-to-date</span></div>
</div>
<h3 style="text-align: left;">
</h3>
<h3 style="text-align: left;">
Getting remote changes down to your local version and "syncing a fork" (sounds weird, eh?)</h3>
<div>
It is easy to get the changes from <i>your</i> repository to another PC. First you must <i>clone</i> the repository the same way you did above to your other PC. Then when you want to download the changes that were pushed from elsewhere, just do this:</div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> git pull</span></div>
<div>
<br /></div>
<div>
But... this only gets the changes from <i>your own</i> repository, and not from the initial <i>upstream</i> repository. As usual git does not make it easy. Unless it is a one-time help you are giving to a project and you are OK to redo all the mess above months later, syncing with <i>upstream</i> is quite important. Otherwise and with time, your project will drift away from the "official" build to the point it will be much harder to get and merge the changes while dealing with increasing discrepancies and even <i>conflicts</i>. Submitting patches to the original authors will be even more difficult.</div>
<div>
<br /></div>
<div>
You first need to tell that your version should also look for changes from within the original project you forked from (the <i>upstream</i>).</div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
OK let us try to finalize our stuff so that it will also get the changes from the upstream.</div>
<div>
Get its original URL from github, and add it to the local copy this way:</div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> git remote add upstream https://github.com/MarlinFirmware/Marlin.git</span></div>
<div>
<br /></div>
<div>
Now we check all the repositories which changes will be taken from:</div>
<div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> git remote -v</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> origin git@github.com:MoonCactus/Marlin-JFR-features.git (fetch)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> origin git@github.com:MoonCactus/Marlin-JFR-features.git (push)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> upstream https://github.com/MarlinFirmware/Marlin.git (fetch)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> upstream https://github.com/MarlinFirmware/Marlin.git (push)</span></div>
</div>
<div>
<br /></div>
<div>
Now, to download specifically the changes that are made in the original repository into your repository, we need more obscure and brain-damaging commands:</div>
<div>
<br /></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> git fetch upstream</span></div>
<div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> From https://github.com/MarlinFirmware/Marlin</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> * [new branch] Development -> upstream/Development</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> * [new branch] revert-1350-Development -> upstream/revert-1350-Development</span></div>
</div>
<div>
<br /></div>
<div>
<b>Branches? Only monkeys need branches!</b></div>
<div>
<div>
<br /></div>
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiG_QV6lb0jn0u5Pi42daLqirc04M2H0bJi9kZQm1tJl7MaXftfyu_iKGkwku8mLdFbGKaXIpldqWsaJCx7CO8cr0Et3TKd_qItZdN43RJMW8MC6SXkywxX0dbnlYc5c1Om_DAlTrZZVqGo/s1600/git-typical-rebase.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiG_QV6lb0jn0u5Pi42daLqirc04M2H0bJi9kZQm1tJl7MaXftfyu_iKGkwku8mLdFbGKaXIpldqWsaJCx7CO8cr0Et3TKd_qItZdN43RJMW8MC6SXkywxX0dbnlYc5c1Om_DAlTrZZVqGo/s1600/git-typical-rebase.png" width="295" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Or... a <i>typical</i> hellish source code sharing system!<br />
From <a href="http://stackoverflow.com/a/25468472/2638860">this answer</a> at stackoverflow.</td></tr>
</tbody></table>
<div>
Branches allow a project to move on while a stable version of the sources is kept. This is mostly for safety and to "freeze" the state of a project in a "stable" state, where only bug fixes are made. New features are made only in a development or experimental branch. Then you "simply" switch between the development and production branches, according to the current work that need to be done (do not get confused!). Indeed, when you want to make it funnier, you can create many branches, give them obscure names and get changes from one withing another and so... But branches are another hellish topic, i.e. advanced uses of git that I do not need here (e.g. <a href="http://marklodato.github.io/visual-git-guide/index-en.html#merge">this post</a>).</div>
</div>
<div>
<br /></div>
<div>
Our own sub-project may not need branches... But the original project does have a few, so we need to deal with them a little bit at least.<br />
<br />
In our case, the branch named <span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">revert-1350-Development</span> looks enough dubious to me that I will not even go and try to get more information about it... I will assume the first one is the only useful one. Surprisingly, there is no "stable" or "production" branch for this project!</div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> git merge upstream/Development</span></div>
<div>
<br /></div>
<div>
If you need to deal with local branches, and not-yet committed changes, then you need to read about more <a href="https://help.github.com/articles/syncing-a-fork/">gory details</a> (drowning a spoon, oh no, syncing a fork).<br />
<br />
Or check this useful, short but comprehensive dynamic <a href="http://ndpsoftware.com/git-cheatsheet.html">cheat cheat</a>.</div>
<div>
<br />
<b><u>Note</u></b>: git comes with a very useful interactive tool based on a local web server (default is to use the light <a href="http://www.lighttpd.net/">lighttpd</a> that you may have to <span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">apt-get install lighttpd</span> first - but it runs also also with apache, see the git <a href="http://git-scm.com/docs/git-instaweb">reference here</a>). Just move to your repository and type <span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">git instaweb</span>. It will launch a web navigator, that lets you parse and compare branches and history in depth.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi9IKxuW6vWUAV1Hoz_bFUgm7leq8ySmPVi5ubpF3A_4lIyPwtxr9DnT4DZD62-1koJX38g8vA6jlDszUphT24cfv2ivC3Pmbwo-TkdhAnmHb1RK3pNCW-Jl427vhL5GWz-a9jBLWxA4goS/s1600/git_instaweb.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="336" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi9IKxuW6vWUAV1Hoz_bFUgm7leq8ySmPVi5ubpF3A_4lIyPwtxr9DnT4DZD62-1koJX38g8vA6jlDszUphT24cfv2ivC3Pmbwo-TkdhAnmHb1RK3pNCW-Jl427vhL5GWz-a9jBLWxA4goS/s1600/git_instaweb.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><b><a href="http://git-scm.com/docs/git-instaweb">git instaweb</a></b> is a very nice GUI to parse an existing repository!</td></tr>
</tbody></table>
<br /></div>
<div>
<h3>
Pull requests, aka submitting a change to the original authors... at last!</h3>
</div>
<div>
Everyone benefits from a project that is maintained in a good shape. This is also why there are often separate "stable" (even sometimes obsolete), and development branches. The stable branch ought to be fully functional, with only bug fixes pushed into it.</div>
<div>
<br /></div>
<div>
So, make sure your own stuff works well! Do not submit broken stuff to programmers or they will hate you :)</div>
<div>
<br /></div>
<div>
Also, make sure your new feature or bug fix is useful to others, and that it neither breaks something far far away in the original code source... or they will hate you alike.</div>
<div>
<br /></div>
<div>
You need also to comment it properly and follow the guidelines (code style and so). Anyway, your patch will probably be refused if it does not seem good enough for the maintainers! And they may also hate you ;)</div>
<div>
<br /></div>
<div>
So enough joking... the deal is to tell the maintainer that your branch has something new, that they can grab and integrate it in their own (upstream) repository. This is mostly why your changes should be minimal: be as close as possible to their latest versions before you submit your so-called <i>pull request</i>.</div>
<div>
<br /></div>
<div>
<br /></div>
<div>
Strangely, the pull request must be made from a web browser, not from the console.</div>
<div>
Actually here the official documentation is linear and easy to follow. May be this is because it moves a bit away from the overly complex guts of git into something much easier now (and I really am a console guy though!).</div>
<div>
<br /></div>
<div>
So the next steps is to <a href="https://help.github.com/articles/using-pull-requests/">ask the maintainers to integrate your change</a>. And this is made straightforward in the official documentation this time.</div>
<div>
<br /></div>
<div>
<br /></div>
<div>
> Still, feel free to ask when you want me to explain it further in this post !</div>
<div>
<br /></div>
<div>
I just hope this post could help a few developers to contribute to open source projects.</div>
<div>
<br /></div>
<div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: right;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj8bSKzKUtxSx2N21lc5PXLMwAX9Z8MeaTfrpN9_SMUZt_yqSl8HEdAfRJGpXlGZqK47Tnqqu0ulYJJh8DnC9xtaFleUHuSC0dYtazt-gnalR3NFRI0Rpy3uWN1tm70zQ46xEa65pUUdChU/s1600/git-fractals-sierpinski-5.png" imageanchor="1" style="clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj8bSKzKUtxSx2N21lc5PXLMwAX9Z8MeaTfrpN9_SMUZt_yqSl8HEdAfRJGpXlGZqK47Tnqqu0ulYJJh8DnC9xtaFleUHuSC0dYtazt-gnalR3NFRI0Rpy3uWN1tm70zQ46xEa65pUUdChU/s1600/git-fractals-sierpinski-5.png" width="379" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">A sierpinsky triangle... <a href="http://philippe.bruhat.net/stuff/git-fractals/sierpinski.html">made with git</a> by <a href="https://github.com/book">BooK</a> !</td></tr>
</tbody></table>
</div>
<h3 style="text-align: left;">
A word on merge and conflicts</h3>
<div style="text-align: left;">
While I did minor modifications to my pull request to match expectations, the master evolved. Which produced conflicts in a few files. So I had to tackle merging the two sets of changes.</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
Tell <span style="font-family: "courier new" , "courier" , monospace;">git</span> about your preferred comparison tool, which is the excellent <span style="font-family: "courier new" , "courier" , monospace;">meld</span> for me on Linux, that also does 3-way merge nicely:</div>
<div style="text-align: left;">
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> git config merge.tool meld</span></div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
Then to get up to date with the remote source:</div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> git fetch upstream</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> git checkout Development # may generate conflicts</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> git stash # in which case this saves your changes aside, see <a href="http://git-scm.com/book/en/v1/Git-Tools-Stashing">here</a></span><br />
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> git mergetool # open your interactive merging tool, to solve the conflict</span></div>
<div>
<br class="Apple-interchange-newline" />
Note that the file shown in the middle is the common ancestor to "theirs" and "ours". There is no need to change it as it is only included for reference and to better understand/solve the conflicts. So the deal here is to take bits from "theirs" (right file) and insert them in "ours", while not overriding our own new features.</div>
<div>
<br /></div>
<div>
Once the changes are merged/solved, you can commit the result and proceed:</div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> git commit</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> git merge upstream/Development</span></div>
<div>
<br /></div>
<div>
Now check the status of our version with <span style="font-family: "courier new" , "courier" , monospace;">git push</span>. In my case, I suspect that my editor removed spurious white spaces, and it resulted in 174 commits, but in fact it was the files and modifications that got added by the upstream into my own repository -- no harm!</div>
<div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> git status</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> On branch Development</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> Your branch is ahead of 'origin/Development' by 174 commits</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> (...)</span></div>
</div>
<div>
<br /></div>
<div>
But still, there were two configuration files I inadvertently pushed into my pull request, that I wanted to revert to the remote pristine "upstream" versions (i.e. drop all my own changes on them). I followed information from <a href="http://stackoverflow.com/questions/692246/undo-working-copy-modifications-of-one-file-in-git">this post</a>: (the easiest is to check the pull request file list in a browser, e.g. <a href="https://github.com/MarlinFirmware/Marlin/pull/1423/files">here</a>):</div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> git checkout upstream/Development -- Configuration_adv.h Configuration.h</span><br />
<div>
<br />
Had to do this for a few files (huh?):<br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> git reset HEAD Configuration_adv.h Configuration.h</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> git commit -a</span><br />
<br /></div>
</div>
<div>
And finally (had to <span style="font-family: "courier new" , "courier" , monospace;">git add</span> a few files btw):</div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> git push # publish your local commits</span></div>
<div>
<br />
Your "saved" differences are still there:<br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> git stash list</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> <i>stash@{0}: WIP on Development: 85e5aa4 Generalized enqueue_commands_P, and moved them to Marlin_main as they should</i></span></div>
<div>
<br />
<h3 style="text-align: left;">
OK, OK, let's use branches, then...</h3>
Actually I learnt the hard way that a pull request is a good time to create a new branch... This way, the existing work is "saved" in a known state (i.e. the pull request), if I ever it needs to be re-worked. And at the same time it makes it possible to move further in other developments:</div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> git checkout -b for_RMUD # weird name eh? but I know exactly what it means!</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> <i>Switched to a new branch 'for_RMUD'</i></span><br />
<br />
Here I created a new branch with a nice name (!) that will hold variations that are specific to my own needs, but that I do not want to commit to upstream. As shown, creating a branch sets you in by the way.<br />
<br />
So we can now apply the stashed changes we recorded in the previous paragraph:<br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> git stash apply stash@{0}</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"><i> Auto-merging Marlin/Marlin_main.cpp</i></span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"><i> Auto-merging Marlin/Marlin.h</i></span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"><i> Auto-merging Marlin/Configuration.h</i></span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"><i> CONFLICT (content): Merge conflict in Marlin/Configuration.h</i></span></div>
<div>
<br /></div>
<div>
When we get another conflict, we solve it again with <span style="font-family: "courier new" , "courier" , monospace;">git mergetool</span>, as previously.</div>
<h3 style="text-align: left;">
</h3>
<h3 style="text-align: left;">
</h3>
<h3 style="text-align: left;">
Addendum: add your own LCD controller menus in Marlin</h3>
<div>
Just clone the source code from https://github.com/MarlinFirmware/Marlin.git , then open ultralcd.cpp and to the function named lcd_prepare_menu() for example.</div>
<div>
<br /></div>
<div>
There you will see commands like this:</div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> MENU_ITEM(gcode, MSG_DISABLE_STEPPERS, PSTR("M84"));</span></div>
<div>
<br /></div>
<div>
This just adds a command named thanks to <span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">MSG_DISABLE_STEPPERS</span> (check the translation strings in the project files!), and that inserts the <span style="font-family: "courier new" , "courier" , monospace;">M84</span> command in the current buffer that is being processed.</div>
<div>
But the existing state of Marlin will not allow more than one command.</div>
<div>
<br /></div>
<div>
My Delta printer used M7XX commands to calibrate the level of its bed. These functions have since disappeared from Marlin (replaced by something else). But the full story was:</div>
<div>
<br /></div>
<div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> M702 ; reset the leveling bed values</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> G28 ; home</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> G1 X-77.94 Y-45 Z36 F8000 ; move above first corner</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> G4 S3 ; wait for 3 seconds</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> M701 P0 ; record first calibration point with the Z probe</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> G1 X77.94 Y-45 Z36 ; go to second calibration point</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> G4 S3 ; and so on...</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> M701 P1</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> G1 X0 Y90 Z36</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> G4 S3</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> M701 P2</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> M700 ; compute and store the leveling values</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> G1 X0 Y0 Z100 F8000</span></div>
</div>
<div>
<br /></div>
<div>
This was definitely not one unique g-code command... With the patch I have just <a href="https://github.com/MarlinFirmware/Marlin/pull/1423">submitted</a> I now write it this way:</div>
<div>
<br /></div>
<div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> MENU_ITEM(gcode, "Calibrate bed", PSTR("M702\nG28\nG1 X-77.94 Y-45 Z36 F8000\nG4 S3\nM701 P0\nG1 X77.94 Y-45 Z36\nG4 S3\nM701 P1\nG1 X0 Y90 Z36\nG4 S3\nM701 P2\nM700\nG1 X0 Y0 Z100 F8000"));</span></div>
<div>
<br /></div>
<div>
I also added a "hovering/spiral" triangular movement above all three corners to check that my bed is level. First pass is 1mm above bed, second pass is 0.3mm above bed, and slower:</div>
<div>
<br /></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> MENU_ITEM(gcode, "Check level", PSTR("G28\nG1 X0 Y0 Z1 F4000\nG1 X-77.94 Y-45 Z1\nG1 X77.94 Y-45\nG1 X0 Y90\nG1 X-77.94 Y-45\nG4 S2\nG1 X-77.94 Y-45 Z0.3 F2000\nG1 X-77.94 Y-45\nG1 X77.94 Y-45\nG1 X0 Y90\nG1 X-77.94 Y-45\nG1 X0 Y0 Z0"));</span></div>
<div>
<br /></div>
<div>
Finally three more commands, to insert or retract the filament:</div>
<div>
<br /></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> MENU_ITEM(gcode, "Retract filament", PSTR("M302\nM82\nG92 E0\nG1 F4000 E-800"));</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> MENU_ITEM(gcode, "Insert filament", PSTR("M302\nM82\nG92 E0\nG1 F4000 E60"));</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> MENU_ITEM(gcode, "Finalize filament", PSTR("G1 F4000 E790"));</span></div>
</div>
<div>
<br /></div>
<div>
Once done, you must run the Arduino IDE, open your modified Marlin project, rebuild and upload the firmware to your printer. And here it is, a nice and tailored firmware menu entry:</div>
<div>
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgxvm7UVIlp1ApPHxJnOCNNiZe31wrKTRieg2_UGi-OTng79QXc2f5IMuivvitZHazA1fbrO6HcCC7EEwT-AG37VMtQ40pTlc8hor5rlq7nVl8U1jHSU9nBv7UOqsd6mCMHyEtROrOs_cBB/s1600/2015-01-27+00.26.28.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="248" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgxvm7UVIlp1ApPHxJnOCNNiZe31wrKTRieg2_UGi-OTng79QXc2f5IMuivvitZHazA1fbrO6HcCC7EEwT-AG37VMtQ40pTlc8hor5rlq7nVl8U1jHSU9nBv7UOqsd6mCMHyEtROrOs_cBB/s1600/2015-01-27+00.26.28.jpg" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Improved menu entries in Marlin with multiple g-code commands.<br />
This is very useful to calibrate the bed of my Delta printer.</td></tr>
</tbody></table>
<div>
<br /></div>
<div>
Without the patch to Marlin, I had to save these to separate files on each of the SD cards I could use with the printer, or to send them over USB to the printer from a PC, which I do not like at all. Another solution would have been to write a dedicated command in <span style="font-family: "courier new" , "courier" , monospace;">ultralcd.c</span> and attach it to a menu entry.</div>
<div>
<br /></div>
<h3 style="text-align: left;">
What about Printrun custom buttons? Multi line commands support alike!</h3>
<div>
By the way, I used Pronterface a lot during the initial calibration of my printer. It has very convenient "custom buttons" but they suffer from the same limitation: you can only give them one g-code command!</div>
<div>
<br /></div>
<div>
In fact, copy/pasting a sequence of multiline commands does work, until you restart restart Pronterface since it then keeps only the first line. This was quite annoying because of the lng sequence I used to calibrate my printer.</div>
<div>
<br /></div>
<div>
It can be tweaked very easily, by adding the line in bold to the following function in <span style="font-family: "courier new" , "courier" , monospace;">printrun/pronsole.py</span>:</div>
<div>
<br /></div>
<div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> def precmd(self, line):</span></div>
</div>
<div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> <b>line= line.replace("|", "\n") # JFR allow multiline GCODE button</b></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> if line.upper().startswith("M114"):</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> self.userm114 += 1</span></div>
<div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> (...)</span></div>
</div>
</div>
<div>
<br /></div>
<div>
This way, custom buttons may hold "multiline" commands, by separating them with a "|" (pipe) in place of a newline "\n". This tricks lets Pronterface reload the buttons with no additional fix to its source code.<br />
<br />
<u>update</u>: oops. The <a href="https://github.com/kliment/Printrun/issues/616">author</a> just told me I could instead have used the "macro" option, and then have added a custom button that plays the macro. This also does keep the newlines unchanged. Still, it is a bit counter-intuitive that the custom button shall be restricted to a single command imho.</div>
<div>
<br /></div>
<div>
<i>And no, I will certainly NOT set up an entire github fork just for one single line of source code! :D</i></div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEitDrTEG3CK_xM2Xt6gIgQMUgn6yTy7q2Ugvg5hlKhr3fnJb7bcu977j-h-nB20Xm5bglsb0lKijthInDx6Kv0ucJS71CnJkoQJndSdvkR4x1XMyZ-CTQLm69ptWZes7R7r8JUaFsVI07x0/s1600/pronterface-mutiline-comannd_custom-buttons.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="360" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEitDrTEG3CK_xM2Xt6gIgQMUgn6yTy7q2Ugvg5hlKhr3fnJb7bcu977j-h-nB20Xm5bglsb0lKijthInDx6Kv0ucJS71CnJkoQJndSdvkR4x1XMyZ-CTQLm69ptWZes7R7r8JUaFsVI07x0/s1600/pronterface-mutiline-comannd_custom-buttons.jpg" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">This is a modified Pronterface that allows multiline gcode commands in the custom buttons!</td></tr>
</tbody></table>
<br />
<div>
<br /></div>
</div>
Jeremie Francoishttp://www.blogger.com/profile/02984201174566394892noreply@blogger.com0tag:blogger.com,1999:blog-3615478772815290200.post-25981541750677682562014-11-23T02:24:00.007+01:002020-11-08T12:48:25.330+01:00How to use Openscad (4): children and advanced topics<div dir="ltr" style="text-align: left;" trbidi="on">
<h3>
<span style="font-family: inherit;">Part 4/5: children, factorized placement and chained hulls</span></h3>
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; margin-left: 1em; text-align: right;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgfvVS1Ey-UfFCAXKPAzb7HQTk5HwWSlv3TBL66z2ujOXUw1t0-_KotFLNIMwXKLnOZDCLc6AVuBGQfc9iiRiAgcB4x9xHH7S_SjbboLVZPUvXdQ2W33rh0bed1n4I-mHC06lV3CGuUCVvK/s1600/gears_in_gears_planetary.png" style="clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" height="263" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgfvVS1Ey-UfFCAXKPAzb7HQTk5HwWSlv3TBL66z2ujOXUw1t0-_KotFLNIMwXKLnOZDCLc6AVuBGQfc9iiRiAgcB4x9xHH7S_SjbboLVZPUvXdQ2W33rh0bed1n4I-mHC06lV3CGuUCVvK/s1600/gears_in_gears_planetary.png" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Yes, it was made with Openscad and it is parametric!<br />
(extreme <a href="http://www.thingiverse.com/thing:264769">collaborative work</a>, picture by N.Goodger)</td></tr>
</tbody></table>
<div>
<a href="http://www.tridimake.com/2014/11/howto-openscad-iteration-extrusion.html">Previously</a> in this tutorial for the Openscad CAD software, we talked only about modules that behaved as <i>shapes</i>.</div>
<div>
<br /></div>
<div>
<br />
A powerful and often ignored feature of Openscad is that modules can also behave as if they were <i>operators</i>, exactly like the <span style="font-family: "courier new" , "courier" , monospace;">translate()</span>or <span style="font-family: "courier new" , "courier" , monospace;">color()</span> operators. They do not create shapes on their own, but they modify the subsequent commands.<br />
<br />
In Openscad, it is possible through the use of <b>children</b>. But first, let us create and discuss a bit about a common-case example.</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
<div>
<br />
<br />
<a name='more'></a><br />
This article is part of a longer serie:<br />
<ol>
<li><a href="http://www.tridimake.com/2014/09/how-to-use-openscad-tricks-and-tips-to.html"><span face=""arial" , "helvetica" , sans-serif">Introduction to constructive solid geometry with OpenSCAD</span></a></li>
<li><a href="http://www.tridimake.com/2014/09/howto-openscad-variables-modules-parametric-designs.html"><span face=""arial" , "helvetica" , sans-serif">Variables and modules for parametric designs</span></a></li>
<li><a href="http://www.tridimake.com/2014/11/howto-openscad-iteration-extrusion.html"><span face=""arial" , "helvetica" , sans-serif">Iteration, extrusion and useful parametrized CSG techniques</span></a></li>
<li><a href="http://www.tridimake.com/2014/11/how-to-use-openscad-4-children-and.html"><span face=""arial" , "helvetica" , sans-serif"><b>Children, factorized placement and chained hulls</b></span></a></li>
</ol>
<br />
<h3>
How can "negative" shapes extend outside of their module?</h3>
This is a common design problem with the constructive solid geometry paradigm.<br />
<br />
Let us consider a support for an electronic board. Each of the "pegs" is made of a cylinder, a bevel at the base, and a hollow cylinder for the screw. We conveniently put all these in a "peg" module.<br />
<br />
But we want the screws to go all through the support, which itself it added outside of the module...<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-pvgXvni9LBhO5biUnVFC_6w_apEAfvmFM6HQxZy8mIQZHaBLkM2awOs_ch8f1Ib2V3Z0JG6XjMwxdxRmeqQh6GsRkJjgaASWkb6DwEsyijVv8QWaVuRxKFJA2aOcOIbtvMuu9KnohoTH/s1600/pegs1.png" style="margin-left: auto; margin-right: auto;"><img border="0" height="331" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-pvgXvni9LBhO5biUnVFC_6w_apEAfvmFM6HQxZy8mIQZHaBLkM2awOs_ch8f1Ib2V3Z0JG6XjMwxdxRmeqQh6GsRkJjgaASWkb6DwEsyijVv8QWaVuRxKFJA2aOcOIbtvMuu9KnohoTH/s1600/pegs1.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="font-size: 13px;">Failed! The peg holes do not go through the blue plate...</td></tr>
</tbody></table>
Forget about the dimensions, we do not care here.<br />
<br />
As we have seen, it is a good practice to factorize the peg shapes into a module, and then to iterate four times on it, like this:<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;">screw_dist=40; // PCB hole spacing (square)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">height=10; // peg height</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">peg_d=20; // peg diameter</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">screw_d=10; // hole diameter</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">plate_th=1; // plate thickness</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">tol=0.05; // used for CSG subtraction/addition</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"></span><br />
<span style="font-family: "courier new" , "courier" , monospace;"></span>
<span style="background-color: #fce5cd; font-family: "courier new" , "courier" , monospace;">module one_peg()</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">{</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> difference()</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> {</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> union()</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> {</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> // main cylindrical body</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> cylinder(r=peg_d/2,h=height);</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> // with a tronconic base (bevel)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> cylinder(r1=peg_d/2+2,r2=peg_d/2,h=5);</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> }</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> translate([0,0,-</span><span style="font-family: "courier new" , "courier" , monospace;">tol</span><span style="font-family: "courier new" , "courier" , monospace;">]) // screw hole</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> cylinder(r=screw_d/2,h=height+2*tol); // through hole</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> }</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">}</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"></span><br />
<span style="font-family: "courier new" , "courier" , monospace;"></span><span style="font-family: "courier new" , "courier" , monospace;">// Helper module: centered cube on (X,Y) but not on Z, like cylinder</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">module centered_cube(size)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">{</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> translate([-size[0]/2, -size[1]/2, 0])</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> cube(size);</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">}</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"></span><br />
<span style="font-family: "courier new" , "courier" , monospace;"></span><span style="font-family: "courier new" , "courier" , monospace;">// Now call and build the four pegs</span><br />
<span style="background-color: #fce5cd; font-family: "courier new" , "courier" , monospace;">for(r=[0:90:359])</span><br />
<span style="background-color: #fce5cd; font-family: "courier new" , "courier" , monospace;"> rotate([0,0,r])</span><br />
<span style="background-color: #fce5cd; font-family: "courier new" , "courier" , monospace;"> translate([screw_dist/2,screw_dist/2,0])</span><br />
<span style="background-color: #fce5cd; font-family: "courier new" , "courier" , monospace;"> one_peg();</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"></span><br />
<span style="font-family: "courier new" , "courier" , monospace;"></span><span style="font-family: "courier new" , "courier" , monospace;">color([0,0,1])</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> translate([0,0,-</span><span style="font-family: "courier new" , "courier" , monospace;">plate_th</span><span style="font-family: "courier new" , "courier" , monospace;">])</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> centered_cube([</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> screw_dist+peg_d*2,</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> screw_dist+peg_d*2,</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> plate_th+tol]); // slightly higher to avoid gaps</span><br />
<div>
<br /></div>
<br />
But when we add the blue bottom plate, flush with the pegs, the holes are no more open!<br />
<br />
So how do we fix this?<br />
<br />
<br />
<br />
Making holes longer will not help, because they apply only to the shapes defined in the <span style="font-family: "courier new" , "courier" , monospace;">one_peg</span> module (i.e. only the cylinders and before the plate is added).<br />
<br />
A way out could be to take the negative (hollow) cylinder out of the module, and remove them to the union of the pegs and the plate. But it breaks the very idea of a module by sharing "internal" information with the outside (it crosses the module encapsulation). It also makes the source code not very readable and less parametric.<br />
<br />
Or the module itself could be written with a "positive" and "negative" version like this. The changes are <span style="background-color: #fce5cd;">highlighted</span>.<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;">screw_dist=40; // PCB hole spacing (square)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">height=10; // peg height</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">peg_d=20; // peg diameter</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">screw_d=10; // hole diameter</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">plate_th=1</span><span style="font-family: "courier new" , "courier" , monospace;">; // plate thickness</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">tol=0.05; // used for CSG subtraction/addition</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">module one_peg(<span style="background-color: #fce5cd;">positive_shape=true</span>)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">{</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> <span style="background-color: #fce5cd;">if(positive_shape)</span></span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> {</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> // main cylindrical body</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> cylinder(r=peg_d/2,h=height);</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> // with a tronconic base (bevel)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> cylinder(r1=peg_d/2+2,r2=peg_d/2,h=5);</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> }</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> <span style="background-color: #fce5cd;">else // "negative" shape (carve the inner peg cylinder)</span></span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> {</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> translate([0,0,-</span><span style="font-family: "courier new" , "courier" , monospace;">tol</span><span style="font-family: "courier new" , "courier" , monospace;"> -</span><span style="font-family: "courier new" , "courier" , monospace;">plate_th</span><span style="font-family: "courier new" , "courier" , monospace;">]) // screw hole</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> cylinder(r=screw_d/2,h=height+2*tol + </span><span style="font-family: "courier new" , "courier" , monospace;">plate_th</span><span style="font-family: "courier new" , "courier" , monospace;">); // hole</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> }</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">}</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">// Helper module: centered cube on (X,Y) but not on Z, like cylinder</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">module centered_cube(size)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">{</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> translate([-size[0]/2, -size[1]/2, 0])</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> cube(size);</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">}</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="background-color: #fce5cd; font-family: "courier new" , "courier" , monospace;">difference()</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">{</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> </span><span style="font-family: "courier new" , "courier" , monospace;">union()</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> {</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> // Now call and build the four pegs positive shapes (not carved)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> for(r=[0:90:359])</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> rotate([0,0,r])</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>translate([screw_dist/2,screw_dist/2,0])</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> one_peg(</span><span style="background-color: #fce5cd; font-family: "courier new" , "courier" , monospace;">positive_shape=true</span><span style="font-family: "courier new" , "courier" , monospace;">);</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;"> color([0,0,1])</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> translate([0,0,-plate_th])</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>centered_cube([</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> screw_dist+peg_d*2,</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> screw_dist+peg_d*2,</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> plate_th+tol]); // higher to avoid gaps with the pegs!</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> }</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="background-color: #fce5cd; font-family: "courier new" , "courier" , monospace;"> // And finally carve the pegs (all through the plate itself)</span><br />
<span style="background-color: #fce5cd; font-family: "courier new" , "courier" , monospace;"> for(r=[0:90:359]) // repeat the positioning</span><br />
<span style="background-color: #fce5cd; font-family: "courier new" , "courier" , monospace;"> rotate([0,0,r])</span><br />
<span style="background-color: #fce5cd; font-family: "courier new" , "courier" , monospace;"> translate([screw_dist/2,screw_dist/2,0])</span><br />
<span style="background-color: #fce5cd; font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>one_peg(positive_shape=false);</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">}</span><br />
<br />
Now there is something annoying: positioning the "positive" peg shapes and the "negative" peg shapes rely on fully duplicated code. This is bad.<br />
<br />
Indeed, any change in the positioning would need to be duplicated. Bug fixes also! Duplicating code adds uninteresting codelines and it is prone to bugs, because a bug fix may be forgotten as the programmer does not know where and how many times the code was duplicated. It soon becomes very hard to maintain and upgrade such a design!<br />
<br />
This is why I often use a "placement" module for the location of the pegs.<br />
<div>
<br /></div>
<br />
<h3 style="text-align: left;">
Referring to the children of a module: how it works</h3>
This is a somehow tricky but very powerful Openscad feature.<br />
<div>
It is not usually found in other languages, which may be the reason why it is too often overlooked by programmers who use openscad.</div>
<div>
<br /></div>
<div>
Now, it is extremely powerful as it makes the source code much cleaner, and it allows many optimizations.</div>
<br />
<div>
In practice, when you are in a module, Openscad creates two special variables for you, that refer to the shapes that are in the <i>scope</i> of the module when it gets used.</div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">children</span> - an vector that holds reference to each of shapes that are impacted by the module</div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">$children</span> holds the number of shapes that <i>follows</i> the module use</div>
<br />
To get an indivudual value of a vector in Openscad, you can use this syntax:<br />
<span style="font-family: "courier new" , "courier" , monospace;">children(i)</span><br />
<br />
Now, the first children of the module will start at index zero (not one!). So the last children really is <span style="font-family: "courier new" , "courier" , monospace;">children($children-1)</span>. Accessing the vector at index <span style="font-family: "courier new" , "courier" , monospace;">$children</span> is an error, just like trying to use a negative number. This is the norm in most of the programming languages when dealing with arrays: the first item is at index zero.<br />
<div>
<br /></div>
So what is a child now? It is any primitive or composed shape that appear right "under" the module call itself.<br />
<br />
Check the example below, where <span style="font-family: "courier new" , "courier" , monospace;">translate_children()</span> iterates on its children, so as to translate each of them on the X axis by a value which is proportional to their order of appearance, before "calling them":<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiU1k1WoXDvkcUzOAILf3Gj9yOLBRFBm7iigVfdt6KxvnmApG1N7fxsVr5trMdWAnqCwkQAs6Oxc0WMIfksFSnkvRxf8DamzEiQ4GlVkYWCilVeBAZFv3qrvtrY_RXenSCepaOFmVSq_GkK/s1600/children1.png" style="margin-left: auto; margin-right: auto;"><img border="0" height="280" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiU1k1WoXDvkcUzOAILf3Gj9yOLBRFBm7iigVfdt6KxvnmApG1N7fxsVr5trMdWAnqCwkQAs6Oxc0WMIfksFSnkvRxf8DamzEiQ4GlVkYWCilVeBAZFv3qrvtrY_RXenSCepaOFmVSq_GkK/s1600/children1.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Efficiently translating the "children" of a module proportionally to their order of appearance!</td></tr>
</tbody></table>
<br />
Now, a children really is a shape that is "just below" the module. In the following, the cube and the cylinder are seen from within the module as a single child object (which they really are!)<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiO7sObINoVM_ykSn6t-AY6NMzkV6wZ2fJJDAg7Cu0aPUqrGi4PlIP7ErFvEey2rFCCrMQV6M1pcBJMYpOI5dksztnPUzGWXvsu6na_JsjRdVWFElv3WyC3kjUdTe8ekseHjakMRstjdOIN/s1600/children2.png" style="margin-left: auto; margin-right: auto;"><img border="0" height="280" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiO7sObINoVM_ykSn6t-AY6NMzkV6wZ2fJJDAg7Cu0aPUqrGi4PlIP7ErFvEey2rFCCrMQV6M1pcBJMYpOI5dksztnPUzGWXvsu6na_JsjRdVWFElv3WyC3kjUdTe8ekseHjakMRstjdOIN/s1600/children2.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Children are really only at the top level withing a module!</td></tr>
</tbody></table>
For the same reason, the iteration below is also one single "unioned" object for the module. It does not see the individual sub-shapes!<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEilAUS_CrrxnqPx9leSeO0TTF0p6VTUtF-N7eb9eFqFsOAYWswNBz_AkAYavydKx7LlOhcSGycW-gnmTcf1TxthM-0x9yypbLn8QkzLd84R-qrObP4piPVuoWYN2ITIr0zSyYO0Km296j44/s1600/children3.png" style="margin-left: auto; margin-right: auto;"><img border="0" height="280" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEilAUS_CrrxnqPx9leSeO0TTF0p6VTUtF-N7eb9eFqFsOAYWswNBz_AkAYavydKx7LlOhcSGycW-gnmTcf1TxthM-0x9yypbLn8QkzLd84R-qrObP4piPVuoWYN2ITIr0zSyYO0Km296j44/s1600/children3.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Hence, the $children feature does not "see" the individual cubes either (they were merged beforehand)!</td></tr>
</tbody></table>
The last case occurs because <span style="font-family: "courier new" , "courier" , monospace;">for</span> does an implicit union on the items. This problem is highlighted by the weird but required <span style="font-family: "courier new" , "courier" , monospace;">intersection_for()</span> in the official <a href="http://en.wikibooks.org/wiki/OpenSCAD_User_Manual/The_OpenSCAD_Language#Intersection_For_Loop">documentation</a>, that will be of no help here though...<br />
<br />
<h3 style="text-align: left;">
A module as a positioning tool: using the <i>children</i> array</h3>
<br />
Back to our PCB holder... Thanks to Openscad's <span style="font-family: "courier new" , "courier" , monospace;">$children</span> feature, we now can <i>factorize both the duplication and the placement</i> of each of the four individual pegs. Here again the changes are <span style="background-color: #fce5cd;">highlighted</span> when compared to the previous source code.<br />
<br />
We do it this way:<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;">screw_dist=40; // PCB hole spacing (square)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">height=10; // peg height</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">peg_d=20; // peg diameter</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">screw_d=10; // hole diameter</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">tol=0.05; // used for CSG subtraction/addition</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">plate_th= 1;</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="background-color: #fce5cd; font-family: "courier new" , "courier" , monospace;">module peg_positions()</span><br />
<span style="background-color: #fce5cd; font-family: "courier new" , "courier" , monospace;">{</span><br />
<span style="background-color: #fce5cd; font-family: "courier new" , "courier" , monospace;"> for(r=[0:90:359]) // it will make 4 versions of the sub-shapes</span><br />
<span style="background-color: #fce5cd; font-family: "courier new" , "courier" , monospace;"> rotate([0,0,r])</span><br />
<span style="background-color: #fce5cd; font-family: "courier new" , "courier" , monospace;"> translate([screw_dist/2,screw_dist/2,0])</span><br />
<span style="background-color: #fce5cd; font-family: "courier new" , "courier" , monospace;"> {</span><br />
<span style="background-color: #fce5cd; font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>for(i=[0:$children-1])</span><br />
<span style="background-color: #fce5cd; font-family: "courier new" , "courier" , monospace;"> children(i); // do each of the shapes that come after us</span><br />
<span style="background-color: #fce5cd; font-family: "courier new" , "courier" , monospace;"> }</span><br />
<span style="background-color: #fce5cd; font-family: "courier new" , "courier" , monospace;">}</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">module one_peg(positive_shape=true)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">{</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> if(positive_shape)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> {</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> // main cylindrical body</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> cylinder(r=peg_d/2,h=height);</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> // with a tronconic base (bevel)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> cylinder(r1=peg_d/2+2,r2=peg_d/2,h=5);</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> }</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> else</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> {</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> translate([0,0,-</span><span style="font-family: "courier new" , "courier" , monospace;">tol</span><span style="font-family: "courier new" , "courier" , monospace;"> -</span><span style="font-family: "courier new" , "courier" , monospace;">plate_th</span><span style="font-family: "courier new" , "courier" , monospace;">]) // screw hole</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> cylinder(r=screw_d/2,h=height+2*tol + </span><span style="font-family: "courier new" , "courier" , monospace;">plate_th</span><span style="font-family: "courier new" , "courier" , monospace;">); // hole</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> }</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">}</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">// Helper module: centered cube on (X,Y) but not on Z, like cylinder</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">module centered_cube(size)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">{</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> translate([-size[0]/2, -size[1]/2, 0])</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> cube(size);</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">}</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">difference()</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">{</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> union()</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> {</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> // Now call and build the four pegs</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> <span style="background-color: #fce5cd;">peg_positions()</span></span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> one_peg(positive_shape=true);</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;"> color([0,0,1])</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> translate([0,0,-plate_th])</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> centered_cube([</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> screw_dist+peg_d*2,</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> screw_dist+peg_d*2,</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> plate_th+tol]); // higher to avoid gaps with the pegs!</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> }</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;"> </span><span style="background-color: #fce5cd; font-family: "courier new" , "courier" , monospace;">// And finally carve the pegs (all through the plate itself)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> <span style="background-color: #fce5cd;">peg_positions()</span></span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> one_peg(positive_shape=false);</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">}</span><br />
<br />
What happens here? The module <span style="font-family: "courier new" , "courier" , monospace;">peg_position()</span> does not create any shape on its own. Instead it does all the work to duplicate and position each of the pegs, and only then it refers to its own children to do something. We have a unique children here each time, a call to the <span style="font-family: "courier new" , "courier" , monospace;">one_peg()</span> module.<br />
<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhekAwpix7mYoMbrq-mIOlafMxSOwjZMaDkCkzZLO3nl-tqRii3IdUQ2C-psjaiWXYws8TgcSyu5RVfcqk8jsu3WzBHpYTgY5QO8L9o2zQT4O0k25eXs-k2Dp0kDF5AFVPBqbapJQn-_QWt/s1600/pegs_holed_with_openscad_children.png" style="margin-left: auto; margin-right: auto;"><img border="0" height="341" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhekAwpix7mYoMbrq-mIOlafMxSOwjZMaDkCkzZLO3nl-tqRii3IdUQ2C-psjaiWXYws8TgcSyu5RVfcqk8jsu3WzBHpYTgY5QO8L9o2zQT4O0k25eXs-k2Dp0kDF5AFVPBqbapJQn-_QWt/s1600/pegs_holed_with_openscad_children.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Here we are. Through-holes for the PCB pegs.</td></tr>
</tbody></table>
<br />
To conclude this part, we can merge everything in a single compact module, with an "action" argument. I generally do it this way:<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;">screw_dist=40; // PCB hole spacing (square)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">height=10; // peg height</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">peg_d=20; // peg diameter</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">screw_d=10; // hole diameter</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">tol=0.05; // used for CSG subtraction/addition</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">plate_th= 1;</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">module peg(action)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">{</span><br />
<span style="background-color: #fce5cd; font-family: "courier new" , "courier" , monospace;"> if(action=="position")</span><br />
<span style="background-color: #fce5cd; font-family: "courier new" , "courier" , monospace;"> {</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> for(r=[0:90:359])</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> rotate([0,0,r])</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>translate([screw_dist/2,screw_dist/2,0])</span><br />
<span style="background-color: #fce5cd;"><span class="Apple-tab-span" style="font-family: "courier new" , "courier" , monospace; white-space: pre;"> </span><span style="font-family: "courier new" , "courier" , monospace;">{</span></span><br />
<span style="background-color: #fce5cd; font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> for(i=[0:$children-1])</span><br />
<span style="background-color: #fce5cd; font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> children(i); // do the shapes that come after us!</span><br />
<span style="background-color: #fce5cd; font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>}</span><br />
<span style="background-color: #fce5cd; font-family: "courier new" , "courier" , monospace;"> }</span><br />
<span style="background-color: #fce5cd; font-family: "courier new" , "courier" , monospace;"> else if(action=="add")</span><br />
<span style="background-color: #fce5cd; font-family: "courier new" , "courier" , monospace;"> {</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> // main cylindrical body</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> cylinder(r=peg_d/2,h=height);</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> // with a tronconic base (bevel)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> cylinder(r1=peg_d/2+2,r2=peg_d/2,h=5);</span><br />
<span style="background-color: #fce5cd; font-family: "courier new" , "courier" , monospace;"> }</span><br />
<span style="background-color: #fce5cd; font-family: "courier new" , "courier" , monospace;"> else // "remove"</span><br />
<span style="background-color: #fce5cd; font-family: "courier new" , "courier" , monospace;"> {</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> translate([0,0,-tol -</span><span style="font-family: "courier new" , "courier" , monospace;">plate_th</span><span style="font-family: "courier new" , "courier" , monospace;">]) // screw hole</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> cylinder(r=screw_d/2,h=height+2*tol+</span><span style="font-family: "courier new" , "courier" , monospace;">plate_th</span><span style="font-family: "courier new" , "courier" , monospace;">); // through hole</span><br />
<span style="background-color: #fce5cd; font-family: "courier new" , "courier" , monospace;"> }</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">}</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">// Helper module: centered cube on (X,Y) but not on Z, like cylinder</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">module centered_cube(size)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">{</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> translate([-size[0]/2, -size[1]/2, 0])</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> cube(size);</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">}</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">difference()</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">{</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> union()</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> {</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> // Now call and build the four pegs</span><br />
<span style="background-color: #fce5cd; font-family: "courier new" , "courier" , monospace;"> peg("position")</span><br />
<span style="background-color: #fce5cd; font-family: "courier new" , "courier" , monospace;"> peg("add");</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;"> color([0,0,1])</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> translate([0,0,-plate_th])</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> centered_cube([</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> screw_dist+peg_d*2,</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> screw_dist+peg_d*2,</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> plate_th+tol]); // higher to avoid gaps with the pegs!</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> }</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="background-color: white;"><span style="font-family: "courier new" , "courier" , monospace;"> </span><span style="font-family: "courier new" , "courier" , monospace;">// And finally carve the pegs (all through the plate itself)</span></span><br />
<span style="background-color: #fce5cd; font-family: "courier new" , "courier" , monospace;"> peg("position")</span><br />
<span style="background-color: #fce5cd; font-family: "courier new" , "courier" , monospace;"> peg("remove");</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">}</span><br />
<br />
<br />
The result is a code which is much more readable, and more useful. Still one has to split the added shape and the subtracted shape, and it must be taken into account. The "remove" part must be positioned correctly in the CSG tree, after the plate is merged with the positive peg shapes.<br />
<br />
Now, whenever other shapes must be positioned relatively to the pegs, we can use the convenient <span style="font-family: "courier new" , "courier" , monospace;">peg("position")</span> module call, and group the shapes in a union that will be "preprocessed" by the module.<br />
<br />
<br /></div>
<div>
<h3 style="text-align: left;">
Another very useful use of children : "Serial hull", aka "chained hull"</h3>
<br />
Remember the wedge in our previous post? It was built out of "support walls" to intersect a torus and leave only a variable sector. We had to revert to sequence of pairs of convex hulls in order to create the appropriate (concave) final shape.<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhgsiK7u32kHCKFzCNoJVHxGC8sunHdTYse3MiQFpvmhy50DsDxFRI1JT8RxJUrfN5LqrRU8flmObREKhh9X8U-duehSnV4D5dujeaSGmtq2MicT4I8shjv64qYp_FRVisdhMDvEG4z9Rmf/s1600/wedge_any1.png" style="margin-left: auto; margin-right: auto;"><img border="0" height="134" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhgsiK7u32kHCKFzCNoJVHxGC8sunHdTYse3MiQFpvmhy50DsDxFRI1JT8RxJUrfN5LqrRU8flmObREKhh9X8U-duehSnV4D5dujeaSGmtq2MicT4I8shjv64qYp_FRVisdhMDvEG4z9Rmf/s1600/wedge_any1.png" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">The support structures we used to build a wedge shape that we used<br />
to intersect a torus made from a fully circular <span style="font-family: "courier new" , "courier" , monospace;">rotate_extrude()</span>.</td></tr>
</tbody></table>
<br />
The deal here would be to create a module that does the union of a sequence of hulls in a list of children. Let us call this special module "serial_hull( )".<br />
<br />
Calling it this way:</div>
<div>
<br /></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> serial_hull()</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> {</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> thin_wall1();</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> </span><span style="font-family: "courier new" , "courier" , monospace;">thin_wall</span><span style="font-family: "courier new" , "courier" , monospace;">2();</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> ...</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> thin_wall7();</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> }</span></div>
<div>
<br /></div>
<div>
...would create a convex hull of the shapes 1 and 2, then another hull with the shapes 2 and 3, and so. The resulting convex hulls would then be merged (with the default union operation).<br />
<br />
See how the union of many hulls is definitely <i>not</i> like the hull of all the shapes at once?</div>
<div>
<br /></div>
<div>
Using loops, it becomes straightforward to implement:<br />
<br /></div>
<span style="font-family: "courier new" , "courier" , monospace;"> module </span><span style="font-family: "courier new" , "courier" , monospace;">serial_hull</span><span style="font-family: "courier new" , "courier" , monospace;">()</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> {</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> // let i be the index of each of our</span><span style="font-family: "courier new" , "courier" , monospace;"> children, but the last one</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> for(i=[0:$children-2])</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> hull() </span><span style="font-family: "courier new" , "courier" , monospace;">// we then create a hull between child i and i+1</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> {</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> children(i);</span><span style="font-family: "courier new" , "courier" , monospace;"> </span><span style="font-family: "courier new" , "courier" , monospace;">// use child() in older versions of Openscad!</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> children(i+1); // this shape is i in the next iteration!</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> }</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> }</span><br />
<br />
<div>
Note that we can now join any kind of shapes:</div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> </span></div>
<span style="font-family: "courier new" , "courier" , monospace;"> </span><span style="font-family: "courier new" , "courier" , monospace;">serial_hull</span><span style="font-family: "courier new" , "courier" , monospace;">()</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> {</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> cube(10,center=true);</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> translate([20,0,0]) sphere(10);</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> translate([30,0,0]) sphere(5);</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> }</span><br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhxoq5KXhKBeOKSSwH0M9454Vwz_pQ2f0h9BCasCZPVaKIpebSL1cfEHUqZ-ntry7t6yW4F2wqMIJ0ql-MyLO34ZLc_F_UIbtl16WLqYj000QxcembPBhzxkikuVOSkLTjHLJuHQ9Jdnw5u/s1600/chain_hull.png" style="margin-left: auto; margin-right: auto;"><img border="0" height="313" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhxoq5KXhKBeOKSSwH0M9454Vwz_pQ2f0h9BCasCZPVaKIpebSL1cfEHUqZ-ntry7t6yW4F2wqMIJ0ql-MyLO34ZLc_F_UIbtl16WLqYj000QxcembPBhzxkikuVOSkLTjHLJuHQ9Jdnw5u/s1600/chain_hull.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="font-size: 13px;">Linking a cube, a large sphere, and a smaller one with a union of consecutive convex hulls, the pretty way!</td></tr>
</tbody></table>
<i><u><br class="Apple-interchange-newline" />Note</u></i>: if you are using an old version of Openscad you will have to use "child(index)" in place of "children(index)" (they just changed the name of the variable for more consistency).<br />
Reciprocally, you can use "child" is a newer version, but you will get a warning stating "DEPRECATED: child() will be removed in future releases. Use children() instead.".<br />
<div>
<br /></div>
<div>
<br /></div>
<h3 style="text-align: left;">
So will it help our parametric wedge, to build a partial "rotate extrude"?</h3>
<div>
<br /></div>
Now let us try and go back to our partial torus... It will fail if we try naively...<br />
<br />
Remember, we have seen the issue in the introduction to <span style="font-family: "courier new" , "courier" , monospace;">$children</span> above: the module sadly considers the <span style="font-family: "courier new" , "courier" , monospace;">for</span> loop on the <span style="font-family: "courier new" , "courier" , monospace;">wedge_wall()</span> as a single child, and not as separate shapes.<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;">module chained_hull()</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">{</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> for(i=[0:$children-2])</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> hull()</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> {</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> children(i);</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> children(i+1);</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> }</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">}</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span><span style="font-family: "courier new" , "courier" , monospace;">module wedge(angle, extent=100, height=100, center=true)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">{</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> module wedge_wall()</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> {</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> translate([0,0,(center==true ? -height/2 : 0)])</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>cube([extent,0.1,height]);</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> }</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span><span style="font-family: "courier new" , "courier" , monospace;"> <span style="background-color: #fce5cd;">chained_hull() // will this create consecutive hulls? NO!!</span></span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> {</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> for(r=[0:45:angle-1]) // implicit union of all the items!!</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> rotate([0,0,r])</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> wedge_wall();</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> rotate([0,0,angle]) // this is only the second child!</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> wedge_wall();</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> }</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">}</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span><span style="font-family: "courier new" , "courier" , monospace;">wedge(angle=270);</span><br />
<br />
<br />
In fact, and I would like to be corrected, I do not know how we could use <span style="font-family: "courier new" , "courier" , monospace;">$children</span> and "exploded" <span style="font-family: "courier new" , "courier" , monospace;">for</span> loops at the same time.<br />
<br />
<br />
So far, the most compact version I could make is to build the angular sector this way, where some thin walls may be stacked on each other at angle "angle" (no harm with respect to CSG manifold policies).<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;">module chained_hull()</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">{</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> for(i=[0:$children-2])</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> hull() // here we do it another way (without a secondary loop)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> {</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> children(i);</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> </span><span style="font-family: "courier new" , "courier" , monospace;">children</span><span style="font-family: "courier new" , "courier" , monospace;">(i+1);</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> }</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">}</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">module wedge(angle, extent=100, height=100, center=true)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">{</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> module wegde_if(sub)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> {</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> // Revert to angle zero in case the provided one "sub"</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> // exceeds the wedge maximum angular size "angle":</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> rotate([0,0,( <span style="background-color: #fce5cd;">angle>sub ? sub : angle)</span>])</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> translate([0,0,(center==true ? -height/2 : 0)])</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>cube([extent,0.1,height]);</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> }</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;"> chained_hull() // explicit children makes it work...</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> {</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> // Create the appropriate thin walls each 45° around Z</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> // They cannot be made with a "for" loop b/c of the implicit</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> // union it does, which would fail with the chained_hull()</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> wegde_if(0);</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> wegde_if(45);</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> wegde_if(45*1);</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> wegde_if(45*2); // wedge_if() "flattens" sections that are</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> wegde_if(45*3); // </span><span style="font-family: "courier new" , "courier" , monospace;">past the user-provided "angle", so only</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> wegde_if(45*4); // the right number of sections will be</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> wegde_if(45*5); // generated!</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> wegde_if(45*6);</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> wegde_if(45*7);</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> wegde_if(45*8); // this last one is "chopped" to "angle"</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> }</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">}</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">intersection()</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">{</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> rotate_extrude(convexity=10)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> translate([40,0,0])</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> circle(r=30);</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"># wedge(angle=240); // "hash sign" to see it as below!</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">}</span><br />
<div>
<br /></div>
<div>
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhz7xtCmvk8mDUYLK3-j_NTI6CEz2Cv3jd1ct8IVlxgKRiny8yHP0i7FQub398zRvsu-RvA9KybVXSCLpNjYqUcB0wi6hPWhDQUfzzdSKR2ch_qzTqqiGOU9IBRVR3KjSbQuzFpk8ny-PEJ/s1600/section_of_a_torus_final.png" style="margin-left: auto; margin-right: auto;"><img border="0" height="341" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhz7xtCmvk8mDUYLK3-j_NTI6CEz2Cv3jd1ct8IVlxgKRiny8yHP0i7FQub398zRvsu-RvA9KybVXSCLpNjYqUcB0wi6hPWhDQUfzzdSKR2ch_qzTqqiGOU9IBRVR3KjSbQuzFpk8ny-PEJ/s1600/section_of_a_torus_final.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">As can be seen, we eventually designed our partial but generic torus!</td></tr>
</tbody></table>
<br />
<h3 style="text-align: left;">
One last attempt to get rid of the manual repetitions: if/then readability issues</h3>
<br />
As usual there are numerous ways to achieve the same goal. We can use only convex wedges and decide either to <span style="font-family: "courier new" , "courier" , monospace;">intersect</span> or to <span style="font-family: "courier new" , "courier" , monospace;">subtract</span> it from the torus. This way we also can rely on for-loops to build the wedge and stay compatible with the <span style="font-family: "courier new" , "courier" , monospace;">chained_hull()</span>...<br />
<br />
But <span style="font-family: "courier new" , "courier" , monospace;">if/else</span> constructs are usually considered bad practice because they disrupt the CSG tree.<br />
Also, because of restrictions in the CSG algorithms, they cannot apply only to the <i>choice</i> of the operation (<span style="font-family: "courier new" , "courier" , monospace;">intersection</span> versus <span style="font-family: "courier new" , "courier" , monospace;">difference</span>), so as to keep a common "content".<br />
<br />
For example, the following is illegal. It will not compile:<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;">if(condition)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> intersection()</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">else</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> difference()</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">{</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> cube([100,100,100],center=true);</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> sphere(r=55);</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">}</span><br />
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
This is why using if/then does generally not help to keep the code factorized. It should be written like this, repeating the content twice :(<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;">if(condition)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> intersection()</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> {</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> cube([100,100,100],center=true);</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> sphere(r=55);</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> }</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">else</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> difference()</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> {</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> cube([100,100,100],center=true);</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> sphere(r=55);</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> }</span><br />
<br />
This is why I tend to favor the former use of valued conditionals like <span style="font-family: "courier new" , "courier" , monospace;">(test ? then_value : else_value)</span> where only <i>values</i> are changed and not the <i>operations</i>. There is a second reason in my opinion: it tends to be faster when rendering the design (probably because cache and optimization are more efficient on a static CSG tree).<br />
<br />
Anyhow, here is the variant with only convex wedges, which is nonetheless more parametric (there are no more "hand placed" thin walls at each 45°).<br />
By the way, we made the <span style="font-family: "courier new" , "courier" , monospace;">wedge_this</span> now a modifier on its own:<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;">module chained_hull()</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">{</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> for(i=[0:$children-2])</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> hull()</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> {</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> children(i);</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> children(i+1);</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> }</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">}</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">module wedge_this(angle, extent=100, height=100, center=true)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">{</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> module convex_wedge(a) // compact but works ONLY for a<=180°</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> {</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> translate([0,0,(center==true ? -height/2 : 0)])</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> chained_hull()</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> {</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>for(r=[0:45:a-1]) rotate([0,0,r]) cube([extent,0.1,height]);</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>rotate([0,0,a]) cube([extent,0.1,height]);</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> }</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> }</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;"> <span style="background-color: #fce5cd;">if(angle<=180)</span> // then intersect the wedge with the children</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> {</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> <span style="background-color: #fce5cd;">intersection()</span></span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> {</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> for(i=[0:$children-1]) children(i);</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> convex_wedge(angle);</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> }</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> }</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> else // else subtract the reciprocal wedge from the children</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> {</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> <span style="background-color: #fce5cd;">difference()</span></span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> {</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> for(i=[0:$children-1]) children(i); // union of the children</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> scale([1,-1,1]) convex_wedge(360-angle); // reciprocal wedge</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> }</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> }</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">}</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">// Usage example:</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">wedge_this(angle=265)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> rotate_extrude(convexity=10)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> translate([40,0,0])</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> circle(r=30);</span><br />
<div>
<br /></div>
<br />
I am not sure the if/then makes it more readable, but you just got more food to crunch! :)<br />
<br />
<br />
<h2 style="text-align: left;">
About these tutorials and a (temporary?) conclusion...</h2>
<br />
I wrote this introduction to Openscad to help people try and learn it in the first place, and from scratch. The order I presented the features may work as a step-by-step tutorial but they are probably very bad as a reference guide. Google may help bring back some parts, but once here I suggest that the best place to move forward is the <a href="http://en.wikibooks.org/wiki/OpenSCAD_User_Manual/The_OpenSCAD_Language">official and comprehensive documentation</a>. or just the short list of all <a href="http://www.openscad.org/cheatsheet/index.html">the functions and features</a> of the language. Update: see last paragraph for links.<br />
<br />
As we have just seen, keep in mind that there are always many different ways to design one object.<br />
<br />
But make sure you think about re-usability, parametric designs, and that you avoid pitfalls in the very first place. Because of lack of policies, there are just too many Openscad designs that are completely unusable... including some of my early ones, that I learnt the hard way. Parametric designs are a huge winner for 3D printers, because they let you tweak the tolerances easily with the reality of the first prototype. You need 0.2 mm more clearance? Openscad computes it all over again and you can print it again, it is amazingly efficient.<br />
<br />
Yes, Openscad is a very powerful tool to design 3D shapes. It is not interactive, but it is nonetheless one of the very best, free and ubiquitous tools to design semi-industrial parts, like 3D printer links. It is not well suited to artists because it lacks fundamental primitives likes bezier curves or splines (well, almost since <a href="https://www.youtube.com/watch?v=v8KHLpAYj6Q">they can be coded separately</a>), and no mouse will help you in the design process beyond rotating the part and zooming on it, and contrary to most of the heavy-loaded and often expensive CAD software.<br />
<br />
But this is why Openscad is a powerful tool also in my opinion: I do not have to learn and keep practicing hundreds of shortcuts in Blender to be able to design whatever I need. I mostly never had something I could not make with openscad, and this is also why I keep on falling back to it, even when I wish it had a few more features like bevels, local variables or "professional" output formats and dimensions.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgAJ7cWfLoT911V3z-gXYc1LQVye5y9B-o1mC7emWuPWrIhJgfr4mlg7DzNHTNAKc9MBDtKboDuXV6Dv1TBFR682a4Wjs8E1v-1dOH1lCrKYTQ4bLXs1YSU2guEMThslOSUr28cJ49DlbH5/s1600/openscad_ellipse.png" style="margin-left: auto; margin-right: auto;"><img border="0" height="244" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgAJ7cWfLoT911V3z-gXYc1LQVye5y9B-o1mC7emWuPWrIhJgfr4mlg7DzNHTNAKc9MBDtKboDuXV6Dv1TBFR682a4Wjs8E1v-1dOH1lCrKYTQ4bLXs1YSU2guEMThslOSUr28cJ49DlbH5/s640/openscad_ellipse.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">More features? Here is an example to make an ellipse() out of a function and thanks to polygon().<br />
The deal is to generate the pairs of [x,y] points oursleves, which opens many possibilities.</td></tr>
</tbody></table>
<br />
<i>Final note</i>: so why article #4 out of #5? OK, OK, I originally intended to write one more article related to a some features I left out here, like functions and <a href="http://eribuijs.blogspot.fr/2017/03/creating-complex-shapes-openscad.html">polygons</a> (<a href="https://www.youtube.com/watch?v=57tpSpBzXZY">video</a> here), command line invocation with pre-defined variables to automate the generation of parametric objects, animation (shaping with time such as in <a href="https://github.com/kevinsa5/cad/blob/master/bomber.scad">this script</a>), basic routines and tricks that I often use when designing complex shapes (e.g. <a href="https://www.thingiverse.com/thing:1929831">bezier curves</a>), or <a href="https://github.com/JustinSDK/lib-openscad">scripts</a>, including some that are useful to render the views (e.g. povray)...<br />
<br />
But as you can see, more and more people provide high quality advanced information on Openscad nowadays, so you have multiple links to follow from now on. Nonetheless, I still think about this elusive fifth page, years after I wrote this serie ;)<br />
<br />
Advanced libraries: <a href="https://github.com/Irev-Dev/Round-Anything">"Round-Anything"</a><br /><br />Primitives: <a href="https://github.com/nophead/NopSCADlib/blob/master/libtest.png">https://github.com/nophead/NopSCADlib/blob/master/libtest.png</a></div>
Jeremie Francoishttp://www.blogger.com/profile/02984201174566394892noreply@blogger.com0tag:blogger.com,1999:blog-3615478772815290200.post-31718965684204040462014-11-22T20:57:00.001+01:002015-12-28T11:43:41.545+01:00How to use Openscad (3): iterations, extrusions and more modularity!<div dir="ltr" style="text-align: left;" trbidi="on">
<h3>
<span style="font-family: inherit;">Part 3/5: iteration, extrusion and useful parametrized CSG techniques</span></h3>
<h3>
<span style="font-family: inherit;">Repeating shapes</span></h3>
<div>
<span style="font-family: inherit;">As we saw in the <a href="http://www.tridimake.com/2014/09/howto-openscad-variables-modules-parametric-designs.html">previous article</a>, repeating a shape by copy/pasting its Openscad definition is a bad practice. It increases the risk of mistakes just because of the slight changes that have to be made on each of the copies. </span><span style="font-family: inherit;">And any "regularity" should be factorized: let the computer do our work!</span><br />
<span style="font-family: inherit;"><br /></span>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhPun0RU8Bu8gz5JrOkKBtkYRplSsm-llLOojsFBfceW_K_I4eA8mlygHtl4TLLDScUFO5f03h_VcQXCFYBHO9M2VkL0nNQHChSCoQthWA7FY030Nwb4adTB6RSEDnXaN_RnPlzmXbSxdy6/s1600/ugly_hull.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="262" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhPun0RU8Bu8gz5JrOkKBtkYRplSsm-llLOojsFBfceW_K_I4eA8mlygHtl4TLLDScUFO5f03h_VcQXCFYBHO9M2VkL0nNQHChSCoQthWA7FY030Nwb4adTB6RSEDnXaN_RnPlzmXbSxdy6/s1600/ugly_hull.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="font-size: 13px;">The former way we built a (partially) rounded cube. Four copy/pastes? Boo!</td></tr>
</tbody></table>
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">See how the four columns really are all the same cylinder, where only the position changes? </span><span style="font-family: inherit;">This is where we can and we should use </span><b style="font-family: inherit;">loops</b><span style="font-family: inherit;"> instead. And once again there are different ways to do so.</span></div>
<div>
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;"></span><br />
<a name='more'></a><span style="font-family: inherit;"><br /></span>
This article is part of a longer serie:<br />
<ol>
<li><a href="http://www.tridimake.com/2014/09/how-to-use-openscad-tricks-and-tips-to.html"><span style="font-family: Arial, Helvetica, sans-serif;">Introduction to constructive solid geometry with OpenSCAD</span></a></li>
<li><a href="http://www.tridimake.com/2014/09/howto-openscad-variables-modules-parametric-designs.html"><span style="font-family: Arial, Helvetica, sans-serif;">Variables and modules for parametric designs</span></a></li>
<li><a href="http://www.tridimake.com/2014/11/howto-openscad-iteration-extrusion.html"><span style="font-family: Arial, Helvetica, sans-serif;"><b>Iteration, extrusion and useful parametrized CSG techniques</b></span></a></li>
<li><a href="http://www.tridimake.com/2014/11/how-to-use-openscad-4-children-and.html"><span style="font-family: Arial, Helvetica, sans-serif;">Children, factorized placement and chained hulls</span></a></li>
</ol>
<span style="font-family: inherit;"><br /></span></div>
<div>
<span style="font-family: inherit;">The "for( x = range ) block;" repeats the block once with <i>x</i> set to each of the given values in the <i>range</i>, just like if Openscad was automatically copy/pasting the command block.</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">Ranges may be a list of values, separated by a comma, like this (one loop within another loop):</span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> union()</span><br />
<span style="font-family: Courier New, Courier, monospace;"> {</span><br />
<span style="font-family: Courier New, Courier, monospace;"> for(x=[-10,+10])</span><span style="font-family: 'Courier New', Courier, monospace;"> // repeat the following with two variants for x</span><br />
<div>
</div>
<span style="font-family: 'Courier New', Courier, monospace;"> </span><span style="font-family: 'Courier New', Courier, monospace;"> </span><span style="font-family: 'Courier New', Courier, monospace;"> </span><span style="font-family: 'Courier New', Courier, monospace;"> </span><span style="font-family: 'Courier New', Courier, monospace;">{</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> for(y=[-10,+10]) </span><span style="font-family: 'Courier New', Courier, monospace;">// repeat again but this time for y</span><br />
<div>
<div>
</div>
<span style="font-family: 'Courier New', Courier, monospace;"> </span><span style="font-family: 'Courier New', Courier, monospace;"> </span><span style="font-family: 'Courier New', Courier, monospace;"> </span><span style="font-family: 'Courier New', Courier, monospace;"> </span><span style="font-family: 'Courier New', Courier, monospace;"> </span><span style="font-family: 'Courier New', Courier, monospace;"> </span><span style="font-family: 'Courier New', Courier, monospace;">{</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> translate([x,y,0])</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> cylinder(r=8,h=50, center=true);</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> </span><span style="font-family: 'Courier New', Courier, monospace;"> </span><span style="font-family: 'Courier New', Courier, monospace;"> </span><span style="font-family: 'Courier New', Courier, monospace;"> </span><span style="font-family: 'Courier New', Courier, monospace;"> </span><span style="font-family: 'Courier New', Courier, monospace;"> </span><span style="font-family: 'Courier New', Courier, monospace;">}</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> </span><span style="font-family: 'Courier New', Courier, monospace;"> </span><span style="font-family: 'Courier New', Courier, monospace;"> </span><span style="font-family: 'Courier New', Courier, monospace;"> </span><span style="font-family: 'Courier New', Courier, monospace;">}</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> // two more shapes</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"> cube([20,20+2*8,50], center=true);</span></div>
<span style="font-family: Courier New, Courier, monospace;"> cube([20+2*8,20,50], center=true);</span><br />
<span style="font-family: Courier New, Courier, monospace;"> }</span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<span style="font-family: inherit;">So what goes on here?</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">Openscad sets </span><span style="font-family: Courier New, Courier, monospace;">x</span><span style="font-family: inherit;"> to the first value of its range -10, then it does the same with </span><span style="font-family: Courier New, Courier, monospace;">y</span><span style="font-family: inherit;"> (to its first value, -10 also).</span><br />
<span style="font-family: inherit;">Then, within the inside </span><i style="font-family: inherit;">loop</i><span style="font-family: inherit;">, it does a translation to </span><span style="font-family: Courier New, Courier, monospace;">(x,y) </span><span style="font-family: inherit;">and adds a cylinder there.</span><br />
<span style="font-family: inherit;">Once done, it <i>loops</i> with the second value of y (it sets </span><span style="font-family: Courier New, Courier, monospace;">y</span><span style="font-family: inherit;"> to +10), and adds another cylinder at (-10,10).</span><br />
<span style="font-family: inherit;">When it reaches the end of the y range, it <i>loops </i>on x next time, with </span><span style="font-family: Courier New, Courier, monospace;">x</span><span style="font-family: inherit;">=+10 and so it does again a loop on </span><span style="font-family: Courier New, Courier, monospace;">y</span><span style="font-family: inherit;">=-10 and again with </span><span style="font-family: Courier New, Courier, monospace;">y</span><span style="font-family: inherit;">=+10.</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">Overall, the inner cylinder will be created once for each of the four locations! Hence t</span><span style="font-family: inherit;">he result looks like exactly like previously, but <i>without the repeated code</i>.</span></div>
<div>
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">This writing is more compact, and it helps to convert the source code to a more compact and parametric version: indeed, </span><span style="font-family: inherit;">the size and roundness can easily be made variable now, and be set once at the beginning.</span><br />
<span style="font-family: inherit;"><br /></span><span style="font-family: inherit;">I would write it this way, to minimize the presence of the <i>hardcoded</i> value "10". The idea really is to put 4 cylinders around the vertical axis at the same distance. This distance should be seen only once for more readability and easier parametrization.</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;"> See how the remaining of the code becomes both generic and more readable with these refinements?</span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"> // Parameters</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> size=20;</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"> roundness=8;</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"> height=50;</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> // Shapes</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"> union()</span></div>
<div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> {</span><br />
<span style="font-family: Courier New, Courier, monospace;"> for(x=[-1,+1])</span><br />
<div>
<span style="font-family: Courier New, Courier, monospace;"> for(y=[-1,+1])</span><br />
<span style="font-family: Courier New, Courier, monospace;"> translate([x*</span><span style="font-family: 'Courier New', Courier, monospace;">size/2</span><span style="font-family: Courier New, Courier, monospace;">,y*</span><span style="font-family: 'Courier New', Courier, monospace;">size</span><span style="font-family: 'Courier New', Courier, monospace;">/2</span><span style="font-family: 'Courier New', Courier, monospace;">,0])</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> cylinder(r=</span><span style="font-family: 'Courier New', Courier, monospace;">roundness</span><span style="font-family: 'Courier New', Courier, monospace;">,h=</span><span style="font-family: 'Courier New', Courier, monospace;">height</span><span style="font-family: 'Courier New', Courier, monospace;">, center=true);</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"> cube([</span><span style="font-family: 'Courier New', Courier, monospace;">size</span><span style="font-family: 'Courier New', Courier, monospace;">, </span><span style="font-family: 'Courier New', Courier, monospace;">size</span><span style="font-family: 'Courier New', Courier, monospace;">+2*</span><span style="font-family: 'Courier New', Courier, monospace;">roundness</span><span style="font-family: 'Courier New', Courier, monospace;">, </span><span style="font-family: 'Courier New', Courier, monospace;">height</span><span style="font-family: 'Courier New', Courier, monospace;">], center=true);</span></div>
<span style="font-family: Courier New, Courier, monospace;"> cube([size + 2*</span><span style="font-family: 'Courier New', Courier, monospace;">roundness</span><span style="font-family: Courier New, Courier, monospace;">, size, </span><span style="font-family: 'Courier New', Courier, monospace;">height</span><span style="font-family: Courier New, Courier, monospace;">], center=true);</span><br />
<span style="font-family: Courier New, Courier, monospace;"> }</span></div>
<div>
<br /></div>
</div>
<div>
<span style="font-family: inherit;"><br /></span>
We already used vectors when specifying the three X,Y,Z arguments used to define cubes or translations for example. These are just vectors of 3 values. Note how they can be stored themselves in variables:<br />
<br />
<span style="font-family: Courier New, Courier, monospace;"> cube_size=[20,10,5]; // a triplet, aka 3-item vector stored</span><br />
<span style="font-family: Courier New, Courier, monospace;"> cube(cube_size); // ...in a variable, used to create a cube!</span><br />
<br />
The "for" loops handle vectors of any size like <span style="font-family: Courier New, Courier, monospace;">[v1,v2,v3,v4]</span>, but we can benefit from a few additional variations, in order to<span style="font-family: inherit;"> improve the 4-cylinder example further.</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">Less code almost always means less bugs: a <i>range</i> can be specified as a list of values as above, but it can also be defined by a </span><span style="font-family: Courier New, Courier, monospace;">[start:step:stop]</span><span style="font-family: inherit;"> triplet. This is done below, where </span><span style="font-family: Courier New, Courier, monospace;">r</span><span style="font-family: inherit;"> is set in turn to 0, then 90, and finally 180. We stop "at" 359°, i.e. before reaching 360° as it would be at the exact same place as 0° (and hence it would create a second, useless, cylinder there).</span><br />
<span style="font-family: inherit;"><br /></span><span style="font-family: inherit;">To do so, we use variable "r" to rotate around the Z axis below. Then, the column seemingly positioned at (10,10) is in fact "rotated" to each of the four symmetrical points around the (0,0) central axis.</span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> </span><span style="font-family: 'Courier New', Courier, monospace;">size=20;</span><br />
<div>
<span style="font-family: 'Courier New', Courier, monospace;"> roundness=8;</span></div>
<span style="font-family: 'Courier New', Courier, monospace;"> height=50;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> union()</span><br />
<span style="font-family: Courier New, Courier, monospace;"> {</span><br />
<span style="font-family: Courier New, Courier, monospace;"> for(r=[0:90:359]) // stop *before* 360° (as 360°=0°)</span><br />
<span style="font-family: Courier New, Courier, monospace;"> rotate([0,0,r])</span><br />
<div>
<span style="font-family: 'Courier New', Courier, monospace;"> translate([</span><span style="font-family: 'Courier New', Courier, monospace;">size/2</span><span style="font-family: 'Courier New', Courier, monospace;">,</span><span style="font-family: 'Courier New', Courier, monospace;">size/2</span><span style="font-family: 'Courier New', Courier, monospace;">,0])</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> cylinder(r=8,h=</span><span style="font-family: 'Courier New', Courier, monospace;">height</span><span style="font-family: 'Courier New', Courier, monospace;">, center=true);</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> // same technique for the "inside" cuboids:</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> for(r=[0,90])</span><br />
<span style="font-family: Courier New, Courier, monospace;"> rotate([0,0,r])</span><br />
<div>
</div>
<span style="font-family: 'Courier New', Courier, monospace;"> </span><span style="font-family: 'Courier New', Courier, monospace;">cube([</span><span style="font-family: 'Courier New', Courier, monospace;">size</span><span style="font-family: 'Courier New', Courier, monospace;">, </span><span style="font-family: 'Courier New', Courier, monospace;">size</span><span style="font-family: 'Courier New', Courier, monospace;">+2*</span><span style="font-family: 'Courier New', Courier, monospace;">roundness</span><span style="font-family: 'Courier New', Courier, monospace;">, </span><span style="font-family: 'Courier New', Courier, monospace;">height</span><span style="font-family: 'Courier New', Courier, monospace;">], center=true);</span></div>
<br />
<span style="font-family: 'Courier New', Courier, monospace;"> }</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
</div>
There are still other ways to create the same design (eg. by intersections, and so).<br />
<br />
I tend to prefer either rotation, or inverted axes (with the scale operator and -1 on some axes). Actually, translating as we did above is probably not the wisest choice, because it does not change the "orientation" of the duplicated object itself. No biggie for a rotation-invariant cylinder, but you see below the issue with a shape that is no more a cylinder.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhN1nxuXPhaMAUDpmRqtbUbXMcrMclO5Qhd596ppvGCTSHSK7-bdYAzcr0hatqtvvLxPeQ8fOUjoGR9ERUA-YIV6L4icS0RoyuPSwZb5dFaeVvCHDRMwEu552t-IlJ_V-6gWjqS-HoxKOIm/s1600/spike1.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="260" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhN1nxuXPhaMAUDpmRqtbUbXMcrMclO5Qhd596ppvGCTSHSK7-bdYAzcr0hatqtvvLxPeQ8fOUjoGR9ERUA-YIV6L4icS0RoyuPSwZb5dFaeVvCHDRMwEu552t-IlJ_V-6gWjqS-HoxKOIm/s1600/spike1.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Translations will keep the same orientation for the four parts!</td></tr>
</tbody></table>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgEnVCtFcfbpj_DHinQZkXiOlJZ59QKWcMTBah2v4Gkm2ZvzNU4FnymRzfHMP9aUxJFr303dNOKYnaOXs40W8Q-FoVu1ZVwWV35XMx5B14w3hDmwpmI10HPGkY5R9UIQEmUsjacy3lzxcZM/s1600/spike2.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="260" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgEnVCtFcfbpj_DHinQZkXiOlJZ59QKWcMTBah2v4Gkm2ZvzNU4FnymRzfHMP9aUxJFr303dNOKYnaOXs40W8Q-FoVu1ZVwWV35XMx5B14w3hDmwpmI10HPGkY5R9UIQEmUsjacy3lzxcZM/s1600/spike2.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Rotation is often preferred as it also "fixes" the orientation of the duplicated part.</td></tr>
</tbody></table>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgPaNLPKiTlyPkPynWb743Y9m69JWr3Teps5lN5eaiqSnLiKl9GbMJgyMNKBLw5Sa2fpaTVRUBu_Ckrmp4rPZV9mrk74mS71CuIE1z30JRyGqB6uNIj6Yi4I_b20M1WZBjMP6A5eSDyRVXL/s1600/spike3.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="260" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgPaNLPKiTlyPkPynWb743Y9m69JWr3Teps5lN5eaiqSnLiKl9GbMJgyMNKBLw5Sa2fpaTVRUBu_Ckrmp4rPZV9mrk74mS71CuIE1z30JRyGqB6uNIj6Yi4I_b20M1WZBjMP6A5eSDyRVXL/s1600/spike3.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">But scaling operators also are useful to invert axes (click to see the code).</td></tr>
</tbody></table>
<h4 style="text-align: left;">
A note on the <i>scope</i> of the variable:</h4>
If you recall, we use curly brackets to group items together, so that a modifier like <span style="font-family: 'Courier New', Courier, monospace;">translate</span> shifts more than only the objects that follows immediately.<br />
<br />
You must also keep this in mind with <span style="font-family: 'Courier New', Courier, monospace;">for</span> loops. The loop variable (like <span style="font-family: 'Courier New', Courier, monospace;">r,x,y</span> above) are usable only within the so-called "scope" of the loop, which is "below" in the hierarchy. No problem when <i>only one operation</i> follows, as in the former cascade of loops.<br />
But as soon as you need more than one command, you need to use braces:<br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">// The following is OK:</span><br />
<span style="font-family: Courier New, Courier, monospace;">for(t=[0:10:100])</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> cylinder(r=t,h=t); // concentric cylinders depends on "t"</span><br />
<div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"></span></div>
</div>
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: 'Courier New', Courier, monospace;">// But let us say you need to see "t" successive values</span><br />
<span style="font-family: Courier New, Courier, monospace;">for(t=[0:10:100])</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> echo(t); // print the value in the console</span><br />
<div>
<span style="font-family: 'Courier New', Courier, monospace;"> cylinder(r=t,h=t); // wrong!</span><br />
<div>
<span style="font-family: 'Courier New', Courier, monospace;"><br class="Apple-interchange-newline" />// It failed because openscad ignores b</span><span style="font-family: 'Courier New', Courier, monospace;">lanks and indentation.</span><br />
<span style="font-family: 'Courier New', Courier, monospace;">// So it read</span><span style="font-family: 'Courier New', Courier, monospace;"> it as if you had written it like this:</span><br />
<span style="font-family: 'Courier New', Courier, monospace;">for(t=[0:10:100])</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> echo(t); // print the variable in the console</span><br />
<span style="font-family: 'Courier New', Courier, monospace;">cylinder(r=t,h=t); // fails! "t" is unknown at this stage.</span></div>
</div>
<div>
<br />
<span style="font-family: 'Courier New', Courier, monospace;">// Use curly brackets to specify the loop content:</span><br />
<span style="font-family: Courier New, Courier, monospace;">for(t=[0:10:100])</span><br />
<span style="font-family: Courier New, Courier, monospace;">{</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> echo(t); // print the value in the console</span><br />
<div>
<span style="font-family: 'Courier New', Courier, monospace;"> cylinder(r=t,h=t); // now OK !</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> // "t" is usable only in the *scope* of the for loop!</span><br />
<div>
</div>
</div>
<span style="font-family: 'Courier New', Courier, monospace;">}</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"><br /></span></div>
Some seasoned programmers use braces all the time, even when they are unneeded. It makes the source code a little longer, but it makes it more consistent. More importantly in my opinion, it lets you add statements later on, without the need to alter existing code -- like the <span style="font-family: 'Courier New', Courier, monospace;">echo</span> above.<br />
<br />
<h3>
Recursive designs, and conditionals</h3>
Only the latest version of Openscad made recursion possible. Previously, variables had the amazing property that they were ... <i>constant</i>! Advanced operators like "assign( )" helped circumvent some of the issues, but they made the source code even worse in my opinion.<br />
<br />
What is recursion? Well, it happens when a module calls <i>itself</i> in order to build more versions of its own shape, smaller or in another place. To avoid looping indefinitely (and killing the computer memory and CPU), we must also introduce conditionals. A <i>test</i> will be made to stop calling ourselves after some condition is met, e.g. like when the part becomes too small.<br />
<br />
Remember the mug-with-a-cup that we made in <a href="http://www.tridimake.com/2014/09/howto-openscad-variables-modules-parametric-designs.html">part two</a>? Here is how we can write a recursive mug, that will add smaller-mugs-in-mugs till it get smaller than the constant wall width. It would not make any sense to go "deeper" in the recursion anyhow.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiONE3Km9V5We048-Akzj70esh49hlRe4rHHxKesZNIw-LGTYZnvidFm3EoNn2kiLqJwHeRIhA0K3sjY7C_VSnGbSsYbolV3cIWbcQ4VhgJgyUB7u9Ry1Z6X6IGcs-8woIa5IprdUQd0ZEk/s1600/recursion.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="203" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiONE3Km9V5We048-Akzj70esh49hlRe4rHHxKesZNIw-LGTYZnvidFm3EoNn2kiLqJwHeRIhA0K3sjY7C_VSnGbSsYbolV3cIWbcQ4VhgJgyUB7u9Ry1Z6X6IGcs-8woIa5IprdUQd0ZEk/s1600/recursion.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">A recursive mug. Make sure you have a version of Openscad that allows this<br />
(an indicator is that the syntax is now colored: another long-waited for feature!)</td></tr>
</tbody></table>
By the way, you see also the use of the "color" operator, that highlights each of the sub-mugs. The color components were chosen according to the size of the mug, so we get an automatic color gradient whatever the depth of the recursion.<br />
<br />
<div style="margin: 0px;">
<div style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;">
<!--StartFragment--><span style="font-family: Courier New, Courier, monospace;"> module mug(width, height, bottom_thickness=2, wall_thickness=5)</span></div>
<div style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;">
<span style="font-family: Courier New, Courier, monospace;"> {</span></div>
<div style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;">
<span style="font-family: Courier New, Courier, monospace;"> r_of_inside=width/2-wall_thickness;</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> echo(width); // print the value in the console</span></div>
<div style="-qt-block-indent: 0; -qt-paragraph-type: empty; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;">
<span style="font-family: Courier New, Courier, monospace;"> </span></div>
<div style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;">
<span style="font-family: Courier New, Courier, monospace;"> color([abs(cos(width)),abs(sin(width)),1]) // color with size</span></div>
<div style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;">
<span style="font-family: Courier New, Courier, monospace;"> {</span></div>
<div style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;">
<span style="font-family: Courier New, Courier, monospace;"> difference()</span></div>
<div style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;">
<span style="font-family: Courier New, Courier, monospace;"> {</span></div>
<div style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;">
<span style="font-family: Courier New, Courier, monospace;"> translate([0,0,height/2])</span></div>
<div style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;">
<span style="font-family: Courier New, Courier, monospace;"> intersection()</span></div>
<div style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;">
<span style="font-family: Courier New, Courier, monospace;"> {</span></div>
<div style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;">
<span style="font-family: Courier New, Courier, monospace;"> cube([width,width,height], center=true);</span></div>
<div style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;">
<span style="font-family: Courier New, Courier, monospace;"> scale([1,1,height/width])</span></div>
<div style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;">
<span style="font-family: Courier New, Courier, monospace;"> sphere(width/2 * sqrt(2));</span></div>
<div style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;">
<span style="font-family: Courier New, Courier, monospace;"> }</span></div>
<div style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;">
<span style="font-family: Courier New, Courier, monospace;"> translate([0,0,bottom_thickness])</span></div>
<div style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;">
<span style="font-family: Courier New, Courier, monospace;"> cylinder(r=r_of_inside,h=height+0.1);</span></div>
<div style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;">
<span style="font-family: Courier New, Courier, monospace;"> }</span></div>
<div style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;">
<span style="font-family: Courier New, Courier, monospace;"> }</span><br />
<span style="font-family: Courier New, Courier, monospace;"> // At this stage we are back to the default union() behavior</span></div>
<div style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;">
</div>
<div style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;">
<span style="font-family: Courier New, Courier, monospace;"> if(width > wall_thickness*2) </span><span style="font-family: 'Courier New', Courier, monospace;">// only if there is room!</span></div>
<div style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;">
<span style="font-family: Courier New, Courier, monospace;"> mug(width/2, height+width/5); // </span><span style="font-family: 'Courier New', Courier, monospace;">add a smaller mug here</span></div>
<div style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;">
<span style="font-family: Courier New, Courier, monospace;"> }</span></div>
<div style="-qt-block-indent: 0; -qt-paragraph-type: empty; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;">
<br /></div>
<span style="font-family: Courier New, Courier, monospace;"> mug(width=100,height=60); // calling the top object</span><!--EndFragment--></div>
<div style="margin: 0px;">
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: inherit;">If you still get only one mug, check the console for an error like "</span>WARNING: Ignoring recursive module instanciation of 'difference'.". This would tell that your version of Openscad does not support recursion and that you should probably upgrade. In the "Help / About" menu, check that the version is more recent than the 2014.01.29 (e.g. the 2014.04.02 as above).<br />
<br />
<br />
Also the generated sizes are now harder to track, so we used the <b>echo</b> command to show how to get the value of width each time the module is called:<br />
<br />
<span style="font-family: Courier New, Courier, monospace;"> echo(width);</span><br />
<br />
After you refresh the design, the console dumps the following:<br />
<div style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;">
<!--StartFragment--><span style="font-family: Courier New, Courier, monospace;"> ECHO: 100</span></div>
<div style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;">
<span style="font-family: Courier New, Courier, monospace;"> ECHO: 50</span></div>
<div style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;">
<span style="font-family: Courier New, Courier, monospace;"> ECHO: 25</span></div>
<div style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;">
<span style="font-family: Courier New, Courier, monospace;"> ECHO: 12.5</span></div>
<br />
<span style="font-family: Courier New, Courier, monospace;"> ECHO: 6.25</span><!--EndFragment--><br />
<br />
<br />
<i><u>Important note</u></i>: the very weird properties of <i>variables</i> in Openscad will not be discussed here. Even though recursion was recently allowed and not discussed in the following document, I highly suggest reading this detailed <a href="https://docs.google.com/file/d/0B2JeabMAGYGqakE2dS0tUVc3Rnc/edit">presentation</a> of variables when you need it, written by <a class="g-profile" href="https://plus.google.com/101448691399929440302" target="_blank">+Stephanie Shaltes</a>. By the way, she regularly posts about advanced subjects in Openscad so she may be interesting to follow on G+.<br />
<div>
<br /></div>
</div>
<h3>
Advanced concepts</h3>
The <b>minkowski</b> operator is quite cool. But it is so slow that we almost never use it. The effect is like when a shape is used to paint or "brush" a parent shape: e.g. a small sphere will "round" all the edges and surfaces of a given reference object.<br />
<br />
Shown below is an example where we use only 2D shapes, that Openscad also supports (we then use <span style="font-family: Courier New, Courier, monospace;">square</span> in place of <span style="font-family: Courier New, Courier, monospace;">cube</span>, <span style="font-family: Courier New, Courier, monospace;">circle</span> for <span style="font-family: Courier New, Courier, monospace;">spheres</span> and so).<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgRp3cap9I6SucP9DvG4rNfgVNrhFwXF9PX8PPLxHIn97iSuF_MG5rairqujWWUK5j5sfWwMY0N7x38Vfa4eoPZ1HgdWBXHuh8HOsSIbd3hVsn8pLMScGhvK3e2iPOYguPFmk_GEOlzKOwI/s1600/minkowski.gif" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="196" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgRp3cap9I6SucP9DvG4rNfgVNrhFwXF9PX8PPLxHIn97iSuF_MG5rairqujWWUK5j5sfWwMY0N7x38Vfa4eoPZ1HgdWBXHuh8HOsSIbd3hVsn8pLMScGhvK3e2iPOYguPFmk_GEOlzKOwI/s1600/minkowski.gif" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="font-size: 13px;">The minkowski operator, illustrated here on 2D Openscad shapes.<br />
It does works in 3D also but is so slow that the shape is usually better designed otherwise.</td></tr>
</tbody></table>
<br />
More importantly, there are also two kinds of <b>extrusions</b>, linear and circular, that makes 3D shapes out of 2D shapes.<br />
<br />
They are very useful to create 3D shapes out of "industrial" 2D designs (often based on the <a href="http://en.wikipedia.org/wiki/AutoCAD_DXF">Autocad </a><a href="http://en.wikipedia.org/wiki/AutoCAD_DXF">DXF</a> file format that Openscad knows how to import).<br />
<br />
Here we will "raise" our former 2D shape vertically and make it a 3D shape, here is what we write:<br />
<br />
<span style="font-family: Courier New, Courier, monospace;"> linear_extrude(height=30)</span><br />
<span style="font-family: Courier New, Courier, monospace;"> {</span><br />
<span style="font-family: Courier New, Courier, monospace;"> minkowski()</span><br />
<span style="font-family: Courier New, Courier, monospace;"> {</span><br />
<span style="font-family: Courier New, Courier, monospace;"> union()</span><br />
<span style="font-family: Courier New, Courier, monospace;"> {</span><br />
<span style="font-family: Courier New, Courier, monospace;"> square([20,20]);</span><br />
<span style="font-family: Courier New, Courier, monospace;"> translate([20,10]) </span><span style="font-family: 'Courier New', Courier, monospace;">circle(r=6);</span><br />
<span style="font-family: Courier New, Courier, monospace;"> }</span><br />
<span style="font-family: Courier New, Courier, monospace;"> circle(r=4);</span><br />
<span style="font-family: Courier New, Courier, monospace;"> }</span><br />
<span style="font-family: Courier New, Courier, monospace;"> }</span><br />
<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgkkplA4sq5VsXucbRbM9EOer9BtFGzolFej7k51_lwi98FacOa_c-nO4scBufqn0bcLncRLx3z8KhVAUBS_Wjhpxe-JxyD2I-rzNmJDVzTJSgNFXOHKpzri4ooQ0f-xEX_6wH_gzj5y6Pa/s1600/linear_extrude.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="243" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgkkplA4sq5VsXucbRbM9EOer9BtFGzolFej7k51_lwi98FacOa_c-nO4scBufqn0bcLncRLx3z8KhVAUBS_Wjhpxe-JxyD2I-rzNmJDVzTJSgNFXOHKpzri4ooQ0f-xEX_6wH_gzj5y6Pa/s1600/linear_extrude.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="font-size: 13px;">3D linear extrusion of the former 2D shape</td></tr>
</tbody></table>
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
Contrary to the linear extrusion, the <span style="font-family: Courier New, Courier, monospace;">rotate_extrude( )</span> operator can be used to create a "ring" out of a 2D profile. This is how we extrude a rough circle into a torus (note how the circle must be translated out of the origin to do so!).<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg7NpMJskLSndz2HsnDyOzni6YO_xytMgQ8iw2r2LKvbVLrLzjEIlW7e7PDkbKbROu-Di79zbSUj7VELidp3xlaLyLsSNBJE58RHGapORc3FTFeVO0PJqS8dGgbELLcYCrlM_zDBlvGZX7-/s1600/rotate_extrude.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="207" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg7NpMJskLSndz2HsnDyOzni6YO_xytMgQ8iw2r2LKvbVLrLzjEIlW7e7PDkbKbROu-Di79zbSUj7VELidp3xlaLyLsSNBJE58RHGapORc3FTFeVO0PJqS8dGgbELLcYCrlM_zDBlvGZX7-/s1600/rotate_extrude.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="font-size: 13px;">Rotational extrusion of a basic 2D hexagon (a 6-segment circle)</td></tr>
</tbody></table>
For the most curious readers, these extrusion operators have trickier optional properties (see the <a href="http://en.wikibooks.org/wiki/OpenSCAD_User_Manual/2D_to_3D_Extrusion">official documentation</a> for more on this). If you cut the toroid by an orthogonal plane you will find the 6-segment primitive circle (hence the rough look).<br />
<br />
<br />
One annoying thing with the "rotate_extrude( )" is that it does not allow partial rotations. It will always "close the loop".<br />
<br />
So when you need only 1/4th of a turn (i.e. a partial 90° rotation), say, then the best way is to intersect the shape with a cube, like this:<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjD_3OKMvsL-Yn1T_ysHU6aott5njEMcrBWJ6uPjZr-hLcRFBy6CR2jaACEbUrkqddkvUZV0ETS0Coi892rUXL3uZb7Dd8ZKZ6XwFETuMY7p1GGBq10NGUCEGuoN_WFBHClSw7_nEeJJ2Fa/s1600/rotate_extrude_partial.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="195" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjD_3OKMvsL-Yn1T_ysHU6aott5njEMcrBWJ6uPjZr-hLcRFBy6CR2jaACEbUrkqddkvUZV0ETS0Coi892rUXL3uZb7Dd8ZKZ6XwFETuMY7p1GGBq10NGUCEGuoN_WFBHClSw7_nEeJJ2Fa/s1600/rotate_extrude_partial.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="font-size: 13px;">Easy 90° slice of the torus, with an intersection of the former torus<br />
and a big cube that stands in the positive (X,Y,Z) spatial quadrant.</td></tr>
</tbody></table>
<br />
Now, for any angles smaller than 90°, we can create a "wedge" shape by means of a convex hull around two very thin slices (almost flat cuboids), where one of them is rotated by the expected angle (see, by the way how modules can be defined within modules).<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi2OZiTAS-WXLbOC2CKffIIL3eya_K0ZV8l_o0FHk-eQ8-N1WqbEmBpGWjV8EY4Hm_mOiCy1kI4VbcrquyxTalc68-vY_C3bvQEX_aF5nSC3Yyr9pUw4zIKsr6n0iExVWAZs9_w3o1R38aj/s1600/wedge_45.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="207" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi2OZiTAS-WXLbOC2CKffIIL3eya_K0ZV8l_o0FHk-eQ8-N1WqbEmBpGWjV8EY4Hm_mOiCy1kI4VbcrquyxTalc68-vY_C3bvQEX_aF5nSC3Yyr9pUw4zIKsr6n0iExVWAZs9_w3o1R38aj/s1600/wedge_45.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="font-size: 13px;">A 45° "slice" of the initial torus, but it works only with for small wedges.</td></tr>
</tbody></table>
The "wedge_wall" thickness should be chosen below the 3D printer resolution, e.g. as low as 0.02 mm. But take care as too small a value and Openscad may just "skip" the shape!).<br />
<br />
You may have seen the use of the weird expression <span style="font-family: Courier New, Courier, monospace;">(center==true ? -height/2 : 0)</span>. This is a compact form of a conditional, usually barely readable: "if center is true, then replace the expression by the value -height/2 else use the value 0". This is a short way to code a condition, which is used here to shift the part downwards by half the height in order to center it, like it is done with cylinders.<br />
<br />
We did not use a more usual "if" test, as in the recursive mug. It would make life harder as "if" works with shapes, and not operators: the "if" condition cannot apply on the presence of the "translate" operation itself, but only on whole shapes. The "?" shorter version applies only on mathematical expressions, suitable here. All in all, in some case we will ask for a translation of (0,0,0), which works!<br />
<br />
<br />
Anyhow. The above wedge design fails when the angle is larger than 90°, as the hull will flatten the two-wall wedge (see the animation below).<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgWCjPd3d_Vwy8H7djvA_kbaLjbKMG5sdk11MpqkMRqN7-uT78df7E9tWQUkClnLCUEcZ8OpmQ2Qjhn-apwpHw_gS82HbcUX2pey4NaeESkvRTBDxipQLyMg7pA1XP79rltpiQ87xq8w1aM/s1600/wedge_hull_anim.gif" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="178" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgWCjPd3d_Vwy8H7djvA_kbaLjbKMG5sdk11MpqkMRqN7-uT78df7E9tWQUkClnLCUEcZ8OpmQ2Qjhn-apwpHw_gS82HbcUX2pey4NaeESkvRTBDxipQLyMg7pA1XP79rltpiQ87xq8w1aM/s1600/wedge_hull_anim.gif" width="200" /></a></td></tr>
<tr><td class="tr-caption" style="font-size: 13px;">A convex hull between the first and<br />
last "wall" fails with any large angles!<br />
We will see Openscad animation later.</td></tr>
</tbody></table>
<br />
To create a pseudo-wedge that really can span 360°, we can use a succession of hulls no bigger than 45°, and that are progressively rotated around the Z axis.<br />
<br />
So using a loop is very natural to generate the intermediate walls, spaced here at 45° of each other.<br />
Still, we need to add the last wall "manually" as it may not fall on a multiple of 45° as below.<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEij-3wAbZhgP5-02KwZMwBO-2otkn0Wt-_pG-N_A1i4F_Z9AmCgrareBQoZNgeJwniKYNsNYQ_OnW0oxwXmvxEEoj9lNnBd_HKVFiQ5ih4oKh7aKqmCKMwQpePF21gn5iia41qBHVd6EtEu/s1600/wedge_any1.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="167" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEij-3wAbZhgP5-02KwZMwBO-2otkn0Wt-_pG-N_A1i4F_Z9AmCgrareBQoZNgeJwniKYNsNYQ_OnW0oxwXmvxEEoj9lNnBd_HKVFiQ5ih4oKh7aKqmCKMwQpePF21gn5iia41qBHVd6EtEu/s1600/wedge_any1.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Angularly-spaced thin wall to help building the required concave wedge.</td></tr>
</tbody></table>
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;"> module wedge(angle, extent=100, height=100, center=true)</span><br />
<span style="font-family: Courier New, Courier, monospace;"> {</span><br />
<span style="font-family: Courier New, Courier, monospace;"> module wedge_wall()</span><br />
<span style="font-family: Courier New, Courier, monospace;"> {</span><br />
<span style="font-family: Courier New, Courier, monospace;"> translate([0,0,(center==true ? -height/2 : 0)])</span><br />
<span style="font-family: Courier New, Courier, monospace;"> cube([extent,0.1,height]);</span><br />
<span style="font-family: Courier New, Courier, monospace;"> }</span><br />
<span style="font-family: Courier New, Courier, monospace;"> </span><br />
<span style="font-family: Courier New, Courier, monospace;"> for(r=[0:45:angle-1])</span><br />
<span style="font-family: Courier New, Courier, monospace;"> rotate([0,0,r])</span><br />
<span style="font-family: Courier New, Courier, monospace;"> wedge_wall();</span><br />
<span style="font-family: Courier New, Courier, monospace;"> rotate([0,0,angle])</span><br />
<span style="font-family: Courier New, Courier, monospace;"> wedge_wall();</span><br />
<span style="font-family: Courier New, Courier, monospace;"> }</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;"> wedge(angle=200);</span><br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
Now, we want a shell somehow like a hull around this skeleton...<br />
<br />
But a regular <span style="font-family: Courier New, Courier, monospace;">hull( )</span> around the thin walls would fail badly, as it would "fill" also straight from the first wall to the last wall. The required concavity made by the first and last walls would not be respected. Sure, as the operator builds a <i>convex</i> hull. A concave hull probably has no meaning anyway, we must build it by hand.<br />
<br />
So what's the trick? The expected concave wedge shape can be made by unions of successive hulls!<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiHzQVo9QTZYxTEiv6oV9hmXHJVT1DKeqIi-EhzBwBuD8fDmuE4GnNvkEBU8Uznx0YgKWxMkzmFBG_CCWYEJcOVoCAyqR8FFkZtZguySjQ3p3vEsvLxHnWJqOOWwRB5gZ9Mp-dIK22mMUZn/s1600/openscad_ugly_hulls.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="251" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiHzQVo9QTZYxTEiv6oV9hmXHJVT1DKeqIi-EhzBwBuD8fDmuE4GnNvkEBU8Uznx0YgKWxMkzmFBG_CCWYEJcOVoCAyqR8FFkZtZguySjQ3p3vEsvLxHnWJqOOWwRB5gZ9Mp-dIK22mMUZn/s1600/openscad_ugly_hulls.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Here is our first attempt at a potential "concave" wedge.<br />
It works but it makes a dirty source code (so far).</td></tr>
</tbody></table>
This is how we did it. We also introduces the <span style="font-family: Courier New, Courier, monospace;">min(v1,v2,v3..)</span> and <span style="font-family: Courier New, Courier, monospace;">max()</span> mathematical operators (weirdly, they do not take a vector as argument but a list of variables).<br />
<span style="font-family: Courier New, Courier, monospace;"></span><br />
<span style="font-family: Courier New, Courier, monospace;"></span>
<span style="font-family: Courier New, Courier, monospace;"> module wedge(angle, extent=100, height=100, center=true)</span><br />
<span style="font-family: Courier New, Courier, monospace;"> {</span><br />
<span style="font-family: Courier New, Courier, monospace;"> module wedge_wall()</span><br />
<span style="font-family: Courier New, Courier, monospace;"> {</span><br />
<span style="font-family: Courier New, Courier, monospace;"> translate([0,0,(center==true ? -height/2 : 0)])</span><br />
<span style="font-family: Courier New, Courier, monospace;"> cube([extent,0.1,height]);</span><br />
<span style="font-family: Courier New, Courier, monospace;"> }</span><br />
<span style="font-family: Courier New, Courier, monospace;"> </span><br />
<span style="font-family: Courier New, Courier, monospace;"> for(r=[0:45:angle-45-1])</span><br />
<span style="font-family: Courier New, Courier, monospace;"> {</span><br />
<span style="font-family: Courier New, Courier, monospace;"> hull()</span><br />
<span style="font-family: Courier New, Courier, monospace;"> {</span><br />
<span style="font-family: Courier New, Courier, monospace;"> rotate([0,0,r]) wedge_wall();<span class="Apple-tab-span" style="white-space: pre;"> </span></span><br />
<span style="font-family: Courier New, Courier, monospace;"> rotate([0,0,min(angle,r+45)]) wedge_wall();</span><br />
<span style="font-family: Courier New, Courier, monospace;"> }</span><br />
<span style="font-family: Courier New, Courier, monospace;"> }</span><br />
<span style="font-family: Courier New, Courier, monospace;"> hull()</span><br />
<span style="font-family: Courier New, Courier, monospace;"> {</span><br />
<span style="font-family: Courier New, Courier, monospace;"> rotate([0,0,max(0,angle-45)]) wedge_wall();</span><br />
<span style="font-family: Courier New, Courier, monospace;"> rotate([0,0,angle]) wedge_wall();</span><br />
<span style="font-family: Courier New, Courier, monospace;"> }</span><br />
<span style="font-family: Courier New, Courier, monospace;"> }</span><br />
<span style="font-family: Courier New, Courier, monospace;"></span><br />
<span style="font-family: Courier New, Courier, monospace;"></span>
<span style="font-family: Courier New, Courier, monospace;"> wedge(angle=200);</span><br />
<br />
The <span style="font-family: Courier New, Courier, monospace;">min</span> and <span style="font-family: Courier New, Courier, monospace;">max</span> are required to avoid overshooting the expected wedge <span style="font-family: Courier New, Courier, monospace;">angle</span>.<br />
<br />
Here are the result of the intersection of our wedge and the initial torus, that finally does it.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh6zY6YK1KB5Zb7CxQWJMmrM7o-KW7cXbcpqZXCrNJwFRTZgKINjiizOYNXrcGCU4Pm1hgzEeLdj9kjpsvJz0VpSEvcQxBlp0bXCuNeSs4GgMKBNHPofJ9Q5nNBsBzvDn6CXdZCn2bhGmAT/s1600/wedge_convexity_issue.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="170" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh6zY6YK1KB5Zb7CxQWJMmrM7o-KW7cXbcpqZXCrNJwFRTZgKINjiizOYNXrcGCU4Pm1hgzEeLdj9kjpsvJz0VpSEvcQxBlp0bXCuNeSs4GgMKBNHPofJ9Q5nNBsBzvDn6CXdZCn2bhGmAT/s1600/wedge_convexity_issue.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">It works! The parametric wedge "sliced" the torus the way we wanted.<br />
Note the "missing" part? It is only a rendering issue, see below!</td></tr>
</tbody></table>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiYJ9a24FXghFw1DaOZJq1bqYH50KiIguB4jxsPI3y1x_yZ6BpfVIlNdkCG__y0zv3NGZkugnwieK7HluFoGdnrmphYsbgm8Et70iQbPbX2E-ebqAfE0UjGa4e2krL1QjbL31qB0IbB1dDx/s1600/wedge_convexity_ok.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="170" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiYJ9a24FXghFw1DaOZJq1bqYH50KiIguB4jxsPI3y1x_yZ6BpfVIlNdkCG__y0zv3NGZkugnwieK7HluFoGdnrmphYsbgm8Et70iQbPbX2E-ebqAfE0UjGa4e2krL1QjbL31qB0IbB1dDx/s1600/wedge_convexity_ok.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Here is why there is a "convexity" parameter in the rotate_extrude(), and a few other<br />
Openscad functions. It helps the renderer by telling to look deeper in the intersection of objects.</td></tr>
</tbody></table>
<br />
<br />
Well... OK, it works... but the source code got much polluted...<br />
<br />
It can get cleaner with the beautiful and somehow forgotten / unusual concept of <span style="font-family: Courier New, Courier, monospace;">children</span> in Openscad. And that will make yet <a href="http://www.tridimake.com/2014/11/how-to-use-openscad-4-children-and.html">another part</a> in this introduction to Openscad (to come!)<br />
<br />
<br /></div>
Jeremie Francoishttp://www.blogger.com/profile/02984201174566394892noreply@blogger.com0tag:blogger.com,1999:blog-3615478772815290200.post-5257886741737677412014-11-06T20:40:00.002+01:002014-11-08T11:55:06.715+01:00Fortune 500 teller? 3D printing trends, reports, analyses and business intelligence...<div dir="ltr" style="text-align: left;" trbidi="on">
<div class="tr_bq">
<h2 style="text-align: left;">
Are the "high-level strategically analyzed reports" worth something?</h2>
</div>
<div class="tr_bq">
Hey, could my blog be so informative? :)<br />
<br />
I am regularly contacted, mostly on linkedIn, by experts that seek data. The last time it was for a company that compiles data and trends "for the Fortune 500 companies". Which does not excite me more than that, and here is why.</div>
<div class="tr_bq">
<br /></div>
<div class="tr_bq">
Such data are usually sold at an incredible price to managers that <i>think</i> they would get a better clue at the market, with the idea that they would be more profitable. But there are two traps here.<br />
<br />
The first one is: am I really enough of an expert to give clues to Fortune 500 companies? I am mostly an iconoclast, e.g. when I say not to invest in Makerbot at all (neither as a customer nor as an investor, but I have a <a href="http://www.tridimake.com/2014/06/do-not-buy-makerbot-3d-printers.html">full-length analysis</a> why I say so), or when I explain why, imho, "pro/expensive" FDM printers are <a href="http://www.tridimake.com/2014/03/quick-comparison-pro-versus-low-cost.html">almost a scam nowadays</a>. OK, I <i>may be</i> better than a monkey and provide a few useful reviews (e.g. <a href="http://www.tridimake.com/2014/07/3D-printing-material-for-artists-bronze-wood-chalk.html">materials for artists</a>, or what <a href="http://www.tridimake.com/2013/04/what-cannot-be-3d-printed.html">cannot be 3D printed</a>...). But still, asking my opinion on the <i>market trends</i> could cast a doubt on the forthcoming corresponding report. Oh, well, may be they also want data from makers -- why not after all.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgI9uWb0I5ug0cO0TAT-CTahYksAs-eXn9syreb_YJZKhsnKRUQ7aQC1YTQeK2P_H1Ah-yp1Lv_8i8wIXmdYD8U8uV9mJFcEI756P64QEuJEW1Sq6TaQ5ASiDnXEWSogZnBuxsLYB-4j3Jy/s1600/dilbert_Dogbert_business_intelligence.gif" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgI9uWb0I5ug0cO0TAT-CTahYksAs-eXn9syreb_YJZKhsnKRUQ7aQC1YTQeK2P_H1Ah-yp1Lv_8i8wIXmdYD8U8uV9mJFcEI756P64QEuJEW1Sq6TaQ5ASiDnXEWSogZnBuxsLYB-4j3Jy/s1600/dilbert_Dogbert_business_intelligence.gif" height="136" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">As a manager, do you really need accurate trends and data?<br />
Or do you need only the <i>feeling</i> that you have some?</td></tr>
</tbody></table>
Secondly and as importantly, the reviews are most often never used in reality. Once bought, they are dropped on the desk of a subordinate in the company, with the advice to get some insight from the document. The underlying idea is: since it is expensive it must be valuable...</div>
<div class="tr_bq">
<br />
<a name='more'></a><br />
<br />
Eventually, the report ends its life miserably in the darkness of the drawer together with a set of abandoned goodies, at the desk of someone further down in the hierarchy... precisely at the level where no more cares about its content.<br />
<br />
For sure, most of the engineers have no big consideration for business compilations, precisely because <i>they</i> know how often and how badly experts fail to predict any trend. But it would also be against the company policies to tell upwards though, so things stay unchanged and lots of money is wasted in the process.<br />
<br /></div>
<div class="tr_bq">
And yes, I do know a few companies that do have lots of dusty compilations like these. By the way, these are soon obsolete (of course you get a discount if you <i>subscribe</i> to the thing...). </div>
<br />
<h3 style="text-align: left;">
Hey, where is my money?</h3>
Back to the guy who contacted me and another reason I did not answer. He basically tells me they would make a pile of money out of the opinions of other people like me. And meanwhile, he tells me they would not pay for the collected data. Oh, sure, I would have a "special offer" on the resulting document. This may be the usual practice, but I disagree nonetheless and it casts another shadow on the seriousness of the document.<br />
<br />
By the way my name most probably would be stripped off the document in the end, so my ego would not get paid either. I just cannot imagine the guy telling at the end he got some of his insights from a blogger at www.tridimake.com ;)<br />
<br />
And finally, it was easier for me to decide that I would keep on making my opinions public and free, instead of feeding a closed and dubious system. Do not believe too much in the fortune 500 tellers ;)<br />
<div>
<h3 style="text-align: left;">
Conclusion: what I think about consulting firms, trends and reports</h3>
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiMiyket6kRa4L7Ii3jvwF0qtfD8iDiMMr_zJl2RXWtglwkGqhirAm1C5tPCgt-_5oP2TtrnL0R5ITFpuUeaoybRWx_OA9VbGgLrdrFllDDk6TaSwb2GqdY4YMySMAUSD4BxKT4yuWOUSZX/s1600/prediction.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiMiyket6kRa4L7Ii3jvwF0qtfD8iDiMMr_zJl2RXWtglwkGqhirAm1C5tPCgt-_5oP2TtrnL0R5ITFpuUeaoybRWx_OA9VbGgLrdrFllDDk6TaSwb2GqdY4YMySMAUSD4BxKT4yuWOUSZX/s1600/prediction.jpg" height="320" width="319" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">I bet no analyst ever predicted this!<br />
From <a href="http://geek-and-poke.com/">Geek&Poke</a> by Oliver Widder</td></tr>
</tbody></table>
As a manager I was always highly suspicious of costly external data trend and analyses. I would often better trust both my nose and my employees (that's how business is started anyway). Relying on external views that you cannot assess is uselessly risky in my opinion, and there are tons of heavy historical mistakes made by analysts that highlights it. Also relying on others for one's own strategy and evaluation skews the whole business, it puts everyone in the same bag, and eventually it can fail so hard as to provoke a huge crash of the economy (see, e.g. the paragraph on <a href="http://blogs.cfainstitute.org/investor/2014/10/20/nobel-laureate-myron-scholes-on-the-common-mistakes-research-analysts-make/">AAA</a> backfire from this nobel laureate).<br />
<br />
<br />
<br />
Now, as an individual, it boils down to whether I consider myself such an expert on the market of 3D printing, and whether I should help building such reports for free... I certainly can tell for the last one: no, I will not feed the trolls. And actually I do not care if I am a "valuable" expert for Fortune 500 companies. I would better help smaller companies.<br />
<br />
<br />
<br />
So if my answer below brings one smile on your face, then you will not make me richer but you will still make my day:<br />
<br />
<blockquote class="tr_bq">
<span style="color: #444444; font-family: Georgia, Times New Roman, serif;">Hello,</span><span style="color: #444444; font-family: Georgia, Times New Roman, serif;"><br /></span><span style="color: #444444; font-family: Georgia, Times New Roman, serif;">Thanks a lot for your attention. I am however really too busy for an exclusive interview in the next weeks.</span><span style="color: #444444; font-family: Georgia, Times New Roman, serif;"><br /></span><span style="color: #444444; font-family: Georgia, Times New Roman, serif;">I would gladly help, but I would better share my opinion on my popular blog.</span><span style="color: #444444; font-family: Georgia, Times New Roman, serif;"><br /></span><span style="color: #444444; font-family: Georgia, Times New Roman, serif;">Still, please feel free to provide me with some specific questions that you would like me to address. I would reply to you specifically for what I think would not fit on my blog.</span><span style="color: #444444; font-family: Georgia, Times New Roman, serif;"><br /></span><span style="color: #444444; font-family: Georgia, Times New Roman, serif;">best regards,</span> </blockquote>
<blockquote class="tr_bq">
<span style="color: #444444; font-family: Georgia, 'Times New Roman', serif;">Jérémie</span></blockquote>
<br />
And unsurprisingly, I got no subsequent email after my answer. Time is money, isn't it ?<br />
<br />
<br />
For reference, here is the email I first got from linkedIn:<br />
<br />
<br />
<div>
</div>
<br />
<blockquote style="-webkit-text-stroke-width: 0px; color: black; font-family: 'Times New Roman'; font-size: medium; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px;">
<div style="margin: 0px;">
<span style="color: #444444; font-family: Georgia, Times New Roman, serif;">On 09/24/13 12:51 AM, xxxxx wrote:</span><span style="color: #444444; font-family: Georgia, Times New Roman, serif;">--------------------</span><span style="color: #444444; font-family: Georgia, Times New Roman, serif;"><br /></span><span style="color: #444444; font-family: Georgia, Times New Roman, serif;">Dear Jeremie F, </span><span style="color: #444444; font-family: Georgia, Times New Roman, serif;"><br /></span><span style="color: #444444; font-family: Georgia, Times New Roman, serif;">Greetings for the day! </span><span style="color: #444444; font-family: Georgia, Times New Roman, serif;"><br /></span><span style="color: #444444; font-family: Georgia, Times New Roman, serif;">Allow me to introduce myself as a Research Analyst at MarketsandMarkets, a global market research and consulting firm based in the U.S. We, at MarketsandMarkets, publish high-level strategically analyzed reports for over thirteen industry verticals and serve as a business intelligence partner to Fortune 500 companies across the world. We are studying the ”Global 3D printing materials by Types, Applications and Geography, 2011 - 2020” Market and would be publishing a syndicate market research report on it in November 2013. </span><span style="color: #444444; font-family: Georgia, Times New Roman, serif;"><br /></span><span style="color: #444444; font-family: Georgia, Times New Roman, serif;">Currently, we are in the phase of conducting interviews with some of the industry experts in this market to understand the latest market trends. We understand that you are an expert in this market and hence your views and suggestions will be really insightful and valuable for us. </span><span style="color: #444444; font-family: Georgia, Times New Roman, serif;"><br /></span><span style="color: #444444; font-family: Georgia, Times New Roman, serif;">Following are the major points on which I would like to understand your perspective on the 3D printing materials market: </span><span style="color: #444444; font-family: Georgia, Times New Roman, serif;"><br /></span><span style="color: #444444; font-family: Georgia, Times New Roman, serif;">1. Current and future market trends of the market </span><span style="color: #444444; font-family: Georgia, Times New Roman, serif;"><br /></span><span style="color: #444444; font-family: Georgia, Times New Roman, serif;">2. Growth rate and market size of the market </span><span style="color: #444444; font-family: Georgia, Times New Roman, serif;"><br /></span><span style="color: #444444; font-family: Georgia, Times New Roman, serif;">3. Applications of 3D printing materials, Drivers & restraints of the market. </span><span style="color: #444444; font-family: Georgia, Times New Roman, serif;"><br /></span><span style="color: #444444; font-family: Georgia, Times New Roman, serif;">During this process, we would share our findings and invite your valuable opinion for the same. Once the report is published, we will also share the executive summary and key findings as a token of appreciation. Also, if interested in purchasing the report a special discount will be offered to you. </span><span style="color: #444444; font-family: Georgia, Times New Roman, serif;"><br /></span><span style="color: #444444; font-family: Georgia, Times New Roman, serif;">Kindly suggest a convenient date, time and contact number to reach you. Feel free to forward this mail to your colleagues who would be interested in joining the discussion. </span><span style="color: #444444; font-family: Georgia, Times New Roman, serif;"><br /></span><span style="color: #444444; font-family: Georgia, Times New Roman, serif;">I look forward to hearing from you. Thank You. </span><span style="color: #444444; font-family: Georgia, Times New Roman, serif;"></span><br />
<span style="color: #444444; font-family: Georgia, Times New Roman, serif;"></span><span style="color: #444444; font-family: Georgia, Times New Roman, serif;">Best Regards, </span><span style="color: #444444; font-family: Georgia, Times New Roman, serif;">[xxx]</span><span style="color: #444444; font-family: Georgia, Times New Roman, serif;">[yyy]</span></div>
</blockquote>
</div>
<div>
<br /></div>
</div>
Jeremie Francoishttp://www.blogger.com/profile/02984201174566394892noreply@blogger.com0tag:blogger.com,1999:blog-3615478772815290200.post-38449922460018795822014-09-11T11:51:00.001+02:002016-03-31T22:17:58.895+02:00How to use Openscad (2): variables and modules for parametric designs<div dir="ltr" style="text-align: left;" trbidi="on">
<h3>
Part 2/5: Variable and parametric design</h3>
The <a href="http://www.tridimake.com/2014/09/how-to-use-openscad-tricks-and-tips-to.html">previous part</a> addressed the basics of Openscad. It relied mostly on "immediate values": we were providing dimensions as explicit numbers. If you want to tweak the design dimensions, then you need to parse the scad source code and fix the numbers all everywhere.<br />
<br />
In fact "hard coded" numbers must be avoided. As opposed to "static" designs, <i>parametric designs</i> give the flexibility to tune the numbers very efficiently at one place only. The good point is that Openscad is one of the best tool to do so.<br />
<div style="-webkit-text-stroke-width: 0px; color: black; font-family: 'Times New Roman'; font-size: medium; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px;">
</div>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="-webkit-text-stroke-width: 0px; font-family: 'Times New Roman'; letter-spacing: normal; margin-bottom: 0.5em; margin-left: auto; margin-right: auto; orphans: auto; padding: 6px; text-align: center; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px;"><tbody>
<tr><td style="text-align: center;"><div style="margin: 0px;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgaUyaDKCq5MbO0DYfNylfwsmmNuUqul5CeJ3T69RmZBcXI9JssDQml-HzQCp1h44WJ5IVs6MUHDL5Xebyg3D1xIS7Dui_ENDrTn1NXQMvk-h35OfFyZtYmxWZMwBMJ741lmcVpIKcKXDh4/s1600/mug2.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="252" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgaUyaDKCq5MbO0DYfNylfwsmmNuUqul5CeJ3T69RmZBcXI9JssDQml-HzQCp1h44WJ5IVs6MUHDL5Xebyg3D1xIS7Dui_ENDrTn1NXQMvk-h35OfFyZtYmxWZMwBMJ741lmcVpIKcKXDh4/s1600/mug2.png" style="cursor: move;" width="400" /></a></div>
</td></tr>
<tr><td class="tr-caption" style="font-size: 13px; padding-top: 4px; text-align: center;"><div style="margin: 0px;">
A larger mug by using the scale operator (from the <a href="http://www.tridimake.com/2014/09/how-to-use-openscad-tricks-and-tips-to.html">"basic" tutorial</a>).</div>
<div style="margin: 0px;">
This is still <i>not parametric</i>, as numbers are hard-coded (a bad practice).</div>
</td></tr>
</tbody></table>
See how the numbers in our mug design above depends on each other? If the cube is to be made taller for any reason, then the intersecting sphere and hollow cylinder must be tuned accordingly in the source code. And this is <i>exactly</i> something a computer can do better than us.<br />
<br />
So let us first convert this design to a parametric version, i.e. a design that can be tweaked with a small set of parameters that all have a clear role (width, height and so).<br />
<br />
<br />
<a name='more'></a><br />
This article is part of a longer serie:<br />
<ol>
<li><a href="http://www.tridimake.com/2014/09/how-to-use-openscad-tricks-and-tips-to.html"><span style="font-family: "arial" , "helvetica" , sans-serif;">Introduction to constructive solid geometry with OpenSCAD</span></a></li>
<li><a href="http://www.tridimake.com/2014/09/howto-openscad-variables-modules-parametric-designs.html"><span style="font-family: "arial" , "helvetica" , sans-serif;"><b>Variables and modules for parametric designs</b></span></a></li>
<li><a href="http://www.tridimake.com/2014/11/howto-openscad-iteration-extrusion.html"><span style="font-family: "arial" , "helvetica" , sans-serif;">Iteration, extrusion and useful parametrized CSG techniques</span></a></li>
<li><a href="http://www.tridimake.com/2014/11/how-to-use-openscad-4-children-and.html"><span style="font-family: "arial" , "helvetica" , sans-serif;">Children, factorized placement and chained hulls</span></a></li>
</ol>
<br />
We are first going to replace most of the numbers by straightforward expressions that refer to <b>variables</b> instead of numbers.<br />
<br />
A variable is just an "alphanumeric tag": it is a name made of letters that mean something for you. You can also use underscores and digits, but the first letter must be a letter and no space is allowed in the name: hence "width", "my_cube_width", "cubeDim1" are three valid variable names (without the double quotes!).<br />
<br />
Once a variable is given a value, it can be used <i>as if it was a number</i>. There are two advantages to use variables: readability and convenience.<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;"> body_diameter=20;</span><br />
<br />
It is easier to read a source code with variables because you can give meaningful names to them: this "body_diameter" makes more sense than any number buried in a mathematical expression.<br />
<br />
For example, you can now replace an obscure shape like this:<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;"> cylinder(r=10);</span><br />
<br />
By this one, which is much more readable:<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;"> body_diameter=20;</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> cylinder(r=body_diameter/2)</span><br />
<br />
In fact, readability is a second benefit, because the foremost advantage is to get rid of rogue "20" or "10" in the source code that are anonymously related to the body size!<br />
<br />
<h3 style="text-align: left;">
Parametric rewrite of the mug source (i.e. <i>depends on variables</i>)</h3>
Back to our mug to make it parametric. First, extract and name appropriately the main characteristics of your design:<br />
<br />
<div style="margin: 0px;">
<span style="font-family: "courier new" , "courier" , monospace;"> width=40;</span></div>
<div style="margin: 0px;">
<span style="font-family: "courier new" , "courier" , monospace;"> height=60;</span></div>
<div style="margin: 0px;">
<span style="font-family: "courier new" , "courier" , monospace;"> bottom_thickness=2;</span></div>
<div style="margin: 0px;">
<span style="font-family: "courier new" , "courier" , monospace;"> wall_thickness=5;</span></div>
<div style="margin: 0px;">
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: inherit;">Then rewrite the former anonymous numbers, by using these variables and mathematical expressions:</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div style="margin: 0px;">
<span style="font-family: "courier new" , "courier" , monospace;"> difference()</span></div>
<div style="margin: 0px;">
<span style="font-family: "courier new" , "courier" , monospace;"> {</span></div>
<div style="margin: 0px;">
<span style="font-family: "courier new" , "courier" , monospace;"> intersection()</span></div>
<div style="margin: 0px;">
<span style="font-family: "courier new" , "courier" , monospace;"> {</span></div>
<div style="margin: 0px;">
<span style="font-family: "courier new" , "courier" , monospace;"> cube([width,width,height], center=true);</span></div>
<div style="margin: 0px;">
<span style="font-family: "courier new" , "courier" , monospace;"> scale([1,1,height/width]) // so that Z=1 is now...</span></div>
<div style="margin: 0px;">
<span style="font-family: "courier new" , "courier" , monospace;"> sphere(width/2 * sqrt(2)); // close to the cuboid edges</span></div>
<div style="margin: 0px;">
<span style="font-family: "courier new" , "courier" , monospace;"> }</span></div>
<div style="margin: 0px;">
<span style="font-family: "courier new" , "courier" , monospace;"> translate([0,0,-height/2+bottom_thickness])</span></div>
<div style="margin: 0px;">
<span style="font-family: "courier new" , "courier" , monospace;"> cylinder(r=width/2-wall_thickness,h=height+0.1);</span></div>
<div style="margin: 0px;">
</div>
<span style="font-family: "courier new" , "courier" , monospace;"> }</span><br />
<br />
<br />
A "good" Openscad source code should almost have no numerical values. Most of the internal stuff is computed out of a minimum set of variables that make sense in the design. Especially, there should be one and only one place to set the geometric dimensions.<br />
<br />
<b>A side note on scale and rotate.</b><br />
<br />
In the above parametrized source, the formerly almost global "scale( )" operator was moved "down in the CSG tree". Just like rotation, scale is an annoying operator because all subsequent axis geometry gets modified. Nothing is "square" anymore (or respectively, well-oriented)! A good indicator that an operator is used "too soon" in the CSG tree is when you suddenly feel the need to reverse its effect (un-scale or de-rotate before you add sub-shapes).<br />
<br />
Better use "scale( )" sparingly, and only when required, closest to the shape that needs it. Here we apply it only to one primitive, the sphere, to elongate it vertically so it matches the cuboid. And this is exactly what we wanted: it makes life easier than to intersect a regular cube with a sphere and then elongate the whole even though the result is the same. Why? Because if you needed to add a regular cylindrical hole in the intersection for example, it would be itself ellipsoidal!<br />
<div>
<br /></div>
<div>
<br /></div>
<i style="text-decoration: underline;">Note</i><i>:</i> so far, better consider Openscad variables as <i>constants</i>! With Opensacd, a variable cannot be re-defined once set (usually at the top of the file or at the top of a module)! More on this later.<br />
<br />
<br />
<h3 style="text-align: left;">
An immediate effect: multiple shapes with one source code!</h3>
<br />
As shown below, the parametrized source code let us generate a mug or an ashtray just by changing the <i>width</i> and <i>height</i> variables to 40 and 60 mm, or 80 and 20 mm respectively (well, a plastic ashtray is <a href="http://www.tridimake.com/2013/04/what-cannot-be-3d-printed.html">not a good idea</a>).<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgtQSAz84DvYLayzfrk7KlUFhftBYCISSWBXaSbTt_pETW_wzXGgkKF-DJaXTRW0f6kebzYmbOp-UFc4dfmyXcNupKJNtkDYz72FgqJsrnSiqCBVw2hrZ2dqrTrIXTiLINaNN1Ig5LrkbqA/s1600/mug_parametric1.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="174" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgtQSAz84DvYLayzfrk7KlUFhftBYCISSWBXaSbTt_pETW_wzXGgkKF-DJaXTRW0f6kebzYmbOp-UFc4dfmyXcNupKJNtkDYz72FgqJsrnSiqCBVw2hrZ2dqrTrIXTiLINaNN1Ig5LrkbqA/s1600/mug_parametric1.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="font-size: 13px;">Two "mugs" made from the same source code: only two numbers were changed (<i>height</i> and <i>width</i>) !<br />
Parametric designs are probably one of the most important characteristics of Openscad.</td></tr>
</tbody></table>
<br />
Often, we have a shape to repeat in different places, like PCB support pillars with the hole for a screw and a bevel at the base. But how do we combine shapes conveniently?<br />
<br />
Imagine a weird case: to reduced spilled coffee, we are going to design a mug with a cup attached to it, using the above two shapes.<br />
<br />
<h3 style="text-align: left;">
Export/import STL files</h3>
Openscad knows how to <b>import</b> raw STL files (triangular meshes, that we described in the first part of this serie). This is mostly useful to tweak an existing design for which no source is given, or not compatible with Openscad. For example, I sometimes design and add manual support walls this way.<br />
<br />
So we could first generate the mug, then export it to an STL file, and finally import the mug STL in our modified source code for the cup.<br />
<br />
Here is how it would look like here:<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiJkoTTIUz2eqBFGmt3M0F7Gsm1kGvihuDwkLcCFw-3lpAzkixm9-K62LoylzYy1Ak_CwF5ub1AxY5pkzSWJhKsl8ENjf-cCtmzAubgLQophMNlyiHCYnFN4TUS4s2-oEC9RiJBVhoUafW3/s1600/mug_import.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="334" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiJkoTTIUz2eqBFGmt3M0F7Gsm1kGvihuDwkLcCFw-3lpAzkixm9-K62LoylzYy1Ak_CwF5ub1AxY5pkzSWJhKsl8ENjf-cCtmzAubgLQophMNlyiHCYnFN4TUS4s2-oEC9RiJBVhoUafW3/s1600/mug_import.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="font-size: 13px;">A nasty way to import a parametric copy of ourselves, with the "import" function of Openscad and after the<br />
mug shape is exported to an STL file. But this is not the right way to do, better use a <i>module</i> of course!</td></tr>
</tbody></table>
<br />
It works as you can see, but this is an ugly solution. See also the rogue translation in the source code to fix the position of the "import( )" statement (the value depends on the height of the internal mug, no more available, and the height of the current mug shape). Do not do that!<br />
<br />
Now, so shall we copy/paste the mug code to get two versions-in-one? Obviously not: once again, the less the number of lines of source code, the less bugs. First, copying/pasting source code is very wrong because any bug left in the copied source will be <i>duplicated.</i> Second, any subsequent improvement need to be re-inserted in the many copies. Third, the copies tend to diverge from each other with time while the unique and "canonical" shape would better have added options instead for more re-usability in the first place.<br />
<br />
<h3>
Writing a module: recyclable and parametric shapes</h3>
Instead of copy/pasting source code, Openscad offers <b>modules</b> that are the right choice here. Modules are like functions (or classes) for the readers who practiced a bit of programming.<br />
<br />
The idea of a module is to create a "generic" shape which depends on some parameters. In fact a module creates a new shape exactly like we have primitive shapes, except that <i>we</i> define the shape!<br />
<br />
Here is how we have to modify our source code:<br />
<br />
<div style="margin: 0px;">
<span style="font-family: "courier new" , "courier" , monospace;"> module mug(width, height, bottom_thickness=2, wall_thickness=5)</span></div>
<div style="margin: 0px;">
<span style="font-family: "courier new" , "courier" , monospace;"> {</span></div>
<div style="margin: 0px;">
<span style="font-family: "courier new" , "courier" , monospace;"> difference()</span></div>
<div style="margin: 0px;">
<span style="font-family: "courier new" , "courier" , monospace;"> {</span></div>
<div style="margin: 0px;">
<span style="font-family: "courier new" , "courier" , monospace;"> intersection()</span></div>
<div style="margin: 0px;">
<span style="font-family: "courier new" , "courier" , monospace;"> {</span></div>
<div style="margin: 0px;">
<span style="font-family: "courier new" , "courier" , monospace;"> cube([width,width,height], center=true);</span></div>
<div style="margin: 0px;">
<span style="font-family: "courier new" , "courier" , monospace;"> scale([1,1,height/width])</span></div>
<div style="margin: 0px;">
<span style="font-family: "courier new" , "courier" , monospace;"> sphere(width/2 * sqrt(2));</span></div>
<div style="margin: 0px;">
<span style="font-family: "courier new" , "courier" , monospace;"> }</span></div>
<div style="margin: 0px;">
<span style="font-family: "courier new" , "courier" , monospace;"> translate([0,0,-height/2+bottom_thickness])</span></div>
<div style="margin: 0px;">
<span style="font-family: "courier new" , "courier" , monospace;"> cylinder(r=width/2-wall_thickness,h=height+0.1);</span></div>
<div style="margin: 0px;">
<span style="font-family: "courier new" , "courier" , monospace;"> }</span></div>
<span style="font-family: "courier new" , "courier" , monospace;"> }</span><br />
<br />
This module generates a new <i>mug shape</i>, just like "cube" or "cylinder" create their respective shapes. Our mug is certainly no more a <i>primitive</i> one though, and it requires up to four parameters, that we had previously introduced with the notion of <i>variables</i>.<br />
<br />
Here, two of the parameters have <i>default values</i>: they are not compulsory when a new mug is created, even though you can <i>override</i> the default value by setting their value. This is quite convenient because we probably do not care much about the thickness except is rare cases.<br />
<br />
<br />
<b>No shape is defined, blank (or un-refreshed display) in Openscad!</b><br />
<br />
Now if you try and run the above, you get nothing new nor updated. In fact the Openscad console tells this:<br />
<span style="font-family: "courier new" , "courier" , monospace;">ERROR: CSG generation failed! (no top level object found)</span><br />
This is one more reminder that you should better always leave the console open, or you will not always understand why nothing appears or where something is broken.<br />
<br />
The error means "nothing is left to be drawn at the end of the code". And this is true since we just have <i>defined</i> the mug shape, but we created none so far. This error also happens in case an abusive intersection leaves no positive shape to display for example.<br />
<br />
<br />
<b>Calling or creating a shape with a module</b><br />
<br />
So to <i>create</i> a version of our original mug, we have to call the module, with the following line.<br />
The line must be placed <i>outside </i>of the module (aka shape definition), for example at the end of the file:<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;"> mug(width=40, height=60);</span><br />
<br />
For the cup/ashtray, it would just be another line:<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;"> mug(width=80, height=20);</span><br />
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">Then, our combined mug+cup shape is just the (default) union of the two shapes.</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">See how powerful Openscad is becoming? And there is more to come...</span></div>
<br />
<br />
<span style="font-family: inherit;">By the way, you will see that I also corrected the vertical offset of the mug shape within the module, so that Z=0 corresponds to the bottom of the shape once created. Indeed, nobody wants the mug "origin" to be positioned at its middle, because it makes life harder for <i>callers</i> of the mug shape (remember the ugly "translate( )" we added when importing the STL above!).</span><br />
<span style="font-family: inherit;"><br /></span><span style="font-family: inherit;">You may also notice that there are no curly braces after the "translate" within the top of the mug module. This is fully OK because there is really only one "command" that needs to be translated after, namely, the (result of the) "difference" that follows. It is up to you to use curly braces everywhere or not. I tend to drop them on short statements, or when I want less "noise".</span><br />
<span style="font-family: inherit;"><br /></span>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhBoKAUaIWinnGVP5QLMxoWJ7A1k7KkJVnH3bs5LcpecjNntFYFupHm5HV7DpIRmemOcfNAChWPj9eWChuwn2nXSJ8AsGmxuP1JTHBEkndZ2B3FKe-suUaORhsDAxE8tbRjcDoov-fm2hdY/s1600/mug_module.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="332" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhBoKAUaIWinnGVP5QLMxoWJ7A1k7KkJVnH3bs5LcpecjNntFYFupHm5HV7DpIRmemOcfNAChWPj9eWChuwn2nXSJ8AsGmxuP1JTHBEkndZ2B3FKe-suUaORhsDAxE8tbRjcDoov-fm2hdY/s1600/mug_module.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="font-size: 13px;">Our coupled mug and teacup thanks to a module that builds generic (aka parametric) mug shapes.</td></tr>
</tbody></table>
<span style="font-family: inherit;"></span><br />
<span style="font-family: inherit;"></span>
<br />
<div style="margin: 0px;">
<span style="font-family: "courier new" , "courier" , monospace;"> module mug(width, height, bottom_thickness=2, wall_thickness=5)</span></div>
<div style="margin: 0px;">
<span style="font-family: "courier new" , "courier" , monospace;"> {</span></div>
<div style="margin: 0px;">
<span style="font-family: "courier new" , "courier" , monospace;"> translate([0,0,height/2])</span></div>
<div style="margin: 0px;">
<span style="font-family: "courier new" , "courier" , monospace;"> difference()</span></div>
<div style="margin: 0px;">
<span style="font-family: "courier new" , "courier" , monospace;"> {</span></div>
<div style="margin: 0px;">
<span style="font-family: "courier new" , "courier" , monospace;"> intersection()</span></div>
<div style="margin: 0px;">
<span style="font-family: "courier new" , "courier" , monospace;"> {</span></div>
<div style="margin: 0px;">
<span style="font-family: "courier new" , "courier" , monospace;"> cube([width,width,height], center=true);</span></div>
<div style="margin: 0px;">
<span style="font-family: "courier new" , "courier" , monospace;"> scale([1,1,height/width])</span></div>
<div style="margin: 0px;">
<span style="font-family: "courier new" , "courier" , monospace;"> sphere(width/2 * sqrt(2));</span></div>
<div style="margin: 0px;">
<span style="font-family: "courier new" , "courier" , monospace;"> }</span></div>
<div style="margin: 0px;">
<span style="font-family: "courier new" , "courier" , monospace;"> translate([0,0,-height/2+bottom_thickness])</span></div>
<div style="margin: 0px;">
<span style="font-family: "courier new" , "courier" , monospace;"> cylinder(r=width/2-wall_thickness,h=height+0.1);</span></div>
<div style="margin: 0px;">
<span style="font-family: "courier new" , "courier" , monospace;"> }</span></div>
<div style="margin: 0px;">
<span style="font-family: "courier new" , "courier" , monospace;"> }</span></div>
<div style="margin: 0px;">
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div style="margin: 0px;">
<span style="font-family: "courier new" , "courier" , monospace;"> // here is the real objects that are made</span></div>
<div style="margin: 0px;">
<span style="font-family: "courier new" , "courier" , monospace;"> union()</span></div>
<div style="margin: 0px;">
<span style="font-family: "courier new" , "courier" , monospace;"> {</span></div>
<div style="margin: 0px;">
<span style="font-family: "courier new" , "courier" , monospace;"> mug(width=40, height=60); // one mug shape1</span></div>
<div style="margin: 0px;">
<span style="font-family: "courier new" , "courier" , monospace;"> mug(width=80, height=20); // another one, different</span></div>
<span style="font-family: "courier new" , "courier" , monospace;"> }</span><br />
<span style="font-family: inherit;"></span><br />
The last "union( )" is spurious, because it is the default operation when more than one shape are provided. But it makes thing clearer.<br />
<br />
<br />
<br />
<span style="font-family: inherit;"></span>
We can also create and use convenient "local" variables in the module. Check the source below: we added the explicit "<span style="font-family: "courier new" , "courier" , monospace;">r_of_inside</span>". This variable is unseen from the outside of the module (<i>caller</i> side). And even though it is used only once at the end of the module, it helps to improve readability.<br />
<br />
Finally, note that I moved the translation by height/2 closer to the "positive" shape. Carving the cylinder is more readable without a centering. This is the same reason we moved the "scale( )" closer to the sphere.<br />
<br />
<div style="margin: 0px;">
<span style="font-family: "courier new" , "courier" , monospace;"> module mug(width, height, bottom_thickness=2, wall_thickness=5)</span></div>
<div style="margin: 0px;">
<span style="font-family: "courier new" , "courier" , monospace;"> {</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> r_of_inside=</span><span style="font-family: "courier new" , "courier" , monospace;">width/2-wall_thickness;</span></div>
<div style="margin: 0px;">
<span style="font-family: "courier new" , "courier" , monospace;"> difference()</span></div>
<div style="margin: 0px;">
<span style="font-family: "courier new" , "courier" , monospace;"> {</span></div>
<div style="margin: 0px;">
<div style="margin: 0px;">
<span style="font-family: "courier new" , "courier" , monospace;"> translate([0,0,height/2])</span></div>
<div style="margin: 0px;">
</div>
<span style="font-family: "courier new" , "courier" , monospace;"> intersection()</span></div>
<div style="margin: 0px;">
<span style="font-family: "courier new" , "courier" , monospace;"> {</span></div>
<div style="margin: 0px;">
<span style="font-family: "courier new" , "courier" , monospace;"> cube([width,width,height], center=true);</span></div>
<div style="margin: 0px;">
<span style="font-family: "courier new" , "courier" , monospace;"> scale([1,1,height/width])</span></div>
<div style="margin: 0px;">
<span style="font-family: "courier new" , "courier" , monospace;"> sphere(width/2 * sqrt(2));</span></div>
<div style="margin: 0px;">
<span style="font-family: "courier new" , "courier" , monospace;"> }</span></div>
<div style="margin: 0px;">
<span style="font-family: "courier new" , "courier" , monospace;"> translate([0,0,</span><span style="font-family: "courier new" , "courier" , monospace;">bottom_thickness</span><span style="font-family: "courier new" , "courier" , monospace;">])</span></div>
<div style="margin: 0px;">
<span style="font-family: "courier new" , "courier" , monospace;"> cylinder(r=r_of_inside,h=height+0.1);</span></div>
<div style="margin: 0px;">
<span style="font-family: "courier new" , "courier" , monospace;"> }</span></div>
<div style="margin: 0px;">
<span style="font-family: "courier new" , "courier" , monospace;"> }</span></div>
<br />
<i><u>Important note</u></i>: there are some heavy restrictions on how you can use variables. Older versions of Openscad had problems when a module called itself for example. No big problem so far, as recursion is an advanced topic that we will tackle in the next article.<br />
<br />
<h3>
<span style="font-family: inherit;">Recycling the modules from other Openscad source files</span></h3>
<span style="font-family: inherit;">Our mug <i>module</i> can be saved to a scad file, as usual. Actually a scad file may contain more than one module.</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">A nice feature is that you can <i>import</i> scad files, just as we imported STL objects previously. Then,</span><span style="font-family: inherit;"> the modules are available in the new file just as if they were default shapes.</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">To do so you can create a new scad file and tell it to import your former mug scad file. I have to admit that the syntax is stupid given that "include" works as a regular function, why does it need to be otherwise for this one (my guess is: a clumsy heritage from the C language)?</span><br />
<span style="font-family: inherit;"><br /></span>
<br />
<span style="font-family: "courier new" , "courier" , monospace;"> include<mug .scad=""></mug></span><span style="font-family: "courier new" , "courier" , monospace;"> <mug.scad ></span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">Now there is a special comment to do. The behavior here is just as if you had copied/pasted the scad source from "mug.scad" in place of the "include" statement. In this case, you will see the mug-with-a-cup that we defined, even without creating any shape in your new file.</span><br />
<span style="font-family: inherit;"><br /></span><span style="font-family: inherit;">So there is another, probably more useful way to recycle your old designs, thanks to another function:</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;"> use</span><span style="font-family: "courier new" , "courier" , monospace;"> </span><span style="font-family: "courier new" , "courier" , monospace;"><mug.scad</span><span style="font-family: 'courier new', courier, monospace;"> </span><span style="font-family: 'courier new', courier, monospace;">></span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> mug(width=40, height=60);</span><br />
<br />
This time, the "use" statement only imports the <i>definition</i> of the modules that were defined in "mug.scad". It will not execute or create anything else though as it bypasses all immediate shapes from within mug.scad.<br />
<br />
Again: "use" statements will never generate shapes, even though we may have left some in "mug.scad". This is <i>very</i> convenient because "mug.scad" can do something on its own without polluting the new code here (e.g. just to show a standalone working example, as we did).<br />
<br />
<u><i>Note</i></u>: there are a lot of almost-official modules, in a library named <a href="http://reprap.org/wiki/MCAD">MCAD</a>. It brings a huge quantity of additional shapes and standard nuts, bolts and other industrial equipment. It is free as much as Openscad, and the source code is <a href="https://github.com/elmom/MCAD">here</a>.<br />
<br />
<h3>
Convex hull: creating complex shapes with basic ones.</h3>
Now, life with Openscad would not be possible without another operator: the <i>convex hull</i>.<br />
<br />
Think of it as the shape that you get when you wrap a plastic film around a bunch of shapes and heat it, with no resulting concave parts. The effect would be the same with soap (only incredibly harder to achieve in real life...)<br />
<br />
A sample will make this clear:<br />
<span style="font-family: "courier new" , "courier" , monospace;"> hull()</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> {</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> cube([10,10,10], center=true);</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> translate([20,0,0]) sphere(r=3);</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> }</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
Below you get an animation that changes from the regular "union( )" to a "hull( )".<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjYRmyNRI9J0-zjzZflO-vWct9MFHW03btZs0fbNXlf-mIFBpAuiIbbQiAaEr4CKDVx26bAFDT8tP_yylzuID0W3AlPT4lC9nS3I-9z32bw7DvOCcxVkzdXhu0DWUqJUpYKO8QNIHG7V5uI/s1600/hull.gif" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="262" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjYRmyNRI9J0-zjzZflO-vWct9MFHW03btZs0fbNXlf-mIFBpAuiIbbQiAaEr4CKDVx26bAFDT8tP_yylzuID0W3AlPT4lC9nS3I-9z32bw7DvOCcxVkzdXhu0DWUqJUpYKO8QNIHG7V5uI/s1600/hull.gif" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="font-size: 13px;">Animation showing the effect of "hull( )", aka "convex hull".</td></tr>
</tbody></table>
<br />
Usually no "complex" shape are used within a hull. But reciprocally, it is very rare that a complex shapes has no hulls.<br />
<br />
There can be any number of shapes within the hull, as we do below: to build a cube with round corners, we are constructing the convex hull of four cylinders.<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;"> hull()</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> {</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> translate([-10,-10,0])</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> cylinder(r=8,h=50, center=true);</span><br />
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> translate([10,-10,0])</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> cylinder(r=8,h=50, center=true);</span></div>
<span style="font-family: "courier new" , "courier" , monospace;"> translate([-10,10,0])</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> cylinder(r=8,h=50, center=true);</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> translate([10,10,0])</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> cylinder(r=8,h=50, center=true);</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> }</span><br />
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<i><u>Note</u>:</i> there are many way to build such a shape, and using a hull is mostly overkill: a union is enough, as we will see later. Anyhow, this is just an illustration of the use of hulls, and remember how wrong it is to use immediate values when they depend on each other! All this is fixed later.<br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">Also, remember that you can prefix a shape with % or # when you want to check its individual contribution to the union!</span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhPun0RU8Bu8gz5JrOkKBtkYRplSsm-llLOojsFBfceW_K_I4eA8mlygHtl4TLLDScUFO5f03h_VcQXCFYBHO9M2VkL0nNQHChSCoQthWA7FY030Nwb4adTB6RSEDnXaN_RnPlzmXbSxdy6/s1600/ugly_hull.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="262" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhPun0RU8Bu8gz5JrOkKBtkYRplSsm-llLOojsFBfceW_K_I4eA8mlygHtl4TLLDScUFO5f03h_VcQXCFYBHO9M2VkL0nNQHChSCoQthWA7FY030Nwb4adTB6RSEDnXaN_RnPlzmXbSxdy6/s1600/ugly_hull.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="font-size: 13px;">One way to build a (partially) rounded cube.<br />
We will do this better later...</td></tr>
</tbody></table>
<span style="font-family: inherit;"><br /></span><span style="font-family: inherit;">In fact, there are two improvements to be made, at least.</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">First, a hull is a lengthy operation, as Openscad needs to compute a lot of shapes. It is usually kept for shapes that cannot be achieved otherwise.</span><br />
<span style="font-family: inherit;"><br /></span><span style="font-family: inherit;">Indeed, the above is faster when we realize it no more than a union of 4 cylinders and 2 cuboids, this way:</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;"> union()</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> {</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> translate([-10,-10,0]) </span><span style="font-family: "courier new" , "courier" , monospace;">cylinder(r=8,h=50, center=true);</span><br />
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> translate([10,-10,0]) </span><span style="font-family: "courier new" , "courier" , monospace;">cylinder(r=8,h=50, center=true);</span></div>
<span style="font-family: "courier new" , "courier" , monospace;"> translate([-10,10,0]) </span><span style="font-family: "courier new" , "courier" , monospace;">cylinder(r=8,h=50, center=true);</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> translate([10,10,0]) </span><span style="font-family: "courier new" , "courier" , monospace;">cylinder(r=8,h=50, center=true);</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> cube([20,20+2*8,50], center=true); // space left inside</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> cube([20+2*8,20,50], center=true); // and in the other way</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> }</span><br />
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<span style="font-family: inherit;">Then, a second improvement should be made as this is no proper way to code anyway.</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">Remember what I said about copy/pasted code: avoid copy/pasting at all costs!</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">Here, it ought to be made with <i>loops</i>, i.e. repeated shapes (and not repeated typing). Which is </span><span style="font-family: inherit;">the subject of the </span><a href="http://www.tridimake.com/2014/11/howto-openscad-iteration-extrusion.html" style="font-family: inherit;">third article</a><span style="font-family: inherit;">, that tackles more advanced CSG techniques in Openscad.</span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
</div>
Jeremie Francoishttp://www.blogger.com/profile/02984201174566394892noreply@blogger.com0tag:blogger.com,1999:blog-3615478772815290200.post-48172563483750455222014-09-11T11:49:00.001+02:002020-12-17T08:35:33.823+01:00How to use Openscad (1), tricks and tips to design a parametric 3D object<div dir="ltr" style="text-align: left;" trbidi="on">
<h3 style="text-align: left;">
Part 1/5: Introduction to constructive solid geometry with Openscad</h3>
<div>
<div>
Some technical and non-technical people keep asking me how I create new designs. As often, after a few personal replies, I end up heading to the blog to share the answer as they keep asking for more.</div>
<div>
<br /></div>
<div>
Also, I long wanted to write a pragmatic and step-by-step introduction, howto and tutorial to Openscad. The idea is to help people even with no programming skills (mostly in this part) and to bring newcomers to a point that they can design their own 3D objects (<a href="http://www.tridimake.com/2014/09/howto-openscad-variables-modules-parametric-designs.html">part two</a>). Interestingly, Vicariously, Openscad is very interesting to get a glimpse at what programming is because you get an immediate, visual feedback of your actions (even my mother, a former history teacher, was eventually able to get a clue at what my job was about). Once understood these concepts, it may be much easier to move to other languages.</div><div>
<br /></div>
<div>
<div>Now, if only a few readers become "designers" by reading this I will be quite happy. If some people realize that programming is not that obscure I will be happy also. Meanwhile, I will have given a detailed answer to my friends and contacts!</div>
</div>
<div>
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiTPoF0IyZiruuGDqvEi9SWNvqj7saSNDNtIGWRTeF2lyYg_44rlnZOnmzKZe92PGcDkXhpLPiJEZ25B32pY21gOLVjR0pmKXKPrXwFry-7psk928DEcsDtO6O4x5uipIcm9jI8q3CHfAqN/s1600/gopro-mount-mooncactus.jpg" style="margin-left: auto; margin-right: auto;"><img border="0" height="308" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiTPoF0IyZiruuGDqvEi9SWNvqj7saSNDNtIGWRTeF2lyYg_44rlnZOnmzKZe92PGcDkXhpLPiJEZ25B32pY21gOLVjR0pmKXKPrXwFry-7psk928DEcsDtO6O4x5uipIcm9jI8q3CHfAqN/s1600/gopro-mount-mooncactus.jpg" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">A non-obvious <a href="http://www.thingiverse.com/thing:62800">GoPro mount</a> of mine, that is fully customizable thanks to Openscad.<br />
It looks complex, but it is still exclusively made of spheres, cylinders, and cubes with a few basic "joints".</td></tr>
</tbody></table>
<div>
A forthcoming last part will deal with the complex features of Openscad. This one is for people that either learn fast or for those that are already proficient with the usual features of Openscad.<br />
<ol>
<li><a href="http://www.tridimake.com/2014/09/how-to-use-openscad-tricks-and-tips-to.html"><span face=""arial" , "helvetica" , sans-serif"><b>Introduction to constructive solid geometry with OpenSCAD</b></span></a></li>
<li><a href="http://www.tridimake.com/2014/09/howto-openscad-variables-modules-parametric-designs.html"><span face=""arial" , "helvetica" , sans-serif">Variables and modules for parametric designs</span></a></li>
<li><a href="http://www.tridimake.com/2014/11/howto-openscad-iteration-extrusion.html"><span face=""arial" , "helvetica" , sans-serif">Iteration, extrusion and useful parametrized CSG techniques</span></a></li>
<li><a href="http://www.tridimake.com/2014/11/how-to-use-openscad-4-children-and.html"><span face=""arial" , "helvetica" , sans-serif">Children, factorized placement and chained hulls</span></a></li>
</ol>
</div>
</div>
<div>
<br /></div>
So first, what is <a href="http://www.openscad.org/">Openscad</a>? Within the <a href="http://en.wikipedia.org/wiki/Computer-aided_design">CAD family</a>, it is a 3D modeler: a software that helps you to create 3D objects. There are many such tools, but this one is used extensively in the 3D printing community, not only because it is free but because is it really efficient for some kind of objects.<br />
<br />
It may or may not suit your mind, but with time I am able to "see" the shape I describe, not as text but directly as shapes. I guess it depends on people, but I am sure there are people that are not programmers that can think alike. And if you are already a programmer with no industrial goal then you really should give it a try. It will be a breeze to use up to a productive level, especially if you do not want to invest time in a new and hellish interactive user interface!<br />
<br />
The <a href="http://en.wikibooks.org/wiki/OpenSCAD_User_Manual">official manual</a> is OK but it does not really work as an introduction. The navigation is also sometimes difficult to the point google is more useful. There is a nice raw <a href="http://www.openscad.org/cheatsheet/index.html">cheat sheet</a> also <strike>but it has no link to the respective functions (what a pity!)</strike> (update: it does now!). In any case, these fail to help <i>to learn</i> Openscad quickly in my humble opinion.<br />
<br />
<br />
<a name='more'></a><br />
This article is part of a longer serie:<br />
<ol style="text-align: left;">
<li><a href="http://www.tridimake.com/2014/09/how-to-use-openscad-tricks-and-tips-to.html"><span face=""arial" , "helvetica" , sans-serif"><b>Introduction to constructive solid geometry with OpenSCAD</b></span></a></li>
<li><a href="http://www.tridimake.com/2014/09/howto-openscad-variables-modules-parametric-designs.html"><span face=""arial" , "helvetica" , sans-serif">Variables and modules for parametric designs</span></a></li>
<li><a href="http://www.tridimake.com/2014/11/howto-openscad-iteration-extrusion.html"><span face=""arial" , "helvetica" , sans-serif">Iteration, extrusion and useful parametrized CSG techniques</span></a></li>
<li><a href="http://www.tridimake.com/2014/11/how-to-use-openscad-4-children-and.html"><span face=""arial" , "helvetica" , sans-serif">Children, factorized placement and chained hulls</span></a></li>
</ol>
<br />
<div>
<br /></div>
<br />
<br />
<b>Why Openscad?</b><br />
<br />
The software shines whenever you want:<br />
<br />
1) precise placement of object (as all objects have explicit numbered coordinates and sizes)<br />
<br />
2) easily modifiable design, e.g. when you want to make a wall thicker or a hole larger, and the whole design adapts to the new numbers automatically. It is thus easy to find the "optimum" geometry, weight or robustness for real-life applications.<br />
<br />
3) a text-readable design, and easily recyclable components or behaviors<br />
<br />
<br />
It is no surprise that Openscad is best suited to mechanical designs. As we said, compared to other 3D modelers, it shines when a number of iterations are required before the optimum geometry is obtained, because everything is controlled by numbers that can be tweaked extremely easily and at will (when it is programmed correctly).<br />
<br />
Now reciprocally, Openscad fails badly with organic shapes though: it is not the right tool to design a mascot, statue, or non-abstract art. My only attempt at art was the arguable <a href="http://www.thingiverse.com/thing:139945">bird-o-matic</a> generator, which creates simplified bird shapes with a few geometric shapes ;)<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgDGUWsvNTSqB0Bf4TqQ8KZcAI2iRo07rJwa1FYm66In1y5Fp9YysvDgHWnbRYxXEK1WCIlH3p-JDuWzfDZp1xiRylLvAcMJoRyiZm11h0_LNO1cU_OcLVGcTQGy9niVw1WKZnqiRSUMaPH/s1600/bird-o-matic.png" style="margin-left: auto; margin-right: auto;"><img border="0" height="264" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgDGUWsvNTSqB0Bf4TqQ8KZcAI2iRo07rJwa1FYm66In1y5Fp9YysvDgHWnbRYxXEK1WCIlH3p-JDuWzfDZp1xiRylLvAcMJoRyiZm11h0_LNO1cU_OcLVGcTQGy9niVw1WKZnqiRSUMaPH/s1600/bird-o-matic.png" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">An attempt to generate <a href="http://www.thingiverse.com/thing:139945">bird shapes</a> from one single design.<br />
Openscad is usually not a good tool for artists.</td></tr>
</tbody></table>
<br />
<br />
<br />
<h3 style="text-align: left;">
Introduction</h3>
<div>
<br /></div>
Openscad is still <i>programmed</i>. Designs are described within a text file, that it parses to generate and show 3D shapes. The mouse is only useful to view, zoom and rotate around the generated shape.<br />
<br />
But do not be afraid if you are not a programmer as you still can do a lot by following very intuitive rules.<br />
<br />
<h4 style="text-align: left;">
CSG and incremental design</h4>
<div>
<br /></div>
The basic ideas of <a href="http://en.wikipedia.org/wiki/Constructive_solid_geometry">constructive solid geometry</a> is not unlike the process an artist follows when he works with clay: he starts with nothing, and then he adds or removes material to make a shape that becomes closer and closer to his final idea. Parts of the object can also be made separately, like hands or arms for a statue that are stuck to the trunk once finalized.<br />
<br />
Openscad and CSG in general works the exact same way, except that each of the steps is described with names and explicit commands, that are applied one after another. "Carving" is even easier than in real life because any shape can be removed (including complex ones that are themselves built by adding elements!).<br />
<div>
<br /></div>
<h4 style="text-align: left;">
Encoding of a 3D object</h4>
<div>
<br /></div>
You can bypass this section when you do not care or if you feel lost, but it may help understand better.<br />
<br />
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; text-align: right;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEifITBlNMruBCKghC2YVTDLr7yQb2xcMQBvdq9a1tGOGheH6aHO2AAsdQ5illhrzSnXowbusc1ArZ2zx2nAE9ec26MI6pjzb5Hy2s000OrbsK8Iw6AWJijvjjB4wZsfq5hh98tI-3Wt71tV/s1600/rough_sphere.png" style="clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" height="288" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEifITBlNMruBCKghC2YVTDLr7yQb2xcMQBvdq9a1tGOGheH6aHO2AAsdQ5illhrzSnXowbusc1ArZ2zx2nAE9ec26MI6pjzb5Hy2s000OrbsK8Iw6AWJijvjjB4wZsfq5hh98tI-3Wt71tV/s1600/rough_sphere.png" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">A 3D sphere! Actually, it is a mesh of triangles<br />
that <i>approximates</i> what we think is a perfect sphere.</td></tr>
</tbody></table>
Virtual 3D designs are fed to printers through <a href="http://www.tridimake.com/2012/10/the-software-side-of-view.html">a slicer</a>, which computes the many commands to move the printer motors and temperatures. The most common file format to give to a slicer is <a href="http://en.wikipedia.org/wiki/STL_(file_format)">STL</a>, which is a primitive but powerful way to encode a 3D geometrical shape.<br />
<br />
But... it is only an <i>approximation</i> of the 3D object, with a mesh of 3D triangles, also called a <i>wireframe</i>.<br />
<br />
The STL file can even be opened with a text editor to show that it is a dumb list of triangles, that themselves rely of a set of points (known as 3D <a href="http://en.wikipedia.org/wiki/Vertex_(geometry)">vertices</a>). In fact, STL files can easily be generated by homemade programs to create mathematical shapes.<br />
<br />
<i><u>Note</u></i>: newer formats are slowly emerging, like the <a href="http://en.wikipedia.org/wiki/Additive_Manufacturing_File_Format">AMF</a>, (appropriately named "Additive Manufacturing File Format"). Indeed, STL only stores really basic information, while more and more is expected: curved surfaces, material, densities, heads, settings and so. In some time <a href="http://en.wikipedia.org/wiki/Voxel">Voxels</a> formats may raise, especially well suited to local material and properties. But for now, they have their own set of serious problems (mostly memory requirements).<br />
<br />
<br />
<h4 style="text-align: left;">
Where to get it? Just beware of older "pre-built packages".</h4>
<div>
</div>
As a general rule, you often benefit from getting the latest version directly from the <a href="http://www.openscad.org/downloads.html">official website</a>, especially on Linux where the regular packages exist, but which are sometimes seriously outdated ("apt-get"). When you have a weird behavior, such as corrupted 3D rendering, check your version first!<br />
<br />
Note: as an open source program, you have full and free access to the <a href="https://github.com/openscad/openscad">source code</a>. But it is worth only if you need to, or if you want to play with a promising feature which is being implemented by the developers and not yet released... and if you feel like you want to rebuild it yourself!<br />
<div>
<br /></div>
<h4 style="text-align: left;">
How to edit an Openscad file: the embedded editor</h4>
<div>
The editor that comes bundled with Openscad is poor at best (<u>update</u>: it got way better in March 2015!).</div>
<div>
<br />
I wish the authors spent the time on Openscad core functionalities itself, as the editor lacks many of the features a modern editor has. Now everything is free so it is difficult to complain, and, well, some like to use embedded editors! But if at least it was enhanced specifically with, say, "point and click" links between the 3D preview and the editor like the promising and gorgeous <a href="https://plus.google.com/explore/coffeescad">coffescad</a>... But no, it even had no "Search" for years and it only recently introduced colored keywords. Interestingly, we get the same issue with the <a href="http://arduino.cc/en/main/software">Arduino</a> processing IDE.<br />
<br />
So I highly recommend you use a fast, powerful and regular text editor instead (notepad++, UltraEdit, kate, gnome-editor... Please, just avoid the stinking default windows notepad, which is as useful as an ashtray on a motorbike). Then, you will like to hide and forget the embedded editor (tick "menu "View / Hide editor" in the Openscad menu).<br />
<div>
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjYlagyGH0ZmnfQhpTdvrQaQQyBdE2p8BFnlGUw6gJ9pdKtbhVLz6HmQt_Q9hJ2sGlSZJlRYVst99A3i6T9w41qmtSUVBcvjQgQS2e5c4Uf8XqTx7hbPFEJDoJjWo-5bHarbPwoopRrjh9C/s1600/kate_openscad.png" style="margin-left: auto; margin-right: auto;"><img border="0" height="203" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjYlagyGH0ZmnfQhpTdvrQaQQyBdE2p8BFnlGUw6gJ9pdKtbhVLz6HmQt_Q9hJ2sGlSZJlRYVst99A3i6T9w41qmtSUVBcvjQgQS2e5c4Uf8XqTx7hbPFEJDoJjWo-5bHarbPwoopRrjh9C/s1600/kate_openscad.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">A text editor with syntax coloring for Openscad (kate / Kubuntu / Linux)</td></tr>
</tbody></table>
There are also extensions to color the language keywords according to the Openscad syntax. If you do not get them from <a href="http://en.wikibooks.org/wiki/OpenSCAD_User_Manual/Using_an_external_Editor_with_OpenSCAD">this page</a>, you may find them with Google with your editor name and "syntax coloring Openscad".<br />
<br />
<div>
Now when editing the design, you would have to press F5 to refresh the view when the source changes.<br />
I recommend you tick instead the "Automatic Reload And Compile" option in the "Design" menu, so that Openscad refreshes the view as soon as you save your work. Only when the design is incredibly complex it makes sense not to refresh each time. But in this case, it is better to "deactivate" part of the design when you work on some other (we'll see this in "debugging" below).</div>
<div>
<div>
<br /></div>
<div>
Also, when you are done, you will need to export your file in the STL format, for the slicer to process it and to generate the so-called "gcode" commands to print the object. To do so, just press "F6" and Openscad computes the shape thoroughly, then "Export as STL..." (in the newest version of Openscad, this is in the "File" menu, while former versions had it in the "Design" menu).</div>
<div>
<br /></div>
<div>
Now, be aware that your <i>source code</i> extension is ".scad". Do not confuse it with the the generated STL file! Scad files describe the <i>shapes</i> in the Openscad language, while STL files are raw geometric triangular meshes. There is no way to restore a scad file from an STL, so make sure to save your scad design files (they are more important than the STL files).</div>
</div>
</div>
<div>
<br /></div>
<div>
<h3>
Basic language items</h3>
</div>
<div>
<br /></div>
Openscad language mostly looks like the C computing language, or even Java, Javascript or... well many of the modern languages. But keep reading please, because it is also way simpler both to write and to debug!<br />
<br />
Of course, typos are still forbidden, as they generate dreaded "syntax errors". When Openscad does not understand what you are trying to tell him (i.e. it seems not to react to your change), you should check the "console" of Openscad (disable the tick mark in the "View / Hide Console" menu). This is where you read the erroneous line number. Then go back to your editor and fix the error!<br />
<br />
Each command you give to Openscad must end with a semicolon. This is to tell Openscad that it has to do something at this point, while the former elements are preparing the work to do, like positioning the item or applying a transformation, and eventually telling the shape:<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;"> sphere(20);</span><br />
<br />
As you can see, the <i>parameters </i>are given in a pair of parentheses. Here we tell that the "sphere" has a radius of 20. Units are all millimeters, so if you want a huge and out of bounds 20-inch ball, just multiply the value:<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;"> sphere(20 * 25.4); // as 1 inch is 25.4 millimeters</span><br />
<br />
See also above? I wrote a <i>comment</i> in the source. Easy: Openscad ignores all text which is past a tight pair of slash characters until the end of the line. So this is where you put reminders, todos or any kind of useful information, mostly to be able to read the source months later! I highly recommend you put comments at every place that you may stumble upon later and ask "what the heck did I do here?".<br />
<br />
Of course, you can add, subtract, multiply or divide numbers. There is also a small set of usual mathematical functions like abs(x) for the absolute value of the number x, cosines and so. Usually, there is no need to <a href="http://en.wikibooks.org/wiki/OpenSCAD_User_Manual/Mathematical_Functions">check the list</a> if you ever programmed once.<br />
<br />
Enough for the theory, as it will be made easier with examples.<br />
<div>
<br /></div>
<h3 style="text-align: left;">
Basic shapes and language items</h3>
<div>
<br /></div>
<div>
The "primitive" shapes in Openscad are surprisingly few: spheres, cylinders, and cubes. Period.</div>
<div>
<br /></div>
<div>
Everything is made with these shapes, including the very complex one below (OK, with the help of a few smart operations that I will explain later).</div>
<div>
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjMlvDXC-HI4k4dad8-87xcHWbawHTTr0ruQS76d9-WUmNh87zNpmRGX2KgBu6Zj5MOTfTSQu3RiSo_AMOHAirO1NsERSqAQsPoVlQzKy5BhasK7MxApYg7qk-8NQlH_1JUHxJ4TVJmuPyA/s1600/rollerstruder.png" style="margin-left: auto; margin-right: auto;"><img border="0" height="261" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjMlvDXC-HI4k4dad8-87xcHWbawHTTr0ruQS76d9-WUmNh87zNpmRGX2KgBu6Zj5MOTfTSQu3RiSo_AMOHAirO1NsERSqAQsPoVlQzKy5BhasK7MxApYg7qk-8NQlH_1JUHxJ4TVJmuPyA/s1600/rollerstruder.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">The <a href="http://www.tridimake.com/2013/04/rollerstruder-filament-feeder-driver.html">rollerstruder</a>, a filament driver for 3D printers.<br />
Still made only of cubes, spheres, and cylinders, but 1000+ lines of Openscad!</td></tr>
</tbody></table>
<div>
<br /></div>
<div>
<br /></div>
<b>The primitive </b><b>sphere</b><b>, and how to view your shape</b><br />
<b><br /></b>
<br />
Let's start with the minimal or so-called <i>primitive</i> shapes. These are the basic building blocks, not unlike lego bricks except that there are fewer of them, and that we are going to distort them a lot later!<br />
<br />
Just write the following in a file named "temp.scad", which you open with Openscad. Use F5 to refresh the view after you save the file unless you have configured it for an automatic refresh (see above).<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;"> sphere(20);</span><br />
<br />
It will create and show a sphere that has a radius of 20 mm (i.e. a diameter of 40 mm). As shown, the sphere is centered on the three X,Y,Z axes by default.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQpt-qzgSmr_WhGAPMfa417SJkR-0LvfL-CFVziv6BqdvGundYPVCAA67qWkIaDIK9MuiVP9R9h9Q2fdOqgamC2phWxPHFYpK1OICwSLeDmMcMhyphenhyphenrbmIPdp0ocgULvyCSTXnoNS2O_OM1j/s1600/sphere.png" style="margin-left: auto; margin-right: auto;"><img border="0" height="263" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQpt-qzgSmr_WhGAPMfa417SJkR-0LvfL-CFVziv6BqdvGundYPVCAA67qWkIaDIK9MuiVP9R9h9Q2fdOqgamC2phWxPHFYpK1OICwSLeDmMcMhyphenhyphenrbmIPdp0ocgULvyCSTXnoNS2O_OM1j/s1600/sphere.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">A dumb sphere of radius 20 mm.</td></tr>
</tbody></table>
You can move around the object with:<br />
- left click + drag to rotate the view<br />
- right click + drag to translate the view<br />
Additionally, you can zoom with the mouse wheel (or shift + right click + drag).<br />
None of these will change the shape nor its position in space: only your point of view will vary.<br />
If you get lost, you can restore "easy" point of views with the well-named "View" menu.<br />
<br />
The origin is shown as the intersection of the main long line segments, of course, buried in the sphere above. But check the tiny (X,Y,Z) axes at the bottom left of the screen: they really help when you start to translate objects for example, as the design becomes more complex.<br />
<br />
Back to the sphere...<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;"> sphere(20);</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span> Now, and contrary to many languages, Openscad lets you <i>name explicitly </i>the parameters. I highly recommend this usage. Here you would re-write the above statement this way:<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;"> sphere(r=20);</span><br />
<div>
<br /></div>
<div>
In the above, "r" is called a "parameter". Naming parameters makes it more readable and less prone to errors (well, especially when there is more than one value to give). In fact named parameters usually become compulsory at some time.</div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<b>Another primitive shape: the cylinder</b><br />
<b><br /></b></div>
<div>
<br /></div>
<div>
To create a cylinder, just clear your source and type this instead:<br />
<br /></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> cylinder(r=10, h=20);</span></div>
<div>
<br /></div>
<div>
You see now why naming parameters is useful? Without them it would be impossible to tell which is the radius and which is the height: with names, the order of the properties no more counts:<br />
<br /></div>
<div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> cylinder(h=20, r=10);</span></div>
</div>
<div>
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiFIBgQQOCVL_Qns3Yz3F47KO1pJbKkLvC0ehZ8jN_rcvQgawzquaooF-Lk8i3lghOnfphp-htZI4bnwquhS18Sk8oFnOE5pckjwhs4ywiftwwjPVLxUUtQHoIQRqqpy-1ySgcYUUNzCN6Z/s1600/cyl_not_centered.png" style="margin-left: auto; margin-right: auto;"><img border="0" height="262" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiFIBgQQOCVL_Qns3Yz3F47KO1pJbKkLvC0ehZ8jN_rcvQgawzquaooF-Lk8i3lghOnfphp-htZI4bnwquhS18Sk8oFnOE5pckjwhs4ywiftwwjPVLxUUtQHoIQRqqpy-1ySgcYUUNzCN6Z/s1600/cyl_not_centered.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Default cylinder placement: flat on the (X,Y) plane.</td></tr>
</tbody></table>
<div>
<br /></div>
<div>
Actually, you could omit "h", and it will revert to the default value of 1 mm. Hence, to create a 20 mm wide and 1 mm thick "coin", you could write only this:</div>
<div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span> <span style="font-family: "courier new" , "courier" , monospace;"> cylinder(r=10);</span></div>
</div>
<div>
<br />
Of course, it not recommended as we usually never omit "r" nor "h" for a cylinder.</div>
<div>
<br />
But there are other parameters that are often left out, like this one:</div>
<div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> cylinder(h=20, r=10, center=true);</span></div>
</div>
<div>
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhBn5p8H_jEqVUZuZZuAu6e_XV5UJtBWWsMrQhMa7UIZ5G6ymFyqP9FZwrdTL6IFW1iOjxryWEIihORIbABikxoI7N4jI_f8P_SkiwjW0qdx4ox2AwUlSBItYyeKbmIjccgjBYIeIOIydda/s1600/cyl_centered.png" style="margin-left: auto; margin-right: auto;"><img border="0" height="262" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhBn5p8H_jEqVUZuZZuAu6e_XV5UJtBWWsMrQhMa7UIZ5G6ymFyqP9FZwrdTL6IFW1iOjxryWEIihORIbABikxoI7N4jI_f8P_SkiwjW0qdx4ox2AwUlSBItYyeKbmIjccgjBYIeIOIydda/s1600/cyl_centered.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Explicitly "centered" cylinder: it is now halfway into the (X,Y) plane.</td></tr>
</tbody></table>
<div>
<br /></div>
<div>
The latter tells Openscad to "center" the shape vertically: it is now halfway through the floor, whereas it was flat on it when "center" before (because the <i>default</i> value for "center" is false!).<br />
<br />
Hence any of the two following commands create/define the exact same cylinder. However, it is not a good practice to randomize the order of your parameters as it makes the source harder to read! Better stick to one convention only:</div>
<div>
<br /></div>
<div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> cylinder(r=10, h=20);</span></div>
</div>
<div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> cylinder(</span><span style="font-family: "courier new" , "courier" , monospace;">h=20</span><span style="font-family: "courier new" , "courier" , monospace;">, </span><span style="font-family: "courier new" , "courier" , monospace;">center=false, </span><span style="font-family: "courier new" , "courier" , monospace;">r=10); // same stuff</span></div>
</div>
<div>
<br /></div>
<div>
<br />
Another optional parameter is a secondary radius. This effectively shapes the cylinder as a tronconic shape:<br />
<br />
<br />
<div style="-webkit-text-stroke-width: 0px; color: black; font-family: "Times New Roman"; font-size: medium; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px;">
</div>
<br />
<div style="-webkit-text-stroke-width: 0px; color: black; font-family: "Times New Roman"; font-size: medium; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px;">
<div>
<div style="margin: 0px;">
<span style="font-family: "courier new" , "courier" , monospace;"> cylinder(</span><span style="font-family: "courier new" , "courier" , monospace;">h=20</span><span style="font-family: "courier new" , "courier" , monospace;">, r1=10, r2=5</span><span style="font-family: "courier new" , "courier" , monospace;">); // two radii make a cone!</span></div>
</div>
</div>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgwNqR7DhCYr7DVjtStTjU5F_mPwvu7HNw1wdy_0daPtc9P-7rCCAp2gBVhL08nBqX5Em3n3NgMlZ2OSLGeLvjAjQ83MDxOgGYx7GFd2sykTU9izWdoe_b0nEx0BPVQeeGZRohYeLDqNHdj/s1600/cone.png" style="margin-left: auto; margin-right: auto;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgwNqR7DhCYr7DVjtStTjU5F_mPwvu7HNw1wdy_0daPtc9P-7rCCAp2gBVhL08nBqX5Em3n3NgMlZ2OSLGeLvjAjQ83MDxOgGYx7GFd2sykTU9izWdoe_b0nEx0BPVQeeGZRohYeLDqNHdj/s1600/cone.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">A cylin... ah, well, no, a <i>cone</i>: primary and secondary radii can be specified!</td></tr>
</tbody></table>
<br /></div>
<div>
As we have seen with the scad-to-STL process, the cylinder really is approximated with spatial triangles, not curves. Remember: all boils down to triangular meshes at the end!<br />
<br />
Given the size of the cylinder, Openscad tries to guess how many facets it shall use to get a correct approximation of the "ideal" cylinder. But sometimes you want either more for a finer surface, or you want a specific number of facets.</div>
<div>
<br /></div>
<div>
This happens when you want to model hexagonal nuts for example: they are just cylinders with 6 facets after all!</div>
<div>
<br /></div>
<div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> cylinder(r=10, h=20, $fn=6);</span></div>
<div>
</div>
</div>
<div>
<br /></div>
<div>
The special "$fn" variable sets the number of facets that are generated to create a shape. But do not tweak it only to get finer details!<br />
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjFm2bd6TYHrANnIfh1S6uUFNLsQfFBx0zk73SGEXdOA3bkH8kuHiK9nCBHFelYx3hP73Xrb2lhzqkxUdp0vPGdnch03PebzPj2Iu_coH71Z0E5FQaaiTK7QiqZ_WaZ1u7V0nrbARqHo8B/s1600/cyl_hex.png" style="margin-left: auto; margin-right: auto;"><img border="0" height="256" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjFm2bd6TYHrANnIfh1S6uUFNLsQfFBx0zk73SGEXdOA3bkH8kuHiK9nCBHFelYx3hP73Xrb2lhzqkxUdp0vPGdnch03PebzPj2Iu_coH71Z0E5FQaaiTK7QiqZ_WaZ1u7V0nrbARqHo8B/s1600/cyl_hex.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Specifying the number of facets of a cylinder for a hexagonal shape with the $fn variable.</td></tr>
</tbody></table>
<div>
<br />
Of course, with 4 facets you would get a tower that actually is a "cube", but there is a specific primitive for this.<br />
<br />
<h3 style="text-align: left;">
Interlude: a technical note about the precision of the facets</h3>
<div>
<br /></div>
You can skip this paragraph unless you feel comfortable or interested by the underlying triangular 3D mesh. As we have seen all the shapes are composed of triangles at the lower level.<br />
<u><br /></u> We see these facets in Openscad, even without asking for it explicitly. But by choosing "View / Wireframe", you can see that even flat rectangular facets are subdivided into triangles!<br />
<br />
Now, when you want to get a finer surface, please do not use "$fn" as many people tend to do. Its purpose is to set the number of facets in very specific cases as above (the hexagonal nut), and not really to define the geometric resolution.<br />
<br />
Indeed, the right "number" of facets depends on the size of the object, which is hard to tell when it gets scaled or buried in other larger shapes. For example, asking for 100 facets on a 1 mm wide cylinder is nonsense. It would slow your computer quite a bit, and even more for more complex shapes.<br />
<br />
To set the resolution or "smoothness" of the mesh, there are two dedicated variables: "$fs" and "$fa". They respectively define the "maximum <b>s</b>ize" and "maximum <b>a</b>ngle" of the facets. The maximum size makes Openscad subdivide the facet when it becomes too large. More useful, the maximum angle tells Openscad to break/fragment a facet in two when the angle a facet has with its neighbors goes above a certain level.<br />
<br />
Hence, in order to get a very smooth surface, you use smaller values, like 1 for $fa and/or 0.5 for $fs. You can tell it this way:<br />
<br />
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> cylinder(r=3, h=10, $fa=1, $fs=0.5);</span><br />
<br /></div>
<div>
Zooming the view on the cylinder will now show that it got smoother (technically "approximated with many more facets").</div>
<div>
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjgXDt43nAFlHpFqpdzzsBPLCMAm_DUT3P4lgBiQx61icyKZG6HCtEWrdMZQrVE7LoSnGjsJFYQ3WdJfGV7yrq01wq0xiFbhYYeeO7B2wwR5RC_hWMF6hInZJ30hIXBlWd2YCeGbTW3MsmU/s1600/mesh_precision.gif" style="margin-left: auto; margin-right: auto;"><img border="0" height="237" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjgXDt43nAFlHpFqpdzzsBPLCMAm_DUT3P4lgBiQx61icyKZG6HCtEWrdMZQrVE7LoSnGjsJFYQ3WdJfGV7yrq01wq0xiFbhYYeeO7B2wwR5RC_hWMF6hInZJ30hIXBlWd2YCeGbTW3MsmU/s1600/mesh_precision.gif" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Two mesh precision, animated, defined by the $fa and $fs special properties.<br />
See also how you can use spaces and newlines just to better format the source!</td></tr>
</tbody></table>
<div>
<br /></div>
If you want to achieve the same resolution for each and every primitive shape in your design, it is easier to set them as the default values, like this:<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;"> $fa=0.5; // default minimum facet angle is now 0.5</span><br />
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> $fs=0.5; // </span><span style="font-family: "courier new" , "courier" , monospace;">default</span><span style="font-family: "courier new" , "courier" , monospace;"> </span><span style="font-family: "courier new" , "courier" , monospace;">minimum facet size is now 0.5 mm</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> cylinder(r=3,h=10);</span><br />
<br /></div>
<div>
<div>
The deal is these values are used unless a primitive has his own explicit values (as above for the cylinder: they get the priority of course). And unless $fn is explicitly given, it is computed according to the $fa and $fs values. Here we are.</div>
</div>
<div>
<br /></div>
<div>
Another useful strategy is to use $fa=1 and $fs=1.5 as long as you are in the design phase, building your shapes. This gives you a fast and reactive rendering. Only once you are done, you can set them to smaller values, so as to save/export a very smooth STL mesh (i.e. once the design is done). It will grow larger as a file also (no need to have 80MB STL files for a 3D printer, as it cannot be so precise!).<br />
<br />
By the way, setting both $fa and $fs to less than 0.5 is probably overkill. It would generate a huge number of facets, i.e. a large amount of resulting gcode, with segments that are often smaller than what the printer is capable of. More importantly, if you use a serial link like a USB tethered printer, small pauses may happen as the link is overflown. Even with an SD card, the Arduino may fail to keep up with the conversion in real time (esp. on delta printers). And not having a smooth movement impacts the print significantly! Chose a proper trade-off!<br />
<br /></div>
<div>
<br /></div>
</div>
<div>
<br /></div>
<h3 style="text-align: left;">
<span style="font-family: inherit;">The cube, and [X,Y,Z] vectors in Openscad</span></h3>
<br />
Mathematically speaking, these are <a href="http://en.wikipedia.org/wiki/Cuboid">cuboids</a> (flattened cubes), but that's how Openscad names them.<br />
Anyhow, they use a special notation or "syntax": instead of explicit naming them, you provide the 3 sizes along the X, Y, and Z axes respectively this way :<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;"> cube([20,10,5]);</span><br />
<br />
See the three-numbers-in-brackets? They define a 3-element "vector", where the components set the dimensions of the cube on the X, Y and Z directions respectively.<br />
<br />
Do not forget the square brackets or Openscad will yell at you in the "console" windows (once again it is almost necessary to leave it open -- not shown on the screenshots here though!).<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh8owmY3A4VVQg8YWIEZVIWsLm_rFfdZx-mpiqckRWnSa-7pocLtqTT5i6IcUJ0q3CiFI3JsqGfbxzyhbBP_gLnKCd19nNwkvNHp2qkhduYHXKIwwDXIaFkECf7_MSewCqnlTujMKp2l2W0/s1600/cube.png" style="margin-left: auto; margin-right: auto;"><img border="0" height="256" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh8owmY3A4VVQg8YWIEZVIWsLm_rFfdZx-mpiqckRWnSa-7pocLtqTT5i6IcUJ0q3CiFI3JsqGfbxzyhbBP_gLnKCd19nNwkvNHp2qkhduYHXKIwwDXIaFkECf7_MSewCqnlTujMKp2l2W0/s1600/cube.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Cube (default placement is towards the positive X,Y,Z directions)</td></tr>
</tbody></table>
So we have created here a cube that is 40 mm along the X axis, 10 mm on Y and 5 mm high.<br />
<br />
One problem with cubes is they are either in the positive quadrant (X,Y,Z) as above, or they are fully centered on the origin of the axes when the "center" parameter is true like below:<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEge4ablGCf4UVuRqC4aqDR3-c9pMdRimdSgn-ak0OXRpExqY1F5IVoSomUIq5fRnR_2wV0Z1L1ApS96o4Afp24bB9wkIWxjtWzSqwS1Vy0SyVYaabtvufcQ32pPhN0bKsg2bSmG1WyLwc6Y/s1600/cube_centered.png" style="margin-left: auto; margin-right: auto;"><img border="0" height="256" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEge4ablGCf4UVuRqC4aqDR3-c9pMdRimdSgn-ak0OXRpExqY1F5IVoSomUIq5fRnR_2wV0Z1L1ApS96o4Afp24bB9wkIWxjtWzSqwS1Vy0SyVYaabtvufcQ32pPhN0bKsg2bSmG1WyLwc6Y/s1600/cube_centered.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Cube (centered on all three axes)</td></tr>
</tbody></table>
We are going to see how to "fix" this now.<br />
<br />
<h3 style="text-align: left;">
Basic <i>operations</i>: where it all starts!</h3>
<div>
<br /></div>
<b>First of all, let us translate some cube (i.e. shift the position of the </b><b>object</b><b>)</b><br />
<b><br /></b>
<br />
As we have seen, there is no way to lay a cube like cylinders, i.e. centered on X,Y where the bottom is kept at position Z=0. But Openscad, as any CSG modeler, has a set of basic geometrical transformations.<br />
<br />
And the easiest one is the translation which is exactly what we need here. But contrary to the primitive shapes, a translation does not <i>define</i> an object. Instead, it <i>modifies</i> the object that follows.<br />
<br />
Like the cube, translations expects a vector of 3 values, one per axis.<br />
<br />
We can now translate our cube, with the following syntax:<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;"> translate([0,0,2.5]) cube([20,10,5],center=true);</span><br />
<br />
It does not matter how much space or new lines you put in between the two, or after of before the commas and other symbols. But you should write the semicolon only <i>at the end</i>, after you are done telling that something really is done: "<i>translate</i>" always expects a shape to follow!<br />
<br />
Once again, translations, as all the other non-primitive operations, do not do anything by themselves, they just "modify" the shapes that come right after them.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhLNBfEO_SYGUCh3Ba08n4ua18_y7QG88F2sVVz1-rxAtJxgM78OCISE5ZQQhkrxVsm_d2X4CsjOcDNH4yjIp78QSgyMhPkC4lKcir4jXx3GpzI9c0PozJ8YbgFxCVLGwEEKgoKHgUL-N_f/s1600/cube_centered_XY.png" style="margin-left: auto; margin-right: auto;"><img border="0" height="255" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhLNBfEO_SYGUCh3Ba08n4ua18_y7QG88F2sVVz1-rxAtJxgM78OCISE5ZQQhkrxVsm_d2X4CsjOcDNH4yjIp78QSgyMhPkC4lKcir4jXx3GpzI9c0PozJ8YbgFxCVLGwEEKgoKHgUL-N_f/s1600/cube_centered_XY.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">We raised the previously centered cube flat on the (X,Y) plane,<br />
thanks to a translation of half its height toward positive Z.<br />
<br /></td></tr>
</tbody></table>
What it does is to leave the cube at the same X and Y positions (zero offset on X and on Y), but it moves the cube up by 2.5 mm on Z (of course, negative numbers would sink the cube towards the bottom).<br />
<br />
In our case, the cube was 5 mm tall and positioned halfway on the (X,Y) plane. This is why we are raising it by 2.5 mm, i.e. half of its height: the result is a cube centered only on X and Y, and which is now flat on the (X,Y) plane at Z=0.<br />
<br />
Just like default cylinders are laid out!<br />
<br />
<br />
<b>Union of shapes: where "constructive solid geometry" start to make sense!</b><br />
<b><br /></b>
<br />
Now for a new and important operation! So-called "unions" are also the default behavior in Openscad when you write more than one shape. What happens is that they get added/merged/fused together.<br />
<br />
So when you write:<br />
<div style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; margin: 0px; text-indent: 0px;">
<!--StartFragment--><span style="font-family: "courier new" , "courier" , monospace;"> cube([20,20,20], center=true);</span></div>
<span style="font-family: "courier new" , "courier" , monospace;"> sphere(14);</span><!--EndFragment--><br />
<br />
Then Openscad creates a new shape which surface really becomes a mix of a cube and a sphere, as shown below!<br />
<div>
<br /></div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgbW47LX6-WlmJpQ14Ay8Zri_mqCcKQrak0N28SLRvU8nR7b5U3xF8ySY2XiTYc4s1_7r2OL4RTv9dVSmQTAzp0fWndytAC2I6ykqOOXcwF-rfTCn4KAu0_vV1Hq4_teHXyn-3acdw0soI5/s1600/cube_sphere_union.png" style="margin-left: auto; margin-right: auto;"><img border="0" height="255" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgbW47LX6-WlmJpQ14Ay8Zri_mqCcKQrak0N28SLRvU8nR7b5U3xF8ySY2XiTYc4s1_7r2OL4RTv9dVSmQTAzp0fWndytAC2I6ykqOOXcwF-rfTCn4KAu0_vV1Hq4_teHXyn-3acdw0soI5/s1600/cube_sphere_union.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Union (addition) of a cube and a slightly larger sphere in Openscad.<br />
The union( ) operator is implicit. The result really is a mix of both.</td></tr>
</tbody></table>
<br />
Oh, by the way: to make it clearer, you can give a color to one of the shapes, by specifying a vector of three R,G,B values (they are numbers within 0 and 1, and not 255 as usual).<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg6tVZi6DKue6NriuAxkK1BlESPiTc4saM3VXT6-4ZL9vy2BSz70Gb7AaNbyNUYpdynBM9TfjgsioZt1FpF1RlhLpGcUsYwD3j7bEKHUWEbhKr5kp-q-62XqTw0F7l56y5m8F9Hq_upTpyO/s1600/color.png" style="margin-left: auto; margin-right: auto;"><img border="0" height="252" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg6tVZi6DKue6NriuAxkK1BlESPiTc4saM3VXT6-4ZL9vy2BSz70Gb7AaNbyNUYpdynBM9TfjgsioZt1FpF1RlhLpGcUsYwD3j7bEKHUWEbhKr5kp-q-62XqTw0F7l56y5m8F9Hq_upTpyO/s1600/color.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="font-size: 13px;">Using colors and an explicit union() to understand what happens!</td></tr>
</tbody></table>
Actually, you will get the exact same behavior with this slightly more <i>verbose</i> way. Being able to write explicit "unions( )" operators is often required, as we will see in a short moment.<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;"> union()</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> {</span><br />
<!--StartFragment--><span style="font-family: "courier new" , "courier" , monospace;"> cube([20,20,20], center=true);</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> sphere(14);</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> }</span><br />
<br />
It creates a new (non-primitive) shape by fusing the primitives that are given inside the pair of curly braces, merging them into each other.<br />
<div>
<br /></div>
The above syntax is new, however. Easy! You can consider curly braces { like this } to be nothing more than a way to <i>group</i> shapes so that a former operator like our "union( )" is applied to the <i>whole</i> group.<br />
<br />
We use curly braces in many cases: for example, to <b>translate</b> the two object by 10 mm further on the Y axis and 3 mm downwards on the Z, we would use this syntax:<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;"> translate([0,10,-3])</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> {</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> cube([20,20,20], center=true);</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> sphere(14);</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> }</span><br />
<br />
Of course, you are not limited to two shapes: you can add as many as you want.<br />
<br />
Make sure to understand the importance of these curly braces, because only the cube would be shifted if written like this:<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;"> translate([0,10,-3])</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> cube([20,20,20], center=true);</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> sphere(14);</span><br />
<br />
<div>
<span style="font-family: inherit;">Remember, spaces are only conventions to make it more readable, and an operator only applies to the next "block". Indentation is just a convention. So if you are unsure, you can always add curly braces after such an operator, even if there is only one object that gets translated.</span><br />
<span style="font-family: inherit;"><br /></span> <span style="font-family: inherit;">So curly braces are just a way to group a bunch of shapes that are modified altogether.</span></div>
<br />
<br />
<b>Now for some real difference...</b><br />
<b><br /></b>
<br />
As much as you can add one primitive to another, you can also subtract one shape from another, effectively <i>carving</i> the first shape by means of the second shape.<br />
<br />
The "difference( )" operator also applies on a number of shapes, just as the union above. Now the order is important: the first shape is created as usual (<i>positive</i> shape), and then are the shapes of every other subsequent item subtracted from it (they ate the <i>negative</i> shapes), i.e. removing material each time.<br />
<br />
Consider this example:<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;"> difference()</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> {</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> cube([20,20,20], center=true);</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> sphere(14);</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> }</span><br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjfQsckzsjzrJ9mG-WWjdB8xkcy3KooXPHm8i7UG0IZyiKU47pvo-1LWAEJeQfSvr7CPDpjvMQSa-2_VCojktgeQ0zGvGzZ2JYkP9cc60CUO7Le3abAUq9dA1A_CoLwVUAT1sqZm060xKxy/s1600/cube_sphere_diff.png" style="margin-left: auto; margin-right: auto;"><img border="0" height="255" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjfQsckzsjzrJ9mG-WWjdB8xkcy3KooXPHm8i7UG0IZyiKU47pvo-1LWAEJeQfSvr7CPDpjvMQSa-2_VCojktgeQ0zGvGzZ2JYkP9cc60CUO7Le3abAUq9dA1A_CoLwVUAT1sqZm060xKxy/s1600/cube_sphere_diff.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Difference (subtraction) of a cube and a slightly larger sphere in Openscad<br />
Do you see how the sphere became a "negative shape"?<br />
The first shape is "solid", and all subsequent shapes remove material from it.</td></tr>
</tbody></table>
<div>
<span style="font-family: inherit;"><br /></span> <span style="font-family: inherit;"><br /></span></div>
<div>
<b>The danger of CSG subtraction: dreaded undefined surfaces!</b><br />
<b><br /></b></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<span style="font-family: inherit;">There is an extremely important thing to know here. When you subtract a shape from another one, you must make sure not to leave any wall or surface with no thickness. Seriously, this happens often if you do not take care of it.</span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<span style="font-family: inherit;">Say e.g. you want a cube with a </span>cylindrical<span style="font-family: inherit;"> hole through it. The naive idea then is to create a cube and then subtract a cylinder from it. And it can be done like this, true?</span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> difference()</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> {</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> cube([20,20,20]); // a 20 mm cube</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> translate([10,10,0]) // move origin</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> cylinder(r=5,h=20);</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> }</span></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhvO9NDGmtJfODauXqQHgAxUbK2aq8dCpW9zzRtfju24HNE6uDFogrfYVyR3N90zDyf1NkjvmaufbLI07bjymuskqk9n9yirheJrMVt3yShM1OmbKTiPqg0-eXabW4W5U__Y6_hVegI2nCU/s1600/cube_cylinder_non_manifold.png" style="margin-left: auto; margin-right: auto;"><img border="0" height="255" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhvO9NDGmtJfODauXqQHgAxUbK2aq8dCpW9zzRtfju24HNE6uDFogrfYVyR3N90zDyf1NkjvmaufbLI07bjymuskqk9n9yirheJrMVt3yShM1OmbKTiPqg0-eXabW4W5U__Y6_hVegI2nCU/s1600/cube_cylinder_non_manifold.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Terribly wrong! This definition leaves the top hole surface undefined:<br />
hey, is it within or outside of the object? This surface has no thickness!</td></tr>
</tbody></table>
<div>
<span style="font-family: inherit;">But this is <i>wrong</i>! Really! Think about the poor computer: at the cylinder outer limits you created surfaces with no thickness at all. The result is said to be "<i>non manifold</i>".</span><br />
<span style="font-family: inherit;"><br /></span> <span style="font-family: inherit;">Such wrong surfaces cannot be parsed correctly by 3D printer slicers: shall they really create an infinitely thin surface there or just drop it? Contrary to most serious CAD tools, the so intuitive </span><a href="http://www.sketchup.com/">Sketchup</a> is very broken in this regard, as it leaves a lot of undefined surfaces while the user design them interactively (in turn, it explains why so many Sketchup designs are so hard to slice and to 3D print -- and why I just cannot recommend this CAD software... at least check regularly with a 3D slicer to know when your design broke!).<br />
<br />
More annoying even, such undefined surfaces are very hard to find and fix afterward.</div>
<div>
<span style="font-family: inherit;"><br /></span> <span style="font-family: inherit;">So what should we do?</span><br />
<span style="font-family: inherit;"><br /></span></div>
<div>
<span style="font-family: inherit;">The only safe solution is always to carve <i>a bit more</i> than what you want intuitively!</span></div>
<div>
<span style="font-family: inherit;">So, making the cylinder one more millimeter taller lets it protrude out of the cube, right?</span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> difference()</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> {</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> cube([20,20,20]); // a 20 mm cube</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> translate([10,10,0])</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> cylinder(r=5,h=20+1); // carve 1 mm higher</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> }</span></div>
</div>
<!--EndFragment--><br />
<div>
<span style="font-family: inherit;">No, wrong again! Do not forget that the same issue exists at the base of the cylinder also (Z=0), it is left neither in or out of the resulting shape.</span></div>
<div>
<span style="font-family: inherit;"><br /></span> <span style="font-family: inherit;">The only real solution is to make sure the subtracted cylinder protrudes from <i>both sides</i>:</span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> difference()</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> {</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> cube([20,20,20]); // a 20 mm cube</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> translate([10,10,-1]) // start 1 mm below the surface</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> cylinder(r=5,h=20+1+1); // and go 1 mm above</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> }</span></div>
</div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<span style="font-family: inherit;">In this last fix, the cylinder really starts one millimeter below the (X,Y) plane, and stops one millimeter above the top of the cube.</span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgtOxLr4XDeJkcoSxy7kdRpuKwM8fwCDYYxlp8OK7peHhMgfdVD_cqB5zO_JTca_bTb3kmevtMRQVMaMqVLeFxkaY_7eS9l9oUesrOx38mSkZV1_OXOpbmFjhwCvLOd2gJa9-X60EreLoaC/s1600/cube_cylinder_manifold.png" style="margin-left: auto; margin-right: auto;"><img border="0" height="255" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgtOxLr4XDeJkcoSxy7kdRpuKwM8fwCDYYxlp8OK7peHhMgfdVD_cqB5zO_JTca_bTb3kmevtMRQVMaMqVLeFxkaY_7eS9l9oUesrOx38mSkZV1_OXOpbmFjhwCvLOd2gJa9-X60EreLoaC/s1600/cube_cylinder_manifold.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">The right way to subtract a shape in CSG: the shape to remove must<br />
not leave any undefined surface, so it must protrude a bit from the shape to carve.</td></tr>
</tbody></table>
<div>
<br /></div>
<h3 style="text-align: left;">
<b>Debugging designs, looking for non-manifold issues</b></h3>
<div>
<br /></div>
<div>
<span style="font-family: inherit;">Openscad offers nice ways to double check design problems. Especially, subtracted objects are hard to see (obviously!), so they cause a lot of headaches at first.</span></div>
<div>
<br /></div>
<div>
<span style="font-family: inherit;">But you may prefix any command or block with a hash character, and Openscad displays it as semi-transparent:</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> difference()</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> {</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> cube([20,20,20]);</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> translate([10,10,-1])</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> #cylinder(r=5,h=20+2); // made half transparent to check!</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> }</span></div>
</div>
</div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg26l5ATlxZpyf4i2RW0hW-3afqbvFMT6HF2empb-IPatbbxWnK0pU7zd5r3xVTag41e1LhNLvzN2_M1tOe-kxMtyf0PwE3zOqmo2u3i6dIiv3Qq5JGxIkkmodsYgtpQoflDSRPPgzlMX6Y/s1600/debugging.png" style="margin-left: auto; margin-right: auto;"><img border="0" height="255" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg26l5ATlxZpyf4i2RW0hW-3afqbvFMT6HF2empb-IPatbbxWnK0pU7zd5r3xVTag41e1LhNLvzN2_M1tOe-kxMtyf0PwE3zOqmo2u3i6dIiv3Qq5JGxIkkmodsYgtpQoflDSRPPgzlMX6Y/s1600/debugging.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Using a hash to double check that the cylinder to subtract protrudes from the cube<br />
on both sides. When rendered (F6), it will still be removed from the shape.</td></tr>
</tbody></table>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<span style="font-family: inherit;">Now, other "special" characters provide more ways to help debugging the design.</span></div>
<div>
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgw2joFlteJ5O7IFAod9mqS7VDC2v5YcypF7YVDzE-yKDBYyBkIIp5DVQauhAH12FmrIZAPEDDuMZUkF0RUbaBrZ1jgK5HHnAS14Pwe6aF9JjG_YJ5hiy7m9fPuXnrSaArXSJltztkjYLQM/s1600/propeller.gif" style="margin-left: auto; margin-right: auto;"><img border="0" height="258" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgw2joFlteJ5O7IFAod9mqS7VDC2v5YcypF7YVDzE-yKDBYyBkIIp5DVQauhAH12FmrIZAPEDDuMZUkF0RUbaBrZ1jgK5HHnAS14Pwe6aF9JjG_YJ5hiy7m9fPuXnrSaArXSJltztkjYLQM/s1600/propeller.gif" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">A <a href="http://www.openscad.org/">propeller design</a> from the official website, where the enclosure is a "ghost" just to provide a context.<br />
Only the propeller will make it to the output file when exported to STL.</td></tr>
</tbody></table>
<div>
<span style="font-family: inherit;">When a shape is prefixed with a star "*", Openscad will completely bypass it. It will not be shown, nor computed, not even appear in the "compiled" final shape (F6). This is useful when you are building a complex design and do not want to be distracted by parts that are not related to the one that is being designed, either for better viewing or because they slow down the rendering.</span></div>
<div>
<span style="font-family: inherit;"></span><br />
<span style="font-family: inherit;"></span></div>
<div>
<span style="font-family: inherit;">Reciprocally, an </span>exclamation<span style="font-family: inherit;"> mark "!" prefix will show only the given part (it hides all the others parts of the design). I use it all the time when I want to work on a sub-part of a complex design, without any disturbance from the remaining.</span></div>
<div>
<span style="font-family: inherit;"></span><br />
<span style="font-family: inherit;"></span></div>
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; text-align: center;"><tbody>
<tr><td><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgYM_hHc1vEEuBRfXcBuB2m1eJav6QrMSSOkd1v3_EnCF6hYi0b_RREyW2inwLG1RB0rb234HjLD0M24ma3fiTXvKiY1FXLWSoTyBnB6zP2pbFxkeT-THDrr6GmvT0kbN84zlQBHTM4FONZ/s1600/perspective0.png" style="margin-left: auto; margin-right: auto;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgYM_hHc1vEEuBRfXcBuB2m1eJav6QrMSSOkd1v3_EnCF6hYi0b_RREyW2inwLG1RB0rb234HjLD0M24ma3fiTXvKiY1FXLWSoTyBnB6zP2pbFxkeT-THDrr6GmvT0kbN84zlQBHTM4FONZ/s1600/perspective0.png" width="140" /></a></td></tr>
<tr><td class="tr-caption" style="font-size: 13px;">Disabling perspective is useful<br />
to check alignment (bottom)</td></tr>
</tbody></table>
<div>
<span style="font-family: inherit;">As shown in the complex shape above, the percent sign "%" is also very useful. It shows the shape as half transparent like with the hash sign, but, in addition, the part will not be included in the final shape (F6, STL). This is very useful to draw bearings or other hardware components, or spaces that shall not be crossed in a design, and <i>without impacting the final object</i>. I call these "ghosts". And they also often </span>embellish<span style="font-family: inherit;"> the rendering!</span></div>
<div>
<span style="font-family: inherit;"></span><br />
<span style="font-family: inherit;"></span></div>
<div>
<br /></div>
<div>
<span style="font-family: inherit;">We already talked about the "color( )" operator, that just changes the color of a shape to make it stand out, with no other sort of impact on the final design. Note however that </span>once a color is given to a shape, no sub-part can be re-colored. Subsequent calls to color() in the branch of the CSG tree will be ignored (yes, it sounds like a bug, and an annoying one when debugging: you will have to remove the topmost color definition and duplicate it in the branches below).</div>
<div>
<span style="font-family: inherit;"></span><br />
<span style="font-family: inherit;"></span></div>
<div>
<br />
Also in the view menu, you can show/hide the underlying triangular mesh, which is not that useful in my opinion.<br />
<br />
<br />
But the menu also lets you disable the perspective. I often leave it in orthogonal mode, because it is easier to see whether parts are correctly aligned or not, and also to get a better sense of gaps between parts.<br />
<br />
And well, being less pretty does not mean being less efficient ;)</div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<span style="font-family: inherit;"></span><br />
<br />
<h3 style="text-align: left;">
Rotation: a necessary evil</h3>
<br />
Using once again a three number vector, you can specify a rotation as well, on each X,Y,Z axis.<br />
<br />
In practice, we very rarely give more than one value at a time to the "rotate( )" operator because it makes things immediately hard to follow! It is usually better to write two consecutive rotations than a combined one.<br />
<br />
Here is an example:<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;"> rotate([90,0,0])</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> {</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> cylinder(r=2, h=10);</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> }</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span> It first rotates the axis system by 90° anticlockwise around the X axis (the trigonometric way), and only then it creates a thin cylinder. The result is the following:<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhdxwvFkJaqr0fD3OLdm_1-Rdd6UMsRcuuB2_ClK4pUhYdUnX_goL7-QpzHAwi0PjMS4OwptBTcU_2PPHyXIIEnb0mY32GVcVXCcRpIKoUrt182-lTFhC1rtm9BN6abQEiz2gdwnBeOpjDZ/s1600/cyl_rot.png" style="margin-left: auto; margin-right: auto;"><img border="0" height="256" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhdxwvFkJaqr0fD3OLdm_1-Rdd6UMsRcuuB2_ClK4pUhYdUnX_goL7-QpzHAwi0PjMS4OwptBTcU_2PPHyXIIEnb0mY32GVcVXCcRpIKoUrt182-lTFhC1rtm9BN6abQEiz2gdwnBeOpjDZ/s1600/cyl_rot.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="font-size: 13px;">Rotated cylinder, by 90° <i>anticlockwise</i> around the X axis.<br />
I tend to get the direction wrong all the time!</td></tr>
</tbody></table>
Easy so far, right?<span style="font-family: inherit;"></span></div>
<div>
<br /></div>
<div>
But things tend to get more complicated if you rotate a complex shape and then try to work within the shape... The axes are no more oriented as the small X,Y,Z triplet in the bottom left of the view, so it is easy to get lost and to start translating shapes along the wrong direction.<br />
<br />
Indeed: in the fallen cylinder above, the Z axis became an inverted version of the Y axis. Huh.</div>
<div>
<br /></div>
<div>
<br />
<div style="-webkit-text-stroke-width: 0px; color: black; font-family: "Times New Roman"; font-size: medium; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px;">
<div>
</div>
</div>
<br />
<div style="-webkit-text-stroke-width: 0px; color: black; font-family: "Times New Roman"; font-size: medium; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px;">
<div style="margin: 0px;">
The best thing to do is</div>
<div style="margin: 0px;">
1) to practice a lot and flex your mind in a virtual 3D space (it does work after a while), or</div>
<div style="margin: 0px;">
2) simpler, use the "!" prefix on the block you are editing and after the "rotate( )". You then are back in an upright coordinate system! Once done, just remove the exclamation mark.</div>
</div>
</div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0zI5cRy8vT1hlNWiD6OXVyMswNofuhEJtNQSDhJyws_vEyb067bTEdrwu_rjg0yc_y-pykbFSOWDvSDGfhLsPxuxD0aHFsKTMN1l_Ds9vviSLQK6uTyXbnHarrtaqSt_ySnlzS9wWIDBW/s1600/debug_rotation.png" style="margin-left: auto; margin-right: auto;"><img border="0" height="252" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0zI5cRy8vT1hlNWiD6OXVyMswNofuhEJtNQSDhJyws_vEyb067bTEdrwu_rjg0yc_y-pykbFSOWDvSDGfhLsPxuxD0aHFsKTMN1l_Ds9vviSLQK6uTyXbnHarrtaqSt_ySnlzS9wWIDBW/s1600/debug_rotation.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Using the "!" prefix is really useful to work in upright coordinates.<br />
Rotated shapes makes life harder as axes no more match those of the main view.<br />
Did you see BTW that we <i>had</i> to use a union to "group" the two shapes?</td></tr>
</tbody></table>
<div>
<br /></div>
<h3 style="text-align: left;">
<span style="font-family: inherit;">Designing more complex shapes</span></h3>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<span style="font-family: inherit;">We have seen the difference of two objects, but you can also have an </span><b>intersection</b><span style="font-family: inherit;">:</span></div>
<div>
<span style="font-family: inherit;"></span><br />
<span style="font-family: inherit;"></span></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgBBUdUAtyqObIankzCqM2fonAwG2w_s37IqbhWsjmkrrCkiHp0pPhx-fgk-mtZQZnlsT_ND0BIKEp3sC5C1i65NqDjYhMdtnnfe0Erj_01Gy-ljkFbERPFHCI6HFeqUBhcA86GkZmmjKhf/s1600/cube_sphere_inter.png" style="margin-left: auto; margin-right: auto;"><img border="0" height="255" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgBBUdUAtyqObIankzCqM2fonAwG2w_s37IqbhWsjmkrrCkiHp0pPhx-fgk-mtZQZnlsT_ND0BIKEp3sC5C1i65NqDjYhMdtnnfe0Erj_01Gy-ljkFbERPFHCI6HFeqUBhcA86GkZmmjKhf/s1600/cube_sphere_inter.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Intersection of two objects. The order no more imports.</td></tr>
</tbody></table>
<div>
<span style="font-family: inherit;">Thanks to the curly braces, we know how to design more complex shapes</span><span style="font-family: inherit;">. Remember, </span>there could be one, two or any number of shapes within the curly braces, including non-primitive shapes!<br />
<div>
<br /></div>
<span style="font-family: inherit;">For example, we create a simple mug by "carving" a vertical hole right in the middle of the former shape. We need a proper vertical offset to keep some material at the bottom (BTW, remember to let the hole protrude from the top, right? Use a hash or a percent prefix to double check if in doubt).</span></div>
<div>
<span style="font-family: inherit;"></span><br />
<span style="font-family: inherit;"></span></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjVjyLzIACbRrve6e7BysKw8QVxBhCN-oDcd8wxIV-PbCiltZcFVhoDoyz0_JcpTOspPPf6aaeHKtbQooBrfcTSEa_fK23U2YbGdoOO-H9rmysgAunZ7xyAuUJINYmsoCLd1hOpr_WDblJB/s1600/mug.png" style="margin-left: auto; margin-right: auto;"><img border="0" height="255" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjVjyLzIACbRrve6e7BysKw8QVxBhCN-oDcd8wxIV-PbCiltZcFVhoDoyz0_JcpTOspPPf6aaeHKtbQooBrfcTSEa_fK23U2YbGdoOO-H9rmysgAunZ7xyAuUJINYmsoCLd1hOpr_WDblJB/s1600/mug.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">A simple mug with a slightly more comple shape.</td></tr>
</tbody></table>
<div>
<span style="font-family: inherit;"></span><br />
<span style="font-family: inherit;"></span></div>
<div>
<span style="font-family: inherit;">The above shows how we usually work with CSG: build and refine shape after shape, making it more complex each time. It requires a bit of practice and people are not equal in this regard. But it is pretty efficient and not far from what many artists already do - and certainly not different from a programmer's job either!</span><br />
<span style="font-family: inherit;"><br /></span> <span style="font-family: inherit;">Note also that you can "get back" to the former shape simply by prefixing the "</span>intersection<span style="font-family: inherit;">( )" with an exclamation mark. Only this block will then be displayed and the effect of the "difference( )" will then be ignored. This is the easiest way by far!</span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
Now this mug is quite small, isn't it? You could make it bigger in your 3D printer slicer by tweaking the scale, but Openscad does it better as it also computes and fragments the geometry accordingly. Once an STL is produced, a slicer cannot rely on the "real" shape to fragment the mesh correctly when you scale it.<br />
<br /></div>
<div>
Also, scaling is useful as such when designing shapes as we will see.<br />
<br />
The "scale( )" operator also requires a 3-component vector, which values act as multipliers on each of the 3 axes. Here we are making it somehow taller than it is made wider:</div>
<div>
<br /></div>
<div>
<!--StartFragment--><span style="font-family: "courier new" , "courier" , monospace;"> scale([2,2,3])</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> {</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> difference()</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> {</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> intersection()</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> {</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> cube([20,20,20], center=true);</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> sphere(14);</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> }</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> translate([0,0,-10+2])</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> cylinder(r=7,h=20+2);</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> }</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> }</span><!--EndFragment--></div>
<div>
<br /></div>
<div>
Given the scale values, our mug is now really 4 cm wide and 6 cm high (huh, still more like a shot glass than a mug!).</div>
<div>
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgaUyaDKCq5MbO0DYfNylfwsmmNuUqul5CeJ3T69RmZBcXI9JssDQml-HzQCp1h44WJ5IVs6MUHDL5Xebyg3D1xIS7Dui_ENDrTn1NXQMvk-h35OfFyZtYmxWZMwBMJ741lmcVpIKcKXDh4/s1600/mug2.png" style="margin-left: auto; margin-right: auto;"><img border="0" height="252" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgaUyaDKCq5MbO0DYfNylfwsmmNuUqul5CeJ3T69RmZBcXI9JssDQml-HzQCp1h44WJ5IVs6MUHDL5Xebyg3D1xIS7Dui_ENDrTn1NXQMvk-h35OfFyZtYmxWZMwBMJ741lmcVpIKcKXDh4/s1600/mug2.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">A larger mug by using the scale operator.</td></tr>
</tbody></table>
<div>
<br /></div>
<div>
We could tweak further the numbers like this. But it is the proper time to tell about <span style="font-family: inherit;"><i>variables</i> instead. This is the object of the next post. Bravo by the way if you made it to here!</span></div>
<br />
<h3 style="text-align: left;">
Bugging behaviors of Openscad...</h3>
<div>
<br /></div>
Be patient! Sometimes it gets really slow crunching all the numbers. It will not happen with the primitives and operators that were described in this post. But the next two posts really can start and stress your CPU. Some particular construction may (very rarely nowadays) also crash the program, so make sure you save your work regularly. This is a good practice whatever the software.<br />
<br />
<a href="http://www.openscad.org/downloads.html">Openscad upgrades</a> are quite rare, but they are usually bringing real stuff. And it is not a real issue because it is already packed with the necessary tools, even for complex designs (you know <a href="http://en.wikipedia.org/wiki/KISS_principle">KISS</a> ?). And even if it has a few "oddities", it really is an extraordinary and productive tool to create parametric engineering designs, for 3D printing or other uses.<br />
<br />
Always use comments, so that you can read yourself again next time And try to keep parts of the design together, that match functions in the final designs (e.g. clearly separated door, hinge, and body).<br />
<br />
I wish the CSG manifold constraints are enforced automatically in some cases. It might be possible to know automatically when the negative shape shall extend slightly beyond the boundary. But for now, it is up to you to take care of this. It is extremely important as you may run in trouble. With complex shapes, nasty effects otherwise appear, that are so bad that Openscad refuses to generate the STL with F6!<br />
<br />
It is not well suited for organic shapes (<a href="http://kitwallace.tumblr.com/post/134738715634/catmull-clark-surface-smoothing">or is it</a>?), so real artists may feel it rough. But programmers feel at home, and average people do not have to experience the very steep learning curves of heavier CAD software.<br />
<br />
While I talk about professionals: no way you can get a "professional" layout like below directly from openscad. It may be a showstopper for many professional uses, even though slices can be exported in DXF into other software for "packaging". Until recently (March 2015), there was even no scale on the screen, and people designed their own Openscad <a href="http://www.thingiverse.com/thing:6823">rulers</a> (to include and prefix with a "percent" character of course). But most of them slow things, and they are not as convenient as if it was in the software. But things get (slowly) better with time :) I wish we had automatic part labeling, etc.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEirCjjSsbmYGz2Wtq1kuceypIshuy0ctI2sGPwd5xlZ3vFN4_x86bhAvbKnHrg7DRd2U8SIY4DYmL1hZe-m2Rmjod6OZ6174Ctou3G-QVGAS8XgeO2x6AUHzjia1T4hyphenhyphen61TQ_SUC2u_587S/s1600/Schneckengetriebe-ComputerAidedDesign-Wikipedia.png" style="margin-left: auto; margin-right: auto;"><img border="0" height="282" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEirCjjSsbmYGz2Wtq1kuceypIshuy0ctI2sGPwd5xlZ3vFN4_x86bhAvbKnHrg7DRd2U8SIY4DYmL1hZe-m2Rmjod6OZ6174Ctou3G-QVGAS8XgeO2x6AUHzjia1T4hyphenhyphen61TQ_SUC2u_587S/s1600/Schneckengetriebe-ComputerAidedDesign-Wikipedia.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><span style="font-size: x-small;"><span style="font-size: 12.8px;">Openscad</span><span style="font-size: 12.8px;"> will not generate </span><a href="http://en.wikipedia.org/wiki/Computer-aided_design">such</a> professional document directly.</span></td></tr>
</tbody></table>
Local coordinate systems are tricky, especially after rotations. But life is made much simpler with the use of the exclamation mark (aka "show only this part of the design"). And... there are better practice with so-called <i>modules,</i> which is part of the <a href="http://www.tridimake.com/2014/09/howto-openscad-variables-modules-parametric-designs.html">next article</a> in this tutorial.<br />
<br />
Indeed, if or when you are fine with the concepts shown in this post, you may switch to the <a href="http://www.tridimake.com/2014/09/howto-openscad-variables-modules-parametric-designs.html">next level</a>. It will be all about variables, modules, and parametric designs. Just where Openscad is simply brilliant, and where it gets most of its value in my opinion.<br />
<div>
<br /></div>
</div>
Jeremie Francoishttp://www.blogger.com/profile/02984201174566394892noreply@blogger.com2tag:blogger.com,1999:blog-3615478772815290200.post-61632410785954736532014-08-14T11:31:00.002+02:002015-04-13T09:00:28.846+02:00Home made filament drying box<div dir="ltr" style="text-align: left;" trbidi="on">
<h3 style="text-align: left;">
How to make a simple dehydrator (drying box) with a solar vacuum tube</h3>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiAvAS_GBMh3ABUIcfJdjsxEyfbh908cnC2TRtkY_pxIiEowJLDBXvrPnzuAmNY9oeIUy7uRdX49doPuvgngZ-Nyhm4LHlaYwY44EE0fckRIkyTQe8uqxQ9A23dI_zUprx48rLRbDqctb2T/s1600/drier_moisture_absorber_box.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiAvAS_GBMh3ABUIcfJdjsxEyfbh908cnC2TRtkY_pxIiEowJLDBXvrPnzuAmNY9oeIUy7uRdX49doPuvgngZ-Nyhm4LHlaYwY44EE0fckRIkyTQe8uqxQ9A23dI_zUprx48rLRbDqctb2T/s1600/drier_moisture_absorber_box.jpg" height="233" width="320" /></a>A short and probably overkill post for a passive and zero carbon footprint drying box (not counting the required one to make the tube).<br />
<br />
I use a spare, high tech and powerful vacuum solar tube, but it is easy to make something with a copper or steel tube painted in black, around which you slide larger transparent plastic bottles. Such insulation is required to avoid the ambient air temperature from cooling your own heated air.<br />
<br />
The second required item is a brand used low-tech cardboard box.<br />
<br />
<br />
<a name='more'></a><br />
Drying filament is important, especially with some materials like Nylon that absorbs ambient moisture quite easily (PLA almost does not have this problem). With a non-dry filament you may get bubbles exploding at the nozzle (hint: hissing & steam!), and this makes the layers very rough. Now, even if it has an arguable benefit for a better bonding with the subsequent layer, too much will make the part look ugly. But this is really the subject of <a href="http://www.tridimake.com/2014/01/how-to-3d-print-nylon-and-trimmer-line.html">another post</a> in this blog.<br />
<br />
I seal my spools in a bag, together with some desiccant. The whole is put in the cardboard box, that I close with scotch tape. Unless the cardboard box itself is made waterproof, the idea is to have a "double sealed" box, so that only the moisture from the filament is absorbed, not that of the ambient air!<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiYCrCtcYb78pLdGnoIahKsEnTcbNdlKooxBw2mvP2ZE3Sxa8PnLnblhwhVRDeSB3nUwDvW4WTLtCEM6rdhyOcckRoKhxNkXkvVvUEHVgydgCO1bIydoDuqoR53JhxTTpm0gyVQz7Hufmvw/s1600/IMG_2366-SolarNylonDrier.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiYCrCtcYb78pLdGnoIahKsEnTcbNdlKooxBw2mvP2ZE3Sxa8PnLnblhwhVRDeSB3nUwDvW4WTLtCEM6rdhyOcckRoKhxNkXkvVvUEHVgydgCO1bIydoDuqoR53JhxTTpm0gyVQz7Hufmvw/s1600/IMG_2366-SolarNylonDrier.JPG" height="494" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Home made solar dehydrator. The bag inside with the <a href="http://www.tridimake.com/2014/01/how-to-3d-print-nylon-and-trimmer-line.html">trimmer line</a> includes also some moisture absorber.</td></tr>
</tbody></table>
I carved a tight hole in the cardboard box wall for the solar tube output, which is high enough on the wall to get a minimal slope (and better air flux inside the tube). Then, I leave it one day long outside during a sunny days:.<br />
<br />
As you can see, temperatures stay below 50°C, which is suitable also for PLA (a big dangerously high). Anyhow, it is well enough even for Nylon after I leave it for about one (mostly sunny) day.<br />
<br />
<br />
There are obviously other techniques and kinds to dry a filament, you can see more in my post <a href="http://www.tridimake.com/2014/01/how-to-3d-print-nylon-and-trimmer-line.html">about Nylon</a> for example, or at 3Dprintingforbeginners (below).<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjYyxIyG-2wBVRQAMIXIvanB6xoZoJY9xxSj7SGTxUnBcRCOaUJJIzDEEt2fZVlkOSHrzvg-O0xEq3OX4u2GOjhp51GgT5VGEebkXEQfNPCQggnYS9_-R0D8vFKH42AfWIy2gh8osvjc8MZ/s1600/Filament-Storage_20_vacuum_bag.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjYyxIyG-2wBVRQAMIXIvanB6xoZoJY9xxSj7SGTxUnBcRCOaUJJIzDEEt2fZVlkOSHrzvg-O0xEq3OX4u2GOjhp51GgT5VGEebkXEQfNPCQggnYS9_-R0D8vFKH42AfWIy2gh8osvjc8MZ/s1600/Filament-Storage_20_vacuum_bag.jpg" height="426" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">More realistic: with vacuum storage bags. Ref. <i>how to store 3D printing filament</i> at <a href="http://3dprintingforbeginners.com/how-to-store-3d-printing-filament/">3dprintingforbeginners</a>.</td></tr>
</tbody></table>
<br />
<br />
<h3 style="text-align: left;">
A word on desiccants (aka moisture-absorbers) - and on colorblindness</h3>
<div>
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="clear: right; float: right; margin-bottom: 1em; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh3dhpJTk9NUm6nDdvVESwB1CpW3KLPEeSc997OsOZ0toFSYkgmBps_6GdDcuMwf0y5ZdvrjRt_AufutnOyxT1hWByRqNMZl9Y8FYvooBSCr0Qw4bd3VIYhl91HCHzz7EKLhBol60wG3e3g/s1600/IMG_2406.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh3dhpJTk9NUm6nDdvVESwB1CpW3KLPEeSc997OsOZ0toFSYkgmBps_6GdDcuMwf0y5ZdvrjRt_AufutnOyxT1hWByRqNMZl9Y8FYvooBSCr0Qw4bd3VIYhl91HCHzz7EKLhBol60wG3e3g/s1600/IMG_2406.JPG" height="213" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">125 grams of color-changing & re-usable deluxe desiccant</td></tr>
</tbody></table>
<div>
I first used these small bags that come with electronic appliances, but then I switched to some heavier stuff.</div>
<div>
<br /></div>
<div>
There are very convenient indicating silica gels, aka color-changing desiccants, that give an indication when they have absorbed too much moisture and they need to be dried themselves (infinitely re-usable).</div>
<div>
<br /></div>
<div>
As I am color blind, I chose the "nasty" one: it is <a href="http://en.wikipedia.org/wiki/Desiccant">enriched with cobalt</a> (it turns purple when moist). My motive was because the other easily available kind changes to a color I can hardly differentiate!</div>
<div>
<br /></div>
<div>
<i></i><br />
<i></i></div>
<div>
<i></i><br />
<i></i></div>
<div>
<i></i><br />
<i></i></div>
<div>
<i></i><br />
<i></i></div>
<div>
<i>By the way</i>, "color blindness" is a real stupid name in English. We do see colors! But I just have harder times to tell or distinguish between two specific colors, according to lighting or fatigue. Think of it, just as "normal" people could not agree if a nice blue-green color is either blue or green, then I can't tell whether a "greenish red" is obviously green or red (one sensor is missing in between so that there is a shade from red to green for me). This is all about sensitivity (and no, I definitely do not see red as green and green as red: this would be simply not having learnt my colors properly at school!).</div>
<div>
<br /></div>
<div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: right;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj686XPIyQi363sgg8bwFtN0WFKER0HnuF2eVziFvkK12QHYLv-npo0rrr7YdkxOLTB4zgOim5QPvbQE_O28pIKzxkwOInzLI-lBD5NzfT0OEmJ225w25iToDu7xk5gWepPMr6ctkoKtrtz/s1600/IMG_2409-NylonOrange-DroneFoot.JPG" imageanchor="1" style="clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj686XPIyQi363sgg8bwFtN0WFKER0HnuF2eVziFvkK12QHYLv-npo0rrr7YdkxOLTB4zgOim5QPvbQE_O28pIKzxkwOInzLI-lBD5NzfT0OEmJ225w25iToDu7xk5gWepPMr6ctkoKtrtz/s1600/IMG_2409-NylonOrange-DroneFoot.JPG" height="218" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Well printed dried <a href="http://www.tridimake.com/2014/01/how-to-3d-print-nylon-and-trimmer-line.html">Nylon trimmer line</a> (230°C, 40mm/s, 0.2mm layers).<br />
Yeah, this one is quite orange - and I do read it.</td></tr>
</tbody></table>
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
</div>
</div>
Jeremie Francoishttp://www.blogger.com/profile/02984201174566394892noreply@blogger.com1