The GPIO module (General Purpose Input Output) is an additional, optional PCB that can be connected to the Original Prusa MK4/S, MK3.9/S, or MK3.5/S.
The module provides expanded functionality by allowing the control of external devices through connections to the GPIO board pins, which can operate in either INPUT or OUTPUT mode. This versatility opens up a wide range of potential use cases.
Share and discuss your projects with the other members of the Prusa Community on our official forum. We have created a dedicated GPIO section.
The module can control a camera shutter at a precise moment, making it ideal for creating visually perfect time-lapses, where each picture is captured at the exact same point in time.
Beyond controlling a camera shutter, the module can be used for various other applications. For example, it can trigger external lighting to illuminate the print area at specific stages of the printing process, ensuring optimal lighting conditions for quality checks or photography. Additionally, it can be configured to activate cooling fans or other peripheral devices, such as extractors or alarms, based on custom G-Code execution during prints, helping maintain optimal operating conditions and improving the safety and efficiency of the 3D printing environment.
Another powerful use case is the integration of a macro keyboard, where each keypress can trigger the execution of specific G-Code commands. This setup allows for rapid manual control of the printer's functions, such as starting or pausing a print, adjusting temperatures, or moving the print head to an exact position. The ability to trigger custom actions with a simple keypress can significantly streamline workflows, making the GPIO expansion module a versatile and indispensable tool for those looking to fully customize and optimize their 3D printing setup.
While the ability to trigger G-Code via GPIO inputs adds great flexibility, it also comes with limitations and potential risks. Improper use or poorly timed G-Code commands can interfere with the printing process, leading to print failures or even damage to the printer. It’s crucial to thoroughly test any custom G-Code setups in a controlled environment before deploying them in actual print jobs to avoid unintended consequences.
The schematics are open source, and available on our page Open Source at Prusa Research.
The board features 8 pins, numbered 0-7. Pins 0-3 can be used as output, and pins 4-7 can function as either input or output. Each pin is of the open-drain type when used as an output, meaning it is controlled by a transistor that connects the pin to the ground (0 V) when active. When the pin is inactive, it remains "floating", which means it is not connected to any specific voltage, but due to internal pull-up resistors, the voltage on the pin can hover around 3.3 V.
The behavior of the pins in an open-drain state when used as outputs can be explained as follows:
This "floating" state may cause the pin to pick up random electrical noise or interference, leading to unintended behavior if not properly managed.
When the pins are used as inputs, they can detect the voltage level applied to them. The input state is influenced by the presence of pull-up resistors, which can help ensure a consistently high voltage (3.3 V) when no other voltage source is applied.
The board allows the connection of external pull-up resistors via solder jumpers labeled JP4 to JP7. These solder jumpers are located in the center of the board and are connected to the corresponding pins:
Solder jumpers JP7 to JP4 can be used to connect integrated pull-up resistors, which ensures that the pins remain at a high voltage (3.3 V) when not actively driven low by an external source or by the pin's output state. These pull-up resistors have a value of 10K ohms, which is a standard value to provide stable voltage without excessive current draw. If no resistor is connected to the solder jumper, the pin may remain in a floating state, potentially leading to unstable behavior. JP stands for "jumper," and if no resistor is connected, it creates no resistance.
For less experienced users, it's important to understand that open-drain outputs do not inherently produce a high voltage (3.3 V) but rather allow a connection to ground (0 V). Pull-up resistors are necessary to ensure that the pin remains at a high voltage when turned off or when used as an input. If not properly managed, a "floating" voltage can cause the pin to pick up electrical noise, leading to unwanted switching or system instability.
The following is a sequence of custom G-Code commands used for controlling the GPIO board. This allows you to configure output states, read input states, and manage other advanced settings on the board through G-Code instructions, integrating them seamlessly with your 3D printer’s workflow.
To control the output pins on the GPIO board, you can use the following G-Code commands:
M262 P<base 10> B<base 10>
M264 P<base 10> B<0 or 1>
M265 P<base 10>
M267 R<1-3> B<0-255>
To read the state of pins or set up configurations, use the following G-Code commands:
M263 P<base 10>
M261 A<slave device address base 10> B<number of bytes> S<style>
M268 R<base 10>
To configure input pins for your setup, each input pin is automatically mapped to a specific G-code file located on the USB drive. These files must be stored in a folder named "macros" and follow a strict naming convention: the file name must be in the format
btn_{pin_number}.gcode
where {pin_number} corresponds to the specific GPIO pin you are using. All letters in the file names must be lowercase.
The system supports 8 input pins on the GPIO board, and each pin can be mapped to a unique G-code file in this way.
When a G-code file is triggered via its corresponding input pin, the G-code stored in that file is immediately injected into the ongoing process. Please note that there is a size limit for each G-code file, which must not exceed 1024 bytes.
When an input pin is configured using M262 and set to 1 (input mode), the state of the pin is periodically checked every 0.5 seconds.
If a button connected to the pin is pressed (pin state goes LOW), it triggers a macro button. For example, a button on pin 7 can automatically execute a macro stored in the file macros/btn_7.gcode on a USB drive. The macro is injected into the print sequence, with a size limit of 1024 bytes.
Configuration of the pins and their states are stored in EEPROM, ensuring that pin settings (output/input modes, polarity, and states) are preserved even after a power cycle.
Changes made via M262, M264, M267, or any other relevant G-Code will update the EEPROM, so the settings are persistent.
For pins 0-3, which lack internal pull-up resistors, configuring them as input without additional external circuitry may result in an inverted logic state. This can inadvertently trigger macro execution due to their default idle state being LOW (0).
You can invert the logic of input pins using the Polarity Register (M267 R2 B<value>). This feature is particularly useful for pins that do not have pull-up resistors (pins 0-3), which default to an idle state of 0 (LOW) and might trigger unwanted actions when left unconfigured.
The primary difference in behavior between the pins comes from the fact that pins 4-7 can utilize internal pull-up resistors, which hold them at a HIGH state (3.3 V) when not actively driven LOW. However, these pull-up resistors are only active if the corresponding solder jumpers (JP4 to JP7) are connected. If these jumpers are not soldered, pins 4-7 behave similarly to pins 0-3, defaulting to a floating state.
When using input pins to trigger macros, the system is designed to detect a LOW state as indicating a pressed button. For pins without active pull-up resistors, this default LOW state can inadvertently trigger macros unless polarity inversion is used.
When configuring or writing to pins, the system outputs a warning via the serial port if there is a mismatch between the intended operation (e.g., trying to write to an input pin). It is essential to correctly configure pins using M262 to avoid such conflicts.
Insert the code in the exact spots where it is needed, after/before another particular G-Code command. In the example screenshot, the custom G-Code that controls the GPIO board is set through PrusaSlicer and is positioned after each layer change. However, it can be positioned at any point.
In the image attached below, we can see the connection between the GPIO module and the addon controller responsible for controlling the Original Prusa Enclosure's fan filter and LED.
If you have a question about something that isn't covered here, check out our additional resources.
And if that doesn't do the trick, you can send an inquiry to [email protected] or through the button below.