Automate Syncing of G-Code files (Toshiba FlashAir + Prusa MK3 3D Printer)


Recently, I’ve been playing around with 3D printers and having a blast doing so! But one thing has always troubled me: the manual process of sending sliced G-Code files to the printer. I know, first world problems…In this installment, I’d like to propose a viable alternative to this rather common conundrum. So if you’re into 3D printing, read on, it might just save you some grief…

Introduction

The Problem: USB/Serial Interface

Now before you get all up in arms and cry foul, I know there’s a simple approached – a newer Raspberry Pi with WiFi and Octoprint, right? Well, yes, sort of. And although I already use Octoprint (for monitoring really) it sadly introduces print degradation, albeit through no fault of its own.

Let me explain. When connected to the USB interface, as Octoprint requires you to do, your rather weak 8-bit 3D printer needs to parse the thousand of lines of incoming G-Code to print your model at a constant rate. Under the right circumstances, or wrong in this case (and also vastly determined by the complexity of your model) the USB/Serial interface can become saturated with data. And while the SD card slot with it’s faster speed throughput has no problems, the USB port connecting your printer to the Raspberry Pi simply cannot keep up and send G-Code fast enough, which ultimately causes jerky and stuttered movements.

These movements translate into artifacts marring up the finish of your prints. I’ve experienced this aberration with a cheap Creality Ender 3 as well as a rather expensive Prusa i3 MK3. You can read more about it here if you think I’m imagining it or delusional.

So the alternative for good quality prints remains using the full sized SD card to copy sliced files to, which means inserting the card into your computer then printer, and rinse and repeat. This could get tiresome fast, especially if your printer is ways away from your computer, and more so, introduce premature wear into your card slots. But luckily technology to the rescue…

The Solution: Toshiba FlashAir WiFi Card

Originally designed to send photos to devices, the Toshiba FlashAir with it’s onboard WiFi, perfectly fits the bill – enabling us to use the SD slot (for perfect prints) and use WiFi for wireless transmission of files.

Toshiba FlashAir W-04

Toshiba FlashAir W-04

Although the setup could be slightly unintuitive, I’ll show you how I went about it and how I automated the process of syncing a local folder and a remote share on the FlashAir card in an almost transparent way! Let’s begin.

Overview

Before we begin, I’d like to preface this guide with the following message: this guide assumes you are using a Prusa i3 MK3 running firmware 3.7.1 and Mac OS X. Now whether the FlashAir works with any other 3D printer is unknown to me at this time. In reality, if it has a full sized SD card slot, it’s worth a try. I invite those who are curious to try and report back. Don’t get mad at me if it doesn’t work with your printer. But the scripts should work on any platform, with little to no modification.

Also this guide assumes you are somewhat comfortable with basic command line stuff (i.e.: editing simple configuration changes, ease with the Mac OS X terminal/command line, and good with a text editor like nano or vi.) You should also have a good understanding of basic networking and know how to inspect your router’s configuration, pinging a device, etc. I’ll try to be as thorough as possible, but there’s a limit. Please brush up the aforementioned concepts prior to continuing.

Tools Required

Well, a 3D printer and and FlashAir card/ I believe W-04 is the current version of the card. As such, these steps will be for this version of the card. I’m assuming it’s backwards compatible with the W-03 version, but can’t guarantee it. To be safe just get the W-04, probably hard to get any other actually. Oh, you’ll also need a computer and text editor, but I’ll assume most already have this, I hope…
As I said, I’m using the Mac OS X as my operating system.

FlashAir Configuration

So we’ll need to get the FlashAir card configured first. Although Toshiba provides a tool to simplify the WiFi setup with your network, we’ll go down the manual route, just because.

Firmware Upgrade

Before you get too excited let’s begin with the boring stuff. Let’s update the card’s firmware. Go here and download the appropriate OS version of the firmware installer. Follow the on-screen instructions, and don’t be upset if the installer asks you to eject the card a total of 3 times during the install. The current version of the FlashAir firmware is 4.0.0.3.

WiFi Setup

