Welcome to PolyChemPrint3’s User Guide and Software Documentation!

PolyChemPrint3 is an open source benchtop additive manufacturing software developed at the University of Illinois by Bijal Patel and Dr. Ying Diao. For more information, please visit the project homepage and Diao Research Group homepage.

This readthedocs.io page contains:

A ‘user guide’ with instructions on setting up and operating the program.

A ‘software guide’ intended as a programming aid that contains the organized python docstrings for the modules, classes, and methods of this object-oriented program.

Note: If you use this software/code, please cite the original paper listed on the project homepage! It really helps!

Program Overview

PolyChemPrint3 (PCP3) is a command-line interface (CLI) Windows/Linux program that handles communication between the user and additive manufacturing(AM) hardware. In some ways, PCP3 offers overlapping functionality with 3D printer control software such as pronterface and 3D slicing programs such as slic3r or Cura, but optimized for AM research with unconventional, non-FDM toolheads such as pneumatic (melt) extruders, LASERs, syringe pumps, etc.

_images/overview.png

At the most basic level, users can directly send commands to the motion axes and toolhead to execute GCode move sequences and simple tool on/off/ power set commands. The next level up is to use parameterized, hardcoded ‘sequences’ to execute specific 2D and 3D patterns such as meanderlines, cuboids, electrode patterns, etc. For more complex 2D/3D patterns, GCode files created by slicers such as GCodeTools in Inkscape and Cura/ Slic3r can be imported as sequences. Finally, any combination of sequences can be chained together into ‘Recipes’, offering a ‘code-free’ way to build-up complex patterns. Automatic data-logging exports print parameters to text files to optimize parameter screening.

Note: Even if you have identical hardware to the original developers, the software will need some initial setup - so pay careful attention to the “Installation and Setup” section. Best of luck!

Installation and Setup

Requirements/Supported OS

PCP3 is designed to run on Windows and Linux distributions with Python 3 on even very low spec hardware. At the end of the day, for just sending commands between hardware, there really isn’t much you need in terms of specialized system specs. Just serial ports that can be connected to your desired hardware.

In our lab, we have run PCP3 on Debian 9/ Mint 19 Linux PCs and on Windows 10 using Ananconda as the python environment.

Installing Anaconda (optional)

To use polychemprint3, you need to have a python 3 environment set up. If you are on Linux, your distribution most likely has python 3 installed out of the box. If not, a simple way to set things up is to use Anaconda, a free and open source python distribution comonly used in data science.

After successfully installing Anaconda, open Anaconda Navigator and launch anaconda prompt. Boxed in red below:

_images/AnacondaBoxRed.png

Installing PCP3 from PyPi via pip

After opening the appropriate terminal window (Anaconda Prompt/Terminal/Command Prompt), enter:

pip install --no-cache-dir --pre --upgrade polychemprint3

Press enter and polychemprint3 should install with any required dependencies automatically.

To run the program, just type

polychemprint3

into the terminal window and the program should launch

_images/Polychemprint.png

Run from Source (from Github)

All source code (for PCP3 and this manual) is posted on github at https://github.com/BijalBPatel/PolyChemPrint3 . Three branches are maintained:

  • Master: The main stable release
  • Beta: A test release which may have new features we are testing. This is the version we run in our lab.
  • Dev: Testing release for new and semi/not working features.

If you are new to github, there are many quick tutorials online - such as this.

Setting up new Hardware

