After using my original Raspberry Pi LCD Case for a few months on the road and corrupting my SD card (like you do), I decided it was time for a couple upgrades. Not all Raspberry Pi SD cards will suffer this fate but if you are running a database application and pulling the power cord to shut it down, you’re just asking for it.

The initial goal was to add a manual on/off button to allow for clean shutdowns and avoid future SD card corruption. Nice and simple (yeah right). There are a handful of tutorials that include scripts for doing this. I didn’t try any of them but if you want a good place to learn about your options, the best write up I found was here. The most “robust” methods seemed complicated enough that I held off on doing this for a couple weeks. Eventually, a better solution presented itself so I went with that instead. Enter, the LiFePo4wered Pi.

This little UPS for the Pi is pretty cool. I’ve seen some trolling commenters say that this is overkill and overpriced. For some well engineered peace of mind, I couldn’t disagree more. On top of the manual on/off button that I was originally looking for, this thing will allow the Pi + LCD to be completely portable and SELF-monitoring since it automatically does a clean shutdown when the battery gets too low. Say goodbye to corrupted SD cards!

This wasn’t the only upgrade I was thinking of (because of course, “Everything is Complicated”). I also had issues with the placement of the LCD display. The goal of the original case was to keep it small. Putting the display on top seemed to take up the least space. In practice the display ended up being useless because of this placement. The original case was zip-tied to a rack bag shelf. The display faced the side of the bag which prevented me from seeing it. So the next upgrade was to move the display to the “front”.

Two more simple upgrades. (1) Improve access to the Pi’s connections and (2) make it more “rack mountable”. I say that in quotes because the final version was designed for a specific rack shelf. There are no “rack ears” like you might expect from a traditional rack mounted piece of hardware. And of course, maintain the original venting that was incorporated into the first one.

Required Parts, Tools, Files, etc.

  1. Raspberry Pi 3 or 2
  2. 16×2 LCD Display
  3. LiFePO4wered/Pi stackable header and mounting kit recommended
  4. Rack Mount RPi LCD Case 2 (top).stl
  5. Rack Mount RPi LCD Case 2 (bottom).stl
  6. (2) 2-Port Panel Mount USB Connector
  7. (1) Panel Mount Ethernet Connector
  8. (4) 3/16″ No.1 Sheet Metal Screws (for the display)
  9. (3) 5/16″ No. 1 Sheet Metal Screws (for the Pi)
  10. (6) M3-0.50 x 10 Pan Phillips Screws (for the connectors)
  11. 3mm or 1.75mm Black ABS Filament
  12. misc. wires/connectors

Difficulty

Moderate? I probably wouldn’t take this on as my first project but if you’ve followed any of the Adafruit – Raspberry Pi tutorials before then you can probably handle this just fine.

