Tool free swappable, bed probing hot end mount.

Like many things in life, this printer modification evolved into something much more than my original intention. By way of introduction, this picture shows my original hot end mount and X and Y axes.

original

As readers of my blog will know, I use a Diamond mixing hot end. This is a rather ungainly beast with 3 heat sinks sticking out at 28 degrees taking up quite a lot of space and weighing in at around 250gms (excluding any extruders). Because of the weight, the engineer in me decided that the best way to mount it would be to fix it between two parallel rails, rather than having it hanging over the side of a single rail, which is why I ended with a such a huge X carriage. It was heavy too. The X carriage including the hot end weighed 690gms and the Y carriage with the X rails fitted weighed in at 1,210gms so my combined Y axis weight was a whopping 1,900gms. Having said all that, I regular used to print at 90mm/sec with non print moves set to 350mm/sec with accelerations set to 1200mm/sec^2 and the thing was absolutely rock solid. It was impossible by hand, to “flex” the hot end in any way.

My issue was that I have another Diamond hot end, fully assembled but with a 0.9mm nozzle that I intend to use with Taulman T glass filament, and changing the hot end was a complete pain. So I set out to make a new mount that would enable me to quickly swap hot ends, preferably without the need to use any tools. I also decided to abandon the dual X rail setup and replace the two 2020 extrusions with a single 2040 extrusion. Part of me still thinks this was bad idea from a rigidity point of view, but there are other benefits such as weight savings and increased range of movement which I hope will outweigh the negatives.The next two pictures are Open Scad images of the new X carriage.

OpenScadCarriage

OpenScadWithDiamond

The red part is the new Diamond hot end mount. Effectively, the mount has a sort of Dovetail slot around the two sides and the bottom, into which the mount slides.This is a close up of the actual Diamond hot end mount.

DiamondMount

At this point, I realised that I could solve another minor issue that I had. That is, I use an IR mini height sensor but I also use 3DLac on my my glass build plate, and the 3DLac can alter the reflectivity of the glass, meaning that I often had to make adjustments to my Z axis homing. The other problem I have with the IR sensor is that, because of the shape of the Diamond hot end, it is very difficult to mount it anywhere close to the nozzle.So I thought, rather than locking the hot end into place, I could hold it against it’s seat using springs which would allow it to slide up and down. I could then mount the height sensor above the hot end, rather than below it. This would mean that the hot end is itself the height probe. In the event, I discovered a Metrol positioning switch with a claimed repeatability of 0.005mm  and decided to use that above the mount but retain the mini IR sensor below the mount if the sliding arrangement doesn’t work out. I’ll cover the Metrol switch in a separate post.

It took me a few attempts to print the parts such that they would slide easily but at the same time have no “wobble”. It wasn’t too hard though because the bottom of the mount is also a “Dovetail” shape and when the springs act down on the mount, the effect is to pull the two faces together.

Of course, I have reservations about how well these plastic printed parts will last over time but I am optimistic because now that I have installed and set it all up, I have only 0.8mm of movement before the switch triggers and can probably reduce this further. The worst case scenario is that if the sliding\probing\homing aspect proves to be unreliable, I will change the design slightly to clamp the hot end in place and go back to using the mini IR probe for homing.

At least I will be able to quickly change hot ends without using any tools. Here is a little video I made showing how that all works.

As with all these things, the update was much more involved than I first though. The entire upper section of the printer has to be disassembled, including the motor mounts, idlers, and of course the X and Y rails………

stripDown

………but I got it all put back together.

back together

So in practice, what happens for Z homing is that the bed rises, the nozzle touches the glass then the mount gets lifted off it’s seat and slides up until the switch triggers (currently 0.8mm) and my configuration file is set so that Z=0 is 0.8mm below the point where the switch triggers. The switch has 2mm of plunger travel but triggers at 0.3mm so there is a further 1.7mm of plunger travel available. I made use of this by building in a fail safe which is just a micro switch acting on the bed and set to trigger an emergency stop at 1mm after the point where the homing switch should trigger.

limitSwitch

If using the nozzle itself as a means of Z homing proves to be unreliable, I have still achieved my original objective which was to have a means of quickly swapping hot ends. As a bonus, I have gained an extra 50 mm of movement in X  (now 375 mm instead of 325 mm) and 30mm in Y (now 350mm instead of 320 mm). Also, the new X carriage weighs 520gms instead of 690gms and the new Y axis (without X) weighs 820gms instead of 1,210gms giving me a total weight saving in Y of 560gms ( 1,340gms instead of 1,900gms).

The downside is that I can now “flex” the nozzle in the Y direction if I push and pull hard enough, whereas the old design was rock solid. However, I’ve just finished my first print and there is no sign of and “banding” that I would expect to see if the nozzle was moving around during a print. Also, the Z homing is working like a charm and thus far, is consistent and repeatable.

One last thought. With this mounting arrangement, I could fairly easily change to a completely different design of hot end, by making a suitable adaptor. By way of illustration. here is an adaptor that I’ve just made so that I can fit a dial gauge to level the bed.

dialGaugeMount

I’ll give an update in a few weeks or months when I am able to asses how reliable and/or repeatable this turns out to be.

Ian

Late edit. I’ve just finished printing this object which is 133mm tall.

1stPrint

There is no sign of banding and the dimensional accuracy is pretty good. The smaller diameter should be 45mm and it measures at between 45.3 and 45.2 throughout the height. The inner square should be 21mm and measures at between 20.96 and 21.02 and the overall height measure at 132.8mm now that it’s cooled. So although it is possible to flex the hot end in the Y direction by applying force by hand, I’m reasonably confident that there is no movement during normal printing (at least in the centre of the bed).

 

Dual function LED ornament stands

As a change from printing lots of test pieces with no practical value, I thought it was about time I made something useful. I’ve given step by step instructions and a list of materials in case anyone else want to make any of these.

My wife has a growing collection of miniature glass and plastic Christmas trees (one or two of which I have made using Taulman T glass) which come out every year. They look more effective when lit from below so we have one or two of those led stands that one can buy. The trouble is, some of these ornaments are plain glass and look best with coloured light while others are already coloured so look best with white light. The other issue with some of the stands one can buy is that they take those really small button cells which make them expensive to run compared to using say, rechargeable AA or AAA batteries. So I decided to make some that would take rechargeable batteries and that could be switched between colour changing or white.

