Today I’m going to be showing you how to make your own desktop case for a Raspberry Pi 4, which looks like a mini desktop pc.

Raspberry Pi 4 Desktop Case Computer
Raspberry Pi 4 Desktop Case Computer

The body of the case is 3D printed and it has clear acrylic sides so that you’re able to see into it. I’ve used an Ice Tower to cool the CPU, but have mounted the fan onto the side of the case rather than on the heatsink.

OLED Stats Display For Raspberry Pi 4

I’ve also included an OLED display on the front of the case which displays the Pi’s IP address and some stats like the CPU, storage and memory usage, and the CPU temperature.

Here’s a video of the build and the case and display in operation:

What You Need To Make Your Own Raspberry Pi 4 Desktop Case

Raspberry Pi 4 Desktop Case Oled Display Ice Tower

In addition to the above, you’ll also need to have access to a 3D printer to print the plastic portion of the case.

I use the Creality Ender 3 Pro which I’ve found to produce great quality prints and is quite affordable.

3D Printer – Creality Ender 3 Pro – Buy Here

You don’t need a laser cutter for this build, although it does help significantly with making the sides. You can also use an online laser cutting service or simply cut your own sides using hand tools. I’ve used a Desktop K40 laser cutter/engraver.

Laser Cutter – K40 – Buy Here

Note: The above parts are affiliate links. By purchasing products through the above links, you’ll be supporting this channel, with no additional cost to you.

Making The Raspberry Pi 4 Desktop Case

3D Printing The Body

I started out by designing the 3D printed body of the case in Tinkercad.

Designing The Case In Tinkercad

I drew a rough outline of the case and then positioned the Raspberry Pi within the case so that the USB and Ethernet ports are available through the front and the Power, HDMI, and audio ports are accessed through the side panel.

The OLED display is positioned on the front of the case above the ports. The OLED display will be held in place with two small clips on the top edge and a screw with a plastic clip at the bottom, a design which I’ve used before on my Arduino based reaction timer.

Designing The Case Mounting Footprint

The Pi is going to be mounted onto the brass standoffs which came with the Ice Tower, so I added some holes to accommodate the M2.5 threads.

I don’t remove the SD card on the back of the Pi very often, so I didn’t add a cut-out for it. If you do, then just add a circular cut-out to the case at the back so that you can still access it. It is going to be a bit of a chore to swap the SD card if you don’t have this cut-out as you’ll need to remove the Pi from the case to access it, I’m happy with doing this if I ever need to change the card.

3D Printing The Case Housing

I 3D printed the Raspberry Pi 4 Desktop Case using Black PLA with a 0.2mm layer height and 15% infill. I also added print supports for the cutouts for the display and ports on the front. You’ll probably need to add these as well, which is easy to do in your slicing software. You’ll also need to print the small plastic display clamp.

3D Printed Components

Install The Raspberry Pi & Ice Tower

Now that the main body of the case is complete, let’s mount the Raspberry Pi into it. Start by screwing the brass standoffs into the holes in the base.

Standoffs Mounted Into The Case

I’ve just changed the orientation of the screws and standoff mounts supplied with the Ice Tower so that they screw straight into the bottom of the case and don’t require and through holes. If you follow the Ice Tower installation manual, you’ll notice that the standoffs and screws are installed the opposite way around.

Remove The Fan From The Ice Tower

Next, we need to remove the fan from the Ice Tower so that we can attach it to the acrylic side panel. By moving the fan onto the side panel, we make sure that cool air is being drawn in from the outside of the case and then has to leave from the exhaust air vents on the opposite side.

Mount The Ice Tower Legs

Add the support brackets to the bottom of the Ice Tower heatsink as per the instructions. Make sure that you follow the correct orientation of these.

Secure The Pi With The Second Set Of Brass Standoffs

Place the Raspberry Pi into position and then use the second set of brass standoffs, screwed into the bottom set, to secure it.

Install The Ice Tower

Stick the heat sink pad onto the Pi’s CPU and peel off the top layer of protective film. Position the Ice Tower heat sink onto the heat pad on the CPU and then secure it with the four screws into the brass standoffs.

Install The OLED Display

