Fixing Cura Temperature "Bug"

I'm not entirely sure what version this "bug" started to present itself, but as of Cura 2.3.1 it is definitely an issue. I never store material temperatures in my GCODE. Partially because I like to change materials a lot, and mainly because even among PLA or ABS suppliers, filament varies and I often find that 5-10°C differences in my material printing temperatures are needed depending on filament brand.

My general workflow is to design a part, export it as an STL, slice that STL in Cura, and then store the GCODE file inside of OctoPrint for future reprints of that part, without needing to re-slice in the future. For that reason alone, storing a material temperature in the GCODE itself makes little sense. Cura's process of selecting the model, printer, material and preset really only makes sense if you're physically printing from Cura, which I would guess is not the norm given how many people are using non-Ultimaker printers, and printing from solutions like OctoPrint.

The way Cura behaves in this regard is a little odd. If you don't add a printing temperature to your preset, Cura will add a M109 S0 to the start of your GCODE during slicing. Effectively telling your printer to set it's temperature to zero. You've now preheated your printer to the correct temperature for your material, hit print, and nothing happens since your printer is now waiting for the temperature to be set to zero.

In previous versions of Cura, this was not the behavior. No temperature (or a temperature set to zero) told Cura you wanted to manually preheat at the printer and it never tried to overpower that decision. That is unfortunately no longer the case, but there is a workaround.

Navigate to your "Machine Settings" (Settings -> Printer -> Manage Printers), and click the "Machine Settings" button on the dialog for the selected printer. At the bottom left corner you'll see "Start GCODE" which allows you to enter anything you want your printer to do before printing, such as a homing, or a bed leveling. Now you may be thinking that the M109 we want to get rid of would be here and we can just comment it out, but that is also sadly not the case. We actually need to trick Cura into thinking that we are setting a temperature manually so that it doesn't insert the generic M109. To do this, add the following two lines:

; M140 S0 ; set the bed temperature

; M104 S0; set the extruder temperature

Note that these lines are both commented out (with the ;). This is intentional if you want to be able to preset your temperature at the printer itself. Simply having a M140 and M104 in the start GCODE even though they are commented out, is enough for Cura to think you've handled it and not force it's own M109.

Pine64 & OctoPrint (Part 3) - Now With mFi Control

I've been reliably using OctoPrint on a Pine64 since I wrote the original two parts (Part 1, Part 2) of this series back in January. I was a bit behind on OctoPrint updates (running 1.3.2), and took the opportunity this weekend to upgrade to the latest stable version (1.3.4), and add in the custom action I've been meaning to create for remotely powering up my 3D printer.

I've been using a Ubiquiti Networks mPower-Mini to control power to my 3D printer since day one. In addition to providing remote on/off capabilities, these devices also allow you to track and trend power consumption and other metrics. Ubiquiti has unfortunately ended development of the mFi controller, but these devices are still manufactured for users willing to script their own interface to them. I've been working my way off of my existing mFi controller for this reason, and figured it was time to connect my mFi switch to an action inside of OctoPrint. This allows OctoPrint to issue the on/off commands directly to the outlet, without needing to login to the mFi controller, portal, or mobile app.

Note that while Ubiquiti is no longer formally supporting these devices, they are readily available with a wide array of community support. That said, in theory, you could likely adapt this script to work with any number of Wifi enabled outlets, such as the TP-Link HS100.

Assuming you followed my guide to installing OctoPrint in Part 2, your OctoPrint scripts are probably located in /usr/local/etc/OctoPrint/scripts. This script is adapted from the work Scott Emery has shared on the Ubiquiti Community forums.

Start by creating the file to contain our script by running nano /usr/local/etc/OctoPrint/scripts/mfictrl. Scott's script contains a lot of additional features that we won't use (yet), but I've included the entire script here for completeness. One adaptation I made was to remove the dimmer mode from the on/off functions, ensuring that the switch behaves as a relay and not as a dimmer.