Initially, I had planned to use rechargeable PP3 9V batteries. These would have been easier to fit inside the base and would have meant that I could run 2 or 3 LEDs in series with a single current limiting resistor. However, when I looked into the capacity of these batteries, the amp hour rating is very low which would have meant that they would only have lasted about 8 to 10 hrs between charges. So, I decided to use AA size cells instead, which have a much higher capacity. The voltage drop across the super bright white LEDs is 3 volts and for the colour changing it was 2.4 volts (variable depending on which colour is being produced) so I needed at least 3 batteries to give me 4.5 volts and the LEDS would have to wired in series, each with it’s own current limiting resistor.

The colour changing LEDs are not as bright as the white LEDs so I decided to use 4 colour changing ones and 2 white ones.

In addition to the LEDS, I also needed a switch. I had hoped to use a miniature ON-OFF-ON slide switch but was unable to find one. The best I could find was On-On which would switch between colour changing and white but had no centre “OFF” position so I ended up using two switches. One for ON-OFF and the other for Colour – White. If you can find an ON-OFF-ON version, it would simplify the wiring quite a bit.

Then I needed clips to hold the batteries and provide electrical contact, some wire and some strip board.

The complete list of materials for one of theses stands is as follows.

2 off super bright white 5mm LEDS (one could also use 3mm)

4 off slow colour changing 5mm LEDs (or 3mm)

1 off piece of strip board 25mm x 25mm

3 off Keystone AA (-ve) contact part No 209. These are the dimensions

209

3 off Keystone AA (+ve) contact part number 228 as below

228

2 off switches PIC part number SS-22f25-G dimension as below

pic-ss-22f25-g

Printed parts – Base, Top and Insert. These can be found on Thingiverse here Printed parts files

The first thing was to make up the strip board LED modules. Each LED has it’s own current limiting resistor, the value of which will depend on the specification of the LEDs. In my case I used 220 Ohm and 180 Ohm. The +ve input to all 4 of the colour changing resistors are connected together as are the 2 +ve inputs for the white resistors. The -ve side of all the LEDS are connected together.  Here is a picture of one of the made up boards.

strpboardmodule

The 4 colour changing LEDS are on the outside and the 2 white ones are on the inside. The red wire is the +ve for the white LEDs and the Orange is the +ve for the colour changing LEDS. The black wire is the common -ve.

A quick note about using these slow colour changing LEDS. When they are first turned on, they are all the same colour and start to slowly fade to the next colour. However, they don’t all change at the same rate. So after a period if time they get “out of sync”. This results in many more combinations of colour which are more subtle than just RGB and in my opinion, give some quite pleasing effects.

The next thing was to design and print the base which holds everything together. Here is one of those bases.

unwiredbase

And here is one with everything wired up.

wiredbase

The pictures should be self explanatory. The base is designed to take the switches which are a snug fit but slide in from the top. The clips for the batteries are a press fit from the top. NOTE, solder the wires to the clips before fitting the clips otherwise the heat will melt the plastic. The lower right hand battery clip is the +ve terminal which goes to the centre terminal of the ON-OFF switch which is at the top. One side of this switch goes to the centre terminal of the changeover switch which is on the right. The red wire from the LEDs goes to one side of the changeover switch and the orange wire goes to the other side of the switch. The black -ve LED wire goes to the -ve battery clip which is the top right one. The batteries are then connected in series -ve to +ve as shown by the blue wires. As I mentioned before, life would have been a lot easier if I could have found a miniature ON-OFF-ON switch rather than having to use two ON-ON switches.

Here is a finished base with batteries installed. For testing, these are just ordinary A batteries, not rechargeable. The LED board sits in a recess but I used a couple of spots of silicone sealant to hold the LED board in place (but any glue will do).

withbattswhite

I forgot to take a picture of the top but here is an image from OpenScad

ledstandtop

It is designed to just clip on and has 2 “prongs” which locate it and also hold the switches in place. The rectangular cut out takes a clear insert which I printed separately.

ledstandinsert

I printed the inserts using Taulman T glass clear. They simply press in and I used some clear silicone sealant to hold them in place. Here is a picture of three of them.

tops

I actually made 10 of these. One was a working prototype so “er in doors” has 9 useful ones.

nineoff

Here is a picture of one of them in white. The featured image at the top shows it in colour mode. Sorry about the reflections of my window blind which show on the top but you’ll get the idea.

finishedwhite

I put all the files including the OpenScad file on Thingiverse so you can play around with the design as you see fit – maybe you’ll be able to find an On-Off-On switch to simplify things. Here is that link again Printer parts files

 

 

 

 

 

 

The “stripey toothpaste” effect of the Diamond hot end.

As readers of my bog will know, I have been using a Diamond hot end for quite some time. One of the issues with this hot end is that it doesn’t actually mix colours all that well. What happens is that the filament exits the nozzle somewhat like stripey toothpaste. The featured image above shows how this manifests itself. This was a simple hollow cylindrical container that I created by using a custom script to alter the mixing ratios in 1% increments at every layer change. So, the colours “fade” from 100% Red and 0% Blue to 0%Red and 100% Blue then from 100%Blue and 0% Yellow to 100% Yellow and 0%Blue and finally from 100%Yellow and 0%Red back to 100% Red and 0% Yellow.

The three pictures above are the same object viewed from different angles. The one on the left is roughly at the angle where the Blue filament enters the hot end, the one in the middle is roughly where the Yellow enters and the one on the right is roughly where the Red enters. You can see that the colour is biased towards the inlet position in the hot end for that particular filament.

The effect can be largely negated by using translucent filaments.

Or, it can be exploited. To explore this a bit further, I created a simple pyramid and orientated it on the build plate such that each face was in line with each of the filament inlet positions. I defined a single tool with mixing ratio of equal proportions for each of the 3 filaments. In this case, the filaments that happened to be loaded at the time were Red, Black and Gold. So the tool was using roughly 1/3rd of each colour. Then I printed the object just as one would using a “normal” hot end and took three pictures, each at 120 degrees around the object. Here they are:

blackredsmall

redgoldsmall

goldblacksmall

As you can see, each face is a different colour although they were all printed at the same time, using the same tool with no fancy tool changes or post processing. The top picture shows mostly Black on the left and mostly Red on the right. The next picture down with the object turned 120 degrees shows mostly Red now on the left and mostly Gold on the right. The last picture is with object turned another 120 degrees so the mostly Gold is now on the left and mostly Black is on the right. I say “mostly” because there is some mixing of the colours on each face but they are strongly biased towards the position where each filament enters the hot end.