PCP3 as written uses pySerial to communicate with hardware devices. To add a new tool, begin by cloning and renaming one of the existing tool.py files in the polychemprint3/tools directory. We will then go line by line and replace comment text and parameters such as device address, baudrate, etc with the values that correspond to your particular hardware. Here we highlight key parameters to change:

  1. In the __init__ method, set the devAddress, baudRate, commsTimeOut, and other parameters to reflect your hardware.
  2. Next, go through each of the methods (activate, deactivate, engage, disengage, setValue, startSerial, etc), and write the necessary code to complete the communication loop with your hardware. If your device has a simple arduino based controller, these methods may be very simple (see Laser6W.py). If the device uses a special packet-based protocol, this can be more challenging, but see ultimusExtruder.py for a good example of this.
  3. No matter what, make sure the methods specified in the toolSpec.py abstract base class are filled out in your new code file.
  4. Once the tool.py file is complete, restart PCP3 and check that it properly is loaded [the starting load text will indiciate “PASS” for both conditions.

Modifying Marlin Firmware

If you are using a consumer 3D printer for your motion axes, there is a high likelihood you will need to modify the stock Marlin firmware to work with PCP3. Our main goal is to force the command acknowledge statement “ok ….” to only be sent from the printer AFTER all motion steps are complete. If you are running on Linux, you may also need to change the firmware baudrate for compatibility. Here is how:

  1. Download the Marlin firmware source files either from your printer manufacturer’s webpage, or from the main Marlin Firmware webpage

  2. If you are getting firmware from the Marlin site, see if you can find the configuration files for your printer in the MarlinFirmware Github folder that corresponds to your printer.

  3. Dowload arduinoIDE and from Tools -> Boards -> Board Manager install the RAMBo board files.

  4. Open all of your Firmware files in arduino IDE by running the Marlin.ino file in the Marlin folder.

  5. If necessary, in the conditionals.h file, set the baudrate to your desired value.

  6. Navigate to the Marlin_main.cpp file and find the “process_next_command()” method. At the very end of this method (see image), add the following statement:

    stepper.synchronize(); //PAUSES UNTIL MOTION COMPLETE BEFORE SENDING OK
    
    _images/marlinfw.png
  7. Compile as hex and export

  8. Use a program such as cura to load your new firmware onto your printer.

Note: Be sure to save the old firmware, you will need it to go back to normal FDM 3D printing.

Configuration/About Menu

The configuration/about menu Configure/About Menu allows users to view program and license information about Polychemprint3. This menu also includes options to change the level of output details, and switch axes and tools the program is controlling. Here is what Configuration/About Menu looks like:

_images/configuration.png

View Program Details and License Text

By typing command 0 in Configuration/About Menu, program details and license text will be displayed on the terminal like the following:

_images/license.png

Change Level of Output Detail

By entering command 1 in Configure/About Menu, the amount of details presented in the program will be altered. Currently, only two levels of output details exit: “more” level and “less” level. Whether this alternation increases or reduce amount of information displayed depends on the current level of output details. If the program is in the “more” level, type in 1 will change to “less” level and vice versa.

_images/outputlevel.png

Change Axes and Tool

Command 2 and 3 in Configure/About Menu change the axes and tool that polychemprint3 is controlling. Axes represents the hardware in charge of movements, for example if polychemprint 3 is controlling a 3D printer, axes should be set to that 3D printer since it controls movement in x, y, and z directions. In order to change the axes, type 2 in the command line and terminal will display all the axes that is loaded into polychemprint3 and ask for user input to select the device need to be activate like the following(boxed in yellow):

_images/axes.png

Right now, the program is loaded with two axes: lulzbotTaz6_BP and nullAxes. To select the desired axes, simply type in the corresponding commands (boxed in yellow) on the left of axes names, in this case A0 or A1. Tools are hardware that does not control movement. For example, in laser cutting, the amount of energy emitted need to be controlled, so laser will be tool in this case. The change tool procedure works the same way as change axes: type 3 in command and select the desired tool using commands show on the left of tool name (boxed in yellow).

_images/tool.png

Hardware Menu

This menu allows for the most basic communication to the hardware: line by line command entry and execution, along with some hotkeys for jogging the motion axes.

_images/hardwaremenu.png

GCODE Entry

Direct GCODE commands are accepted as input in Hardware Menu. For example, if the axes need to be moved in the positive x direction for 20 mm, Gcode command “G0 X20” can be typed in to perform such task, as shown below.

_images/GcodeControl.png

Controlling Tools

Set Tool Value

Type in T[value] under Hardware Menu allows users to directly set tool values. For example, to set tool value to 100, users can type in T100 in terminal and program will give an output indicting value is set like the following:

_images/toolvalue.png
Turning Tool On and Off

Type in Toff or Ton to engage tool dispense or disengage tool dispense. It works just like a switch that turns the tool from off to on or on to off.

_images/ToolOnOff.png

But if the current state of tool is off and a Toff command is executed, program will give a warning message saying that “Dispense already off”. If the current state is on, Ton command is sent, program will also give error message saying “Dispense already on” These are handy for troubleshooting sequences/recipes, but are otherwise just for your information.

_images/ToolAlreadlyOn.png

Hotkeys for Jogging Axes

For convenience, the following commands jog axes for small distance movement in all direction. (Note that these are not case sensitive)

Command Direction Distance
a -x 1mm
d x 1mm
r -y 1mm
f y 1mm
s -z 1mm
w z 1mm
x -z 0.1mm
z -z 0.01mm
_images/MoveAxes.png

Clean and Raise Routines

Commands 1 and 0 provide convenient ways to lift the toolhead 20 mm. If command 0 is chosen,the terminal will prompt on whether to lower 20mm or not. Type in Y, axes will be lowered for 20 mm in Z direction. Type in N, axes will stay still.

_images/CleanAxes.png

T ? , / . Commands

Functions of T ? , / and . have been described in user guide section 3.3. Please see it for more information.

Quit Hardware Menu

To exit out of the Hardware Menu, type q in the prompt and you will be returned to the Main Menu.

Sequence Menu

In this menu, users perform various operations with parameterized ‘sequence’ files that describe basic motion/tool paths.

_images/sequence.png

Each sequence shown in the menu (labeled S#) corresponds to an individual python file that gives the ‘blueprint’ for the sequence. For example, entering “S6” opens the “Line” submenu as shown below:

_images/sequenceLine.png

From this submenu, the parameters of the sequence can be modified. These include basic notetaking parameters, such as the creation date of the sequence, description, name etc. and actual geometric/ execution parameters such as the printing speed, length, and tool on/off values.

After the sequence parameters have been finalized, the bracketed commands at the bottom can be used.

  • ADD inserts the sequence into the active recipe at a given index
  • PRIME generates the python commands that will be executed when the sequence is run and stores them in RAM
  • VIEW displays the python commands in the terminal for user inspection
  • GO begins execution of the program
  • q quits the menu and returns to the main menu

The Sequence Library

Users can create and add sequences by cloning the python files in the polychemprint3/sequence folder and modifying parameters. By default, releases of polychemprint3 contain the following sequences built-in:

Basic Move Sequence

BasicMove is a sequence that control axes to move in x, y and z direction. Its menu looks like the following:

_images/basicmove.png

The top five commands (P1 to P5) introduce the basic information of this sequence including the name, created date and etc. P6 allows user to change the reference the command is execute from, whether relative to current position or the absolute reference, which is the origin. P7 is the axes speed that controls how fast axes should move and the unit is in mm/min. P8 through P10 represent the distance axes is going to move move in x, y, and z direction. The unit is in mm.

PRIME,VIEW, and GO

After modifying a parameter, GO command allows the execution of the sequence and corresponding Gcode command will be displayed on the terminal. It is highly recommended to do PRIME and VIEW command before engaging printing sequence. PRIME command will generate the print commands without actual execution done by hardware and VIEW will show those commands on terminal for user to review. Thus, it is best to do PRIME and VIEW to check on print commands in case there is errors that might break hardware

Circle Sequence

Circle is a sequence that lets axes moves in a circle with radius set by user. Below is the menu of circle:

_images/Circle.png

P1 through P5 inform users the basic information of this sequence. P6 controls the speed of the axes movement and unit is in mm/min. P7 command controls the radius of the circle. Since hardware like 3D printer is limited to straight move only, axes have to move step by step in x and y direction to create roughly round object. That is where P8 comes from. It represents the step axes moves in x and y. A smaller P8 value lead to a more circular shape.

Tool ON and OFF Value

P9 and P10 control the on and off tool value. For example, when trying to do laser cutting, the energy of laser when print, on value, will be like 100 watts, and off value will be 0. Users should adjust the P8 and P9 based on the tool they are using.

Cuboid Sequence

Cuboid sequence allows a cuboid to be created. Here is what the menu looks like:

_images/cuboid.png

P1 through P5 inform users the basic information of this sequence. P6 controls the speed of the axes movement and unit is in mm/min. P7 through P9 controls the width, length, and height of the cuboid. The unit for those value is in mm. P10 controls layer height. Since this is a 3D object, 2D layers needs to be build up to form 3D shapes. Layer height is the distance axes need to move in positive z direction when one layer is done printing.

Tool ON, Tool OFF, PRIME, VIEW, and GO commands have been described in user guide 6.1.1 and 6.1.2. Please see them for more information

GapLine Sequence

GapLine is a sequence that creates multiple rows of line segments in x direction with a gap between each segment. Here is what the menu looks like:

_images/gapline.png

P1 through P5 inform users the basic information of the gapLine sequence. P6 controls printing speed which is how fast axes moves when materials are been printed. P7 controls travel speed which is how fast axes move when no material is been deployed but the sequence is still running for example, during printing of the gap between lines. P8 controls length of each line segment and P9 represents the size of gap between line segments. P10, number of rows, is how many rows of line are there to be print. P11 controls spacing between each row, which is the distance axes moves in y direction when done printing one row. P12, z-hop, value is the distance to move axes in positive z direction when printing gap.

Tool ON, Tool OFF, PRIME, VIEW, and GO commands have been described in user guide 6.1.1 and 6.1.2. Please see them for more information

Line Sequence

Line sequence allows single straight line to be created in either x or y direction. The menu looks like the following:

_images/line.png

P1 through P5 inform users the basic information of the line sequence. P6 controls moving speed of axes when printing. P7 lets user choose the direction of printed line. Two options are available: x or y direction. P8, line length, represents distance axes move in printed direction. This unit is in mm.

Tool ON, Tool OFF, PRIME, VIEW, and GO commands have been described in user guide 6.1.1 and 6.1.2. Please see them for more information

Pause Sequence

Pause Sequence lets axes to pause for a certain amount time before precede to next movements. Usually pause is used to create time gap between sequences in a recipe. Here is what the pause menu looks like:

_images/pause.png

P1 through P5 inform users the basic information of the pause sequence. P6, pausetime, is the time to wait before next command is send. For example, when circle sequence and line sequence are written into recipe to be execute simultaneously, add pause sequence between them will allow axes to be stopped for certain time after completion of circle. P7 gives user ability to control whether precede to next sequence after waiting time runs out. Typing Y in P7 will let program ask for user prompt to resume when pause time expired,and typing N will have program automatically move on to next commands when pause time expired.

Tool ON, Tool OFF, PRIME, VIEW, and GO commands have been described in user guide **6.1.1 and 6.1.2. Please see them for more information

Plate Sequence

Plate Sequence will print one line after another with each line at different row and eventually forms a plate. Its menu is shown as follow:

_images/plate.png

P1 through P5 inform users the basic information of the line sequence. P6 controls moving speed of axes when printing. P7, line direction, controls the direction each line is printed. If it is set x, straight lines will be printed in x direction and axes will move line pitch distance in y direction after the completion of each line. In order to form a plate with not no gap present between lines, P8 should be set to the width of each line. If P7 is set to y, straight lines will be printed in y direction with axes moving line pitch distancing in x direction after each line to create plate. P9 controls how long each line should. P10 is how many lines the sequence is going to print. The sequence also allows altering of print speed or tool value after completion of each line. For example, by setting P14, speed increment, to 10 and set P15, speed operation, to +, printing speed value will be added by 10 after each line. This works the same for tool value increment Currently, four speed operations are available, +, *, -, /. But please note that having large value of increments could let to value out of bound and damage machine. Users should have a roughly estimating of the final value of speed and tool value before printing.

Tool ON, Tool OFF, PRIME, VIEW, and GO commands have been described in user guide 6.1.1 and 6.1.2. Please see them for more information.

Pyramid Sequence

Pyramid Sequence allows a pyramid to be created. Here is what the menu looks like:

_images/pyramid.png

P1 through P5 inform users the basic information of this sequence. P6 controls the speed of the axes movement and unit is in mm/min. P7 through P9 control the width, length, and height of the cuboid. The unit for those value is in mm. P10 controls layer height. Since this is a 3D object, 2D layers needs to be build up to form 3D shapes. Layer height is the distance axes need to move in positive z direction when one layer is done printing.

Tool ON, Tool OFF, PRIME, VIEW, and GO commands have been described in user guide 6.1.1 and 6.1.2. Please see them for more information

Rectangle Sequence

This sequence controls axes to moves followimg circumference of a rectangle, thus create a rectangle shape. Here is what the menu looks like:

_images/rectangle.png

P1 through P5 inform users the basic information of the line sequence. P6 controls moving speed of axes when printing. P7 and P8 controls the width and length of rectangle and the unit is in mm. Not width line is oriented in y direction and length line is oriented in x direction.

Tool ON, Tool OFF, PRIME, VIEW, and GO commands have been described in user guide 6.1.1 and 6.1.2. Please see them for more information

SetToolStatus Sequence

This sequence is typically implemented in a recipe between two sequences to change the status or the value of tool. Here is what it looks like:

_images/toolstatus.png

P1 through P5 informs users the basic information of the line sequence. P6 lets user decide on tool status. There choices are available: change tool status to on, off, or not change. P7 controls the new tool value. For example, if circle sequence has juts been complete with a tool on value of 100, setting P7 to 200, will alter the tool on value of the next sequence to be 200.

Not very certain what this sequence does

Tool ON, Tool OFF, PRIME, VIEW, and GO commands have been described in user guide 6.1.1 and 6.1.2. Please see them for more information

Triangle Sequence

Triangle Sequence allows a triangle shape to be created. Here is what the menu looks like:

_images/triangle.png

P1 through P5 inform users the basic information of the line sequence. P6 controls moving speed of axes when printing. The unit is in mm/min. In order to create a unique triangle, three pieces of information are needed: two sides length and the angle they formed. P7 through P9 control those information. For side lengths, units are in mm. For angle, the unit is in degree. P10, steps in x and y, is necessary due to the axes’ limited ability of only creating straight line. Since one side of triangle has to be diagonal line. To create it, axes needs to be move in small steps in x and y direction. The small the value is, the more accurate the triangle is going to be.

Tool ON, Tool OFF, PRIME, VIEW, and GO commands have been described in user guide 6.1.1 and 6.1.2. Please see them for more information

Importing GCode Sequences

PCP3 can natively import GCode generated by external slicer programs through specific GcodeFile sequences. For 2D (single layer) patterns, it is often easier to generate GCode from a vector image in the free software InkScape. For 3D (multilayer) patterns, Cura and slic3r are good options for converting .STL CAD files to Gcode. In both cases, it is very important to choose slicing settings that will ‘play nice’ with PCP3. For further details and tutorials, see the specific sequence pages below.

GcodeFileInkScape Sequence

This sequence allows locally stored Gcode file obtained through InkScape software to be imported into polychemprint3.Here is what menu of this sequence looks like:

_images/inkscapemenu.png

P1 through P5 inform user the basic information of the GcodeFileInkScape sequence. P6 gives users options to select the objective file. Users can either type in the full file path or just type in File to opens up a GUI window and choose the matching file like follow:

_images/inkscapeopenfile.png

P7 controls moving speed of axes in x and y direction when printing and P8 represents the speed of axes when tool is not print but sequence is still running. P9 is the speed of axes when traveling in z direction. The unit regarding speed is in mm/min. P10, Z hop height, controls the distance axes moves in positive z direction when two lines are crossed. Axes need to be move up to avoid collision of material, thus called hop height. The unit is in mm.

Inkscape 2D GCODE Tutorial

The free and open source vector image software Inkscape can be used to generate G-code for complex 2D patterns that can then be imported into polychemprint3. We will be using the plugin GCodeTools (included by default with Inkscape).

Below is a step-by-step tutorial for creating a vector image and generating PCP3-compatible GCode.

Step 1: Set Canvas Dimensions

  1. Open InkScape
  2. Click File -> Document Properties
  3. In the window that appears, set the page size and units. Note: the bottom left corner is the (0,0) coordinate.

Step 2: Draw your pattern (ex: text, shapes, and bezier curves)

  1. Create a layer for your pattern (shift + ctrl + L) to open the layer window.
  2. From the tools panel at left, choose either the text tool or one of the drawing tools and draw your pattern.
  3. For complex patterns, it can be helpful to paste a picture into a layer below your working layer, set it to ~60% opacity, lock it, and then ‘trace’ a pattern on your working layer with bezier curves.
  4. Note: There is technically a way to auto-generate paths from non-vector drawings, but I have not been able to get it to work. After import an image into Inkscape, you can click Path-> Trace Bitmap. In the window that appears, choose a tracing mode and your path will be generated. Unfortunately, all modes generate ‘double-paths’ except centerline tracing, which just crashes (as of 12/17/20).

Step 3: Convert to Path

  1. Select all of your ‘artwork’ in the working layer.
  2. From the top toolbar, choose Path -> Object to path
  3. Before you proceed, go to node view (n) and try to simplify the nodes as much as you can while maintaining pattern fidelity. Having a huge number of nodes will lead to having many many tiny steps that the printer will execute, increasing pritn time and reducing stability. If you have overlapping nodes (e.g., two lines coming to a point), use the ‘join nodes’ tool to combine them.
  4. At this stage, your artwork is complete. Clone this layer to a new layer above this one and hide and lock all sublayers.

Step 4: Setup Orientation Points

  1. From the top toolbar, choose Extensions -> GCodeTools -> Orientation Points.
  2. In the window that appears:
    1. Choose 2-points mode
    2. Set Z surface to 0.000
    3. Set Z-depth to -1.
  3. Click Apply when you are done and you should see two coordinates point appearing on your drawing sheet. One on the bottom left corner with coordinates of (0,0; 0,0; 0,0). The other one on the on the bottom margin of drawing sheet with coordinates of (100.0; 0.0; -1.0)

Step 5: Setup the Tool

  1. From the top toolbar, choose Extensions -> GCodeTools -> Tools Library.
  2. In the window that appears, select the ‘default’ tool and press Apply.
  3. A text panel will appear on top of your drawing. Move it to the side with the selection tool (S) and then select the text editing tool (T).
  4. Edit the following parameters in the text panel.
    1. Set diameter to your tool diameter (optional).
    2. Set feed to 9999.
    3. Set penetration feed to 9998.
    4. Set passing feed to 1000.

Step 6: Enter G-code processing parameters

  1. From the top toolbar, choose Extensions -> GCodeTools -> Path-to-Gcode. A window with 4 tabs will appear.
  2. In the “Path to GCode” tab, set the cutting order to “pass by pass” and use depth function d.
  3. In the “Options” tab, set the ‘Offset along Z axis’ to 1.00. Also, check the “Select all paths if nothing is selected” checkbox.
  4. In the “Preferences” tab:
    1. Enter the filename for your exported G-code file.
    2. Enter the full path to the export directory in the ‘directory’ field.
    3. Set ‘Z safe height for G00 move over blank’ to 2.00’
  5. Generate log files if you would like.
  6. At this stage, everything is ready to generate a gcode file. Save another copy of this file and delete all sublayers.

Step 7: Generate and export G-code File

  1. With the “Path-to-Gcode” tab of the “Path-to-Gcode” panel open, click apply.
  2. If a warning appears that no paths were selected, just press ok and GCodeTools will attempt to use all paths.

Step 8: Validate GCode File [Strongly recommended]

  1. Open the G-code file that you have generated and look through it for obvious errors such as:
    1. No/ very few commands -> Likely the plugin didnt select your drawing, or your drawing wasnt in the top layer.
    2. Printing steps aren’t at Z0, travel steps arent at Z3. -> you have made a mistake in steps 4 or 6.
  2. Use a program like CAMotics or NC Viewer to visually inspect the toolpath BEFORE you try it on the printer.

GcodeFile3DSlicer Sequence

This sequence allows locally stored Gcode file obtained through InkScape software to be imported into polychemprint3.Here is what menu of this sequence looks like:

_images/GCode3DMenu.png

P1 through P5 are basic information describing the sequence. P6 gives users options to select the .gcode file. Users can either type in the full file path or type in “File” to opens up a GUI window and choose the matching file like follow:

P7 - P9 Allow the user to set the tool on, off, and travel values. Upon importing FDM Gcode, the program automatically converts from extruder positions to tool on/off triggers.

Cura 3D GCode Tutorial

Cura is a free software that converts CAD files (commonly .STL) into GCode for FDM printers. We do not give an exhaustive tutorial of Cura here, but instead briefly outline the process and note the parameters you must select in order for PCP3 to properly import GCode.

Steo 0: Printer/ Program Settings

Either create a “Custom FFF Printer” or modify your 3D printer’s profile to reflect the following.

  1. Delete any start or end Gcode.
  2. Set the origin at center of the bed.
  3. Select Marlin as the Gcode flavor.
  4. Set the nozzle diameter to the diameter of the nozzle you are using (or feature size of LASER etch lines etc.)

Step 1: Import STL file

  1. Click File on the top bar and select Open Files

  2. Select the STL file you want to generate G-code from .

  3. Properly adjust orientation of your object. Make sure it is in contact with the bed.

  4. In the print settings make the following changes:

    1. Set the layer height to the height of your material under the desired printing conditions
    2. Set the print speed (for all parts) to be the desired printing speed.
    3. Turn off build plate adhesion tools like skirts or brims (unless you want them)

Step 2: Slice Object

  1. After done adjusting parameters, the bottom right corner will state “Ready to Slice”
  2. Please wait until it states “Ready to Save to File” and precede to step 3

Step 3: Generate G-code

  1. Click “Save to File” button on the bottom right corner
  2. Select the desired directory and click save
  3. GCODE file is generated.

Recipe Menu

Recipe are a combination of sequences to be executed in series. The constituent sequences each can take on their own parameters and duplicates are allowed. This can be very useful for combinatorial screening, or even just for printing a batch of identical samples in one long run, without user intervention. It is also possible to include ‘interrupt’ sequences that prompt for user input, e.g. to confirm the nozzle is clean/ swap out substrates/ etc. between prints. Because recipes can become quite long, they are stored as text files (.yaml) and only one recipe is fully loaded into RAM at a time, the “active recipe”. For convenience, basic details of all recipes can be seen from the loading screen.

Note: Recipes are NOT meant to be created outside of PCP3. Although it is possible to edit .yaml files, it is not encouraged.

The recipe menu is shown below:

_images/recipe.png

At program launch, no recipe is loaded and thus sequences cannot be added.

Creating a new Recipe

To build a new recipe, type 3, Build a New Recipe, in Recipe Menu and the program will ask for user input regarding the name and description of the new recipe. The newly created recipe will be empty of any sequences. Picture below shows the procedure on create a new recipe (commands entered are boxed by red). By default, the new recipe becomes the active recipe.

_images/buildrecipe.png

Modifying/Saving Active Recipe

Type 2 in Recipe Menu to access the Modify/Save Active Recipe menu and users can adjust that recipe by remove/add sequences, change parameters, or saving to the yaml file.

_images/modifyrecipe.png
Edit basic information

One bottom portion of Modify/Save Active Recipe menu, information about activated recipe is shown. Description information includes name, description, creation date are shown. To modify these information, type 0 in terminal to edit text in P0 through P2(commands entered are boxed by red).

_images/editrecipe.png
Add Sequence

To add a sequence, type 1 in the terminal and user will be brought to print sequence menu to choose a sequence to add. Type the code of the sequence user want and the matching sequence menu will be displayed for user to edit parameters. (For more detailed information about sequences, please see sequence menu). After finishing modifying parameters, type in ADD in terminal to add that sequence to sequence list, program will ask for user input about which index should the new sequence be occupying. This decides on the executing order sequences. Pictures below reveals process of add line sequence to a recipe (commands entered are boxed by red).

  1. Type in 1 to add sequence command
_images/addrecipe.png

2.Select a sequence( in this example, select line sequence)

_images/selectsequence.png
  1. Modify line sequence parameter and type in command add
_images/addsequence.png
  1. Select the index to be occupied by new sequence
_images/selectindex.png
Edit Sequence

To edit a sequence that is already in sequence list, type 2 in terminal under Modify/Save Active Recipe menu. The terminal will ask for user input of sequence code (in the form of S#). Select the sequence wanted to be modified and the matching sequence menu will be brought up. Edit parameters and type in q to quit the sequence menu. The editing process of sequence is complete. Following pictures shows a process of editing line sequence (commands entered are boxed by red).

1.Select Edit Sequence

_images/editsequence.png

2.Modify parameters

_images/modifyparameter.png

3.Quit the sequence menu

_images/quitsequence.png
Remove Sequence

To remove a sequence in sequence list, type 3, Remove sequence, in terminal under Modify/Save Active Recipe menu and then type in the index of sequence that needs to be removed. The following picture shows the removal of line sequence (commands entered are boxed by red).

_images/remove.png
Recorder Sequence

To change the order of sequence in recipe, type 4, Recorder Sequence, in terminal under Modify/Save Active Recipe menu and type the index of sequence that need to be changed and then typed the index that sequence is going to occupy. A single re-order process is complete. This re-order procedure will be continued until user type q to quit the re-order sequence function. The following picture shows the change order process (commands entered are boxed by red).

_images/recorder.png
Save Modifications
After finishing editing recipe, users must save the modified sequence list to yaml file in recipe folder. Otherwise, if the program is closed or reset, changes made will not no longer exist. To save a recipe, type save in terminal under Modified/Save Active menu. (Note, after adding a sequence and quit the Sequence Menu, program will not return to Modified/Save Active menu, please remember to return to Main Menu, and go to Recipe Menu, and go to Modified/Save Active Recipe menu in order to do save command)
Quit Modify/Save Active Recipe Menu
To exit out of the Hardware Menu, type q in the command and you will be in the Recipe Menu.

Browse/Load Stored Recipes

Type command 1 in the Recipe Menu will allow program to search through polychemprint3/recipe folder and display names, creation dates and descriptions of recipes stored locally.

_images/recipebrowse.png

By entering a recipe code(1,2,3,4,etc.), users can choose to activate a recipe in the program. The current active recipe name will also be shown in recipe menu (boxed in yellow).

View Recipe Details

To view information on activated recipe, type view under Recipe Menu and terminal will deliver information of name, description, and also the contents of the active recipe.

Execute Recipe Menu

To execute a recipe, first type Prime in terminal under Recipe Menu to convert active recipe into python code. Then type in GO to begin recipe execution. Before the recipe begins, it will prompt for a log file name to deposit full recipe details into. Logs are saved as text files in the polychemprint3/Logs folder.

PCP3 Package Overview

PCP3 is written in Python following object-oriented programming (OOP) principles, meaning that data and methods are organized in terms of distinct “objects” with clearly defined attributes and behaviors, which are only instantiated (given specific values) in the __main__.py method. This modular approach (see Figure below) greatly simplifies the process of adding additional hardware and sequences by isolating these blocks of code into distinct submodules (folders) that are separate from the more complex user interface and main methods. In order to add a new sequence to the program, for example, the user can simply clone one of the existing light blue .py files, rename it and modify the contents to contain the desired motion/tool commands, and place it in the sequence folder. On startup, PCP3 automatically attempts to load any new sequences, axes, or tool .py files, after checking for compiler errors.

_images/CodeMap.png

PCP3 also takes advantage of the OOP concept of inheritance to streamline addition of new code files to the program. The grey boxes in the Figure are effectively blueprints (‘Abstract Base Classes’, in Python) for the class declarations (light blue .py files) that inherit from them (signified by grey arrows from the parent to the child class). This system enforces a standardized format for each type of code file. All ‘sequences’ are required to behave following the rules of the parent sequenceSpec class to compile properly, or else they are not loaded when PCP3 starts. In addition to minimizing runtime errors, this approach provides another way to isolate the user from having to deal with repetitive boilerplate code common across many different objects. For example, there is no need to explicitly write logging methods for each sequence, because they already inherit them from the loggerSpec Abstract Base Class. Finally, the main method contains the data structures which hold all of the instantiated objects as well as containing all Menu classes and driving the user interface.

Sphinx Autodocumentation

Documentation generated using the sphinx autodoc method.

polychemprint3.commandLineInterface

polychemprint3.commandLineInterface.ioElementSpec module

Contains ioElementSpec Abstract Base Class.

First created on Sun Oct 20 00:03:21 2019
Revised (dd/mm/yyyy): 20/12/2020 - BP
Author: Bijal Patel
class polychemprint3.commandLineInterface.ioElementSpec.ioElementSpec(name, **kwargs)

Bases: abc.ABC

Specifies the interface for CLI menus/text/etc.

io_Operate()

Do the primary purpose of the CLI element.

Returns:an optional flag which either reflects how operation went, or is direction for future CLI operations.
Return type:str

polychemprint3.commandLineInterface.ioMenuSpec module

Contains ioMenuSpec Abstract Base Class.

First created on Sun Oct 20 00:03:21 2019
Revised (dd/mm/yyyy): 20/12/2020 - BP
Author: Bijal Patel
class polychemprint3.commandLineInterface.ioMenuSpec.ioMenuSpec(menuTitle, menuItems, menuDesc='', menuInstruc='Choose from the following menu items:', lastCmd='', memCmd='', **kwargs)

Bases: polychemprint3.commandLineInterface.ioElementSpec.ioElementSpec, abc.ABC

Specifies the interface for CLI menus.

ioMenu_printMenu(showStoredCmds=True)

Prints formatted menu options from menuItems dict.

ioMenu_updateStoredCmds(lastCmd, memCmd)

Updates stored commands local to this menu item from inputs.

Parameters:
  • lastCmd (str) – specifying the last command entered
  • memCmd (str) – specifying the command saved to memory
io_Operate()

Performs menu operations and loops on user input. :returns: Title of next menu to present. :rtype: str

polychemprint3.commandLineInterface.ioTextPanel module

Contains ioTextPanelSpec Abstract Base Class.

First created on Sun Oct 20 00:03:21 2019
Revised: 20/10/2019 00:34:27
Author: Bijal Patel
class polychemprint3.commandLineInterface.ioTextPanel.ioTextPanel(panelTitle, fullFilePath, **kwargs)

Bases: polychemprint3.utility.fileHandler.fileHandler, polychemprint3.commandLineInterface.ioElementSpec.ioElementSpec

Specifies the interface for CLI menus.

io_Operate()

Prints formatted text from file.

polychemprint3.data

Subpackages

polychemprint3.data.TextPanels package
Module contents

Module contents

polychemprint3.axes

polychemprint3.axes.axes3DSpec module

Specifies 3D Axes classes, implementations are for specific printers/stages.

First created on Sat Oct 19 20:39:58 2019
Revised: 23/10/2019 14:06:59
Author: Bijal Patel
class polychemprint3.axes.axes3DSpec.Axes3DSpec(name, __verbose__=0, posMode='absolute', **kwargs)

Bases: polychemprint3.utility.loggerSpec.loggerSpec, abc.ABC

Abstract Base Class for 3D Axes.

activate()

Makes required connections and returns status bool.

Returns:True if ready to use False if not ready
Return type:bool
deactivate()

Closes communication and returns status bool.

Returns:True if ready to use False if not ready
Return type:bool
getAbsPosXY()

Gets the current position (absolute) and return XY positions.

Parameters:command (String) – Gcode to write to axes
Returns:[X, Y] X and Y positions as strings
Return type:String
move(gcodeString)

Moves to the specified gcodeString position.

Parameters:gCodeString (String) – Motion command in terms of Gcode G0/G1/G2/G3 supported
poll(command)

Sends message to axes and returns response.

Parameters:command (String) – to write to axes
Returns:Response from axes
Return type:String
sendCmd(command)

Writes command to axes device when ready.

Parameters:command (String) – to write to axes
setPosMode(newPosMode)

Sets positioning mode to relative or absolute.

Parameters:newPosMode (String) – Positioning mode to use for future move cmds
setPosZero()

Sets the current position (absolute) to (0,0,0).

polychemprint3.axes.lulzbotTaz6_BP module

Implements axes3DSpec for lulzbot taz 6 with modified firmware.

First created on Sat Oct 19 20:39:58 2019
Revised: 23/10/2019 14:06:59
Author: Bijal Patel
class polychemprint3.axes.lulzbotTaz6_BP.lulzbotTaz6_BP(name='LulzbotTaz6', posMode='relative', devAddress='/dev/ttyACM0', baudRate=115200, commsTimeOut=0.001, __verbose__=1, firmwareVers='BP')

Bases: polychemprint3.utility.serialDeviceSpec.serialDeviceSpec, polychemprint3.axes.axes3DSpec.Axes3DSpec

Implemented interface for Lulzbot Taz 6 with BP modified firmware.

activate()

Makes required connections and returns status bool.

Returns:True if ready to use False if not ready
Return type:bool
deactivate()

Closes communication and returns status bool.

Returns:True if closed succesfully False if failed
Return type:bool
getAbsPosXY()

Gets the current position (absolute) and return XY positions.

Parameters:command (String) – Gcode to write to axes
Returns:[X, Y] X and Y positions as strings
Return type:String
handShakeSerial()

Perform communications handshake with serial device.

Returns:
  • [1, “Handshake Successful”] – success occured
  • [0, ‘Handshake Failed, Rcvd + message received’] – failure occured
  • [-1, “Error (Handshake with Tool Failed + error text”]) – Error received
move(gcodeString)

Moves axes by set amount.

Parameters:
  • gCodeString (String) – Motion command in terms of Gcode G0/G1/G2/G3 supported
  • Returns (|) –
  • none (|) –
poll(command)

Sends message to axes and parses response.

Parameters:command (String) – to write to axes
Returns:Response from axes
Return type:String
readTime()

Reads in from serial device until timeout.

Returns:All text read in, empty string if nothing
Return type:String
sendCmd(command)

Writes command to axes device when ready.

Parameters:command (String) – to write to axes
Returns:Response from axes
Return type:String
setPosMode(newPosMode)

Sets positioning mode to relative or absolute.

Parameters:newPosMode (String) – Positioning mode to use for future move cmds
setPosZero()

Sets current axes position to absolute (0,0,0).

startSerial()

Creates pySerial device.

Returns:
  • [1, “Serial Device Started successfully”] – started succesfully
  • [-1, ‘Failed Creating pySerial…’] – could not start
stopSerial()

Closes serial devices.

Returns:
  • [1, “Terminated successfully”] – started succesfully
  • [-1, “Error (Serial Device could not be stopped + error text”])
waitReady()

Looks for “ok” in input, waits indefinitely.

Returns:All text read in, empty string if nothing
Return type:String
writeReady(command)

Sends command only after rece0iving ok message.

Parameters
command, string to write to axes
Returns
inp, String read in

polychemprint3.axes.nullAxes module

Implements axes3DSpec as null axes (returns successful to all).

First created on Sat Oct 19 20:39:58 2019
Revised: 23/10/2019 14:06:59
Author: Bijal Patel
class polychemprint3.axes.nullAxes.nullAxes(name='nullAxes', posMode='relative', __verbose__=0)

Bases: polychemprint3.axes.axes3DSpec.Axes3DSpec

Implementing axes3D for null case.

activate()

Makes required connections and returns status bool.

Returns:True if ready to use False if not ready
Return type:bool
deactivate()

Closes communication and returns status bool.

Returns:True if closed succesfully False if failed
Return type:bool
getAbsPosXY()

Gets the current position (absolute) and return XY positions.

Parameters:command (String) – Gcode to write to axes
Returns:[X, Y] X and Y positions as strings
Return type:String
move(gcodeString)

Initializes Axes3D object.

Parameters:
  • gCodeString (String) – Motion command in terms of Gcode G0/G1/G2/G3 supported
  • Returns (|) –
  • none (|) –
poll(command)

Sends message to axes and parses response.

Parameters:command (String) – to write to axes
Returns:Response from axes
Return type:String
sendCmd(command)

Writes command to axes device when ready.

Parameters:command (String) – to write to axes
setPosMode(newPosMode)

Sets positioning mode to relative or absolute.

Parameters:newPosMode (String) – Positioning mode to use for future move cmds
setPosZero()

Sets current axes position to absolute (0,0,0).

polychemprint3.tools

polychemprint3.tools.laser6W module

Implements the Tool base class for Danny’s arduino-uno controlled 6W LASER.

First created on Wed Feb 12 2020
Revised: 12/02/2020
Author: Bijal Patel
class polychemprint3.tools.laser6W.laser6W(name='BlueLASER6W', units='percent', devAddress='/dev/ttyACM1', baudRate=115200, commsTimeOut=0.001, __verbose__=1, **kwargs)

Bases: polychemprint3.utility.serialDeviceSpec.serialDeviceSpec, polychemprint3.tools.toolSpec.toolSpec

Implements the Tool base class for Danny’s 6W LASER.

activate()

Makes required connections and returns status bool.

Returns:True if ready to use False if not ready
Return type:bool
checkIfSerialConnectParamsSet()

Goes through connection parameters and sees if all are set.

Returns:True if all parameters are set, false if any unset
Return type:bool
deactivate()

Closes communication and returns status bool.

Returns:True if deactivated False if not deactivated
Return type:bool
disengage()

Toggles Dispense off.

Returns:
  • [1, “Dispense Off”]
  • [0, “Error (Dispense already off”])
  • [-1, ‘Failed engaging dispense ‘ + inst.__str__()]
engage()

Toggles Dispense on.

Returns:
  • [1, “Dispense On”]
  • [0, “Error (Dispense Already On”])
  • [-1, ‘Failed engaging dispense ‘ + inst.__str__()]
getState()

Returns active state of tool.

Parameters
none
Returns
[1, “Tool On”]
[0, “Tool Off”]
[-1, “Error: Tool activation state cannot be determined + Error]
handShakeSerial()

Perform communications handshake with Tool.

Returns:
  • [1, “Handshake Successful”]
  • [0, ‘Handshake Failed, Received (+ message received’]) – if unexpected input received
  • [-1, “Error (Handshake with Tool Failed + error text”])
loadLogSelf(jsonString)

loads json log back into dict.

Parameters:jsonString (String) – json string to be loaded back in
readTime()

Reads in from serial device until timeout.

Returns:
  • [1, inp String of all text read in, empty string if nothing]
  • [0, ‘Read failed + Error’ if exception caught]
setValue(value)

Set Laser PWM value in percent 1-100.

Parameters:value (String) – New value of pressure out of 100
Returns:
  • [output of writeSerialCommand]
  • [-1, “Error (value could not be set for LASER + error text”])
startSerial()

Creates and connects pySerial device.

Returns:
  • [1, “Connected Succesfully to Serial Device”]
  • [0, ‘Not all connection parameters set’]
  • [-1, “Error (Could not connect to serial device: + error text”])
stopSerial()

Terminates communication.

Returns:
  • [1, “Terminated successfully”]
  • [-1, “Error (Tool could not be stopped + error text”])
writeLogSelf()

Generates json string containing dict to be written to log file.

Returns:logJson – log in json string format
Return type:String

polychemprint3.tools.nullTool module

Implements the Tool base class for a null Tool [no action, returns true].

First created on 13/11/2019 13:33:28
Revised: 17/10/20
Author: Bijal Patel
class polychemprint3.tools.nullTool.nullTool(name='nullTool', units='null', devAddress='unset', baudRate='unset', commsTimeOut=0.5, __verbose__=0, **kwargs)

Bases: polychemprint3.tools.toolSpec.toolSpec

Implements the toolSpec abstract base class for a null tool, a virtual hardware device that only writes to the terminal.

activate()

To be called in main.py to load as active tool. Makes required serial connections and returns status as True/False.

Returns:True if tool serial connection made and tool is ready to use False if error generated and tool is not ready for use
Return type:bool
deactivate()

To be called in main.py to unload as active tool. Closes serial communication and returns status as True/False.

Returns:True if tool serial connection destroyed and tool is succesfully disabled. False if error generated and serial communication could not be suspended.
Return type:bool
disengage()

Turn tool primary action off (stops dispense/LASER beam off, etc).

Returns:status – First element (int) indicates whether disengage was successful (1), already off (0), or error (-1).

Second element (String) provides text explanation.

Return type:two-element list
engage()

Turn tool primary action on (dispense/LASER beam on, etc).

Returns:status – First element (int) indicates whether engage was successful (1), already on (0) or error (-1)

Second element (String) provides text explanation.

Return type:two-element list
getState()

Returns the current dispense/action state (on/off).

Returns:status – First element indicates whether tool is on(1) or off(0) or error(-1).

Second element provides text explanation.

Return type:two-element list
loadLogSelf(yamlString)

loads json log back into dict.

Parameters:yamlString (String) – yaml string to be loaded back in
setValue(value)

Set the primary tool action value (e.g., Laser power, extruder pressure, etc.).

Parameters:value (String) – The new value of the parameter as a string, expressed at arbitrary precision/ without leading zeros. Conversion to hardware specific format occurs internally. e.g., (use 23.456 NOT 0234”)
Returns:status – First element (int) indicates whether value setting was successful (1) or error (-1).

Second element provides text explanation.

Return type:two-element list
writeLogSelf()

Generates yaml string containing dict to be written to log file.

Returns:logyaml – log in yaml string format
Return type:String

polychemprint3.tools.toolSpec module

Contains toolSpec Abstract Base Class.

First created on Sun Oct 20 00:03:21 2019
Revised: 10/17/2020
Author: Bijal Patel
class polychemprint3.tools.toolSpec.toolSpec(name, units, __verbose__, **kwargs)

Bases: polychemprint3.utility.loggerSpec.loggerSpec, abc.ABC

Abstract Base Class for all dispensing/writing tool drivers.

activate()

To be called in main.py to load as active tool. Makes required serial connections and returns status as True/False.

Returns:True if tool serial connection made and tool is ready to use False if error generated and tool is not ready for use
Return type:bool
deactivate()

To be called in main.py to unload as active tool. Closes serial communication and returns status as True/False.

Returns:True if tool serial connection destroyed and tool disabled. False if error generated and serial communication not suspended.
Return type:bool
disengage()

Turn tool primary action off (stops dispense/LASER beam off, etc).

Returns:status – First element (int) indicates whether disengage was successful (1), already off (0), or error (-1). Second element (String) provides text explanation.
Return type:two-element list
engage()

Turn tool primary action on (dispense/LASER beam on, etc).

Returns:status – First element (int) indicates whether engage was successful (1), already on (0) or error (-1) Second element (String) provides text explanation.
Return type:two-element list
getState()

Returns the current dispense/action state (on/off).

Returns:status – First element indicates whether tool is on(1), off(0) or error(-1). Second element provides text explanation.
Return type:two-element list
loadLogSelf(yamlString)

Loads yaml log back into __dict__.

Parameters:yamlString (String) – yaml string to be loaded back in
setValue(value)

Set the primary tool action value (e.g., Laser power, extruder pressure, etc.).

Parameters:value (String) – The new value of the parameter as a string, expressed at arbitrary precision/ without leading zeros. Conversion to hardware specific format occurs internally. e.g., (use 23.456 NOT 0234”)
Returns:status – First element (int) indicates whether value setting was successful (1) or error (-1). Second element provides text explanation.
Return type:two-element list
writeLogSelf()

Generates yaml string containing __dict__ to be written to log file.

Returns:log in yaml string format
Return type:String

polychemprint3.tools.ultimusExtruder module

polychemprint3.recipes

polychemprint3.recipes.recipe module

Specifies modular recipe protocol to link series of sequences

First created on Mon May 11 17:27:00 2020
Revised:
Author: Bijal Patel
class polychemprint3.recipes.recipe.recipe(name: str = 'NoRecipeNameSet', description: str = 'NoRecipeDescriptionSet', dateCreated: str = 'NoDateSet', axes: <module 'polychemprint3.axes.axes3DSpec' from '/home/docs/checkouts/readthedocs.org/user_builds/polychemprint3/checkouts/latest/polychemprint3/axes/axes3DSpec.py'> = <polychemprint3.axes.nullAxes.nullAxes object>, tool: polychemprint3.tools.toolSpec.toolSpec = <polychemprint3.tools.nullTool.nullTool object>, seqList=None, __verbose__: bool = 0, **kwargs)

Bases: polychemprint3.utility.fileHandler.fileHandler, polychemprint3.utility.loggerSpec.loggerSpec

Class for recipes - a series of sequences joined together

addSeq(beforeIndex: int, newSeq: polychemprint3.sequence.sequenceSpec.sequenceSpec)

Adds a copy of the provided sequence to the seqList. :param beforeIndex: :type beforeIndex: int :param newSeq: :type newSeq: sequenceSpec

deleteSeq(index: int)

Adds a copy of the provided sequence to the seqList. :param index: :type index: int

genRecipe()

Loads print sequence into a list into cmdList attribute.

Returns:whether successfully reached the end or not
Return type:bool
loadLogSelf(logString)

loads log back into dict.

Parameters:logString (String) – log string to be loaded back in
operateRecipe(axesIn, toolIn)

Performs print sequence. :returns: Whether recipe successfully completed or not :rtype: bool

reorderSeq(currentIndex: int, newIndex: int)

Moves sequence from currentIndex to newIndex in seqList. :param currentIndex: :type currentIndex: int :param newIndex: :type newIndex: int

writeLogSelf()

Generates log string containing dict to be written to log file.

Returns:log in string format
Return type:String
class polychemprint3.recipes.recipe.recipeStub(name: str = 'NoRecipeNameSet', description: str = 'NoRecipeDescriptionSet', dateCreated: str = 'NoDateSet', **kwargs)

Bases: polychemprint3.utility.fileHandler.fileHandler

Class for recipe stubs, just the name, description, path info

polychemprint3.sequence

polychemprint3.sequence.sequenceSpec module

Specifies modular pre-written motion and dispense sequences for common prints.

First created on Sun Oct 20 00:08:15 2019
Revised (dd/mm/yyyy): 01/18/2021 - BP
Author: Bijal Patel
class polychemprint3.sequence.sequenceSpec.seqParam(name, value, unit, helpString)

Bases: object

Base Class for parameters used in sequences.

class polychemprint3.sequence.sequenceSpec.sequenceSpec(axes: polychemprint3.axes.axes3DSpec.Axes3DSpec = <polychemprint3.axes.nullAxes.nullAxes object>, tool: polychemprint3.tools.toolSpec.toolSpec = <polychemprint3.tools.nullTool.nullTool object>, dictParams: dict = None, __verbose__: bool = 0, tool2: polychemprint3.tools.toolSpec.toolSpec = <polychemprint3.tools.nullTool.nullTool object>, tool3: polychemprint3.tools.toolSpec.toolSpec = <polychemprint3.tools.nullTool.nullTool object>, **kwargs)

Bases: polychemprint3.utility.loggerSpec.loggerSpec, abc.ABC

Abstract Base Class for predefined print sequences.

genSequence()

Loads print sequence into a list into cmdList attribute.

Returns:whether successfully reached the end or not
Return type:bool
loadLogSelf(logString)

loads log back into dict.

Parameters:logString (String) – log string to be loaded back in
operateSeq(**kwargs)

Performs print sequence. :returns: Whether sequence successfully completed or not :rtype: bool

updateParams()
writeLogSelf()

Generates log string containing dict to be written to log file.

Returns:log in string format
Return type:String

polychemprint3.sequence.basicMove module

Moves Axes a set distance in X,Y,Z at set speed

First created on 05/05/2020
Revised: 10/8/2020
Author: Bijal Patel
class polychemprint3.sequence.basicMove.basicMove(axes: <module 'polychemprint3.axes.axes3DSpec' from '/home/docs/checkouts/readthedocs.org/user_builds/polychemprint3/checkouts/latest/polychemprint3/axes/axes3DSpec.py'> = <polychemprint3.axes.nullAxes.nullAxes object>, tool: polychemprint3.tools.toolSpec.toolSpec = <polychemprint3.tools.nullTool.nullTool object>, **kwargs)

Bases: polychemprint3.sequence.sequenceSpec.sequenceSpec

Sequence for a basic translation in a given direction

genSequence()

Loads print sequence into a list into cmdList attribute.

Returns:Whether Command Generation Sequence reaches the end or not.
Return type:bool
loadLogSelf(logString)

loads log back into dict.

Parameters:logString (String) – log string to be loaded back in
writeLogSelf()

Generates log string containing dict to be written to log file.

Returns:log in string format
Return type:String

polychemprint3.sequence.pause module

Sequence for introducing a pause. The length of time can be set, or it can resume on user input.

First created (dd/mm/yyyy): 05/05/2020
Revised (dd/mm/yyyy): 17/12/2020 - BP
Author: Bijal Patel
class polychemprint3.sequence.pause.pause(axes: polychemprint3.axes.axes3DSpec.Axes3DSpec = <polychemprint3.axes.nullAxes.nullAxes object>, tool: polychemprint3.tools.toolSpec.toolSpec = <polychemprint3.tools.nullTool.nullTool object>, **kwargs)

Bases: polychemprint3.sequence.sequenceSpec.sequenceSpec

Sequence for introducing a pause. The length of time can be set, or it can resume on user input.

genSequence()

Loads print sequence into a list into cmdList attribute.

Returns:whether successfully reached the end or not
Return type:bool
loadLogSelf(logString)

loads log back into dict.

Parameters:logString (String) – log string to be loaded back in
writeLogSelf()

Generates log string containing dict to be written to log file.

Returns:log in string format
Return type:String

polychemprint3.sequence.setToolState module

Sequence for changing tool value or dispense state.

First created (dd/mm/yyyy): 05/05/2020
Revised (dd/mm/yyyy): 17/12/2020 - BP
Author: Bijal Patel
class polychemprint3.sequence.setToolState.setToolState(axes: polychemprint3.axes.axes3DSpec.Axes3DSpec = <polychemprint3.axes.nullAxes.nullAxes object>, tool: polychemprint3.tools.toolSpec.toolSpec = <polychemprint3.tools.nullTool.nullTool object>, **kwargs)

Bases: polychemprint3.sequence.sequenceSpec.sequenceSpec

Sequence for changing tool value or dispense state.

genSequence()

Loads print sequence into a list into cmdList attribute.

Returns:whether successfully reached the end or not
Return type:bool
loadLogSelf(logString)

loads log back into dict.

Parameters:logString (String) – log string to be loaded back in
writeLogSelf()

Generates log string containing dict to be written to log file.

Returns:log in string format
Return type:String

polychemprint3.sequence.gapLine module

Predefined print sequence for gapLines.

First created on 13/11/2019 14:41:31
Revised: 5/3/20
Author: Bijal Patel
class polychemprint3.sequence.gapLine.gapLine(axes: <module 'polychemprint3.axes.axes3DSpec' from '/home/docs/checkouts/readthedocs.org/user_builds/polychemprint3/checkouts/latest/polychemprint3/axes/axes3DSpec.py'> = <polychemprint3.axes.nullAxes.nullAxes object>, tool: polychemprint3.tools.toolSpec.toolSpec = <polychemprint3.tools.nullTool.nullTool object>, **kwargs)

Bases: polychemprint3.sequence.sequenceSpec.sequenceSpec

Implemented print sequence for gapLines.

genSequence()

Generates the list of python commands to execute for this sequence (shape).

Returns:whether successfully reached the end or not
Return type:bool
loadLogSelf(logString)

loads log back into dict.

Parameters:logString (String) – log string to be loaded back in
writeLogSelf()

Generates log string containing dict to be written to log file.

Returns:log in string format
Return type:String

polychemprint3.sequence.line module

While dispensing, moves axes a set distance in X,Y,Z at set speed

First created on 13/11/2019 14:41:31
Revised (dd/mm/yyyy): 17/12/2020 - BP
Author: Bijal Patel
class polychemprint3.sequence.line.line(axes: polychemprint3.axes.axes3DSpec.Axes3DSpec = <polychemprint3.axes.nullAxes.nullAxes object>, tool: polychemprint3.tools.toolSpec.toolSpec = <polychemprint3.tools.nullTool.nullTool object>, **kwargs)

Bases: polychemprint3.sequence.sequenceSpec.sequenceSpec

Implemented print sequence for single lines.

genSequence()

Loads print sequence into a list into cmdList attribute.

Returns:whether successfully reached the end or not
Return type:bool
loadLogSelf(logString)

loads log back into dict.

Parameters:logString (String) – log string to be loaded back in
writeLogSelf()

Generates log string containing dict to be written to log file.

Returns:log in string format
Return type:String

polychemprint3.sequence.circle module

polychemprint3.sequence.cuboid module

3D Cuboid with base along the XY axes

First created (dd/mm/yyyy): 05/06/2020
Revised (dd/mm/yyyy): 17/12/2020 - BP
Author: Yilong Chang
class polychemprint3.sequence.cuboid.cuboid(axes: polychemprint3.axes.axes3DSpec.Axes3DSpec = <polychemprint3.axes.nullAxes.nullAxes object>, tool: polychemprint3.tools.toolSpec.toolSpec = <polychemprint3.tools.nullTool.nullTool object>, **kwargs)

Bases: polychemprint3.sequence.sequenceSpec.sequenceSpec

3D Cuboid with base along the XY axes

genSequence()

Loads print sequence into a list into cmdList attribute.

Returns:whether successfully reached the end or not
Return type:bool
loadLogSelf(logString)

loads log back into dict.

Parameters:logString (String) – log string to be loaded back in
writeLogSelf()

Generates log string containing dict to be written to log file.

Returns:log in string format
Return type:String

polychemprint3.sequence.pyramid module

3D Pyramid with base along XY axes.

First created (dd/mm/yyyy): 05/06/2020
Revised (dd/mm/yyyy): 17/12/2020 - BP
Author: Yilong Chang
class polychemprint3.sequence.pyramid.pyramid(axes: polychemprint3.axes.axes3DSpec.Axes3DSpec = <polychemprint3.axes.nullAxes.nullAxes object>, tool: polychemprint3.tools.toolSpec.toolSpec = <polychemprint3.tools.nullTool.nullTool object>, **kwargs)

Bases: polychemprint3.sequence.sequenceSpec.sequenceSpec

Implemented print sequence for circle.

genSequence()

Loads print sequence into a list into cmdList attribute.

Returns:whether successfully reached the end or not
Return type:bool
loadLogSelf(logString)

loads log back into dict.

Parameters:logString (String) – log string to be loaded back in
writeLogSelf()

Generates log string containing dict to be written to log file.

Returns:log in string format
Return type:String

polychemprint3.sequence.rectangle module

2D Rectangle along the XY axes

First created (dd/mm/yyyy): 05/06/2020
Revised (dd/mm/yyyy): 17/12/2020 - BP
Author: Bijal Patel
Author: Yilong Chang
class polychemprint3.sequence.rectangle.rectangle(axes: polychemprint3.axes.axes3DSpec.Axes3DSpec = <polychemprint3.axes.nullAxes.nullAxes object>, tool: polychemprint3.tools.toolSpec.toolSpec = <polychemprint3.tools.nullTool.nullTool object>, **kwargs)

Bases: polychemprint3.sequence.sequenceSpec.sequenceSpec

Implemented print sequence for rectangle.

genSequence()

Loads print sequence into a list into cmdList attribute.

Returns:whether successfully reached the end or not
Return type:bool
loadLogSelf(logString)

loads log back into dict.

Parameters:logString (String) – log string to be loaded back in
writeLogSelf()

Generates log string containing dict to be written to log file.

Returns:log in string format
Return type:String

polychemprint3.sequence.triangle module

polychemprint3.sequence.plate module

Predefined print sequence for plates.

First created on 13/11/2019 14:41:31
Revised:
Author: Bijal Patel
class polychemprint3.sequence.plate.plate(axes: polychemprint3.axes.axes3DSpec.Axes3DSpec = <polychemprint3.axes.nullAxes.nullAxes object>, tool: polychemprint3.tools.toolSpec.toolSpec = <polychemprint3.tools.nullTool.nullTool object>, **kwargs)

Bases: polychemprint3.sequence.sequenceSpec.sequenceSpec

Implemented print sequence for plates.

genSequence()

Loads print sequence into a list into cmdList attribute.

Returns:whether successfully reached the end or not
Return type:bool
loadLogSelf(logString)

loads log back into dict.

Parameters:logString (String) – log string to be loaded back in
writeLogSelf()

Generates log string containing dict to be written to log file.

Returns:log in string format
Return type:String

polychemprint3.sequence.GCodeFileInkscape module

Parameterized code for reading in a gcode file and reprocessing for PCP3

First created on 2020/05/14 18:16:00
Revised: 2020/12/17
Author: Bijal Patel
class polychemprint3.sequence.GCodeFileInkscape.GCodeFileInkscape(axes: polychemprint3.axes.axes3DSpec.Axes3DSpec = <polychemprint3.axes.nullAxes.nullAxes object>, tool: polychemprint3.tools.toolSpec.toolSpec = <polychemprint3.tools.nullTool.nullTool object>, **kwargs)

Bases: polychemprint3.sequence.sequenceSpec.sequenceSpec

Sequence template for importing GCODE motion commands and tool triggers into PCP Recipe framework

genSequence()

Loads print sequence into a list into cmdList attribute.

Returns:Whether successfully reached the end or not.
Return type:bool
importFromGFile()

Attempts to read line by line from GcodeFile at GCodeFilePath and return the read lines as a list.

Returns:
  • bool – True if read from file without an error.
  • list of str – A list containing each line read in as a separate str element.
insertToolCode(procGlines)

Augments procGlines with tool on/off/trv values based on the z-carriage height.

Returns:fullLines – The combined list of Gcode and tool commands.
Return type:list of str
loadLogSelf(logString)

loads log back into dict.

Parameters:logString (String) – log string to be loaded back in
processGCode(GLines)

Parses each line in Glines to remove unusable commands and reconstitutes motion, feed strings with the rates the user provides in the CLI.

Returns:procGlines – A list of GCode lines processed to remove garbage and include user-specified feeds, z height.
Return type:list of str
writeLogSelf()

Generates log string containing dict to be written to log file.

Returns:log in string format
Return type:String

polychemprint3.sequence.GCodeFile3DSlicer module

Parameterized code for reading in a gcode file for 3D printing and reprocessing for PCP3

First created on 05/14/2020 18:16:00
Revised: 11/11/21
Author: Bijal Patel
class polychemprint3.sequence.GCodeFile3DSlicer.GCodeFile3DSlicer(axes: polychemprint3.axes.axes3DSpec.Axes3DSpec = <polychemprint3.axes.nullAxes.nullAxes object>, tool: polychemprint3.tools.toolSpec.toolSpec = <polychemprint3.tools.nullTool.nullTool object>, **kwargs)

Bases: polychemprint3.sequence.sequenceSpec.sequenceSpec

Sequence template for importing 3D GCODE motion commands and tool triggers into PCP Recipe framework

genSequence()

Loads print sequence into a list into cmdList attribute.

Returns:whether successfully reached the end or not
Return type:bool
importFromGFile()

Attempts to read line by line from GcodeFile at GCodeFilePath into memory

insertToolCode(procGlines)
loadLogSelf(logString)

loads log back into dict.

Parameters:logString (String) – log string to be loaded back in
processGCode(GLines)

Attempts to filter line by line from GLines to remove garbage and substitute values

writeLogSelf()

Generates log string containing dict to be written to log file.

Returns:log in string format
Return type:String

polychemprint3.utility

polychemprint3.utility.fileHandler module

Specifies interface for classes that will handle rw ‘data’ files.

First created on Sun Oct 20 00:03:21 2019
Revised: 20/10/2019 00:34:27
Author: Bijal Patel
class polychemprint3.utility.fileHandler.fileHandler(fullFilePath=None, **kwargs)

Bases: object

Class for objects that can read/write to file

appendToFile(outString)

Appends to file with new content from outString.

Parameters:outString (String) – the string to write to the file
Returns:True/False if writing passes/fails + errors
Return type:bool
overWriteToFile(outString)

Completely overwrites file with new content from outString.

Parameters:outString (String) – the string to write to the file
Returns:True/False if writing passes/fails + errors
Return type:bool
peekFile(numLines)

Reads numLines from file and returns.

Parameters:numLines (int) – number of lines to read in from file
Returns:
  • bool – True/ False if read successful
  • [lines] – array of strings read in or [“Failed”]
readFullFile()

Reads the entire file into memory as a list of strings.

Returns:
  • bool – True/False if read passes/fails + errors
  • [lines] – array of strings read in or [“Failed”]
testFileIO(modeString)

Tests if file can be opened and closed.

Parameters:modeString (String) – mode with which to open file (“r,w,r+,a”)
Returns:True/False if test passes/fails + errors
Return type:bool

polychemprint3.utility.loggerSpec module

Specifies interface for all classes to read/write themselves to string.

First created on Sun Oct 20 00:03:21 2019
Revised: 20/10/2019 00:34:27
Author: Bijal Patel
class polychemprint3.utility.loggerSpec.loggerSpec(**kwargs)

Bases: abc.ABC

Abstract Base Class for objects that can generate log strings.

loadLogSelf(yamlString)

loads yaml log back into dict.

Parameters:yamlString (String) – yaml string to be loaded back in
writeLogSelf()

Generates yaml string containing dict to be written to log file.

Returns:log in yaml string format
Return type:String

polychemprint3.utility.serialDeviceSpec module

Interface for all Serial Device objects (extruders/lasers/axes/etc).

First created on Sun Oct 20 00:03:21 2019
Revised: 20/10/2019 00:34:27
Author: Bijal Patel
class polychemprint3.utility.serialDeviceSpec.serialDeviceSpec(devAddress, baudRate, commsTimeOut, **kwargs)

Bases: abc.ABC

Abstract Base Class for all objects using serial device.

checkIfSerialConnectParamsSet()

Goes through connection parameters and sees if all are set.

Returns:True if all parameters are set, false if any unset
Return type:bool
handShakeSerial()

Perform communications handshake with serial device.

Returns:
  • [1, “Handshake Successful”] – success occured
  • [0, ‘Handshake Failed, Rcvd + message received’] – failure occured
  • [-1, “Error (Handshake with Tool Failed + error text”]) – Error received
readTime()

Reads in from serial device until timeout.

Returns:All text read in, empty string if nothing
Return type:String
startSerial()

Creates pySerial device.

Returns:
  • [1, “Terminated successfully”] – started succesfully
  • [-1, “Error (error text”]) – could not start
stopSerial()

Terminates communication.

Returns:
  • [1, “Terminated successfully”] – started succesfully
  • [-1, “Error (Serial Device could not be stopped + error text”]) – could not start