Once completed, you’ll now need to connect the FlashAir to your local WiFi network. Plop you card into your computer to manually modify the configuration file. The card’s configuration is done using a text file. This file is named CONFIG *with no extension* and it resides in the SD_WLAN folder. The folder and the file are hidden, so you’ll have to turn on the Show Hidden Files and Folders function if using Windows. Probably a good idea to rename the old file before modification and/or copy it somewhere safe 🙂 but you already know that, don’t you?

[WLANSD]

ID=PrusaSD
DHCP_Enabled=NO
IP_Address=192.168.1.15
Subnet_Mask=255.255.255.0
Default_Gateway=192.168.1.1
Preferred_DNS_Server=192.168.1.1
Alternate_DNS_Server=192.168.1.1
Proxy_Server_Enabled=NO
Proxy_Server_Name=192.168.1.1
Port_Number=8080

[Vendor]

UPLOAD=1
UPDIR=/G_Code
WEBDAV=2
APPNAME=PrusaFlashAir
CIPATH=/DCIM/100__TSB/FA000001.JPG
APPMODE=5
APPSSID=your_ssid
APPNETWORKKEY=your_password
DNSMODE=1
NOISE_CANCEL=2
VERSION=F15DBW3BW4.00.03
CID=02544d535733324755e2e2b27b011c01
PRODUCT=FlashAir
VENDOR=TOSHIBA
LOCK=1
MASTERCODE=your_cards_mac_address

Really you should only need to change four things here with your favorite text editor: APPSSID, APPNETWORKKEY, MASTERCODE and IP_Address (if your local network is in the 192.168.1.x range). Make the appropriate changes. I won’t go into detail what all the rest means, still a lot more guide to write…

But to be clear if not already, APPSSID and APPNETWORKKEY are the name and password of your wireless network and since my local network is in the 192.168.1.0 range, I chose to statically assign a .15 IP address.

MASTERCODE is the MAC address of the FlashAir card and is located behind the card.

Save the file and plug the card into the printer and if the stars are aligned you should be able to ping the FlashAir card from any other computer on your network. On a terminal and type:

ping 192.168.1.15
PING 192.168.1.15 (192.168.1.15): 56 data bytes
64 bytes from 192.168.1.15: icmp_seq=0 ttl=64 time=0.256 ms
64 bytes from 192.168.1.15: icmp_seq=1 ttl=64 time=0.462 ms

Sweet!

OS Configuration

While the previous steps got us pretty close, as a network folder called G_Code should now be visible across your network via //IP_Address/G_Code, we’ll take it a step further and install some command line tools to help simplify our lives.

At this point, there are two approaches you can go with; using Method 1 (and ignoring most of the remainder of this guide) or Method 2 and continuing with the guide (I suggest Method 1 as it is the shortest).

Method 1 (Quickest & Easiest)

In fact, I rewrote the Sync Script from Method 2 at a later date because I inevitably ran into a Python crash on my Mac OS X. It was quite sporadic but it always came back and was quite annoying. This version of the script does not rely on Python at all and there’s no need to install the Python FlashAirScripts.

Sync Script

You can get this version of the script from here. Once acquired, copy the file SyncToSD2.sh to your local system somewhere and change three variables; LPATH (full local path), RPATH (remote path), and FLASHAIR (IP address of FlashAir card). Once done you can test it and finally integrate it into your workflow as per the Slicer Integration section of this guide.

Method 2 (Requires Python & FlashAirScripts)

FlashAirScripts

I now invite you to install the suite of FlashAirScripts onto your computer. This packages requires Python 3 and will enable us to sync files on the FlashAir card without the need of a File Explorer and use the much reliable API built into the card.

On the Mac there’s a simple way to install Python 3 using brew. If not installed, do so now. Please note, other OSes will differ or Python may already be installed. But on the Mac, there’s really no reason not to install this awesome package manager anyway. Open a terminal and let’s get cracking.

/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

Now install Python 3

brew install python3

Once you installed Python 3 proceed to download the FlashAirScripts from here, unzip and go back in the terminal. Let’s copy the files to our system folder.

