Making a smart enclosure for the Original Prusa MK4

published Feb 04, 2024, last modified Feb 17, 2024

Electronics, ESPHome, and Home Assistant to the rescue.

Making a smart enclosure for the Original Prusa MK4

Note to the reader: this project is as of now still unfinished and awaiting new parts.  Do not attempt to replicate what is shown here yet.  This warning will be removed once the instructions are complete.

I recently acquired a very nice Original Prusa MK4 with its enclosure (which was quite the labor to put together!).

Prusa MK4 printers are fully compatible with Home Assistant — they have their own built-in integration that allows limited control of prints, and lets the user see the status + a preview of the printout.  On that basis, I've already made a dashboard for myself, so I can monitor printing time and state.

Since I'll be printing filaments that emit styrene and other noxious gases, in addition to the enclosure I also ordered the advanced filtration system (and its requisite base board + power supply).  The base board and supply can also power and control an LED strip (24 volts), and the board includes a two-push-button front panel to turn the light and the fan on and off (not depicted here).

While my LED strip is still not here, I could still have put all of this together, and be ready to print noxious filaments.  However, as you can see, I haven't yet put together the advanced filtration system.  Why?

What does "a smart enclosure" mean?

To me, it means:

  • Things that need to happen must be automatic:
    • I shouldn't have to push a button to run the fan.  If the filament I've set the machine to print with is not one of the known non-toxic filaments, the fan shouldn't run needlessly.
    • However, in any other case, the fan should run for the entire duration of the print, and keep going 15 minutes after the printer.
    • Then, the fan should be quiet.
  • Functionally and aesthetically, it should remain "stock":
    • "Digital buttons" notwithstanding, the push buttons on the base board (which attaches to the front panel) should operate correctly, allowing me to manually start and stop both enclosure light and filtration fan as I please.
    • Aesthetically, it should look as close to an unmodified Original Prusa enclosure plus the add-ons Prusa Research sells.
  • Stretch goal: video dashboard!
    • There should be a camera (ideally a device like an ESP32-CAM) filming, that allows me to view what's going on through my Home Assistant office dashboard.
    • When the camera is filming, the enclosure light should automatically come on.  This should be pretty easy to accomplish with Home Assistant, since an automation can turn the light on when the camera begins streaming, and the light can then be turned off when streaming stops.

The technical parts can be done with an ESPHome-programmed ESP32 device.  The aesthetic and functional parts can be done with a little care.

This post explores doing exactly that.

The basics

I need a circuit that does all of the above.  For that circuit to become real, there are a few items I need to add to my shopping list:

First, I'll need an ESP32.  ESP32s are microcontrollers from Espressif that (1) are very cheap (2) are very versatile (3) consume very little power (4) feature a lot of options for input and output, from GPIO through Bluetooth to Wi-Fi.


FIXME: put final device here (after testing ESP CAM cameras) and insert picture.

I'll need two relays.  Think of a relay as a programmable switch: it is an electronic part that receives a low voltage through an input (supplied by the ESP32) and connects a circuit that lets a high voltage pass through.   This is necessary because both the filtration fan and the LED strip require 24 volts and watts of power (supplied by the power adapter Prusa ships), but the ESP32 device "speaks in 3.3 volts" and can only safely do 20 milliwatts (before giving up the magic smoke).  Here's the relay I will be using:

I'll also need a step-down DC-DC converter, to take the 24 volts of the power supply and convert them into 3.3 volts that the ESP32 device needs.

I will need a perfboard (perforated board).  I won't be printing the circuit out on a PCB or use surface-mount components either, but I can't put a breadboard in the enclosure and expect that to be reliable or aesthetic, so I'll use a perfboard instead.  I'll mount the relays, the ESP32 device,the power converter, pin headers and other needed components onto the perfboard.

Some wiring will be necessary as well.  I'll hook up the Prusa base board — which I'll reuse for its push buttons — by placing a JST header on the perfboard, and soldering to the Prusa base board a matching JST cable, both 2.54mm (XH) with 4 pins (two per button).  FIXME: discuss wiring specs for high-power components.

I'll need lighting.  To that effect, I bought a 5 meter LED strip that works with 24 volts DC.  This wll work perfectly with the power supply sent by Prusa Research.  I will not be using the entire roll!  Rather, I'll cut as much of the power strip I think it's necessary to illuminate the enclosure well for the camera to work at night, and then .  For the record, at 24 volts supplied, the roll consumes about 2 amperes — this plus fan would overwhelm the power supply that came with the base board.

From the base board, I will cannibalize the 2 amp fuse and the barrel plug.  I will reuse the 2 amp fuse since it's important for safety, and the barrel plug to connect the power supply to the circuit — this avoids having to strip or solder the power supply's output wiring.

