DR-0001

From 52Pi Wiki
Jump to navigation Jump to search

1U Rackmount for Raspberry Pi 5/4B

DR-0001-1.jpg

Description

This is an upgraded version of a 1U Rackmount designed for compatibility with both Raspberry Pi 5 and Raspberry Pi 4B. It features a motherboard that supports PCIe expansion, allowing the PCIe interface of the Raspberry Pi 5 to be extended to accommodate an M.2 NVMe SSD in 2230/2242/2260/2280 form factors. The expansion board also routes the Raspberry Pi's 5V and GND, SDA, and SCL pins to the rear through PogoPin connectors, providing I2C interface peripherals in a Grove format. Additionally, a red LED is included on the board for the Raspberry Pi ID signal pin, which can be programmed to indicate the current device by controlling the GPIO4 pin's high or low level, acting as a programmable device ID signal light.

The Rackmount supports the connection of up to five Raspberry Pi devices and can also be configured with an OLED display frame in place of one of the Raspberry Pi slots. These components can be easily adjusted and removed due to the use of hand-tightened screws. The OLED display features a 0.91-inch screen and communicates with the Raspberry Pi via I2C protocol, displaying real-time information such as CPU status, memory status, IP information, and serial numbers. The content displayed on the OLED can be fully customized.

Features

  • Compatibility: Designed to work with both Raspberry Pi 5 and Raspberry Pi 4B models.
  • PCIe Expansion Support: Includes a motherboard that enables PCIe expansion, allowing the connection of M.2 NVMe SSDs in various form factors (2230/2242/2260/2280).
  • I2C Interface: The board routes the Raspberry Pi's 5V, GND, SDA, and SCL pins to the rear through PogoPin connectors, offering I2C interface peripherals in a Grove format.
  • Programmable LED Indicator: A red LED on the board serves as a programmable device ID signal, controllable via the GPIO4 pin to indicate the status or identity of the device.
  • Modular Design: Supports the integration of up to five Raspberry Pi devices, with the option to replace one slot with an OLED display frame.
  • OLED Display Integration: The option to include a 0.91-inch OLED screen that communicates with the Raspberry Pi via I2C, displaying customizable information such as CPU usage, memory status, IP address, and serial numbers.
  • Easy Assembly and Disassembly: Components are secured with hand-tightened screws, allowing for convenient adjustments and removal.
  • Customizable Display Content: The information displayed on the OLED screen can be fully customized to meet specific needs or preferences.
  • Rackmount Form Factor: Designed to fit into a 1U rack space, making it suitable for data centers or other environments where space is at a premium.
  • Versatility: The Rackmount can be configured in various ways to suit different use cases, whether for development, testing, or deployment in a production environment.

Specifications

  • Form Factor: 1U Rackmount design suitable for standard 19-inch racks.
  • Raspberry Pi Compatibility: Specifically designed for Raspberry Pi 5 and Raspberry Pi 4B models.
  • PCIe Expansion:Supports M.2 NVMe SSDs in 2230, 2242, 2260, and 2280 form factors. Provides a PCIe interface for high-speed data transfer.
  • I/O Connectivity: Rear I2C interface via PogoPin connectors for external peripherals.
  • GPIO4 pin for programmable LED control.
  • LED Indicator:Red LED for device identification or status indication. Programmable through software to show different statuses.
  • Modular Bays: Five bays for Raspberry Pi devices. One bay can be replaced with an OLED display module.
  • OLED Display Specifications:0.91-inch screen size, 128x32 pixels. I2C communication protocol.
  • Customizable display for system information.
  • Physical Security:Hand-tightened screws for secure mounting of Raspberry Pi devices and OLED display.
  • Ensures stability and ease of maintenance.
  • Power Requirements: Compatibility with Raspberry Pi's standard power supply.
  • Material and Construction: Durable metal construction for the rackmount chassis. High-quality components for reliable performance.
  • Mounting Options: Standard rackmount holes for easy installation into a rack.
  • Includes additional mounting accessories for different setups.
  • Software Compatibility: Compatible with Raspberry Pi's operating system and software ecosystem.
  • Support for GPIO programming for custom LED and device control.