Paste the following script into your mfictrl file, being sure to update the username and password as needed.

Hit Ctrl + X to exit, being sure to save the script, then ensure the script has execution rights by running sudo chmod +x /usr/local/etc/OctoPrint/scripts/mfictrl.

You should now be able to remotely turn on your outlet by running /usr/local/etc/OctoPrint/scripts/mfictrl -l {outlet-ip} ON. Likewise, /usr/local/etc/OctoPrint/scripts/mfictrl -l {outlet-ip} OFF should turn off your outlet.

The last step is to configure custom actions inside of OctoPrint so that the outlet can be turned on/off from the power menu inside OctoPrint. To do this run nano ~/.octoprint/config.yaml, find the system:actions section, and paste the following. Note that spacing on each line here is critical.

Hit Ctrl + X to exit, being sure to save the script, then reboot the system by running sudo reboot. When OctoPrint comes back up, you should now have buttons to enable and disable the printer's power inside the power menu at the top right.

Pine64 & OctoPrint (Part 2)

Picking up where Part 1 left off, it's not time to look at how to install and configure OctoPrint on the Pine 64, setup webcam streaming to OctoPrint, and make our first print!

Important Notes

Before proceeding, it's important to understand how Linux permissions work. When following these instructions, make note as to where commands are run as sudo and when they're not. Do not simply run all of these commands as sudo or do a sudo su before starting, or these instructions will not work. Also make note of character case. OctoPrint and octoprint are not interchangeable, and must be used specifically with the case noted.

Installing OctoPrint

I've derived my install process from the Raspberry Pi Raspbian install instructions for OctoPrint, with just a few subtle changes. One big one being the installation directory, which I've changed to /usr/local/etc/ instead of the user's home directory.

  • Run cd /usr/local/etc to switch to the local etc directory
  • Install all of the required OctoPrint prerequisites by running sudo apt-get install python-pip python-dev python-setuptools python-virtualenv git libyaml-dev build-essential
  • Copy OctoPrint from the GitHub repository by running git clone https://github.com/foosel/OctoPrint.git
  • Navigate into the new OctoPrint folder with cd OctoPrint
  • Configure the virtual environment by running virtualenv venv
  • Perform the PIP install by running ./venv/bin/pip install pip -–upgrade
  • Run the OctoPrint setup script with ./venv/bin/python setup.py install

OctoPrint will by default look at ~/.octoprint/config.yaml for the configuration file, so before we run OctoPrint for the first time, we need to make sure that folder exists and has appropriate security so that OctoPrint can create config.yaml during first run.

  • First, create a folder called .octoprint in your local directory with mkdir ~/.octoprint
  • Ensure that folder is readable by running chmod 755 ~/.octoprint

Before we run OctoPrint for the first time, we want to ensure that our user has access to the Pine64's USB ports by running the following commands, where ubuntu is your username.

  • sudo usermod -a -G tty ubuntu
  • sudo usermod -a -G dialout ubuntu

Now we can start OctoPrint for the first time by running /usr/local/etc/OctoPrint/venv/bin/octoprint. If all goes well, you should see the scripts executing, and you should be able to go to http://{pine64-ip}:5000 from another machine on your network and see OctoPrint.

