While I’ve never had a spool of filament run out mid-print, it was time to prepare for the inevitable. First, I would need a sensor to detect the scenario. Also, time is usually of the essence if you’d like to save the print and swap in new material, and I figured it would be best to get an instant notification via SMS.
I came up with a solution using my preferred 3D printer interface, OctoPrint. It was a bit involved, so buckle up! This guide assumes you have some experience with basic electronics, 3D printing, OctoPrint, and Raspbian (ssh, shell, GPIO).
Filament sensor
You can buy a filament runout sensor for pretty cheap, but I opted to build one with existing parts in my electronics box.
It’s a pretty simple mechanism, you just need a momentary switch, preferably one with a roller to minimize friction. The switch presses up against your filament line and will stay pressed while filament is touching it. When the filament runs out, the switch would be released, triggering the action you want.
For my Creality Ender 3 printer, I found this design on Thingiverse that screws to the z axis. But the roller switches in my parts drawer had a longer lever mechanism, so I remixed the design and stretched it out to fit.
I wired the switch on the two outer leads to be normally closed. That means that when the switch is up, the wires are connected. When the switch is pressed down, the wires are disconnected. I’m not sure if this is the convention with these sensors, but it made sense to me: sending high current when then the target state is detected.
The switch was installed to my Ender 3, and I attached the leads to GPIO4 and GND on the raspberry pi GPIO, simply because they were easy to locate and right next to each other. The connection order or the wires doesn’t matter.
Note that depending on your hardware, you can also wire this sensor directly to your printer’s mainboard and have its firmware handle filament runout detection. But this will only work when you print directly from the board’s SD card reader. It won’t work if you primarily send your jobs through OctoPrint, which we want anyway in order to support SMS notification.
Here it is installed. I run the filament through this housing before it reaches the extruder, I like the open design because I can quickly diagnose any issues here visually:
SMS via email
Next, I needed to figure out how to get my Raspberry Pi to send SMS messages. Now I know there are services like Twilio that offer an API to send text messages, but they aren’t free… so cheapskate that I am, they are out of the picture.
However, I happen to know that most cellular carriers support email to SMS. Here are sms domains of the major US carriers, but you can google for your own. Replace <phone_number> with your full phone number and send yourself a text through your sms email address:
- AT&T: <phone_number>@txt.att.net
- Verizon: <phone_number>@vtext.com
- Sprint: <phone_number>@messaging.sprintpcs.com
- T-Mobile: <phone_number>@tmomail.net
- Cricket: <phone_number>@sms.cricketwireless.net
Note 6/11/2020: According to commenters: “ssmtp isn’t supported in raspbian-buster (and fails to send to gmail at least). msmtp works for me though”
Next on your Raspberry Pi hosting OctoPrint, log in to the console and and install a couple of packages:
sudo apt-get install ssmtp
sudo apt-get install mailutils
You’ll then need to edit a configuration file with your email host providers smtp settings.
sudo nano /etc/ssmtp/ssmtp.conf
I use gmail, so here’s how I configured the file. If you use a different email service you’ll need to hunt down your own SMTP settings (replace appropriate fields with your own data):
root=postmaster
Note that if you 2FA, you may need to set an app-specific password on google for this.
mailhub=smtp.gmail.com:587
hostname=octopi
AuthUser=<gmail_address>@gmail.com
AuthPass=<google_pw>
FromLineOverride=YES
UseSTARTTLS=YES
Now go ahead and give this a try by going back to the command line and sending a test SMS using the following command. You should see a text message pop up on your phone:
echo “Hi. Email to sms test.” | mail <your_phone_number>@<your_sms_domain>
OctoPrint plugin configuration
Now we need to have OctoPrint handle the filament runout detection, and then send an SMS. We’ll need a couple of plugins for this. Install the following plugins by navigating to: OctoPrint Settings > Plugin Manager > Get More.. (scroll all the way down) > Search…
- Action Command Plugin: https://plugins.octoprint.org/plugins/actioncommands/
- Filament Sensor Reloaded:https://plugins.octoprint.org/plugins/filament_sensor_reloaded/
You’ll need to restart your OctoPrint server once they have installed.
Action Command Plugin config
This plugin allows us to respond to action alerts in the gcode of the print job. Namely: M118 //action:<action_name> commands. When these commands are sent, the plugin can detect them by their <action_name>. Then it can execute shell scripts, and thus trigger the system to do anything we want. In our case, this will send an SMS notification using a shell command. This might not make sense in context yet, but stay with me here!
I added three different command definitions: start, interrupted, and done. Then I added the shell scripts I want triggered on each action, respectively:
echo “Your 3D print job is starting…” | mail <my_sms_email_address>
echo “Print was paused. Out of filament?” | mail <my_sms_email_address>
echo “Your 3D print completed!” | mail <my_sms_email_address>
Here is a shot of the OctoPrint settings screen:
Filament Sensor Reloaded plugin configuration
Next we will configure the filament sensor plugin to trigger a pause action on filament runout.
Go to OctoPrint Settings > Filament Sensor Reloaded.
- Set pin to 4 (unless you used a different pin), and board pin mode to BCM.
- Set switch type to Normally Closed (unless you wired your switch normally open, then use the latter).
- Then check “Pause print when out of filament”.
- Leave everything else as-is.
Custom GCODE to trigger SMS and movement
Next, we’re going to add some additional GCODE actions for when the print starts, pauses, and completes. These will trigger the action commands we configured above, and also move the print head out of the way on pause.
Navigate to OctoPrint Settings > GCODE scripts.
While I was doing all this configuration, I thought why not set the following optional SMS notifications for when my job starts and completes:
- Before print job starts: M118 //action:start
- After print job completes: M118 //action:done
Now you will also want some actions on pause and resume. On pause, I want the SMS notification sent, but I also want the print head to move up so I can get in there and clean away oozing filament with a tweezer before I feed in the new spool.
After a print job is paused:
M117 Print Paused ;show message to LCD screen
M118 //action:interrupted ;trigger SMS action
G91 ;set printer to relative positioning
G1 Z10 F1000 ;move print head up by 10
G90 ;set printer back to absolute positioning
Before a print job is resumed:
M117 Print Resumed ;show message to LCD screen
G91 ;set printer to relative positioning
G1 Z-10 F1000 ;move print head back to original position
G90 ;set printer back to absolute positioning
Here is the full screen:
Test it out!
Whew! That should be everything you need. Fire off a print job. If you configured things exactly like above, you should get a SMS that the print job started right away.
To test filament runout, you can simply snip the filament line just before the sensor. Once the filament gets drawn past the switch, this closes the circuit and triggers a pause. Once again, you should get an SMS. Pull out the remaining filament, and feed in a new spool. Then clean away any strings and blobs from the surface of your print with tweezers. Press resume in OctoPrint (but not on the printer) and watch as the print job happily continues!
What else?
Note that this actually sends the SMS on pause, not strictly on filament runout. I tried to configure the “out of filament GCODE” on the sensor plugin, but I couldn’t get it to work.
Another SMS notification I’d like to see is one on thermal runaway detection. Sure would be nice to know if your printer appears to be malfunctioning in a way that might burn down your garage. Octoprint doesn’t seem to have a field for this.
If anyone knows how to set these up, let me know!
Awesome work! Although couldn’t get ssmtp to work switched to msmtp and works great! Thanks for the template to go by. Have you found any other cool work arounds for “safety”?
Glad to hear it. No other safety mods aside from the obvious: turning on thermal runaway protection in Marlin.
A note to those wanting to do this… I have not yet updated my stock firmware. And the custom Action Commands in GCODE did not work, got everything else working up to that point, oh and had to use msmtp to get notifications to work.
Thanks for sharing these instructions. Note that ssmtp isn’t supported in raspbian-buster (and fails to send to gmail at least). msmtp works for me though.
Octopi 0.18.0 and Buster on Pi4: I have an ender 3 v2 and the M117 commands don’t do anything. Octoprint apparently doesn’t recognize action: start…Not one of the ones it lists and doesn’t appear to work. Paused stopped, but I moved the gantry when replacing the filament and it didn’t recover correctly. It also didn’t send the sms for paused. (changes in Buster or 0.18.0?)
Edit: replaced start with begin…works. Changed interrupted to stopped…works. Still, when it resumes, the nozzle is too close to the bed. Maybe need to park and unpark the nozzle?
Thanks for the information. Are you on stock firmware for your E3? A comment above seems to say that not all the commands are not supported on stock firmware. I personally have updated my firmware myself a while ago.
Please update with your gcode if you find a sequence that works. I can add it to the post. Thanks!
Using firmware from Marlin: Ender3-V2-Stock-20201225.bin. I don’t think M117 works on the LCD of the 3v2. May have to update display? I don’t need that so I left it out. Still looking for a good method of pausing. (M600?)
Joe