I just wanted to show this as an illustration that sometimes what may be seen as defective or unwanted behaviour, can be exploited to ones advantage. (That is of course if one has a need for a 3 sided object with each face being a different colour).

Now on to the next picture and one that had me baffled for some time.

colourshiftsmall

I was printing something else when I came across this issue (always an issue – never a problem). So I made a simple rectangle with two holes in it, so that I could evaluate what was happening. As you can see, there is a distinct colour shift. Some sections are darker than others (or lighter depending on your point of view). It was printed mixing two filaments, Blue and White in equal proportions. It is consistent and reproducible. It will happen with any combination of extruders. i.e. extruders 0 and 1, extruders 1 and 2 or extrudes 0 and 2. There is no change in layer height or any sign of over or under extrusion. The extruder gears all appear to rotate at the same speed.

After a lot of head scratching and a lot of testing, I finally realised what was causing it. When it is printing, the infill is at 45 degrees and the head starts just below the left hand hole and moves diagonally in the direction of top left to bottom right whiles traversing toward the right hand side. This is the dark section. So it goes all around the bottom of the hole, then it reaches the right hand side of the hole after which it goes all the way to the top of the print. Then it reaches the right hand side of the right hand hole, and goes around it.

So for all of these moves, each new line of filament (apart from the first line) is supported by or squashed up against, the previous line on the left but has free space on the right.

Once the print head reaches the top right corner of the print, it then moves to the nearest unprinted section which is the top of the right hand hole, nearest to the right hand corner. To continue the print, the head still moves in the same direction diagonally but this time it is traversing from right to left instead of from left to right.

So now, for all these moves each new line of filament is supported by or squashed up against, the previous line on the right but has free space on the left.

Going back to what we now know about the filament coming out as stripey toothpaste, it is reasonable to deduce that the colour of the “mixed” filament changes depending on whether the filament is supported and/or squashed on the left with free space on the right compared to being supported on the right with free space on the left. To put it another way, it seems that the newly extruded filament rolls or twists either towards or away from the previous line of filament thus giving a predominance of one colour over another depending on the direction that the head is traversing.

At least that is my theory. It explains what I have observed happening but like a lot of theories that come up in the world of 3D printing, it isn’t actually proven. The only way to do that would be to put the prints under a microscope.

Looks like that might have to be something to add to my tool box…….watch this space……..

Ian

 

 

Latest update to blog 6th Jan – multi colour printing without wipe and prime towers.

Before I launch into this, it occurs to me that people not familiar with mixing hot ends might be confused when I talk about tool changes. I explain how to define tools in another post, so I won’t go into it again here. Just be aware that a tool change and a colour change are one and the same thing, so I apologise if might use the terms interchangeably.  Also of course, “colour” and “color” are the same thing but I’m English so to me it’s “colour”.

As I reported earlier, I found an issue with the original script when tool (colour) changes were close together. Having looked again at my feeble attempt to write code, I did find the problem – in fact I found a few.

The main issue was that the script would not move a tool change to a position earlier than the previous tool change. On the face of it, that seems logical. However, the script didn’t “remember” that the previous tool change itself had been moved to an earlier position in the file. One way to think about it is a stream of commands with tool changes at various points and we need to move all these tool changes forward in the file by an amount equivalent to, (for the sake of argument) 2.5mm of extruded filament. It shouldn’t matter if there is only 1.0mm of filament between some of these tool changes as they will all be shifted by the same amount.

That was the main thing I needed to fix but while I was looking at the code, I found a couple of other problems. The first was that the way I segmented the moves was incorrect. That is to say that the new tool position is almost invariably somewhere in an existing “XYE” move so that move has to be split, the tool change inserted and then the rest of the move completed. So one line is replaced by two lines with a tool chnage command inserted between them. The amount of filament extruded (the “E” number) was correctly apportioned to each line but the corresponding X and Y amounts were not correctly apportioned.

The other thing I found was that the new lines could be inserted in the wrong place in certain circumstances. As an example, my machine is set to do very fast “non-print” moves so it might have a line something like “G1 X170.329 Y165.990 F21000.000” (a feed rate of 21,000 mm/min or 350mm/sec) followed by “G1 F4800” which sets the speed back down, in this case to 4,800 mm/min or 80mm/sec for normal printing. I discovered that in some instances, the script would put the new segmented moves and tool  change command after the fast non-print move but before the speed change back to normal command. This would have resulted in those two print moves being executed at 350mm/sec which would have been interesting to watch!

So I have deleted the link in the original post to the Python script and here is my latest feeble attempt. It does actually get the job done but I know any professional code writer will probably burst into tears if they see it.

To save a lot of copying, pasting and formatting of text, I’ve take a number of screen “snips” of the code. The comments should make it clear as to what I’m trying to do.

capture1

capture2

capture3

capture4

capture5

capture6

capture7

capture8

I haven’t included a link to the script this time but I’ll make it available if anyone is interested. Just leave a comment if you want me to do this.

Ian

 

Printer beds – construction, flatness, levelling and compensation (is it needed?)

I just wanted to jot down some thoughts I have about printer beds. You can see some pictures of my one here My CoreXY Printer build.

It’s fairly obviously to me that the surface on which we wish to print something has to be flat and level. Assuming we start with a typical layer height of around 0.3mm, then that means the surface needs to be flat and level to a tolerance of around 0.1mm. That is to say that the distance from the tip of the printer nozzle to the build surface needs to be the same within 0.1mm or better, wherever the nozzle is in the X or Y direction. The first layer of a print is absolutely critical. If the nozzle is too close to the bed, then the filament will be squashed and ooze out sideways. In extreme circumstances, the print surface may completely block the nozzle. Conversely, if the nozzle is too far from the bed, then the filament simply won’t stick.

The other thing that we may wish to do is heat the bed. If we were only going to print with PLA, this is not strictly necessary as it is possible to print PLA on an unheated bed and use something like blue painters’ tape. The trouble with that is that the object will often stick to the tape better than the tape sticks to the bed, and it can easily get torn so it has be constantly re-applied. So heating the bed means that we don’t have to use blue tape and we can also print with a variety of different plastics.

