Humidity can ruin 3D printer filaments, some are more sensitive than others, such as ABS which happily absorbs the moisture, causing the filament to expand and spit and steam the moisture out when printing, leaving horrible prints.
This is the story of how the Cambridge MakeSpace filament storage boxes are made and keep the filament in good condition for our members.
This solution was inspired by Stephen Hall's design however we found that when using 2.85mm filament for the Ultimakers it was not possible for the filament to be fed directly from the storage boxes as it would snap or tangle in the box.
This storage system uses an off the shelf 19XL or 25L Really Useful Box(r) and provides a low humidity environment by drying the air in the through silica gel. The boxes are internet connected using a Particle Photon, this is connected to Tinamous to display information about the box so I can know when the gel needs replacing or if the fan has failed without having to go into MakeSpace to check on the boxes.
These boxes have been implemented since about 2015 (yes, it has really taken me that long to write it up!) with some gradual improvements, and have survived the day to day use in MakeSpace (that's no mean feat!). They have provided for a nice storage solution to keep our filament in.
Each box holds 4x 1Kg spools vertically, and possibly a smaller one placed on top of the spools depending on the box lid used), or 5x 750g spools vertically with another laying on top.
The boxes use a fan to help dehumidify the air so they require a 12V power source, the power entry is though the top of the box to make it obvious to members that a cable is attached to avoid strained cables or accidental unplugging. For home use where the boxes might be better stacked the power can be connected from the side.
When originally designing the boxes I tried a few system to reduce the humidity in the boxes, including the mini peltier dehumidifiers, which proved to be utterly useless. Silica gel was an obvious choice but without it being totally open (i.e the beads just poured into the bottom of the box) it was not effective (or rather, it took too long to dehumidify the box after opening).
After various experiments I ended up with a forced air system using a 40mm PC fan controlled by a Particle Photon that also measured the humidity inside the box.
In a home environment where the box is rarely opened you may not require the forced dehumidification, however these boxes are opened numerous times a day as members get filament out to print with, without the fan the silica gel is too slow to dehumidify the air to make any difference.
Another problem faced with the 19XL boxes is the lid has large gaps around it, draft excluder is used to reduce the movement of air, without which the humidity soon rises. A recent improvement to this is with the use of a smaller lid and epoxy resin used to fill the gaps which provides a really good seal. The 25L box comes with this lid and gives extra height, so going forward this will be the ideal box.
I chose to mount the cartridge on the lid rather than in the base of the box as it helps add weight to the lid for a better fit, this also means members are very aware the lid is special and so the lid doesn't go missing and is easier to get the cartridge out to replace the gel.
Maintenance is simple, when the gel needs replacing (I replace it at about 20% humidity) the cartridge is removed from the lid, the gel poured out, then fresh dry gel is poured in, the cartridge put back together and back into the lid, it takes about 15 minutes. The old gel is then dried (electric oven at about 110-120°C, or microwave about 500g on 50% power for 3 minutes, stand, repeat). In normal uses the gel needs to be replaced about once per month, but for a home environment I would expect a lot longer life.
The system composes of two main parts, a 19XL or 25L Really Useful Box(r) and an acrylic silica gel filled cartridge attached to the inside of the lid. Larger boxes can be used but I found that they have a large gap around the lid which significantly reduces the effectiveness. The 19XL and 25L boxes are also ideally sized for standard filament spools.
The cartridge was designed using MakerCase and the json files are available in the github repository case folder should you wish to make changes. Be sure to select 5mm Material Thickness as this is not selected by default when loading. Some manual editing was done for the fan holder.
The designs were cut from a 600x400x5mm sheet of Acrylic.
Once the acrylic is cut (i.e. before gluing) the box lid is drilled using the bottom piece (the one with all the holes as a guide) as a guide for the corner holes. One hole is drilled to begin with and a M4 machine screw used to keep the acrylic in place then the remaining holes can be drilled.
Where the cartridge is powered through the top, the top section is used to align the holes to make the position of the power inlet and drill with a cone drill.
Acrylic Case Cartrige:The acrylic needs to be glued together with acrylic glue. I used Tensol-12. Do NOT use super glue as it turns the acrylic horribly smokey.
I used black electrical tape to hold the acrylic together whilst it is being glued, this works well as it can be stretched over the joint to help keep it tight. Note that this not my actual kitchen top in the photo, but an off-cut I use for messy work.
Be careful to align the acrylic pieces:
- Ensure the end with the 4 PCB mounting holes is at the large opening end of the base.
- Ensure that the cut outs in the side pieces are also at the large opening end.
- DO NOT glue the lid on the acrylic box. This needs to be removable to fit the PCB and to change the gel and fan if it fails.
- DO NOT glue the fan insert in. This is useful to be removed.
It is best to chill the Tensol-12 for 12-24 hours before use so that it becomes nice and thick, otherwise it is difficult to work with. Use only a small amount (follow the instructions). Work in a (very) well ventilated area, the glue has nasty fumes!
A small bead of glue is run around the 4 edges of the base and up the 4 corner edges. It helps to stop just before the top so that you can place the top on to ensure you have a square fit without the top actually getting glued. Leave to set (about 12 hours).
Once the case is ready the electronics and fan can be fitted.
Electronics:The electronics for the cartridge are based around the Particle Photon. Eagle files for the PCB files are available in the GitHub repository, this can be uploaded to OSH Park of your favourite fab house to have the PCBs made.
Most of the PCB is fairly obvious to populate. The LEDs are reverse mount 1206 red, yellow and green (ensure you get the right order) so that they can be seen from outside the box.
Standoff headers are used to socket the photon as this allows a USB lead to be connected to program/power the Photon whilst it's inside the cartridge if this is needed (handy for updating the WiFi connection).
I've used a HTU21D Humidity sensor breakout board from eBay as it's painful to solder and cheaper! Watch the pin ordering as this is the same as the SparkFun breakout but has the pins in a different order.
The 5V for the Photon is provided by a "7805" buck switching converter from the 12V supply. You can use a 7805 but it gets very hot. Again these parts are from your favourite eBay/China seller.
The buzzer is a mechanical buzzer driven at 5V, it's not very loud but you may prefer not to fit it. It will sound when the humidity is high (i.e. you've left the lid off or the gel needs replacing).
The main processor is a Photon from Particle.io, this makes the storage box internet connected so we can monitor the filament storage condition.
The fan is controlled by a P-FET on the high side, this needs a transistor to switch the gate as it is on the 12 volt rail. A N-FET could be used on the low side without needing the additional transistor, but the rotation sensor is referenced to ground and should a PWM speed control be used for the fan this would mess up the rotation sensing.
Final ConstructionAll being well the Electronics can be screwed into the case. Use 8x M3 machine screws into spacers to fix the PCB. It should be mounted with the Photon USB connector pointing out of the case.
The fan is screwed to the fan mount, with a filter going to the silica gel side (and screw heads in the filter, through the fan mount to the fan. The fan wires are shortened and re-crimped to keep it tidy. The fan mount then drops into the cartridge and plugs it onto the 3 pin connector on the PCB. A 2 wire 12V fan can also be used but you will not be able to detect a fan fail.
The DC jack connector is screwed to the lid (if you would prefer a side mounted one this can be mounted somewhere else to allow for stacking boxes), then plugged it onto the 2 pin connector.
Once the glue is set and electronics tested the cartridge is filled with silica gel and attached to the lid. When using the large lid attach draft excluder around the joining section to reduce natural air flow as this allows the humidity to creep up.
With the larger lid I attached the cartridge using wing nuts, this makes it very easy to remove the cartridge. I also added a cheap standalone humidity sensor into the box. Note that this has a minimum humidity range of about 10%, where as the HTU21D will allow us to measure down to -10% (Relative Humidity) and with fresh silica gel the box can easily get down to about -5%.
For the new style lid I found it was more difficult to remove the lid from the box, so I added 3D Printed Pi Handles. These make it a little more difficult to change the silica gel, but much easier to remove the lid.
The firmware is responsible for monitoring the humidity level, reporting this to Tinamous via the Particle cloud and controlling the fan when the humidity is too high.
The humidity is measured approximately once every second, if the humidity is above a predefined maximum level (humidityWarningLevel default = 30%) the fan is stopped as it is assumed the lid has been removed and is in open air, running the fan at this time quickly saturates the silica gel which means I then need to replace it!
Every 10 seconds the fan control is updated (updateFanControl()). If the humidity is above a set value (fanOnAtHumidityLevel default 20%) the fan is run. If it is below 5% then the fan is stopped to increase the working life of the silica gel.
The variable fanOnCount is used to monitor how long the fan has been running for, in this case if the value is > 12 it is assumed that the silica gel is no longer able to dehumidity the box and a status message published to Tinamous.
void updateFanControl() {
int newFanOnCount = fanSpeed - 1;
if (humidity > humidityWarningLevel ) {
// If measured humidity is above 30% (humidityWarningLevel) then
// don't run the fan as the unit is most likely in free air
// and this will ruin the silica gel quickly.
newFanOnCount = 0;
// The humidity will gradually drop once the unit is in a
// controlled environment
// and then the fan can resume
} else if (humidity < 5) {
// Humidity is low, don't bother to run the fan
// so to avoid over using the silica gel tying to create a very low
// humidity environment.
newFanOnCount = 0;
} else if (humidity > fanOnAtHumidityLevel) {
// Humidity is above fanOnAtHumidityLevel and below humidityWarningLevel
// so run the fan to try and drop the humidity.
// If gel needs replacing don't run the fan now
// otherwise it will run constantly.
// System will be power cycled when gel is replaced so the flag resets.
// Manually switching the fan on will also reset this.
if (!gelNeedsReplacing && newFanOnCount == 0) {
// If the fan is off and the gel doesn't need replacing then
// switch the fan on.
newFanOnCount = 1;
}
// If the fans been on for n counts and the humidity has not dropped below our
// fanOnAt level then flag the gel as shot.
if (fanOnCount > 12) {
Particle.publish("status", "Gel is shot, fan's been running for too long. Disabling fan....");
gelNeedsReplacing = true;
}
} else {
// Humidity is below the level we need to wory about
// so don't run the fan, use only the timed interval.
// let the fan run for the timer set.
}
if (newFanOnCount < 0) {
newFanOnCount = 0;
}
setFan(newFanOnCount);
}
void setFan(int fanCount) {
int newfanSpeed = fanCount;
// Store in the Particle variable
fanSpeed = newfanSpeed;
if (fanSpeed > 0) {
digitalWrite(fanControl, HIGH);
digitalWrite(fanLed, HIGH);
fanOnCount++;
} else {
digitalWrite(fanControl, LOW);
digitalWrite(fanLed, LOW);
fanOnCount = 0;
}
}
The function beepIfNeeded() will activate the buzzer if the humidity level is above the warning level and beeps, this is used to indicate that the lid has been left off, the alert is done 5 times after which it is muted until humidity has been restored (this prevents it constantly beeping if the gel is shot).
void beepIfNeeded() {
// Beep a max of n-times when the humidity goes out of range
// Once it's back in range reset the counter.
if (humidity > humidityWarningLevel) {
if (beepedCount<5) {
doBeep(5);
beepedCount++;
} else {
/// Silent beep beep beep to stop it being annoying
}
} else if (humidity < (humidityWarningLevel - 5)) {
//Particle.publish("Status", "Resetting beep counter as humidity < warning level");
beepedCount = 0;
}
}
A few Particle functions are used to allow the configuration to be changed or the fan controlled. These are shown below.
The fan on and high humidity levels are set by the setFanOnAt and setWarnAt functions. fanOn and fanOff allow manual control of the fan, and beep and mute allow control of the buzzer.
void setup() {
......
// register the cloud function
Particle.function("setFanOnAt", setFanOnAt);
Particle.function("setWarnAt", setWarnAt);
Particle.function("fanOn", fanOn);
Particle.function("fanOff", fanOff);
Particle.function("beep", beep);
Particle.function("mute", mute);
......
}
/ =====================================================
// Particle Methods
int setFanOnAt(String level) {
// This relies on level being a single numeric value.
fanOnAtHumidityLevel = level.toInt();
EEPROM.write(1, fanOnAtHumidityLevel);
Particle.publish("Status", "Setting fan trigger humidity level at: " + String(fanOnAtHumidityLevel) + "%");
return fanOnAtHumidityLevel;
}
// Particle Method
int setWarnAt(String level) {
humidityWarningLevel = level.toInt();
EEPROM.write(2, humidityWarningLevel);
Particle.publish("Status", "Setting humidity waring level at: " + String(humidityWarningLevel) + "%");
return humidityWarningLevel;
}
// Particle Method
int fanOn(String command)
{
Particle.publish("Status", "Switching fan on for max. 10 minutes (Reset gelNeedsReplacing).");
// On for 10 mins (6 iterations per min)
setFan(10 * 6);
return 10*6;
}
// Particle Method
int fanOff(String command)
{
Particle.publish("Status", "Switching fan off.");
// On for 0 iterations
setFan(0);
return 0;
}
// Particle Method
int mute(String command) {
int toMute = command.toInt();
if (toMute == 1) {
muted = true;
Particle.publish("Status", "Muted.");
} else {
muted = false;
Particle.publish("Status", "Un muted.");
}
return muted ? 1 : 0;
}
int beep(String command)
{
doBeep(command.toInt());
return 0;
}
These are easily called through the Tinamous device page.
Sensor and control information is pushed to Tinamous on the same 10 second loop as the fan control. If the humidity is above the warning level a status message of "High Humidity" is also published (once only until the humidity is restored), this can be used to send a notification to check the silica gel.
Humidity, temperature, fanOnCount, replaceGel, faultCode and fanPulses and fanTimeRemaining are all published as a senml message to Tinamous via the Particle Cloud. This allows the device functionality to be monitored as well as the actual humidity in the box.
We've had a number of fan failures in the various boxes, most likely down to the use of cheap 40mm fans! So the fanPulsesPerInterval is used, this comes from the fans rotation sensor.
void updateTinamous() {
if (humidity > humidityWarningLevel && !highHumidity) {
highHumidity = true;
Particle.publish("Status", "High Humidity");
}
if (humidity < fanOnAtHumidityLevel) {
highHumidity = false;
}
String senml = "{'n':'Humidity', 'v':" + String(humidity) + "}";
senml+=",{'n':'averageHumidity', 'v':" + String(averageHumidity) + "}";
senml+=",{'n':'temperature','v':" + String(temperature) + "}";
senml+=",{'n':'fanOnCount','v':" + String(fanOnCount) + "}";
senml+=",{'n':'replaceGel','v':" + String(gelNeedsReplacing) + "}";
senml+=",{'n':'faultCode','v':" + String(faultCode) + "}";
// If the fan is running include the fan pulses.
// If == 0 then it's likely the fan was on
// during the last time slice.
if (fanSpeed >= 0) {
senml+=",{'n':'fanPulses','v':" + String(fanPulsesPerInterval) + "}";
senml+=",{'n':'fanTimeRemain','v':" + String(fanSpeed * 10) + "}";
}
Particle.publish("senml", "{'e': [" + senml + "]}");
}
Monitoring:As I am responsible for maintaining the storage boxes in MakeSpace, being able to monitor the humidity level and know when it's time to change the gel is a big bonus. For home use you could just go by the color of the gel (Orange = good, Green/Brown = replace). I also glued in a cheap LCB humidity meter to the cases for a quick check although these are not particularly good and don't measure below 10%.
The Photons are connected to the Particle Cloud and publish the sensor data as described in the firmware section. This by itself is not overly useful, so Tinamous is connected to the Particle Cloud using a ParticleBot to bring is the sensor data, create charts and dashboards and provide notifications.
The Tinamous ParticleBot does most of the work for connecting out Photons for us. From the Bots page a Particle Bot is added and linked to the Particle Cloud account the devices are connected to.
This monitors the Particle Cloud, when new devices are added a digital twin is added to the Tinamous account to represent that. The bot uses the Particle Cloud event stream so no WebHooks or further setup is required. Once a senml message is received it is decoded and stored against the appropriate device (with fields automatically added as required).
The devices are manually tagged with "FilamentBox" as well as PLA or ABS to represent the material storage, this allows us to group the devices for charting or notifications.
The devices are all set to public so anybody can check the humidity level without needing a user account within the MakeSpace Tinamous organisational account.
For example, you can see the PLA Filament Box #1 here: https://makespace.tinamous.com/Devices/PlaFilamentBox
On the devices page you can see the history of humidity level:
Notice the spikes in humidity, this is where the lid was removed. We can drill out further to see how well the box and silica gel are perform, below you can see that the get was replaced around the 4th of June and spikes where the box has been opened to get filament out.
For easier day to day monitoring I also created a dashboard within Tinamous for the filament boxes. Here I can see at a glance if the gel needs replacing (as it does for both the ABS filament boxes).
I used self indicating Silica Gel as this changes color based on the amount of moisture it has absorbed. Once the gel is unable to drop the box below 20% I dry it out (It's usually a green/brown color at this stage).
The gel is spread thinly on baking trays and cooked in an electric oven at 110°C for about 2 hours. The wire coming out is for a Thermocouple, this is connected to a ThingySticks Thermocouple (also Photon based) which can be used to monitor the tray temperature (which is a good indication of how much moisture is in the gel).
I tried a number of different designs of the filament box, the one documented above has worked well and survived the day to day (unintentional) abuse of being in the MakeSpace.
An early attempt based on Stephen Hall's design but we dound that the 2.85mm filament didn't like being straightened in the tubes and broke easily and would also tangle in the box (see the green filament).
The next attempt put the spools in compartments to stop the filament overlapping, however this proved to be very annoying to replace empty spools and didn't cure the problems of snapping filament.
Eventually the idea of the filament spool always being in the box was abandoned, now the spool is removed and attached to the printer in the normal manner.
The first version of the silica gel cartridge was based on another really useful box (the pensil case type) with a fan and a number of holes. This fitted perfectly across the opening of the 19XL boxes but then this needed removing to get the filament out, so the final design was attached to the lid.
Comments