sudo cp sdls sdput sdrm sdtree /usr/local/bin
cp flashair.py  /usr/local/lib/python3.7/site-packages/

Now that that’s done. Let’s test while crossing our fingers.

sdls -a 192.168.1.15

The first time you run this command with the -a switch, a local file gets created so you no longer need to specify the address switch in the future. Hopefully that works for you and you see a listing of files (or none) on the FlashAir card. If so, onto the next step.

Sync Script

What we need now is a script that automates the process of syncing a local folder on our computer and a remote folder on the FlashAir card. In researching this, I came across this awesome Bash script, no use in reinventing the wheel, right?

While this script does a great job at syncing files in one directory that end in .gcode, it does lack the ability to sync already existing files on the FlashAir card. I do find myself re-slicing the same model with small setting changes here are there and unfortunately this script will not upload/overwrite files with the same name.

So, I updated the code.

My version of the script simply determines if there are files modified on the current day in the sync folder, if so, uploads those as well. Here’s a code snippet.

if [ $SAMECOUNT -gt 0 ]; then
    now=$(date +"%m-%d-%Y")
    #Determine if existing files need to be re-uploaded
    for FOO in $SAMELIST ; do
        filedate=$(date -r "${FOO}" "+%m-%d-%Y")
        if [ $now ==  $filedate ]; then
            osascript -e "display notification \"Updated ${FOO}\" with title \"SD Card Sync\""
            FOO_NS="$(echo -e "${FOO}" | sed -e 's/[[:space:]]*$//')"
            ${SDPUT} "${LPATH}${FOO_NS}"
       fi
    done
fi

You can get my modified version from here. Once acquired, copy the file SyncToSD.sh to your local system somewhere. I copied it to /Users/bob/Documents/SyncToSD.sh on my Mac. Anywhere will do, as long as you remember where you put it. We’ll need the path for the last step.

You’ll also need to adjust two variables in the script though.

######################################################
# Customize these variables before using this script
######################################################
# This is the full path to the local folder you want to
# sync with your SD card. Make sure to keep a trailing
# slash at the end
LPATH="/Users/bob/Documents/FlashAir/G_Code/SyncToSD/"

# This is the IP address assigned to the WiFi card.
# Works with hostname also if you have proper DNS
# configured
PRUSA="192.168.1.15"

LPATH is the full path on your computer to the folder which will be used for syncing, could be anything. I used /Users/bob/Documents/FlashAir/G_Code/SyncToSD/ and finally PRUSA is your IP address.

Also, it’s probably a good idea to test this out at this point from the command line.

Slicer Integration

The very last thing to do to make this a seamless operation is to have our slicer execute this script every time we export or save a G-Code file to our sync folder (LPATH).

So now when we save a file to the local sync folder this script will automatically run and upload new files, delete removed files and overwrite files with the same name (given that they were modified on the current day) on the FlashAir card.

In PrusaSlicer this setting is found int Print Settings>Output options>Post-processing scripts. Don’t fret if you’re using another slicer, they all have this basic capability, you just need to find it 🙂

PrusaSlicer: Post-processing scripts

PrusaSlicer: Post-processing scripts

That should do it! Oh wait…

Odds & Ends

It’s worth mentioning that I had a problem with the sdrm command for some reason. This command is supposed to delete files off the FlashAir card. In my case, it wasn’t working and I was greeted with an unsuccessful message. I inspected what was going on and as far as I could tell it wasn’t adding a forward slash before the filename in the path right before sending the DEL command to the API.

So I loaded the file in a text editor :

sudo vi /usr/local/bin/sdrm

I altered this line:

r=requests.get('http://'+card.address+'/upload.cgi?DEL='+card.dir+file)

with this:

r=requests.get('http://'+card.address+'/upload.cgi?DEL='+os.path.join(card.dir, file))

Of course, YMMV and if you happen to come across this problem, you’ll know what to do.

Anyway, that should about do it, post your success stories/failures in the comments below.

Leave a comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.