So what can we use that is flat, level and can be heated? The most common materials are aluminium and glass. Glass on it’s own is maybe not such a good idea as it is easily broken and it isn’t the best thermal conductor. One common arrangement is to use glass with a thin aluminium plate underneath which acts as a heat spreader to the heating element that is attached underneath. Sometimes a wooden (mdf or ply) carrier is used which forms a sandwich with the aluminium heat spreader with the heating element as the filling, and provides some rigidity to the entire assembly. Providing the glass is fairly thick and “unbendable” over the size of the bed, this arrangement could take care of the flatness issue, which just leaves the issue of levelling to be addressed.

On the subject of glass, a word or two of warning. Various 3D printing forums are littered with comments saying that you must use Borosilicate glass because “normal” glass won’t withstand the high temperatures. In my opinion, this is just not true. The important thing is thermal shock. That is to say that if you suddenly heat the glass up (almost impossible to do on a 3D printer) or suddenly cool it by say taking it off the printer and putting in straight in the freezer, then it might well crack. Under normal circumstances, where the glass is allowed to cool naturally at ambient temperatures then there really shouldn’t be a problem. I have certainly never had a problem with any of my 400mm x 400mm x 6mm thick pieces of “normal” float glass, even when heated to around 90 deg C.

Still on the subject of glass, not all glass is flat especially that used for horticultural purposes (greenhouses and the like) and which is probably made from rolled glass. The glass we need is float glass. This glass can additionally be toughened which makes is much more difficult to break. However, I know from hard earned experience that the toughening process will deform the glass such that it is no longer flat. So toughened glass may be safer, but it isn’t flat.

Another common myth that is often propagated on various forums is that glass is an insulator. As someone once pointed out, if that were so we wouldn’t need double glazing. Most of the people who propagate such myths haven’t actually done any testing and they are just repeating what they have read elsewhere. I have done some tests and can say that with the bed heated to 60 deg C  and at an ambient temperature of 21 deg C, the top surface of my 6mm thick glass was measured at 58 deg C. A drop of only 2 deg C.

Now of course, we don’t have to use glass at all. We could simply use thicker aluminium that is guaranteed flat and print directly on to it, and many people do. The aluminium to ask for is “tooling plate” which is guaranteed to be flat. One disadvantage of this is that aluminium is a fairly soft metal and therefore susceptible to damage from knocks and scrapes. So, in my opinion, protecting the surface in some way is a good idea as aluminium tooling plate is expensive to replace.

My personal preference is a combination of thick aluminium tooling plate with a removable glass print surface. Although I could print directly on to the aluminium, the reasons for using glass are that I can quickly swap one piece for another, which enables to start printing another object while the first one is cooling down. Another reason is that I can apply different surfaces to each piece of glass and swap between them. For example, I can have blue tape on one, another could be plain glass with 3dLac applied, a third could have some other “exotic” material attached.

So, now we have a bed that is flat all that remains is to ensure that it is level. Or to put it more correctly in engineering terms “tram” which is derived from the term “trammelling” That is to say that in the X direction, the bed must be parallel with the print head X axis and that in the Y direction, the bed must be parallel with the print head Y axis. Strictly speaking, the entire printer might not be level with respect to the floor on which it stands so the bed might not be level but neither would the axes and they would be “out” by the same amount so it isn’t critical.

I’m not going to go into details of how this should be accomplished. Suffice to say that 3 points define a plane (providing they are not on the same line) and 4 points define a hyperplane if not coplanar (on the same plane).  So 4 (or more) points might define a shape that isn’t a flat plane. i.e. 4 point levelling could impart an undesirable twist to the bed. So ideally, we need to support the bed at 3 points and there should be some adjustment for at least two of these points so that they can be adjusted with respect to the fixed point. This is what is commonly referred to as 3 point levelling. For the best accuracy, these 3 points should be as far away from each other as possible. On my printer, I support the bed using 3 screws, one close to each corner at the front, and one close to the centre at the back. These screws provide lift as well as levelling but I’m not going to go into the mechanics of Z axis movement in this post.

Finally, many people will say that most of the above is irrelevant because many modern printers or printer controllers use firmware to compensate for bed inaccuracies. The latest Duet electronics (of which I am a big fan by the way), even has grid based bed compensation that will compensate not only for the fact that the bed might not be level, but also for the fact that it might not be flat. It will probe the bed over a number of points that the user defines and generate a height map which gets applied to the nozzle height during a print. My concern with this approach is that it encourages people and manufacturers to get sloppy with their design and build quality. It really doesn’t cost much more to “do it right”. In my opinion, any cost saving from a sloppy design of print bed that isn’t inherently level and flat will be outweighed by increases in time spent running the compensation software. People will do doubt argue that running the software need only be done once, as the height map can be saved and re-used. My response is that if a printer bed is inherently non planer or not level, then those errors are unlikely to be constant so it will be necessary to re-run the compensation software periodically. Also, when using something like an Infra Red probe, the probe itself might be affected by dust or debris on the print surface that affects the reflectivity at different points on the surface which would generate an inaccurate height map and make compensation worse than if none were applied.

So although I am a big fan of Duet electronics and firmware, I personally do not use any form of bed compensation. I have built a printer that has a bed that is flat and level and stays that way. My first printer had a flimsy bed that needed constant attention. Every time I used it, I had to home the z axis, then run bed compensation. Now, all I have to do is turn the printer on, select the file to print and walk away. Having tried both approaches, I know which I prefer. Here is a little video that shows how it works in practice. Printing without bed compensation

Further update to blog 6th Jan – Printing without wipe and prime towers

Further to my original post, I have found some inconsistency in results. I had written earlier that my thoughts were that the required purge amount was somehow related to print speed. My suspicion was that there is more molten filament in the melt chamber and above, (before the heat break) when printing at low speed compared to higher speeds. I also said that I needed to do more testing to confirm this.

I have now done that testing and can now confirm that this is not the case and the cause is something else – more later.

Firstly, I should explain my test methodology. I have designed a test piece which is a cube, 60mm x 60mm x 3mm thick. This cube has two rectangular cut-outs, 15mm wide x 40mm long spaced 10mm from each edge and with 10mm between them. This part forms one stl file and is all one colour. Then there are two rectangular shapes which fit into these cut-outs, each one being a separate stl file which is assigned a different colour.

This combined object was sliced in Slic3r. The post-processing script was then run on the gcode file with purge amounts from 2.0 to 4.0 in 0.5 mm steps giving me 5 new files, each with different tool change positions. Each one was then printed with all other print settings the same.

Here is a picture which shows them all.

all6