I'll use ESPHome.  ESPHome is software that makes it extremely easy to program these ESP32 devices; instead of having to hand-roll C++, all I have to do is put together a YAML file (which I'll supply below) and this puts together the totality of the functionality we need from the circuit, straight into autogenerated software.

Step 1: test the buttons

Long story short: if I'm going to govern the filtration fan and the LED strip using both Home Assistant and the front panel, I need to know that:

  • the ESP32 has a switch for the fan, and another switch for the LED strip (accomplished by GPIO outputs)
  • each one of these switches (outputs) can provide 3.3 volts when switched on
  • each button on the basic board corresponds to a switch (accomplished by GPIO inputs)
  • pushing a button toggles its respective switch (therefore each rise of a GPIO input toggles its respective GPIO output on and off)

The best way to see this at work is to assemble an initial prototype using a breadboard.  This prototype contains the bare basics to:

  • Test ESPHome with an ESP32 device; I had an XTVTX device I was happy to use in order to test this.
  • Test the buttons on the Prusa base board.
  • Test that the24 volt supply and step-down DC-DC converter operate correctly.

One small problem: I don't yet have the relays I ordered.  So, as stand-ins for the relays I ordered but don't yet have, I used some old school LEDs (with resistors to prevent ESP voltage from frying them).

I put together the circuit, then flashed the programming code once via USB.  Once flashed, I first disconnected the USB cable and then powered the circuit using a 24 volt DC supply.  When the XTVTX was running and online on my Wi-Fi network, I added it to Home Assistant the usual way (that is, via autodiscovery on Home Assistant's Devices & Services screen).

Use the following tabs to see how the prototype looks, how it was put together, and how it was programmed:

Component hookup

Here's how it's all hooked up:

  • 24 volts to the top positive rail, ground to the negative rail.
  • Top positive rail to the positive input of the DC-DC converter, top negative rail to its negative input.
  • Negative output of DC-DC converter to bottom negative rail, positive output to bottom positive rail.
  • 3V3 and GND on ESP32 to bottom rails (positive and negative, respectively).
  • Cathodes (short legs) of LEDs to bottom negative rail, anodes of LEDs to a 100 ohm resistor each.
  • Other side of each resistor to GPIO output (I chose D24 and D25).
  • GPIO inputs D33 and D32 to one side of each push button each.
  • Bottom negative rail to other side of each push button.

Visual layout

  Here's the test circuit, divided into two photos:

ESPHome source code

And here is the source code for the ESP's programming, which you can copy and paste into your ESPHome editor:

substitutions:
name: button-tester
friendly_name: Button tester

esphome:
  name: ${name}
  friendly_name: ${friendly_name}
  name_add_mac_suffix: false

esp32:
  # XTVTX ESP32 (wroom)
  board: nodemcu-32s
  framework:
    type: arduino

# Enable logging
logger:
  level: debug

# Enable Web.
# Turn me off and enable below.
web_server:
  port: 80
  include_internal: true
  local: true

# Enable Home Assistant API
api:
  encryption:
  key: "<use a key generated by ESPHome>"

ota:
password: "<use an OTA password generated by ESPHome>"

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

button:
  - platform: restart
    name: Restart
    entity_category: diagnostic
    icon: mdi:restart
  - platform: safe_mode
    name: Safe mode restart
    entity_category: diagnostic
    icon: mdi:restart-alert

sensor:
- platform: wifi_signal
  name: "Wi-Fi signal strength"
  update_interval: 10s
  entity_category: "diagnostic"
- platform: internal_temperature
  name: "Device temperature"
  update_interval: 10s
  entity_category: "diagnostic"

binary_sensor:
  - platform: gpio
    icon: mdi:button-pointer
    internal: true
    pin:
      number: GPIO33
      mode:
        input: true
        pulldown: true
    name: "Camera light switch"
    on_press:
      then:
        - light.toggle: camera_light
  - platform: gpio
    icon: mdi:button-pointer
    internal: true
    pin:
      number: GPIO32
      mode:
        input: true
        pulldown: true
    name: "Advanced filtration system switch"
    on_press:
      then:
        - fan.toggle: advanced_filtration_system

output:
  - platform: gpio
    pin: GPIO26
    id: "out_1"
  - platform: gpio
    pin: GPIO25
    id: "out_2"

light:
  - platform: binary
    name: Camera light
    id: camera_light
    output: out_1
    icon: mdi:led-strip-variant

fan:
  - platform: binary
    name: Advanced filtration system
    id: advanced_filtration_system
    output: out_2
    icon: mdi:air-filter

My prototype was indeed successful — activating and deactivating the "light" and the "fan" via Home Assistant worked,  and pushing the buttons on the base board toggled "light" and "fan" respectively.

The story is not over yet!

Sadly, I'm missing a few components to make the circuit fully functional.  But don't worry!  Stay tuned to this very blog post for updates as parts arrive and the final circuit comes together.