Gallery

  • Product outlook
DR-0001-6.jpg


  • Application Senario
DR-0001-2.jpg


NOTE: Raspberry Pis are not included in the package, additional purchase required!

  • Easy to assemble and maintain
DR-0001-3.jpg


DR-0001-12.jpg


  • Customizable OLED display screen, with a size of 0.91 inches
DR-0001-4.jpg


  • Ports Definitions and Featrues

Programmable I/O controlled UID indicator light, which can be programmed to control the LED blinking to indicate the device's location, facilitating faster troubleshooting and easier maintenance operations.

DR-0001-5.jpg


How to connect OLED display to Raspberry Pi on GPIO pins

  • Please refer to following figure to connect OLED display to Raspberry Pi on GPIO.

NOTE: OLED's VCC should be connected to 3.3V power rail, Do not connect it to 5V power rail!!!

DR-0001-7.jpg


  • Grove Connector Support I2C and Uart
DR-0001-8.jpg


  • Accessories Dimension
DR-0001-9.jpg


  • OLED assemble details

Please remove the protection film from acrylic panel and use the washer between OLED PCB board and acrylic panel.

DR-0001-10.jpg


  • PCIe Expansion board for Raspberry Pi 5 only

The expansion board supports M.2 NVMe M-key SSD 2230/2242/2260/2280, and the board will be powered by Raspberry Pi 5 via PogoPin on the PCB board, please make sure the board's pogoins are contact well with the soldering point on back of the Raspberry Pi 5 on GPIO pins.

DR-0001-11.jpg


  • Compatibility

NOTE: please note that Raspberry Pi 4B has no PCIe slot, so if you connected the PCIe expansion board to Raspberry Pi 4B, only Grove I2C and UART, UID LED indicator and OLED display are available, the M.2 NVMe SSD Sock will not work properly!!!

DR-0001-13.jpg


How to assemble it?

  • Please note that there are several details you need to pay attention, plesae check out following figure.
DR-0001-安装.jpg


Package Includes

  • Following figure shows the details of the product:
DR-0001-清单.jpg


How to enable I2C OLED display?

  • We assume that you are using Raspberry Pi OS 64bit(bookworm, the latest official image)

To enable I2C and UART on your Raspberry Pi, you can follow these detailed steps:

Enabling I2C

  • Method 1. Using the Raspberry Pi Configuration Tool:
 
sudo raspi-config

to open the configuration tool. Navigate to `Interface Options`, Select `I2C` and enable it.

  • Method 2. Using the Command Line:

You can also enable I2C by editing the `/boot/firmware/config.txt` file and adding `dtparam=i2c_arm=on` if it's not already present, After making changes, reboot your Pi.

Verifying I2C

  • Install I2C tools using `sudo apt-get install -y i2c-tools`.
  • Use
i2cdetect -y 1

to scan for I2C devices, if you see `3c` means that the OLED display has been recognized by your Raspberry Pi.

Enabling UART

  • Method 1. Using the Raspberry Pi Configuration Tool:
sudo raspi-config

Go to `Interface Options`, Select `Serial` and enable it.

 Note: This will also enable the login shell on the serial port. 
  • Method 2. Using the Command Line:

Edit `/boot/config.txt` and add `enable_uart=1`, save it and then reboot your Pi.

Accessing UART

  • Connect your Pi to a USB-to-TTL converter, On Windows, you may need to install drivers for the converter. on Linux just use a terminal program like `minicom`, `putty`, or `screen` to access the UART interface.