From left to right, they are with 2.0mm purge, 2.5, 3.0,3.5 and 4.0. Ignore the two upper prints for now. If you look very closely, 2.5mm is the optimum. At 3.0 mm you can just see some bleeding creeping in to the upper right corner of the white rectangle. This is where it changed to black filament just a fraction too early. The same is noticeable on the lower left corner of the black rectangle but this has some red creeping in and does not show very well in the photograph.

Here is a close up picture of what 4mm purge looks like.

4mm

Please ignore the overall print quality. These we all printed at 90mm/sec and I did not pay any particular attention to the first layer height. From this picture, it is very clear when the purge amount is too much. You can see some black in the top right corner of the white rectangle and maybe a slight smudging in the bottom right hand corner of the red rectangle. Depending on how good your screen is, you might also be able to see the red smudge on the lower left corner of the black rectangle.

This next picture is a close up of what I deem to be the optimum.

2-5closeup

This is with 2.5mm of purge which is the maximum that doesn’t lead to smudging due to the tool change being premature. If you look very closely you’ll see why this isn’t a perfect technique. The left hand edge of the outline of the black square is grey, rather than black and the bottom edge and part of the right hand edge of the white rectangle is dark grey rather than white. This is the transition period from one colour to another and short of using a some sort of a wipe or prime tower, this is a good as it gets.

Once I had established the optimum purge amount, I then printed the same file at lower speeds to investigate the issue that I had observed and laid theses prints out in the same column. So going back to the first picture, the print immediately above the horizontal row was printed at 50% speed (about 45mm/sec) and the one above that was printed extremely slowly at 20% speed (about 18mm/sec).

Here is a close up of 2.5mm purge but at 20% speed. 2-5at20percentspeed

As you can see, in terms of the purge amount, it is unaffected by print speed. Looking closely, you can still see the light grey on the top and left hand edge of the black rectangle, and the dark grey on the bottom and right hand edge of the white rectangle. As I mentioned above, this is the transition period from one colour to another and short of using a some sort of a wipe or prime tower, this is a good as it gets. Personally, I don’t think it’s bad. Whether it is good enough depends on people’s expectations and the criteria that the final, printed object has to meet.

So, what was my cause for concern? It was printing an object that consisted of a lot of small parts. The nature of the object was that it had to be printed much slower than I normally print and so, when I observed that something wasn’t right with the colour changes, I assumed it was to do with the lower speed. I have now proven that this is not the case. Further analysis of the post processed gcode file for that object shows that there is an error (at least one) in my python script. Basically, it won’t move a tool change further back than the original position of the tool change that came before it. So, if the amount of filament to be extruded between tool changes is less than the amount needed to purge the hot end, it won’t work. I need to address this or (more likely) take a different approach and re-write the script.

So for now, the script works where there is a reasonable amount of filament extruded between tool changes but cannot cope with tool changes that are too close together.

 

 

Multi colour printing without using wipe or prime towers

Most of the problems with multicolour printing revolve around the fact that when switching from one filament to another there is still some of the old filament in the system that needs to be purged before the new filament can be extruded cleanly. The usual approach is to use some sort of wipe or prime tower which is wasteful both in terms of print time and filament usage, so this is an alternative approach to the problem.

I’ve marked this as a feature post. If you are interested in this, check my blog for the latest updates.

As I have promised on a couple of forums, this post will explain in detail the method I am developing to enable 3D printing of multi colour objects without resorting to the use of wipe or prime towers.

For those of you who haven’t been following my endeavours on any forums, here is a link to the video I posted on YouTube which shows the technique in action.

Now before we get too far into the details, I need to explain few things about myself. I was born in 1953 and left school/started work in 1969 at age 16. I learnt my maths using log tables and a slide rule. I’m a mechanical engineer by training but currently (career number 5) I have a small business make designing and building garden decks. What I know about computers, 3D printers, electronics, writing code etc is all self taught through a lot of internet searches and reading a few books and online tutorials so I’m no expert.

I started setting up this blog/web site on 4th January 2017 so I’m still finding may way around. Apart from a brief introductory post, this is the first blog post I have ever made. Therefore, the layout of this blog site may well change (and please excuse any typos)

That’s the excuses out of the way, now down to business…..

The rest of this post assumes that the reader has the tools and techniques available to generate or otherwise obtain a .gcode file for a multicoloured object. I plan to do a separate write up on the method I use, which involves separate .stl files (which I generate using OpenScad) and slic3r but that will have to wait.

There are a number of issues which have to be addressed when printing multicoloured objects and most of them revolve around what happens when switching from one filament to another. My first forays into multicolour printing were with a tricolour Mendel variant which used 3 separate hot ends. I found that there were 4 major drawbacks to this approach. Firstly it was very difficult to get all 3 nozzles at exactly the same height (within less than 0.1mm) and for this setting to be maintained in such a way that inactive nozzles didn’t drag across the printed part. Secondly, it was very difficult to set and maintain  X and Y offsets get the output from all 3 nozzles perfectly aligned. Thirdly, it was necessary to set unused nozzles to a lower standby temperature in order to prevent filament from oozing out and dragging on the print but this was never completely successful. Also, the waiting time for one nozzle to heat up and another to cool down significantly increased the print duration. Lastly, there was the problem of filament oozing from one nozzle as it cooled down and before it reached it’s standby temperature, or another nozzle as it heated up before it reached it’s active temperature.

All of the above problems can by overcome by using a single nozzle – i.e. a mixing hot end. For the purpose of this post, I will define a mixing hot end as one which has multiple filament inputs but a single output (nozzle). I am currently using a Diamond hot end but I am aware that there are other designs.

However, this approach generates a new problem which is that when switching between filaments, there is still some of the old filament left in the nozzle and/or mixing chamber which has to be purged before the next filament comes through. If the colour change coincides with a layer change, this is rarely an issue. Unless the object being printed is really small, what happens is that the purge occurs during the inner perimeter(s) so by the time the outer perimeters are being laid down, the purge has already been completed. Effectively the change over period is hidden inside the object and isn’t visible.

The real problem is when the colour change occurs within the same layer, as in the union flag example that is in the YouTube video, because there is nowhere to hide and any defects will be visible. The usual approach is to move the print head away from the main object, and print some sort of sacrificial tower or use some sort of wiping mechanism to purge out the old filament, then move back to the object and resume printing. This is wasteful both in terms of filament and time, and can lead to a less than satisfactory print finish if filament retraction and recovery are not fully optimised.

