PiRinter3D started its journey into the 3D printing world as an idea. A simple idea, bridge the gap between the software and hardware needed to drive a 3D printer. Traditional 3D printing systems use a PC to model the object to be printed and then use a slicing utility to generate GCODE for the 3D printers interpreter. The GCODE file is then copied onto a digital media card and parsed by the microcontroller running the 3D printer. The microcontroller then passes movement commands to the printer and creates the object from the GCODE that was generated from the model. All of this media swaping and external design workflow has a side effect of restricting the users ability to use, and interface with, the printer itself.
We wanted to build a system that had the ability to create models for printing, be able to slice them, and interface directly with a 3D printer to create the modeled object. We also wanted the flexibility of being able to use FTP and other transfer protocols to upload content onto the system. This functionality allows the older Pi's, which didn't have the horsepower to model and slice, to still have their place amidst the fleet of compatible hardware. We wanted to avoid the networking requirements of a 3 tier architecture and decided to build the software for execution directly on the Pi. We also wanted to provide users with the option to be able to use RDP and VNC protocols to remote control the entire system minimizing the need for external peripherals.
Our proof of concept was brought to life by the mini plotter designed by Jason (AKA Jayho). The first functional prototype was designed using a Python GCode interpreter (orginally designed for a laser engraver) which was modified by Jason to work with plotter. Our hardware setup consisted of two salvaged CD-ROM drive carriages, a solenoid, two L293D Quad Half-H bridge drivers, a HEX inverter, and a transistor.
Several cans of Blatz and a post-it note pad later, Jayho's basement was covered in 3x3 yellow vector drawings consisting of everyting from Yankee logos to chickens and everything in between. We used InkScape to generate GCode for every funny or interesting image we could find and laughed for hours watching the little machine draw pictures. Although the interpreter was functionally correct and met our goal of only using a Raspberry Pi, it had to be run from a terminal and lacked any kind of a user interface. We were pleased with the results of the little plotter and agreed it would be possible to make a Pi controlled 3D printer. Thus we set out to build a RepRap and some electronic circuts to interface with the Raspberry Pi.
Jason did most of the work building the Prusia style RepRap we were going to use for the inital prototype 3D printer. He also designed a motor controller based on the L298 H-Bridge and a circut using 555 timers to read the resistance of the thermistors we were going to be using for the heating elements. Because the Raspberry Pi doesn't have an analog read, a 555 timer setup in astable mode was used to measure the output pulse high time and determine the resistance of the thermistor. Once we knew the resistance value, we could calculate the temperature of the heating element. We added a couple MOSFETS for element switching and we were off. We tested individual components of the code separately and were happy with the results. Even though many prefer to use Arduinos over Raspberry Pis because the of the realtime clock, the fact that all this was running on top of Raspian had little effect on the overall performance.
It all seemed pretty straight forward. We tested individual components of the code separately and were happy with the results. Extra motors turned properly, heating elements triggered right, temperature sensor seems to be working... Time to put it all together.
It took several days of tweaking the software and electronics, but eventually we got the RepRap to gob out some resemblance of a little gear we were using for a test. It was a part of the Wade extruder that broke during initial assembly of the Prusia i3. We quickly realized that the problem was our filament temperature. The PLA filament was not flowing anywhere near the way it needed to. We simply could not use the 555 timer to accuratly measure the high pulse time because of the emulated clock on the Raspberry Pi. Therefore, the filament was getting too hot and then too cold for efficient 3D printing. This coupled with the inability to reliably read the timer using a separate thread compounded the problem. We needed to incorporate an analog to digital converter (ADC) into our project. We decided to use the MCP3008 8 channel ADC chip because of the existing documentation and code from Adafruit available for reading it using Python. It was a piece of cake to setup and with a little research we came up with a good alogrithm for converting the resistance differential into degrees celcius. The only other issue we had was we could only read the temp when parsing the GCode line. We decided to just measure it after every fifth line.
It worked... We were able to actually print the little gear! It wasn't perfect by any means, but it would have functioned fine for replacing the broken one. We ended up printing about 4 more of them; each time tweaking the code and electronics a bit more. We finally made a functioning 3D printer using a Raspberry Pi!
We decided it was time to try printing something else. We designed a cube that was 2CM in all dimensions with a 5mm square cutout through the center. We needed to test our dimensional tolerances and find out if there were any anomalies we didn't expect. The cube printed exceptionally well, perfect dimensionaly and structurally. We started to get pretty excited about the whole thing and I wanted to print a case for one of my newly aquired Pi Zero boards. I found a nice model on Thingiverse and used Slic3r to generate the GCode. I uploaded the file to the Pi and configured the code to print. Everything seemed to be going fine until the printer needed to make a move that was longer than a couple inches.
When we designed the code for the mini plotter the print area we were working with was pretty small, only a couple inches square. Everything we had printed up to this point was no bigger than 30mm. When we tried to print the case for the Pi Zero the perimiters printed fine because they were single axis moves. When it came time for the extruder to infill the base of the case, the print head slowed to a near crawl. This was unacceptable and much to slow for any kind of neat extrusion. There was a logic problem hidden in our code; a problem that would endevor to make us refactor the entire motor driver algorithms.
Timing Is Everything
The motor controller code was using a least common multiple algorithm for determining when and which motors to turn and how much of a delay was required between steps for each. The problem arose when the moves began to get larger. The sheer volume of calculations that the algorithm required brought the little Pi to its knees. Unable to keep up with the motor timing as well as calculate the LCD for each microstep the resulting outcome was a very, very slow 3 axis move. We attempted to optimize the motor controller code for almost a week with little success. It was a snowy and trecherous ride home from work that inspired us to brainstorm a new algorithm for moving the motors. Throughout our conversation we discussed motor timing in great detail. It was in the final turn towards home where we had an epiphany... It wasn't about timing at all, it was all about the ratios.
The old code ...
The new code...
Armed with a new outlook on motor movement and a renewed faith in our ability to troubleshoot and problem solve, PiRinter3D was concieved. It was still in its infancy but was growing up remarkably fast! We used the prototype command line code for several weeks and created many successful 3d prints. we made Pi cases, door stops, and trinkets of all sorts. Finally we decided that it was time to migrate from the Python code we were using for prototyping and give it some real legs. Qt/C++ was the target framework we were going to use to bring PiRinter3D to the world. It was a very exciting time, we were threading motor controllers and thermal probes, creating UI/UX elements, and enhancing the GCode interpreter. Each new addition to the software made it more and more robust and dynamic.
PiRinter3D is being designed from the ground up to be a fully featured 3D printing, CNC, and laser engraving software solution driven completly by the Raspberry Pi.