Remember to check the documentation for your specific Raspberry Pi model, as the steps might vary slightly. If you need more detailed instructions or encounter any issues, refer to the [ https://www.raspberrypi.org/documentation/ ] or community forums for additional support.

How to display customized information on OLED display?

  • Final result
DR-0001 applications-01.jpg


How to customize content on OLED ?

  • For example: If you want to display current IP address of wlan interface and the serial number of your Raspberry Pi 5, please follow next steps to configure it.

Install Virtal environment package

  • Open a terminal and typing following commands:
 
sudo apt update 
sudo apt upgrade -y 
sudo apt -y install virtualenv 
sudo usermod -a -G i2c,spi,gpio pi
sudo apt install python3-dev python3-pip python3-numpy libfreetype6-dev libjpeg-dev build-essential
sudo apt install libsdl2-dev libsdl2-image-dev libsdl2-mixer-dev libsdl2-ttf-dev libportmidi-dev
Install pre-insistpackages.png


Install-pre-insistpackage-02.png


Create virtual environment

virtualenv -p python3 venv 
cd venv/
source bin/activate 

Install SSD1306 driver libarary for OLED 0.91

pip install luma 
pip install luma.core
pip install psutil

Clone luma.examples repository

Log out and in again and clone this repository:

git clone https://github.com/rm-hull/luma.examples.git
cd luma.examples/

Install luma libraries

sudo -H pip install -e . --break-system-packages  
Install luma libraries.png


Test the demo

cd examples/
sudo python 3d_box.py --width=128 --height=32 -r 2 

NOTE:
--width=128 and --height=32 should be added to declear the OLED's resolution information.
-r 2 means --rotate 2 , Allowed values are: 0, 1, 2, 3 (default:0)

If you see a 3D-box rotating animation is in the middle of screen means that you have installed the OLED driver successfully!

Test demo 3dbox.png


Test demo 3dbox-2.png


and then press "Ctrol+C" abort the demo.

Use the demo code

  • There are a lot of demo codes in the examples folder, you can test it as you want.

for example:

sudo python carousel.py --width=128 --height=32 -r 2 

It will display all information of your Raspberry Pi 5 and scrolling display.

Customize the display on screen

Modify the sys_info.py python file and adding your own function to show the information you want, do remember backup the origin file.

cp sys_info.py sys_info.py.bak 
vim.tiny sys_info.py 

Press 'i' to insert mode, and paste following lines into it. you can modify this file by other text editor what you like.

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Copyright (c) 2014-2022 Richard Hull and contributors
# See LICENSE.rst for details.
# PYTHON_ARGCOMPLETE_OK

"""
Display basic system information.

Needs psutil (+ dependencies) installed::

  $ sudo apt-get install python-dev
  $ sudo -H pip install psutil
"""

import os
import sys
import time
from pathlib import Path
from datetime import datetime
import subprocess as sp

if os.name != 'posix':
    sys.exit(f'{os.name} platform is not supported')

from demo_opts import get_device
from luma.core.render import canvas
from PIL import ImageFont

try:
    import psutil
except ImportError:
    print("The psutil library was not found. Run 'sudo -H pip install psutil' to install it.")
    sys.exit()


# TODO: custom font bitmaps for up/down arrows
# TODO: Load histogram


def bytes2human(n):
    """
    >>> bytes2human(10000)
    '9K'
    >>> bytes2human(100001221)
    '95M'
    """
    symbols = ('K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y')
    prefix = {}
    for i, s in enumerate(symbols):
        prefix[s] = 1 << (i + 1) * 10
    for s in reversed(symbols):
        if n >= prefix[s]:
            value = int(float(n) / prefix[s])
            return '%s%s' % (value, s)
    return f"{n}B"


def cpu_usage():
    # load average, uptime
    uptime = datetime.now() - datetime.fromtimestamp(psutil.boot_time())
    #av1, av2, av3 = os.getloadavg()
    #return "Ld:%.1f %.1f %.1f Up: %s" \
    #    % (av1, av2, av3, str(uptime).split('.')[0])
    return "Up: %s" % (str(uptime).split('.')[0])


def mem_usage():
    usage = psutil.virtual_memory()
    return "Mem: %s %.0f%%" \
        % (bytes2human(usage.used), 100 - usage.percent)

def disk_usage(dir):
    usage = psutil.disk_usage(dir)
    return "SD:  %s %.0f%%" \
        % (bytes2human(usage.used), usage.percent)


def network(iface):
    stat = psutil.net_io_counters(pernic=True)[iface]
    return "%s: Tx%s, Rx%s" % \
           (iface, bytes2human(stat.bytes_sent), bytes2human(stat.bytes_recv))

def mem_usage():
    usage = psutil.virtual_memory()
    return "Mem: %s %.0f%%" \
        % (bytes2human(usage.used), 100 - usage.percent)


def disk_usage(dir):
    usage = psutil.disk_usage(dir)
    return "SD:  %s %.0f%%" \
        % (bytes2human(usage.used), usage.percent)


def network(iface):
    stat = psutil.net_io_counters(pernic=True)[iface]
    return "%s: Tx%s, Rx%s" % \
           (iface, bytes2human(stat.bytes_sent), bytes2human(stat.bytes_recv))


def get_ip_address():
    ip = sp.getoutput('hostname -I')
    return "IP: %s" % ip

def get_id():
    id_of_pi = sp.getoutput("cat /proc/cpuinfo | grep -i serial| awk -F: '{print $2}'|xargs")
    return "%s" % id_of_pi


def stats(device):
    # use custom font
    font_path = str(Path(__file__).resolve().parent.joinpath('fonts', 'C&C Red Alert [INET].ttf'))
    #font_path = str(Path(__file__).resolve().parent.joinpath('fonts', 'DejaVuSansMono.ttf'))
    font2 = ImageFont.truetype(font_path, 15)

    with canvas(device) as draw:
        # draw.text((0, 0), cpu_usage(), font=font2, fill="white")
        draw.text((0, 0), get_id(), font=font2, fill="white")
        if device.height >= 32:
            #draw.text((0, 11), mem_usage(), font=font2, fill="white")
            #draw.text((0, 16), disk_usage('/'), font=font2, fill="white")
            draw.text((0, 16), get_ip_address(), font=font2, fill="white")

        if device.height >= 64:
            draw.text((0, 26), disk_usage('/'), font=font2, fill="white")
            try:
                draw.text((0, 38), network('wlan0'), font=font2, fill="white")
            except KeyError:
                # no wifi enabled/available
                pass


def main():
    while True:
        stats(device)
        time.sleep(5)


if __name__ == "__main__":
    try:
        device = get_device()
        main()
    except KeyboardInterrupt:
        pass

Here let me explain to you what i did.

  • adding " import subprocess as sp", this will help me to execute some shell command in OS.
  • adding following parts:
def get_ip_address():
    ip = sp.getoutput('hostname -I')
    return "IP: %s" % ip

def get_id():
    id_of_pi = sp.getoutput("cat /proc/cpuinfo | grep -i serial| awk -F: '{print $2}'|xargs")
    return "%s" % id_of_pi
  • get_ip_address will execute the command "hostname -I" in system and grab the IP address and return it to main process.
  • get_id is to read /proc/cpuinfo file and grab the serial number and return to main process.

Use custom font

   font_path = str(Path(__file__).resolve().parent.joinpath('fonts', 'C&C Red Alert [INET].ttf'))
   font2 = ImageFont.truetype(font_path, 15)   # change font size to 15. 

Modify the draw function

  with canvas(device) as draw:
        # draw.text((0, 0), cpu_usage(), font=font2, fill="white")
        draw.text((0, 0), get_id(), font=font2, fill="white")         ##### draw id on screen at (0,0) position, (x,y)
        if device.height >= 32:
            #draw.text((0, 11), mem_usage(), font=font2, fill="white")
            #draw.text((0, 16), disk_usage('/'), font=font2, fill="white")
            draw.text((0, 16), get_ip_address(), font=font2, fill="white")   #### draw text on (0,16) with IP address. 

How to create a systemd file to make it automatically start at boot up

  • Step1. create a shell script called it 'start_led.sh'
#!/bin/bash
#
cd /home/pi/venv/ && source /home/pi/venv/bin/activate 
/usr/bin/python3 /home/pi/luma.examples/examples/sys_info.py --width=128 --height=32 -r 2 

save it and grant executable permission and test it.

chmod +x start_led.sh 
./start_led.sh

If if works properly, just press "ctrol+c" to abort the test.

  • Step2. create a systemd file and enable it.
sudo vim.tiny /etc/systemd/system/rackmount_oled.service

And then, adding following lines:

[Unit]
Description=Rackmount OLED service on RPi5
DefaultDependencies=no
StartLimitIntervalSec=60
StartLimitBurst=5

[Service]
Type=simple
ExecStart=/bin/bash /home/pi/start_led.sh
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

Save it and quit.

Enable rackmount_oled.service

  • reload daemon
sudo systemctl daemon-reload
  • Enable service
 
sudo systemctl enable rackmount_oled.service 
  • Start service
sudo systemctl start rackmount_oled.service
  • Restart service
sudo systemctl restart rackmount_oled.service 
  • Stop service
sudo systemctl stop rackmount_oled.service
  • Disable service
sudo systemctl disable rackmount_oled.service 

How to enable PCIe function on Raspberry Pi 5?

  • To enable PCIe functionality on the Raspberry Pi 5, follow these steps:

1. Enable the PCIe External Connector:

By default, the PCIe connector on the Raspberry Pi 5 is not enabled. To enable it, you need to add a configuration parameter to the `config.txt` file located in the `/boot/firmware` directory. You can use either of these lines:

dtparam=pciex1

After adding the line, reboot your Raspberry Pi for the changes to take effect.

2.Enable PCIe Gen 3.0 (Optional):

The Raspberry Pi 5's PCIe connection is certified for Gen 2.0 speeds. However, if you want to attempt using Gen 3.0 speeds, add the following line to the `config.txt` file as well:

dtparam=pciex1_gen=3
Be aware that the Raspberry Pi 5 is not certified for Gen 3.0 speeds, and using this setting may result in instability .

3.Booting from PCIe:

If you intend to boot from a device connected via PCIe, such as an NVMe SSD, you will need to modify the boot order in the EEPROM. Use the following command to edit the EEPROM configuration:

sudo apt update 
sudo apt upgrade -y 
sudo rpi-eeprom-config --edit

Then, change the `BOOT_ORDER` line to include NVMe in the boot order:

BOOT_ORDER=0xf416

This setting will make the Raspberry Pi attempt to boot from an NVMe device connected to the PCIe port .

4. Kernel Compilation (Advanced):

If you need to compile the kernel to add support for specific PCIe devices, you can follow the steps outlined in the Raspberry Pi documentation. This involves cloning the Raspberry Pi kernel repository, configuring the kernel with `make menuconfig`, and enabling the necessary modules for your devices . Remember to always check the compatibility of the devices you intend to use with the Raspberry Pi 5's PCIe interface, as not all devices may be supported out of the box.

How to light up identical LED?

To light up UID LED indicator on a Raspberry Pi 4B or 5, you'll make sure the GPIO Pin of the UID LED connected to.

GPIO (General Purpose Input/Output) pins on the Raspberry Pi.

Steps

  • 1. Identify GPIO Pins: GPIO4
  • 2. Power On:

Make sure your Raspberry Pi is powered off before connecting the LED. Once everything is connected, you can power on your Raspberry Pi.

  • 3. Software Setup:

You'll need to write a small program to turn the GPIO pin on and off to control the LED. You can use Python with the `gpiozero` library or `RPi.GPIO` library to control the GPIO pins.

Example Python Code with gpiozero:

from gpiozero import LED
from time import sleep


led = LED('GPIO4')

while True:
    led.on()
    sleep(1)
    led.off()
    sleep(1)

Example Python Code with RPi.GPIO:

import RPi.GPIO as GPIO
import time

# Set the GPIO mode
GPIO.setmode(GPIO.BCM)


GPIO_PIN = 4

# Set up the GPIO pin as an output channel
GPIO.setup(GPIO_PIN, GPIO.OUT)

while True:
    GPIO.output(GPIO_PIN, GPIO.HIGH)  # Turn on the LED
    time.sleep(1)
    GPIO.output(GPIO_PIN, GPIO.LOW)   # Turn off the LED
    time.sleep(1)

# Clean up the GPIO pins before exiting the program
GPIO.cleanup()

Safety Tips:

  • Be careful not to short any pins on the Raspberry Pi.

Keywords

  • 1U Rackmount for Raspberry Pi 5/4B with M.2 NVMe SSD support.