The technique I’m developing and which I am about to share here, simply moves the filament change point to a position earlier in the gcode file. The new position equates to the amount of filament that needs to be extruded in order to purge out the old. The method isn’t perfect because in theory, there is still a “transition” period where what is being extruded is a mixture of the old colour and the new. In practice, by observation I’d estimate this transition to be about 10% of the total “purge amount” and I have found that with the Diamond hot end the optimum purge amount is about 2.0 to 2.5mm of filament so there is around 0.2 to 0.25mm of “transition” filament which is hardly noticeable. Other designs of hot end may have larger mixing chambers, in which it may still be necessary to use some sort of wipe or prime tower. However, my technique could still be applied to take account of much of the purging so any further priming could be achieved by using a very much smaller tower or priming mechanism. One of my planned improvements is to build a small priming tower or similar mechanism into the post processing script, although as I have said earlier, the transition between one colour and the next with the Diamond hot end is really small and hardly noticeable.

As mentioned earlier, the only coding I know how to do is what I have been able to teach myself from internet searches, on-line tutorials and the odd book (some have been very odd). I have used Python just because I found it less of a pain to learn than some other languages that I’ve tried. I am aware that this might not be the best tool and I am deeply aware of my own shortcomings so I think the best approach is for me to post my work flow and explanation of what the code attempts to do. Others with more skill than I have can then use it as basis to write something more efficient (and probably less dangerous). I’ll make the python script available for those want to try it but please don’t blame me if it crashes your PC or worse.

So here goes.

The approach I’m taking is to leave the original file untouched and generate a new file with the colour change commands moved forward in the file but otherwise it’s an exact copy. This enables me to run the script several times on the same file but with a different “purge” setting in order to test and fine tune. The change from one colour to another in the gcode file is accomplished by selecting a new tool. It could be done by having a single tool and changing the mixing ratio but that’s not how slc3r works. So for the rest of this post colour changes will be referred to as tool changes. Note that the code could be adapted to look for M563 commands (mixing ratio changes) instead or as well as “Tn” (tool change) commands.