Now we need to install the OLED display onto the front panel. If your display came without the pins soldered into place, solder them onto the back of the display.

Install The OLED Display

Slide the top edge of the display in under the plastic clips and then gently push it down into position in the cut-out.

Secure The OLED Display Clip

Use the 3d printed clamp to hold it in place with a small screw. You might need a flexible shaft or 90-degree screwdriver to tighten the screw.

Make Up The OLED Display Ribbon Cable Connector

Now we need to prepare the wiring to the OLED display. You’ll need to make 4 connections to your GPIO pins, two for power and two for communication. I made up this short connector cable using some DuPont connectors and some ribbon cable. You can also use some female pin header strips or female breadboard jumpers to connect the display to the Pi.

Plug In The Ribbon Cable Connector

Once your cable is made up, connect it to the back side of the display and then plug the leads into the GPIO pins as follows:

  • VCC to Pin1 3.3V Power
  • GND to Pin14 Ground
  • SCL to Pin3 SCL
  • SDA to Pin2 SDA
GPIO-Pinout-Diagram-2

I’ve noticed that there are two versions of these OLED displays available and they have the power pins the opposite way around, one version has VCC and then GND and one GND and then VCC, so just make sure that you’re connecting power the correct way around for your display.

Make The Acrylic Sides

The internal parts of the case are now mostly done, so let’s make up the acrylic sides to close it up.

Export Side Profile Of Case To Make Acrylic Sides

I started in Tinkercad again and positioned a block in the case roughly where the Ice Tower heat sink is going to be so that the holes for the fan are in the correct place on the side panels. I then exported the side profile of the case and heat sink to open up in Inkscape to draw the laser cutting profile.

We need two sides, one with the fan for the inlet and one with some holes in it for the exhaust air.

Drawing The Acrylic Sides In Inkscape

We can remove the inside edge profile as we only need the outline of the case and the screw holes. We need to add a hole for the fan and the four surrounding holes for the fan screws. We’ll also need to add cut-outs for the ports along the side of the Raspberry Pi.

Making The Hexagon Pattern For The Exhaust Air

Next, I created a mirror of the fan side to the exhaust side and drew a hexagon pattern for the exhaust airflow.

Completed Side Panels

If you’re not going to be laser cutting the sides and you’re cutting them out by hand, then replace these hexagon holes with circular drilled holes (Ø8mm) in the same area.

Laser Cutting The Side Profiles

Now let’s get the sides cut out. I used 2mm clear acrylic for the side panels.

Side Sheets Ready To Be Installed

You can use a colour tinted or opaque acrylic as well if you’d like. A lot of the coloured sheets are only available in 3mm. This won’t really matter, you’ll just have thicker edges.

Screw Fan Onto Side Panel

To mount the fan onto the side panel, you’ll need to press some M3 nuts into the pockets by the screw holes. It’s easiest to place the nut on a flat surface and then press the fan hole over the nut to push it into place. These are tight so that you don’t need to use a spanner to hold them when you tighten the screws.

If you want to re-use the fan screws, they’ll be too short to fit through the acrylic and fan and then into the nuts, you’ll need to press the nuts into the front (acrylic side) of the fan. This isn’t really the best way to attach the fan as you’re not really clamping anything. You’re relying on the friction between the nut and the fan to hold it in place, but it works fine in this case.

Screw Fan Side Panel Onto Case

Screw the fan side panel onto the 3D printed case using four M3 x 8mm hex head machine screws.

Pi 4 Desktop Case - Fan Side Panel In Place

The screws should be a bit tight as the inside of the holes isn’t threaded.

Attach Fan Power

Now plug the fan into the 5V supply on the Pi and then install the other side panel. The red wire to Pin 4 (5V) and the black wire to Pin 6 (Ground).

Pi 4 Desktop Case - Screw On Exhaust Air Side

That’s it for the assembly, the Raspberry Pi 4 Desktop Case is now complete. We just need to get the OLED display working.

Programming The OLED Display

To get the display working, we need to run a Python script. You’ll need to boot your Pi up to do this.

The Raspberry Pi communicates with the display using I2C communication, so you’ll also need to make sure that this is enabled in your preferences. You’ll also need to ensure that the python-smbus and i2c-tools libraries are both installed. They should be by default, but it’s worth checking.