Basic Instructions

  1. As per the original RPi LCD Case; print it first to make sure everything comes out okay. You also won’t know your wiring distances for the display until things are roughly in place.
  2. I started out by attaching the LiFePO4wered/Pi to the RPi itself. The through hole on the Pi that you use for mounting prevents that hole from being used to support the Pi, but I think that’s okay. There are still 3 holes left. I probably could’ve spent more time accommodating the LiFePO4wered/Pi’s form into the case, requests for details from the LiFePO4wered/Pi guy went unanswered and there just weren’t any free mounting holes. This project was already complicated enough.
  3. Before you proceed with mounting the Pi + LiFePO4wered/Pi into the case, you’ll want to install the LiFePO4wered Pi Software. I mention this because the original Pi power input will be covered up once you mount it. This was done intentionally but if you run into issues, you don’t want to pull the Pi out of the case. The HDMI port is also NOT brought up to the front of the panel. So anything that requires a monitor should be done while the case is open.inline-A
  4. I suppose this is worth noting for those who might be concerned. The Pi is mounted to the case, and the LiFePO4wered/Pi is mounted to the Pi. I did purchase the “mounting kit” for the LiFePO4wered/Pi which is essentially a nylon spacer, screw, and nut. The point is, this thing is not exactly stable. I don’t think anything is going to break off or get damaged, but you probably don’t want to put too much strain on it either.
  5. Once you have the Pi and the LiFePo4wered/Pi in place, you can go ahead and attach the panel mount connectors. I wanted to wire the display last so the wiring is accessible, and is separated from the Pi by the panel mount connectors. For display wiring instructions check out this Adafruit tutorial:
    Original Adafruit 16×2 LCD Tutorial
    inline-B

    You can see this in the photos, but I soldered up a small breadboard to the back of the display to simplify some of the wiring. I’ll leave this up to you since I don’t think it warrants any detailed explanation (again, check out the Adafruit Tutorial).
    inline-C inline-D inline-E
  6. Once everything is wired up, you can go ahead and turn it on! Reach in through that handy little button hole and press the touch point on the LiFePO4wered/Pi PCB. As my favorite mis-spelling friend would say; viola! At this point, the display may or may not show anything depending on whether you programmed it by following the Adafruit Tutorial. Regardless, if you want it to display the Wifi, Ethernet, and charging statuses as shown below the script I used is as follows:
    #!/usr/bin/python
    import time
    
    import Adafruit_CharLCD as LCD
    from subprocess import *
    from time import sleep,strftime
    
    # Raspberry Pi pin configuration:
    lcd_rs        = 27  # Note this might need to be changed to 21 for older $
    lcd_en        = 22
    lcd_d4        = 25
    lcd_d5        = 24
    lcd_d6        = 23
    lcd_d7        = 18
    lcd_backlight = 4
    
    # Define LCD column and row size for 16x2 LCD.
    lcd_columns = 16
    lcd_rows    = 2
    
    # Initialize the LCD using the pins above.
    lcd = LCD.Adafruit_CharLCD(lcd_rs, lcd_en, lcd_d4, lcd_d5, lcd_d6, lcd_d7$
    
    lcd.create_char(0, [14, 31, 31, 31, 31, 31, 31, 0])
    lcd.create_char(1, [14, 17, 31, 31, 31, 31, 31, 0])
    lcd.create_char(2, [14, 17, 17, 31, 31, 31, 31, 0])
    lcd.create_char(3, [14, 17, 17, 17, 31, 31, 31, 0])
    lcd.create_char(4, [14, 17, 17, 17, 17, 31, 31, 0])
    lcd.create_char(5, [14, 17, 17, 17, 17, 17, 31, 0])
    lcd.create_char(6, [10, 10, 31, 31, 14, 4, 4, 0])
    
    cmd1 = "ip addr show wlan0 | grep 'inet ' | awk '{print $2}' | cut -d/ -f$
    cmd2 = "ip addr show eth0 | grep 'inet ' | awk '{print $2}' | cut -d/ -f1"
    cmd3 = "lifepo4wered-cli get vbat"
    cmd4 = "lifepo4wered-cli get vin"
    
    def run_cmd(cmd):
            p = Popen(cmd, shell=True, stdout=PIPE)
            output = p.communicate()[0]
            return output
    
    while 1:
            ipaddr1 = run_cmd(cmd1)
            ipaddr2 = run_cmd(cmd2)
            battlvl = int(run_cmd(cmd3), 10)
            inputlvl = int(run_cmd(cmd4), 10)
            lcd.set_cursor(0,0)
            if len(ipaddr1) > 0:
                    lcd.message('%s' % ( ipaddr1 ))
            else:
                    lcd.message('No WIFI        ')
            lcd.set_cursor(0,1)
            if len(ipaddr2) > 0:
                    lcd.message('%s' % ( ipaddr2 ))
            else:
                    lcd.message('No Ethernet    ')
            lcd.set_cursor(15,0)
            if inputlvl > 500:
                    lcd.message('\x06')
            elif battlvl >= 3275:
                    lcd.message('\x00')
            elif battlvl >= 3255:
                    lcd.message('\x01')
            elif battlvl >= 3231:
                    lcd.message('\x02')
            elif battlvl >= 3216:
                    lcd.message('\x03')
            elif battlvl >= 3167:
                    lcd.message('\x04')
            else:
                    lcd.message('\x05')
    

    screen_options-inline

 

Battery Gauge Details

As an after-thought, battery fuel gauges are hard! This was a fun little experiment but the battery indicator isn’t what I would call “accurate”. For those who don’t know, there are ICs specifically designed to provide an accurate battery percentage which relates to the “area under the curve” and factors in the current temperature of the battery. In this case, I am relying on the output voltage reported by the LiFePO4wered/Pi’s CLI and mapping it to an output relating to “typical” conditions.Battery Gauge

I wrote a script to log the battery level every second until it automatically shut itself down. I then picked out cutoff voltages and had the gauge respond accordingly. The result of this inaccuracy has a pretty cool side effect. When the battery level gets close to a cutoff, it will bounce back and forth between the upper and lower battery level icons. Coincidentally, this ends up looking like an animation, as if to say “the battery level is dropping to the next level”. There’s also the potential that a random voltage spike will make the battery appear more full (or empty) then it really is. Since the script is running continuously this should be temporary and resolve itself pretty quickly.

I am a participant in the Amazon Services LLC Associates Program, an affiliate advertising program designed to provide a means for me to earn fees by linking to Amazon.com and affiliated sites.

One thought on “Raspberry Pi LCD Case 2

Leave a Reply