I haven’t yet figured out how to cut and paste the python text while retaining the font colours so I’ll change them manually – hopefully I won’t miss any. Comments are in red and start with a hash (#) String values are in green. My other comments are in blue to denote the fact that are not part of the script.

These first lines should be changed to suit the user. Hopefully the comments make them self explanatory.

sourceFile = “D:\RepRap\G Code Files Diamond hot end\Python test file.gcode” # The full path and file name of the file to be worked on
destinationFile=“D:\RepRap\G Code Files Diamond hot end\Python output.gcode” # the full path and file name of the destination (output) file
temporaryFile =“D:\RepRap\G Code Files Diamond hot end\Python temp.gcode” # A temporary file used to hold smallish sections of the original and which gets read into memory.
purgeAmount =2.5 # This is the amount of filament to be purged when a tool change is needed

The next thing I struggled with was how to detect the start of a print proper. Slic3r inserts all sorts of comments both before and after the actual print and I use quite a complex start gcode in my slic3r setting. In the end I decided to use flags in my start and end gcodes. So the last line of my start gcode is a comment “;begin” and the first line of my end gcode is the comment “;end”. The main reason for doing this is that the script simply looks for the text “T” to detect a tool change and as “T” can be found in comments and both pre and post print sections, I need to restrict the search.  

beginText=“begin” #string to look for to detect start of gcodes proper. This should be the last line of slicer start gcode
endText=“end” #string to look for to detect end of gcodes proper. This should be the first line of slicer start gcode
searchToolText=“T” # String to look for to detect a tool command (which is why we need to restrict the search to between “begin” and “end”
# Tool number could be anything after the “T” so we can’t can’t search for “Tnn” explicitly

Here are all the other variables that I have used. I know that I probably shouldn’t have declared them as global variables but at least they are all in this section so easy to find what they do. I also know that I’ve probably used a lot of unnecessary flags and that they could be boolean rather than integers etc etc.

beginFlag=0 # flag to detect if the word “begin” is present
endFlag=0 # flag to detect if the word “end” is present
#There is nothing to check that begin is indeed before end – maybe do this check too.
toolFlag=0 # flag to detect that tool changes are present
toolChanges=0 # number of tool changes in the file
currentTool=“T0” #default this to “T0”
lineText=“” # text read in from file
startLineNo=0 # the line number in the file immediately after the word “begin”
toolChangeLineNo=0 # the line number in the file where a tool change occurs

newToolPos=0 # the position where the tool command will be inserted
lastLine = 0 # the position of the last line in the temp file
lineToRead=0 # pointer to which line to read in the temp file
estart=0 # position in the line after the letter “E” which denotes the position of the start of digits for extrusion
estring=“” # the string of 7 digits following the letter E
EAmount=0.0 # estring converted to a number
totEAmount=0.0 # the sum of all EAmounts
EAmountNeeded=0 # the purge amount less the totEAmount
notEnoughFlag=0 # flag to set if the the totEAmount is less than needed for a full purge between tool changes

xStartPrev=0 # the position in the previous line where X is
xPrevString=“” # read the 7 characters after “X”
xPrevNum=0.00 # convert to number – First X value

xStartHere=0 # the position in this line where X is
xHereString=“” # read the 7 characters after “X”
xHereNum=0.0 # convert to number – Second X value

xMove=0 #xHereNum-xPrevNum

yStartPrev=0 # the position in the previous line where Y is
yPrevString=“” # read the 7 characters after “Y”
yPrevNum=0.0 # convert to number – First Y value

yStartHere=0 # the position in this line where Y is
yHereString=“” # read the 7 characters after “Y”
yHereNum=0.0 # convert to number – Second Y value

yMove=0 # yHereNum-yPrevNum

E1 = 0 # EAmount-EAmountNeeded
E2 = 0 # EAmountNeeded

X2 =0 # xHereNum
X1 =0 # PrevNum +(xMove/eAmount*E2)
Y2 =0 # yHereNum
Y1 =0 # yPrevNum +(yMove/eAmount*E2)

E1string=“” # used to build insertString1 – 1st E amount
E2string=“” # used to build insertString2 – 2nd E amount
X1string=“” # as above but X values
X2string=“”
Y1string=“” # as above but Y values
Y2string=“”

insertCheck=0 # used in loop to check lines are valid for inserting text
firstInsert=0 # modified from newToolPos if that position contains something other than a normal XYE move
secondInsert=0# as above

insertString1=“” # 1st (new) move string prior to tool change i.e. “G1 Xnnn.nnn Ynnn.nnn En.nnnnn”
insertString2=“” # then the tool change
insertString3=“” # then the second move string

changesDone=0 #number of tool changes done

So now we start the script proper. This section should all be self explanatory. I don’t know how to indent individual lines within a paragraph using this WordPress thingy so I’m having to do it by starting a new paragraph wherever the text needs to be indented.  Therefore there are what look like a lot of blank lines in what follows but Python relies on indentation for the code to work so it’s important that I show it.

# Start by reading through the file to check that “;begin” and “;end” are present
startfile=open(sourceFile,‘r’) # Open file as read only
numLines=sum(1 for line in (startfile))

startfile.seek(0)# set to start of file (just in case)
print (“Checking File…”)
for x in range (0,numLines):

lineText=(startfile.readline())
if endText in lineText:

endFlag=x
break # exit loop on first instance of “end”

for x in range (0,numLines):

lineText=(startfile.readline())
if beginText in lineText:

beginFlag=x
break # exit loop on first instance of “begin”

print (“Number of lines =”,numLines) # Just for info
if beginFlag>0:

print (“\”;begin\” text is present at line “,beginFlag) # Just for info – print a message to say that the search string was present.

else:

print (“There is no \”begin\” statement in the file”) # If not print a different message to say that the string wasn’t found…….
print (“Add \”begin\” to the end of the start gcode in Slicer”) # ….and tell the user what to do about it.
print (“And/Or edit the file and start again”)
startfile.close()
exit() pr# if there is no “begin” text string in the source file then end the script after printing the message and closing the file.

if endFlag>0:

print (“\”;end\” text is present at line “,endFlag) # comments as above
print(“”)

else:

print (“There is no \”end\” statement in the file”)
print (“Add \”end\” to the end of the start gcode in Slicer”)
print (“And/Or edit the file and start again”)
startfile.close()
exit()# if there is no “end” text string in the source file then end the script after printing the message and closing the file.

startfile.close() # I always like to close a file when an operation on it has finished – just in case.

This next bit is just for information really although the number of tool changes is used further on in the code and if there aren’t any tool changes found, it will print a message and exit. 

#so now read through and count the number of tool changes between begin and end
startfile=open(sourceFile,‘r’)
startfile.seek(0)

print (“Checking for tool changes…”)
for x in range (beginFlag,endFlag):

lineText=(startfile.readline())
if searchToolText in lineText:

toolFlag=toolFlag+1

toolChanges=toolFlag-1 # the first occurrence will be the first tool, so take 1 off to get the number of tool changes.
if toolChanges>0:

print (“There are “,toolChanges-1,“tool changes in the file”)
print(“”)
startfile.close()

else:

print (“There are no tool changes in this file”)
print (“So no changes will be made.”)
startfile.close()
exit()

startfile.close()

Now I read through the file and copy everything up to the first tool change into the output file

# Now read through the file and copy everything up to the first tool change
startfile=open(sourceFile,‘r’) # open source file again for reading
startfile.seek(0) # make sure we start at the beginning
endfile = open(destinationFile,‘w’)# open the destination file for writing
print (“Reading file and writing lines up to first tool change”)
print(“”)
#start by copying everything up to the begin statement
for x in range (0,numLines):

lineText=(startfile.readline())#read line from input file
# uncomment the following line with caution – it really slows things down.
#print (lineText)
endfile.write(lineText) # copy line to output file

if beginText in lineText: #is there a tool string present in this line?

startLineNo=x # if so, set the variable StartLineNo to x which will be the text file line number

break #end the loop when the first tool line number has been reached

# end of for loop

endfile.close()

# So now check for first instance of a tool (check gcode file for a “T”)
# also, append all the lines up to this point to the end file
# Start by opening the end file again in append mode

endfile = open (destinationFile, ‘a’) # open again in append mode

for x in range (startLineNo,numLines): # miss out the first lines from 0 to StartLine No

lineText=(startfile.readline())#read line from input file
# uncomment the following line with caution – it really slows things down.
#print (lineText)
endfile.write(lineText) # copy line to output file but this time we are amending it to the end of the file
if searchToolText in lineText: #is the string present in this line?
currentTool=lineText # if so, set the variable CurrentToolText to whatever this line holds (string value)
toolChangeLineNo=x
endfile.close()
break #exit loopif

endfile.close()

# *********** Now it gets tricky************

What I do next is copy chunks of the source file between tool changes into a temporary file. The reason for doing so is that I wanted to read this file into a list so that I can work on it. Maybe I could read the entire file into memory but potentially it could be a huge file and gobble up all the PCs resources. David Crocker (DC42 of Duet fame) has said that if he were doing this in firmware, he would have two streams – the original and the output with the a kind of buffer that would hold just the number of commands that make up the purge amount, rather than this approach which holds all the commands between one tool change and the next before they are written to the output file. Thinking about it, that would be a far better approach but the following is how it is now. So, to continue…

(Oh by the way, there are quite a few commented out print statements in what follows which were only used for debugging)

# Read lines from latest tool to next tool and stick them in a temporary file

for changesDone in range (1,toolChanges):# repeat the rest of this until we reach the end of the file

print (“Doing tool change “,changesDone)
totEAmount=0 # reset to zero
newToolPos=0 # reset to zero

tempfile = open(temporaryFile, ‘w’) # This will create a file if it doesn’t exist and/or overwrite.
print (“Writing to temporary file……”)
for x in range (toolChangeLineNo,numLines): # miss out the first lines from 0 to StartLine No

#print (“Tool change line number = “,toolChangeLineNo)
lineText=(startfile.readline())#read line from input file

# uncomment the following line with caution – it really slows things down.
#print (LineText)
tempfile.write(lineText) # copy line to temporary output file
if searchToolText in lineText: #is the string present in this line?

currentTool=lineText # if so, set the variable CurrentTool (Text) to whatever this line holds (string value)
toolChangeLineNo=x # so update the pointer to the current line number…
break #… and exit loop

if x==numLines: # if we reach the end of the file (we should never get here)
print (“No more tool changes”) # print message, close files and quit

tempfile.close()
endfile.close()
startfile.close()
quit()

#end of x loop – still in changesDone loop

tempfile.close()# Close the file for writing to

#now read the whole tempfile into a list so we can work on it
f=open(temporaryFile,“r”)
templines =f.readlines()
f.close()
lastLine =(len(templines)-1) # Len is the number of lines in the file but the last line will be 1 less because the first line is indexed as 0.
#print (templines[lastline]) # just for debugging
print(“Calculating new tool position”)
#Start at the end of the file and work backwards
# read the 7 characters after the “E” in a line
notEnoughFlag=0 # Reset flag (start at zero)
for j in range(1,lastLine): # set range to the number of lines in the file so that it can’t go back beyond that

lineToRead=lastLine-j # read the line
#print (templines[lineToRead]) # for debugging only – comment out later
if “E” in templines[lineToRead]: # check that the line does actually have an E value

estart=templines[lineToRead].find(“E”) # find the position in the line where E is
estring=templines[lineToRead][estart+1:estart+8] # read the 7 string characters after the E
#print(estring) # just for debugging – comment out later
EAmount=float(estring)# convert the string to a number
#print (EAmount) # just for debugging – comment out later
totEAmount=totEAmount+EAmount # add this amount to the previous amount to get a total
#print (totEAmount) # just for dbugging – comment out later
if totEAmount > purgeAmount:

newToolPos=lineToRead #Set the new tool position to lastline -j (the point in the line where the sum of all the extruder commands excedes the purge amount).
#print(“new tool position “,j)
break #exit the loop

if j==lastLine: # if we go all the way back

newToolPos=lineToRead # then there aren’t enough moves to purge fully so set new tool pos to the earliest position
print (“WARNING Not enough extrusion between tool changes to fully purge”)
notEnoughFlag=1

j=j+1

# so now we have the position for the tool where adding the Eamount from the line after excedes the amount needed to purge
# but it’s counting backwards from the end
print(“Splitting Gcode line at insert point”)
# so I want to use only the amount needed, therefore I have to split the line
#the amount needed will be the ToteAmount minus the purgeAmount
EAmountNeeded = totEAmount-purgeAmount
#get the x an y totals for the line that needs to be split

# ************Trap for the line not being a normal XYE move **************
# ************If it isn’t go back and keep going back until we find one **************

insertCheck=0
secondInsert=newToolPos
if notEnoughFlag==1: # skip the next bit if flag set

insertCheck=0

while insertCheck ==0:

if “G1 X” in templines[secondInsert]:

insertCheck=1
break

else:
secondInsert=secondInsert-1
insertCheck=0

# Now get the x value from this line

xStartHere=templines[secondInsert].find(“X”) # the position in this line where X is
xHereString=templines[secondInsert][xStartHere+1:xStartHere+8] # read the 7 characters after “X”
xHereNum=float(xHereString) # convert to number – Second X value

# and do the same for the y value
yStartHere=templines[secondInsert].find(“Y”) # the position in this line where Y is
yHereString=templines[secondInsert][yStartHere+1:yStartHere+8] # read the 7 characters after “Y”
yHereNum=float(yHereString) # convert to number – Second Y value

#Now do it all again for the previous line

insertCheck=0
firstInsert=newToolPos-1 #take 1 away to get the previous line
if notEnoughFlag==1: # skip the next bit if flag set

insertCheck=0

while insertCheck ==0:

if “G1 X” in templines[firstInsert]:

insertCheck=1
break

else:
firstInsert=firstInsert-1
insertCheck=0

xStartPrev=templines[firstInsert].find(“X”) # the position in the previous line where X is
xPrevString=templines[firstInsert][xStartPrev+1:xStartPrev+8] # read the 7 characters after “X”
xPrevNum=float(xPrevString) # convert to number – First X value

yStartPrev=templines[firstInsert].find(“Y”) # the position in the previous line where Y is
yPrevString=templines[firstInsert][yStartPrev+1:yStartPrev+8] # read the 7 characters after “Y”
yPrevNum=float(yPrevString) # convert to number – First Y value

#Now take one from the other
xMove=xHereNum-xPrevNum
yMove=yHereNum-yPrevNum

# Now split the values

E1 = EAmount-EAmountNeeded
E2 = EAmountNeeded

X2 = xHereNum
X1 = xPrevNum +(xMove/EAmount*E2)
Y2 = yHereNum
Y1 = yPrevNum +(yMove/EAmount*E2)

# Now convert the values back to strings

E1string=“{:.5f}”.format(E1)# 5 decimal places
#print (E1string)
E2string=“{:.5f}”.format(E2)
#print (E2string)
X1string=“{:.3f}”.format(X1)#3 decimal places
#print (X1string)
X2string=“{:.3f}”.format(X2)
#print (X2string)
Y1string=“{:.3f}”.format(Y1)
#print (Y1string)
Y2string=“{:.3f}”.format(Y2)
#print (Y2string)

#build strings to insert
insertString1=“G1 X”+X1string+” Y”+Y1string+” E”+E1string+”\n” # 1st (new) move prior to tool change
insertString2=currentTool # then the tool change
insertString3=“G1 X”+X2string+” Y”+Y2string+” E”+E2string+”\n” # then the second (new) move

#print (insertString1)
#print (insertString2)
#print (insertString3)

#determine the point where the lines need to be inserted
insertPoint=lastLine-j
print (“Appending lines to output file”)
#now open the end file and append this lot to it.
endfile = open(destinationFile,’a’)
for x in range (0,insertPoint):

endfile.write(templines[x])

endfile.write(insertString1)
endfile.write(insertString2)
endfile.write(insertString3)
for x in range (insertPoint+1,lastLine):

endfile.write(templines[x])

endfile.close()
print (“Tool change “,changesDone,“done”)
print(“”)
changesDone=changesDone+1 # so go back and do it all again for the next tool change

# End of changes Done loop

print(changesDone-1,“Tool changes moved”)
print(“”)
if notEnoughFlag==1: # skip the next bit if flag set
print(“WARNING there was insufficient filament extruded to fully purge between at least one of the tool changes”)
endfile.close

# So now all that remains is to append the rest of the source file to the output file

print (“Copying remaining lines to output file…”)
print(“”)
endfile = open(destinationFile,’a’)
for x in range (toolChangeLineNo,numLines):

lineText=(startfile.readline())#read line from input file
endfile.write(lineText)

startfile.close()
endfile.close()
print (“Done..”)

And that my friends is it!!

I don’t suppose anyone will want to copy and paste all the above code so I’ve uploaded the file to my Google drive.

Edit. 24th Jan 2017. I have removed the link to the Python script because there were a number of bugs – see later posts.