This script is mostly based on one of the example scripts in the Adafruit Python Library for OLED display modules, with a few changes by Shakhizat Nurgaliyev to add the CPU temperature and change the format of the display.

# Copyright (c) 2017 Adafruit Industries
# Author: Tony DiCola & James DeVito
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
import time

import Adafruit_GPIO.SPI as SPI
import Adafruit_SSD1306

from PIL import Image
from PIL import ImageDraw
from PIL import ImageFont

import subprocess

# Raspberry Pi pin configuration:
RST = None     # on the PiOLED this pin isnt used
# Note the following are only used with SPI:
DC = 23
SPI_PORT = 0
SPI_DEVICE = 0

# Beaglebone Black pin configuration:
# RST = 'P9_12'
# Note the following are only used with SPI:
# DC = 'P9_15'
# SPI_PORT = 1
# SPI_DEVICE = 0

# 128x32 display with hardware I2C:
disp = Adafruit_SSD1306.SSD1306_128_32(rst=RST)

# 128x64 display with hardware I2C:
# disp = Adafruit_SSD1306.SSD1306_128_64(rst=RST)

# Note you can change the I2C address by passing an i2c_address parameter like:
# disp = Adafruit_SSD1306.SSD1306_128_64(rst=RST, i2c_address=0x3C)

# Alternatively you can specify an explicit I2C bus number, for example
# with the 128x32 display you would use:
# disp = Adafruit_SSD1306.SSD1306_128_32(rst=RST, i2c_bus=2)

# 128x32 display with hardware SPI:
# disp = Adafruit_SSD1306.SSD1306_128_32(rst=RST, dc=DC, spi=SPI.SpiDev(SPI_PORT, SPI_DEVICE, max_speed_hz=8000000))

# 128x64 display with hardware SPI:
# disp = Adafruit_SSD1306.SSD1306_128_64(rst=RST, dc=DC, spi=SPI.SpiDev(SPI_PORT, SPI_DEVICE, max_speed_hz=8000000))

# Alternatively you can specify a software SPI implementation by providing
# digital GPIO pin numbers for all the required display pins.  For example
# on a Raspberry Pi with the 128x32 display you might use:
# disp = Adafruit_SSD1306.SSD1306_128_32(rst=RST, dc=DC, sclk=18, din=25, cs=22)

# Initialize library.
disp.begin()

# Clear display.
disp.clear()
disp.display()

# Create blank image for drawing.
# Make sure to create image with mode '1' for 1-bit color.
width = disp.width
height = disp.height
image = Image.new('1', (width, height))

# Get drawing object to draw on image.
draw = ImageDraw.Draw(image)

# Draw a black filled box to clear the image.
draw.rectangle((0,0,width,height), outline=0, fill=0)

# Draw some shapes.
# First define some constants to allow easy resizing of shapes.
padding = -2
top = padding
bottom = height-padding
# Move left to right keeping track of the current x position for drawing shapes.
x = 0


# Load default font.
font = ImageFont.load_default()

# Alternatively load a TTF font.  Make sure the .ttf font file is in the same directory as the python script!
# Some other nice fonts to try: http://www.dafont.com/bitmap.php
# font = ImageFont.truetype('Minecraftia.ttf', 8)

while True:

    # Draw a black filled box to clear the image.
    draw.rectangle((0,0,width,height), outline=0, fill=0)

    # Shell scripts for system monitoring from here : https://unix.stackexchange.com/questions/119126/command-to-display-memory-usage-disk-usage-and-cpu-load
    cmd = "hostname -I |cut -f 2 -d ' '"
    IP = subprocess.check_output(cmd, shell = True )
    cmd = "top -bn1 | grep load | awk '{printf \"CPU Load: %.2f\", $(NF-2)}'"
    CPU = subprocess.check_output(cmd, shell = True )
    cmd = "free -m | awk 'NR==2{printf \"Mem: %s/%sMB %.2f%%\", $3,$2,$3*100/$2 }'"
    MemUsage = subprocess.check_output(cmd, shell = True )
    cmd = "df -h | awk '$NF==\"/\"{printf \"Disk: %d/%dGB %s\", $3,$2,$5}'"
    Disk = subprocess.check_output(cmd, shell = True )
    cmd = "vcgencmd measure_temp |cut -f 2 -d '='"
    temp = subprocess.check_output(cmd, shell = True )

    # Write two lines of text.

    draw.text((x, top), "IP: " + str(IP,'utf-8'), font=font, fill=255)
    draw.text((x, top+8), str(CPU,'utf-8') + " " + str(temp,'utf-8') , font=font, fill=255)
    draw.text((x, top+16), str(MemUsage,'utf-8'), font=font, fill=255)
    draw.text((x, top+25), str(Disk,'utf-8'), font=font, fill=255)

    # Display image.
    disp.image(image)
    disp.display()
    time.sleep(.1)