OctoPrint will present you with a first run Wizard, asking you to setup a username/password to use when interacting with the system via your browser, and configuring basic parameters of your 3D printer. Create the username and password; OctoPrint will tell you it's optional, but it's just smart system security to do so. You can set basic properties for your printer if you want, or you can do that later (we'll be back), then finish the wizard. We'll come back to OctoPrint later, but for now, go back to your terminal and hit Ctrl + C to kill the OctoPrint script.

If you want to change the port that you use to access OctoPrint, open the config.yaml file by running nano ~/.octoprint/config.yaml. Move down to the server: section, and add/change the port node. In my case, I added port: 8080 to the server node.

Installing Webcam Capabilities

One of the nice features of OctoPrint is the ability to stream a webcam to the browser for remote monitoring of your prints. Additionally, OctoPrint also gives you the opportunity to use this webcam to create timelapse videos of your prints, all configured and delivered through the OctoPrint UI.

  • Make sure you have a webcam that's supported by mjpg-streamer. I'm using a Logitech C920, which works great.
  • Navigate back to /usr/local/etc by running cd /usr/local/etc
  • Install the prerequisites for mjpg-streamer by running sudo apt-get install libv4l-0 fswebcam subversion libjpeg8-dev imagemagick libav-tools ffmpeg cmake
  • Copy mjpg-streamer from the GitHub repository by running git clone https://github.com/jacksonliam/mjpg-streamer.git
  • Navigate into the copied directory with cd mjpg-streamer/mjpg-streamer-experimental
  • Run export LD_LIBRARY_PATH=.
  • Compile the code by running make

We've now installed mjpg-streamer, but need to set it up to start automatically at boot. There's a few mechanisms to start it, and OctoPrint's native instructions have you setup custom actions inside the OctoPrint UI to start and stop the service, but for my purposes it's easier to just have it automatically start when my Pine64 boots up. To achieve this, we need to create a couple scripts.

  • Run nano /usr/local/etc/OctoPrint/scripts/webcam
  • Paste in the following script and save the file
  • Run nano /usr/local/etc/OctoPrint/scripts/webcamDaemon
  • Paste in the following script and save the file; note that if you're using a different camera than the Logitech C920, you'll have to change the camera_usb_options to reflect the config for your webcam. Note that I've set the output port for the webcam stream to 8088. This means that OctoPrint will run on 8080 and the webcam will be available on 8088.
  • Next we need to make both of these scripts executable, by running the following commands:
  • chmod +x /usr/local/etc/OctoPrint/scripts/webcam
  • chmod +x /usr/local/etc/OctoPrint/scripts/webcamDaemon
  • And add the webcam daemon to rc.local by running sudo nano /etc/rc.local, and insert /usr/local/etc/OctoPrint/scripts/webcam start before exit 0:

Making OctoPrint Start Automatically

In addition to automatically starting mjpg-streamer and the webcam services, I also want OctoPrint to start automatically.

  • Edit the octoprint.init file by running sudo nano /usr/local/etc/OctoPrint/scripts/octoprint.init
  • Add new paths the PATH variable by appending :/usr/local/etc:/usr/local/etc/OctoPrint to the end.
  • Copy octoprint.init by running sudo cp /usr/local/etc/OctoPrint/scripts/octoprint.init /etc/init.d/octoprint
  • Make /etc/init.d/octoprint executable by running sudo chmod +x /etc/init.d/octoprint
  • Edit the octoprint.default file by running sudo nano /usr/local/etc/OctoPrint/scripts/octoprint.default
  • Make changes noted below. Be sure to uncomment (remove the # at the start of the line) if you set a value:
  • Copy octoprint.default by running sudo cp /usr/local/etc/OctoPrint/scripts/octoprint.default /etc/default/octoprint
  • Ensure that OctoPrint is added to rc.d for startup by running sudo update-rc.d octoprint defaults

First Reboot

Now that all the services are setup, we can reboot for the first time and validate that all of our services start.

  • Issue a sudo reboot from the terminal to reboot your Pine64.
  • Once the OS boots, wait 30 seconds or so for the services to all spin up, then try hitting OctoPrint in a browser, on the port we defined (in my case 8080): http://{pine64-ip}:8080
  • In another browser tab, attempt to view your webcam stream, on the port we defined (in my case 8088): http://{pine64-ip}:8088/?action=stream

Shutdowns & Reboots

Ideally, we never want to have to SSH into our Pine64 in the future, so we need to configure a way to shutdown the Pine64 or reboot it from inside the OctoPrint UI. Thankfully, OctoPrint gives us the ability to define custom actions, which can call scripts that you define.

First things first, we need our user (in this case ubuntu) to be able to issue shutdown commands without entering a password. To do this, perform the following steps:

  • Run sudo -s
  • Run cat > /etc/sudoers.d/octoprint-shutdown
  • Type ubuntu ALL=NOPASSWD: /sbin/shutdown and hit Enter
  • Press Ctrl + D twice

Now we'll create the actions inside of OctoPrint.

  • Open the OctoPrint config file by running nano ~/.octoprint/config.yaml
  • Scroll down to the system section, or create it if it doesn't exist
  • Define the actions section inside of system, and enter the following actions. Note that spaces and correct indentations here are critical, or they will not work.
  • Save the file, and reboot by issuing a sudo reboot

When the system comes back up, navigate to OctoPrint in your browser, and login. You should now see a System menu at the top right of your screen with options to shutdown and reboot the system.

Final Updates & Package Installs

At this point, it's a good idea to run a sudo apt-getupdate && sudo apt-get upgrade to make sure there's no updates available for your system before we put it into production. I also took this opportunity to install the Arduino core just in case I need it in the future (by running sudo apt-get install arduino arduino-core).

Final Configuration

From here on out we'll do everything in the UI and no longer need our SSH session. Complete the final OctoPrint configuration by hitting the Settings button in the top bar of OctoPrint. Many of these settings will be specific to your 3D printer (including those on the Serial Connection, Printer Profiles, and Temperatures tabs), but some need to match things we've already setup, such as the webcam settings.

On the Webcam & Timelapse tab, set the Stream URL to http://{pine64-ip}:8088/?action=stream and set the Snapshot URL to http://{pine64-ip}:8088/?action=snapshot. Set the FFMPEG path to /usr/bin/ffmpeg. Decide if you want the OctoPrint watermark on your timelapse videos, and set a bitrate for your output videos.

On the API tab, set whether you want the API enabled or not. If you wish to use the Octo app on your phone to monitor your prints, this will need to be enabled, and the API key set inside the app.

On the Folders tab, remember back in Part 1, we created some specific network shares to store our files and timelapse output in. Configure those here, in my case:

  • Upload Folder: /media/RigidBot/Uploads
  • Timelapse Folder: /media/RigidBot/Timelapse
  • Timelapse Temp Fodler: /home/ubuntu/.octoprint/timelapse/tmp
  • Logs Folder: /media/RigidBot/Logs
  • Watched Folder: /media/RigidBot/Watched
  • Actively poll watched folder: Yes

Note that I'm not storing the timelapse temp files on the network share. Those will live on the Pine64 so that FFMPEG can process them more efficiently. Only the final videos will be set to the network share.

Lastly, click on the Software Update tab, then click the little wrench icon at the top right, and set the OctoPrint checkout folder to /usr/local/etc/OctoPrint. This allows OctoPrint to alert you when new versions of the software are available.

Your First Print

That's it. OctoPrint is now installed, configured, and ready to run. Maybe you should consider printing a new case for your OctoPrint Pine64 to test everything out!

Pine64 & OctoPrint (Part 1)

I had a couple Pine64 boards sitting in a drawer, and decided it was finally time to replace that old Raspberry Pi running OctoPrint (err, OctoPi) for my 3D printer. The Raspberry Pi has served admirably, but it was definitely time for an upgrade, and a chance to improve a lot of my overall printing workflow.

The Pine64

If you're unfamiliar, the Pine64 is a 64-bit, single board computer. I'm using the A64+ 2GB board, which comes with a quad core ARM Cortex A53 processor operating at 1.2 Ghz, 2Gb of DDR3 memory, dual core graphics, and gigabit ethernet. With double the memory of the Raspberry Pi 3, plus gigabit ethernet, the Pine64 is a steal at just $29.

Downloading an Image

If you're used to a Raspberry Pi, the initial configuration of the Pine64 is going to feel nice and familiar. Start off by grabbing the image of your choice from the Pine64 Wiki. I didn't want a desktop environment, so I'm using the July 16, 2016 Longsleep image. It has to be said that the downloads from the Pine64 Wiki are painfully slow, so even at just ~170Mb, plan ahead a little. Some of the images listed in the wiki are available via torrent, so if go that route, you'll likely see much better download performance.

Creating the SD Card

Identical to the Raspberry Pi process, you'll want to use something like SD Card Formatter to prep your card, then "burn" the image to it using Win32 Disk Imager. If you happen to be using a Pine64 for another project, you'll notice that the Android images are "burned" using PhoenixCard. Note that these processes are not interchangeable; you cannot make a Linux SD card using PhoenixCard.

Powering Up

Once you've got your SD card ready to go, insert it into the Pine64. For my initial setup, I plugged in a local keyboard and mouse, monitor (via HDMI port), and a network cable. The Pine64 is a bit more power hungry than a Raspberry Pi, and consequently you must use a decent quality USB power adapter that puts out a nice clean 2A. I'm using a Power-over-Ethernet splitter for mine, which splits apart a POE network cable into standard gigabit ethernet and a micro-USB for power. Whatever method you choose will work, don't just grab an old mid-2000s USB adapter from a drawer and expect to be successful.

Logging In

Once you've seen a clean boot, login with the default password for the image you've chosen (credentials will be listed on the Wiki with the download). Any time you've downloaded an image from the community, step 1 should always be to run passwd and change the password! Once you've done that, be sure to expand the root partition to use your full SD card. For my image, a script was included to perform this, so it was as simple as running sudo /usr/local/sbin/resize_rootfs.sh and just watch it do its thing. Now is also a great time to grab and install any updates, since your image may be out of date. Simply run sudo apt-get update && sudo apt-get upgrade.

Mounting Shares

One of the things I always wanted to do with my Raspberry Pi, was point OctoPrint at a network share for logs, timelapse videos and uploads. This gets these files off of my OctoPrint machine, allows me to back them up easier, and makes transferring those files between OctoPrint and my Windows machines much easier. With the limited processing and network bandwidth of the Raspberry Pi, this never really worked well, but it works just fine on a Pine64! I went ahead and created a new user on my Windows network, a network share for my "RigidBot" 3D Printer, and gave that user full control over the share, now we just have to mount it.

  • Start by installing the CIFS utilities by running sudo apt-get install cifs-utils.
  • Create a new file to store your network credentials. It's important that you use a credential file to avoid storing plain text credentials in our mount definition later. Create this file by running sudo nano ~/.smbcredentials.
  • Enter your credentials in this file. It is important that your file is structured the same way as the example below (username on one line, password on the next, etc.). If your user is affiliated with a domain, include the domain line.
    username=myUsername
    password=myPassword
    domain=myDomain
  • Once you've created your file, we need to set the appropriate permissions on it by running chmod 600 ~/.smbcredentials
  • Before we define our mount point, run id and make note of the output. This is likely something like 1000, but we'll need this number to ensure OctoPrint can correctly read and write to our share.
  • Now we're ready to define our mount point and tell the system how to connect. To do this, open up /etc/fstab by running sudo nano /etc/fstab. Here we'll enter a new row that defines the path to our share, the path to our local mount point, the file system type, and our credentials. Be sure to replace SERVERIP, SHARE, USERNAME and ID with your own values. Note that for this step, USERNAME is your Linux logon username, not the network credential. //SERVERIP/SHARE /media/SHARE cifs credentials=/home/USERNAME/.smbcredentials,sec=ntlm,uid=ID 0 0
  • Now, run sudo mount -a to tell the OS to process the changes to our fstab file. If all goes well, you'll now be able to cd /media/SHARE and see any content from your Windows share.

More to Come

In Part 2 we'll look at how to install and configure OctoPrint on the Pine64, setup webcam streaming to OctoPrint, and make our first print!