You’ll need to download the original Adafruit example library from Github to get the setup complete by following these steps.

Open a new terminal window, then navigate to the library’s directory:

cd Adafruit_Python_SSD1306

Install the library for Python 3:

sudo python3 setup.py install

You can then run the above stats.py file or the example stats.py file in the Adafruit directory, you’ll just get a slightly different display layout with the Adafruit example.

Change to the directory containing the stats.py script:

cd examples

Execute the script:

python3 stats.py

You can test run the script to check that your display is working correctly and you don’t get any errors before setting it to run automatically.

To set the script to run automatically, you’ll need to find the script’s directory, then open crontab and add a line to run the script:

@reboot python3 /home/pi/stats.py &

You’ll obviously need to change the directory /home/pi/ to reflect the directory where you have your script saved.

Don’t forget to add the & at the end, this tells the Pi to continue starting up and run the script in the background.

Raspberry Pi 4 Desktop Case Display Showing stats

Reboot the Pi to automatically run the script and you should then see the stats shown on the OLED display when it starts up.

Raspberry Pi 4 Desktop Case Lights
Raspberry Pi 4 Desktop Case With LED Lighting
Pi 4 Desktop Case With LEDs

Let me know if you like this Raspberry Pi 4 Desktop Case or what you’d do differently in the comments section.

Share This Guide

3D Printed Raspberry Pi 4 Desktop Case Pinterest

47 Replies to “DIY Raspberry Pi 4 Desktop Case With OLED Stats Display”

    1. It’s the other way around, the 3D print files are .stl 3d models and the laser cutting files are .svg 2d path files.

    1. I am working on a manufactured version at the moment, there are a couple of minor changes that need to be made to suit the moulding.

      1. Will this be a kit and/or just a finished product? Both are of interest but kit would be really fun to do with my kid! Beautiful job!

        1. It would be a kit to some degree, most cases are. You would still need to assemble the ice tower, mount the OLED display, mount the Pi and then close up the case.

          1. Not with this design, but I’m looking at how to integrate an SSD into a future case. It’s the cable to the USB port that is the problem.

  1. Great job nice project must try this out myself for sure.

    2 things I would like to ask @Michael
    Laser cut link is broke amazon has error can you fix link

    Can you compile all this into a downloadable zip file /pdf guide for us that would be awesome

    Thanks again

    1. Thanks JE, I’ve added an alternative. Unfortunately the suppliers of these usually only keep a few in stock and the product page gets pulled when they run out.

      1. Can you please add a link to the screws and brass stand offs you use for the holes you designed to mount pie? Thanks so much

        1. Hi Brandon, I used the screws and brass standoffs supplied with the Ice Tower, that’s why I haven’t listed them separately. They’re M2.5 screws and 6mm brass standoffs.

  2. Thanks Michael for your reply. Also I was wondering do you sell this item ? I’m going to try to do it all on my own but just in case it doesn’t work out I’m curious what you would charge to make it all ?

    1. Hi Brandon, I’m busy looking at some manufacturing options for the case. Commercial 3D printing is still quite expensive and these take way too long to print on a home 3D printer.

  3. Hi Michael,
    Very nice job! I was wondering how hard it would be to rotate the board so that it can have a cleaner look on the front (just the OLED) and the USB/LAN ports on the back?

    Again, congrats on the great looking case!

    1. That should be difficult, the case is symmetrical, so the easiest would be to just move the display cutout to the back and make the back the front (turn it around).

      Thank you!

  4. What are the measurements for the acrylic parts and the 3d printed case, as I’m ordering them to be laser cut online and they require measurements.

  5. Michael,

    I tried to print this 3d case file tonight and ran into some issues. At 84% the print started print mid air on to nothing and so I was wondering if you have any reasons why I might have had problems with the stl. I’m printing on an ender 5 plus. The file came erected and in your video you show it laying sideways. I’m also wondering if you used supports. Could you possibly send me the profile of your cura print setup? Thanks for all your help on getting me across the finish line on this project.

    1. Hi Brandon,
      Yes, the intention is to print the case on its side, not upright. I’d assume that it most likely failed because there were no supports for the top flat section (if you printed it upright), so the top just spaghetti’s until the printer thinks it’s done. The printer settings in Cura should align with your particular setup, so I’m not sure that sending you the print file would work successfully either.
      If it helps, used Creality Slicer, I turned the case onto its side (the 100mm x 100mm side profile laying flat on the bed) and then used the following settings – 0.2mm layer height, 0.8mm shell thickness, 15% infill, 15mm/s print speed, 210C print temp, 50C bed temp, support type – everywhere, platform adhesion type – none. I’m also using a 0.4mm nozzle and 1.75mm PLA filament.

  6. Thanks again Michael the print turned out great. I’m on my 2nd one now it’s about an 8 1/2 hour print just so everyone else that is interested knows. Also it seems a lot of places that offer cut services for acrylic don’t have 2mm so I seen you said 3mm is fine do I need different screws?

    1. That’s great! Yes, mine took around 8 hours to print as well.
      3mm Acrylic is fine and you won’t need longer screws. M3 x 8mm screws will still give you around 4-5mm screwed into the case to secure the covers.

    2. I printed on a Prusa Mk3 using the PrusaSlicer without supports with the Bottom flat against the print bed and had a half dozen flying strands under the narrow ledge. I used PETG and had a nice finish on the back and front using Hilbert fill pattern top and bottom.
      I am struggling with the software as the Adafruit_GPIO package is not working for me on the RPi4 using the Raspberry OS. Any suggestions?

  7. Michael,
    Thanks for your patience with my questions. Are there any special print instructions for the oled bracket before I attempt to print it?

    1. No problem at all. The clip is pretty small and straight forward, just print it with the largest flat side on the bottom and print it solid (100% infill).

  8. I’ll provide my feedback once I get to that point I just ordered all the extra pieces now that I got the case printed.

  9. The Adafruit library you link to is deprecated, and following your directions (both above and here in the comments results in “ModuleNotFoundError: No module named ‘Adafruit_BBIO'”

    Suggestions?

      1. That got it working somewhat.

        I see stuff on the display but the first two lines are blank, and the bottom two start with b’.

        b’Mem: [data]
        b’Disk: [data]

        Also, the memory data runs off the right-hand side of the display.

  10. Pretty cool little project. I was able to get the display up and running but have two issues I am trying to resolve. 1. I cannot get it to run the script automatically and after I changed the stats.py script it no longer displays the IP address. It has a line for it but the space is blank. Once I figure those issues out I think I will add these displays to my other PI’s.

    1. I was able to resolve the missing IP address by eliminating this portion of the listed changes:

      cmd = “hostname -I | cut -d\’ \’ -f1”
      will be replaced by the following line:
      cmd = “hostname -I |cut -f 2 -d ‘ ‘”

      All of the other modifications were done and I got the perfect display. now to get ot to load on startup…

      1. Hi Matthew,
        Thanks for the update. I’ll have a look at this again, I had to edit that same line (to what you had originally) to get mine to display the IP address otherwise mine was blank.
        Have you managed to get the display to load on startup? Remember to add the #!/usr/bin/python3 line to the beginning of your Python script, it may need to be changed depending on what you’re running it in.

        1. I kind of gave up on it last night and have not started back yet. This is my first time building a system and running anything other than octoprint on a pi for my 3d printers. No coding experience or anything. Planned for this to be a little machine to teach myself some of this other world. All I have done so far is install the Raspberry pi OS and follow your guide. I will probably dive back into it tonight and see what I can figure out.

Leave a Reply

Your email address will not be published.