Functional Pip-boy 3000 Mk IV from Fallout 4

Don't want to see this ad? Sign up for anRPF Premium Membershiptoday. Support the community. Stop the ads.


zapwizard

Sr Member
There have been a few developments I haven't mentioned yet.

The first is I finally found a LCD panel that both should be a perfect fit, and something I can actually drive with an image!

The screen I did want to use only accepts DSI MIPI input, and while in theory the Raspberry Pi can output that signal, the developers an "open source" micro controller, decided to keep the code so that only the two screens they sell can work. All others need to dig into the root coding, and so far after many years I have yet to see a single person implement it successfully.

SPI is a much slower interface, but is also much more compatible, and can be driven by something as simple as an arduino.

The SPI display I found a 4"x4" LCD that is 480x480 pixels, enough to display the text and basic graphics needed for a Pip-Boy.
It should also be much brighter than the VR tweaked screen I was using.

I ordered a couple of them nearly a month ago, but they are on the slow boat from china, so I have no idea when they will arrive.

At the same time I spent over $350 on SparkFun in order to get new development and sensor boards to try to revamp this project. This way I don't have to breadboard every tiny sub-circuit.

I ordered the SparkFun MicroMod with display carrier board. This has a SPI display on board, and I am painfully learning how to get the graphics library to display stuff. So far, I have it displaying just the boot screen text. I am not sure if I want to use the Artemis board or the RP2040 board to drive the thing. The RP2040 is supposed to be much faster, but I am not very familiar with Python, and am much better at coding in C++.

I also ordered the following:
FM Tuner board
Pulse Oximeter and Heart Rate Sensor
Battery charger/ Fuel Gauge
GPIO expander
IR thermal sensor
Motor Driver
9 degree of freedom IMU
A bunch of Qwiic breakouts, splitters and cables

Regarding the question on metal 3D printing: Metal 3D printing is still very expensive. It also still requires lots of supports that have to be manually ground away. It is far from being practical to print out a metal pip-boy body (at least with all the internal structures in place)

However, within the next few months I will have access to a Fuse 1 3D printer. That will make it so that printing out the entire set of parts will drop from $350 to $115. It will at least mean if I need to make any more mechanical changes, they won't be so costly to prototype. The catch is it only makes parts in a dark grey nylon, and some of the parts on the Pip-Boy do need to be white, but there is always paint for that.

All that said, this is still a back burner project for me. I have a few other functional props which may still come first. I need to finish the Dosimeter. I ran into a road block where the MSP430 is very difficult to program without a carrier board, so in-field updates were nearly impossible. I may even report the whole thing over to a more easy to use microcontroller, and simplify some aspects of the design.

I am otherwise spending my free time on Leatherman Tool accessories (and video games). The tool parts sell and help fun the rest of my hobbies. Including ordering all those SparkFun boards. To that end I will soon be revamping my website to be a store, showcase, and blog all in one.
 

Don't want to see this ad? Sign up for anRPF Premium Membershiptoday. Support the community. Stop the ads.

Wellen

New Member
There have been a few developments I haven't mentioned yet.

The first is I finally found a LCD panel that both should be a perfect fit, and something I can actually drive with an image!

The screen I did want to use only accepts DSI MIPI input, and while in theory the Raspberry Pi can output that signal, the developers an "open source" micro controller, decided to keep the code so that only the two screens they sell can work. All others need to dig into the root coding, and so far after many years I have yet to see a single person implement it successfully.

SPI is a much slower interface, but is also much more compatible, and can be driven by something as simple as an arduino.

The SPI display I found a 4"x4" LCD that is 480x480 pixels, enough to display the text and basic graphics needed for a Pip-Boy.
It should also be much brighter than the VR tweaked screen I was using.

I ordered a couple of them nearly a month ago, but they are on the slow boat from china, so I have no idea when they will arrive.

At the same time I spent over $350 on SparkFun in order to get new development and sensor boards to try to revamp this project. This way I don't have to breadboard every tiny sub-circuit.

I ordered the SparkFun MicroMod with display carrier board. This has a SPI display on board, and I am painfully learning how to get the graphics library to display stuff. So far, I have it displaying just the boot screen text. I am not sure if I want to use the Artemis board or the RP2040 board to drive the thing. The RP2040 is supposed to be much faster, but I am not very familiar with Python, and am much better at coding in C++.

I also ordered the following:
FM Tuner board
Pulse Oximeter and Heart Rate Sensor
Battery charger/ Fuel Gauge
GPIO expander
IR thermal sensor
Motor Driver
9 degree of freedom IMU
A bunch of Qwiic breakouts, splitters and cables

Regarding the question on metal 3D printing: Metal 3D printing is still very expensive. It also still requires lots of supports that have to be manually ground away. It is far from being practical to print out a metal pip-boy body (at least with all the internal structures in place)

However, within the next few months I will have access to a Fuse 1 3D printer. That will make it so that printing out the entire set of parts will drop from $350 to $115. It will at least mean if I need to make any more mechanical changes, they won't be so costly to prototype. The catch is it only makes parts in a dark grey nylon, and some of the parts on the Pip-Boy do need to be white, but there is always paint for that.

All that said, this is still a back burner project for me. I have a few other functional props which may still come first. I need to finish the Dosimeter. I ran into a road block where the MSP430 is very difficult to program without a carrier board, so in-field updates were nearly impossible. I may even report the whole thing over to a more easy to use microcontroller, and simplify some aspects of the design.

I am otherwise spending my free time on Leatherman Tool accessories (and video games). The tool parts sell and help fun the rest of my hobbies. Including ordering all those SparkFun boards. To that end I will soon be revamping my website to be a store, showcase, and blog all in one.

This is great news! I'm glad you've been able to make progress and I wish you luck with the dosimeter, and looking forward to an update vid on your YT. And personally once I can and it's finished, use a metal printer, as I'd rather'ed keep the components safe for decades/century's then let human error do a dozy to it so it can be a long time pass me down.
 

iklask

New Member
There have been a few developments I haven't mentioned yet.

The first is I finally found a LCD panel that both should be a perfect fit, and something I can actually drive with an image!

The screen I did want to use only accepts DSI MIPI input, and while in theory the Raspberry Pi can output that signal, the developers an "open source" micro controller, decided to keep the code so that only the two screens they sell can work. All others need to dig into the root coding, and so far after many years I have yet to see a single person implement it successfully.

SPI is a much slower interface, but is also much more compatible, and can be driven by something as simple as an arduino.

The SPI display I found a 4"x4" LCD that is 480x480 pixels, enough to display the text and basic graphics needed for a Pip-Boy.
It should also be much brighter than the VR tweaked screen I was using.

I ordered a couple of them nearly a month ago, but they are on the slow boat from china, so I have no idea when they will arrive.

At the same time I spent over $350 on SparkFun in order to get new development and sensor boards to try to revamp this project. This way I don't have to breadboard every tiny sub-circuit.

I ordered the SparkFun MicroMod with display carrier board. This has a SPI display on board, and I am painfully learning how to get the graphics library to display stuff. So far, I have it displaying just the boot screen text. I am not sure if I want to use the Artemis board or the RP2040 board to drive the thing. The RP2040 is supposed to be much faster, but I am not very familiar with Python, and am much better at coding in C++.

I also ordered the following:
FM Tuner board
Pulse Oximeter and Heart Rate Sensor
Battery charger/ Fuel Gauge
GPIO expander
IR thermal sensor
Motor Driver
9 degree of freedom IMU
A bunch of Qwiic breakouts, splitters and cables

Regarding the question on metal 3D printing: Metal 3D printing is still very expensive. It also still requires lots of supports that have to be manually ground away. It is far from being practical to print out a metal pip-boy body (at least with all the internal structures in place)

However, within the next few months I will have access to a Fuse 1 3D printer. That will make it so that printing out the entire set of parts will drop from $350 to $115. It will at least mean if I need to make any more mechanical changes, they won't be so costly to prototype. The catch is it only makes parts in a dark grey nylon, and some of the parts on the Pip-Boy do need to be white, but there is always paint for that.

All that said, this is still a back burner project for me. I have a few other functional props which may still come first. I need to finish the Dosimeter. I ran into a road block where the MSP430 is very difficult to program without a carrier board, so in-field updates were nearly impossible. I may even report the whole thing over to a more easy to use microcontroller, and simplify some aspects of the design.

I am otherwise spending my free time on Leatherman Tool accessories (and video games). The tool parts sell and help fun the rest of my hobbies. Including ordering all those SparkFun boards. To that end I will soon be revamping my website to be a store, showcase, and blog all in one.
Have you looked at STM chips at all? A few years ago they bought touchgfx and a lot of their higher end chips are supported. Its a WYSIWYG GUI designer that pairs well with their IDE/ecosystem. And lets you edit all the code in C/C++.

I've been meaning to mess around with my Wand Company 2000mkVI for a while now and was going to try out the STM route for electronics.
 

zapwizard

Sr Member
I will take a look. I don't consider myself a great C++ programmer, I can manage with Arduino libraries and code, and write a good state machine, but find I get lost when it gets down to handling some of the lower level stuff. The funny part is the same is true when I try to program in python, I find it to be too unstructured.
 

zapwizard

Sr Member

I did a thing! I managed to learn some Python. (Circuitpython) to be exact.

Over the past few weeks I have spent a little bit of time each day getting the code to the point where I have a workable boot screen. Some aspects of python are easier for me than C++, but some aspects are just as obfuscated and any other programming language. (Especially errors)

First I tried using the SparkFun Artimus board, Arduino code, and their Hyperdisplay library. The Hyperdisplay library is crap. It has one system font, and no support for bitmaps. It was a huge waste of time to even try using it.

I also ordered the MicroMod RP2040 board. It took quite a bit of time to get the screen running, due to me learning Python while eventually figuring out that a single pin was mis-mapped in the board setup (not my fault) that was preventing it from working at all. Finally for some reason my display was inverted but I figured out how to update the LCD initialization code to fix that.

The screen shown in the video is 320x240, and the screen I am still waiting to arrive from China will be 480x480 pixels.
The RP2040 MicroMod board I am using just 265kB of ram, so most of the bitmaps have to be written directly to the screen over SPI.

Ani.jpg


It takes quite of bit of work to make the graphics. Using 7zip: I extracted the SWF files from the Pip-Boy companion app. Then using JPEXS Flash Decompiler: I extracted the SVG graphics files from the SWF files. I process the SVG files in Photoshop. Each one has to be down converted to a small 4-bit bitmap or I will run out of memory.

The animations however can't written directly to the display. Instead I have to make and load a single bitmap. It can then be cycled through sections as sprites. This bitmap does have to fit into the system memory.

Also the memory shown during the boot-up is the actual system memory!

Even things like text take up a large amount of memory. The very first boot image with the numbers flying by had to be truncated down in order for it to be rendered, and sent to the screen fast enough. Too long, and the processor would simply run out of memory while converting the text to a bitmap. I also had to learn to make my own bitmap fonts using the fonts actually used in the companion app.

I wanted to also play audio through the speakers. But I ran into an issue where the processor is just spending too much time driving the display. There was no cycles left over to send out WAV files via PWM. It could play a file okay, but then it would be distorted heavily if anything was happening on screen. So for audio I will need an external audio chip, or I will need to upgrade to a full Raspberry Pi (Which I may end up doing anyways) The audio in the video was faked in a video editor.

If your interested in seeing the code, it is below. Please be kind, it is not optimized and is all just serially written out.
You can see where I tried to get the WAV files playing, and all the memory cleanup I have to do.

I probably won't do much more beyond this until my new display arrives, as it will probably be a pain to get up and running.

Python:
# Imports
import gc
import board
import terminalio
import digitalio
import busio
import time
import displayio
from adafruit_bitmap_font import bitmap_font
from adafruit_display_text import bitmap_label, wrap_text_to_pixels
import adafruit_imageload
import ili9341v
from audiocore import WaveFile
from audiopwmio import PWMAudioOut as AudioOut
from vectorio import Rectangle, VectorShape# 2D Shape library
import adafruit_imageload

# print(gc.mem_free(), "Bytes free at the start")

# Watchdog LED stuff
BLINK_ON_DURATION = 0.5  # How long we want the LED to stay on
BLINK_OFF_DURATION = 0.5  # How long we want the LED to stay off
LAST_BLINK_TIME = -1  # When we last changed the LED state
led = digitalio.DigitalInOut(board.LED1)
led.direction = digitalio.Direction.OUTPUT

#Audio Stuff
SPEAKER = board.PWM1
audio = AudioOut(SPEAKER)

# Display Setup
displayio.release_displays()  # Release any display resources
spi = busio.SPI(board.SCK, MOSI=board.COPI, MISO=board.CIPO)
tft_cs = board.D0
tft_dc = board.D1
tft_reset = board.G2
DISPLAY_WIDTH = 320
DISPLAY_HEIGHT = 240
FPS = 79

display_bus = displayio.FourWire(
    spi,
    command=tft_dc,
    chip_select=tft_cs,
    reset=tft_reset,
    baudrate=100000000
    )

display = ili9341v.ILI9341(
    display_bus,
    width=DISPLAY_WIDTH,
    height=DISPLAY_HEIGHT,
    rotation=0,  # The rotation can be adjusted to match your configuration.
    auto_refresh=True,
    native_frames_per_second=79,
    )

# Colors and fonts
TechMono22 = bitmap_font.load_font("fonts/TechMono-22.pcf")
TechMono12 = bitmap_font.load_font("fonts/TechMono-12.pcf")
RobotoB14 = bitmap_font.load_font("fonts/RobotoB-14.pcf")
Roboto12 = bitmap_font.load_font("fonts/Roboto-12.pcf")
Roboto10 = bitmap_font.load_font("fonts/Roboto-10.pcf")

# Colors
Black = 0x000000
Green = 0x00FF00
Mid_Green = 0x007000
Dark_Green = 0x002000

Four_Color_Palette = displayio.Palette(4)
Four_Color_Palette[0] = Black
Four_Color_Palette[1] = Green
Four_Color_Palette[2] = Mid_Green
Four_Color_Palette[3] = Dark_Green
Four_Color_Palette.make_transparent(0)

group_1 = displayio.Group()  # Make a display group
group_2 = displayio.Group()  # Make a second display group
display.show(group_1) #Start with group 1

print(gc.mem_free(), "Bytes free after display setup screen")

# Boot Screen
#wave_file = open("/wav/UI_PipBoy_BootSequence_A.wav", "rb")
#wave = WaveFile(wave_file)
#audio.play(wave)

text = ("*  1 0 0X0000A4 0x00000000000000000 start memory discovery0 0X0000A4 "
        "0x00000000000000000 1 0 0X0000A4 0x00000000000000000 "
        "start memory discovery 0 0X0000A4 0x00000000000000000 1 0 0x000014 "
        "0x00000000000000000 CPUO starting cell relocation0 0X0000A4 "
        "0x00000000000000000 1 0 0x000009 0x00000000000000000 CPUO launch EFI0 "
        "0X0000A4 0x00000000000000000 1 0 0x000009 0X000000000000E003D CPUO "
        "starting EFI0 0X0000A4 0x00000000000000000 1 0 0X0000A4 "
        "0x00000000000000000 start memory discovery0 0X0000A4 0x00000000000000000 "
        "1 0 0X0000A4 0x00000000000000000 start memory discovery 0 0X0000A4 "
        "relocation 0X0000A4 0x00000000000000000 1 0 0x000009 0x00000000000000000 "
        "1 0 0x000014 0x00000000000000000 CPUO starting cell "
        "relocation0 0X0000A4 0x00000000000000000 1 0 0x000009 "
        "0x00000000000000000 CPUO launch EFI0 0X0000A4 0x00000000000000000 1 0 "
        "0x000009 0X000000000000E003D CPUO starting EFI0 0X0000A4 "
        "0x00000000000000000 "
        )

my_text = bitmap_label.Label(
    TechMono12,
    color=Green,
    text="\n".join(wrap_text_to_pixels(text, DISPLAY_WIDTH, TechMono12)),
)
my_text.y = DISPLAY_HEIGHT
group_1.append(my_text)

# Scroll the group upwards
lines = DISPLAY_HEIGHT
while lines > -320:
    group_1.y = group_1.y - 32
    lines = lines - 32
    display.refresh(minimum_frames_per_second=FPS)

#while audio.playing:
        #pass

# Clean Up
group_1.remove(my_text)
while len(group_1):
    group_1.pop()
del my_text
del text
#audio.stop()
#audio.deinit()
#del wave_file
#del wave
gc.collect()
group_1.x = 0
group_1.y = 0

time.sleep(1)

print(gc.mem_free(), "Bytes free after boot screen")

# OS Text
#wave_file = open("/wav/UI_PipBoy_BootSequence_B.wav", "rb")
#wave = WaveFile(wave_file)
#audio.play(wave)

# Blink the cursor at the start
my_text = bitmap_label.Label(TechMono12, color=Green, text=" ")
my_text.x = 10
my_text.y = 10
group_1.append(my_text)
i = 0
while i < 4:
    my_text.text = "▯"
    time.sleep(0.2)
    my_text.text = " "
    time.sleep(0.2)
    i = i + 1
group_1.remove(my_text)
del my_text
gc.collect()

# Display BIOS style screen
text_array = [
            "************** PIP-05 (R) V7 .1.0.8 **************\n",
            " \n",
            " \n",
            " \n",
            "COPYRIGHT 2075 ROBCO(R)\n",
            "LOADER VI.1\n",
            "EXEC VERSION 41.10\n",
            "264k RAM SYSTEM\n",
            f"{gc.mem_free()} BYTES FREE\n",
            "NO HOLOTAPE FOUND\n",
            "LOAD ROM(1): DEITRIX 303",
            ]
line = 0
y = 10
for text in text_array:
    # BIOS screen
    my_text = "my_text" + str(line)
    my_text = bitmap_label.Label(TechMono12, color=Green, text=" "*len(text))  # Reserve the line of text
    my_text.x = 10
    my_text.y = y
    group_1.append(my_text)
    i = 0
    while i < len(text):
        my_text.text = text[0:i] + "▯"  # Create a cursor that runs
        i = i + 1
    my_text.text = text.strip("▯")  # Remove cursor before moving on
    line = line + 1
    y = y + 16

# Blink the cursor at the very end
i = 0
while i < 6:
    my_text.text = text + "▯"
    time.sleep(0.2)
    text = text.strip("▯")
    my_text.text = text
    time.sleep(0.2)
    i = i + 1

# Scroll the group upwards
lines = DISPLAY_HEIGHT
while lines > -240:
    group_1.y = group_2.y - 30
    lines = lines - 30
    display.refresh(minimum_frames_per_second=FPS)
group_1.remove(my_text)
group_1.x = 0
group_1.y = 0

#while audio.playing:
        #pass

# clean Up
#audio.stop()
#audio.deinit()
#del wave_file
#del wave
while len(group_1):
    group_1.pop()
del my_text
del text_array
gc.collect()

print(gc.mem_free(), "Bytes free after BIOS screen")

# Initiating screen
# Import animation bitmap
vault_boy_bit, vault_boy = adafruit_imageload.load("/gfx/vault_boy_boot/ani2.bmp",
                                                    bitmap=displayio.Bitmap,
                                                    palette=displayio.Palette)
vault_boy_grid = displayio.TileGrid(vault_boy_bit, pixel_shader=vault_boy,
                                     width=1, height=1,
                                     tile_height=102, tile_width=72,
                                     default_tile=0,
                                    x = int(DISPLAY_WIDTH / 2) - 51,
                                    y = int(DISPLAY_HEIGHT / 2) - 70
                                    )

print(gc.mem_free(), "Bytes free after making grid")

# Create text label
my_text = bitmap_label.Label(TechMono22, color=Green, text="INITIATING...")
my_text.anchor_point = (0.5, 0.5)
my_text.anchored_position = (DISPLAY_WIDTH / 2, DISPLAY_HEIGHT -40)
group_1.append(my_text)
group_1.append(vault_boy_grid) # Add to group
vault_boy_grid[0] = 0

print(gc.mem_free(), "Bytes free after making text label")

#wave_file = open("/wav/UI_PipBoy_BootSequence_C.wav", "rb")
#wave = WaveFile(wave_file)
#audio.play(wave)

# Animate!
FRAMES = [0,0,0,0,0,0,0,0,0,0,0,0,1,2,0,0,0,0,0,0,0,0,3,4,5,6,7,7,7,7,7]
G = 0
inc = 1
for i in FRAMES:
    vault_boy_grid[0] = i
    my_text.color = (0,G,0)
    if G <= 32:
        inc = 32
    elif G >= 223:
        inc = -32
    G = G + inc
    time.sleep(0.1)

# Import animation bitmap
vault_boy_bit, vault_boy = adafruit_imageload.load("/gfx/walk/ani.bmp",
                                                    bitmap=displayio.Bitmap,
                                                    palette=displayio.Palette)
vault_boy_grid = displayio.TileGrid(vault_boy_bit, pixel_shader=vault_boy,
                                     width=1, height=1,
                                     tile_height=102, tile_width=50,
                                     default_tile=0,
                                    x = int(DISPLAY_WIDTH / 2) -25,
                                    y = int(DISPLAY_HEIGHT / 2) -68
                                    )
group_2.append(vault_boy_grid) # Add to group

# Rectangle encoding [width,height,x,y,color index] (Top left corner anchored)
shapes = [
    [15,6,153,42,1], # Health bar 1
    [15,6,203,84,1], # Health bar 2
    [15,6,203,139,1], # Health bar 3
    [15,6,153,157,1], # Health bar 4
    [15,6,101,139,1], # Health bar 5
    [15,6,101,84,1], # Health bar 6
    [2,3,12,14,1], # Top Line 1
    [38,2,12,12,1], # Top Line 2
    [2,11,48,1,1], # Top Line 3
    [2,2,50,1,1], # Top Line 4
    [2,2,86,1,1], # Top Line 5
    [2,11,88,1,1], # Top Line 6
    [220,2,88,12,1], # Top Line 7
    [2,3,306,14,1], # Top Line 8
    [53,15,13,206,2], # Stimpak background
    [56,15,74,206,2], # Radaway background
    [72,17,12,223,3], # HP background
    [148,17,86,223,3], # Level background
    [103,8,126,228,2], # Level bar surround
    [99,4,128,230,3], # Level bar dark
    [52,4,128,230,1], # Level bar progress
    [72,17,236,223,3], # AP background
    [27,25,95,172,2], # Gun background
    [15,25,124,172,2], # Ammo background
    [27,25,147,172,2], # Helmet background
    [15,25,175,172,2], # Armor background
    [15,25,193,172,2], # Energy background
    [15,25,210,172,2], # Radiation background
    ]

for shape in shapes:
    my_pallet = displayio.Palette(2) # Make a single color palette
    my_pallet[1] =  Four_Color_Palette[shape[4]] # Set color
    my_shape = VectorShape(shape=Rectangle(width=shape[0],height=shape[1]),x=shape[2],y=shape[3],pixel_shader=my_pallet) #Move and color rectangle
    group_2.append(my_shape) #Add rectangle to the group

# Load Small Icons

# Bitmap encloding [x,y,file] (Top left corner anchored)
bitmaps = [
    [98,178,"/gfx/Handgun.bmp"], # Handgun
    [150,178,"/gfx/Helmet.bmp"], #Reticle
    [128,174,"/gfx/Reticle.bmp"], #Helmet
    [181,174,"/gfx/Shield.bmp"], #Shield
    [198,174,"/gfx/Bolt.bmp"], #Bolt
    [213,174,"/gfx/Radiation.bmp"], #Bolt
    ]
    
for image in bitmaps:
    bitmap, palette = adafruit_imageload.load(image[2],bitmap=displayio.Bitmap,palette=displayio.Palette)
    bitmap_tile = displayio.TileGrid(bitmap, pixel_shader=Four_Color_Palette) #Assign bitmap to TileGrid
    bitmap_tile.x = image[0] #Change location of TileGrid
    bitmap_tile.y = image[1]
    group_2.append(bitmap_tile) #Add tile_grid to group
    display.refresh(target_frames_per_second=FPS) # Wait for the image to load

# Load Text

#Label encoding: [Anchor X, Anchor Y, X, Y, Font, Color, Text]
labels = [
    [0.5,0.5,70,4,RobotoB14,Green,"STAT"],
    [0.5,0.5,112,4,RobotoB14,Green,"INV"],
    [0.5,0.5,154,4,RobotoB14,Green,"DATA"],
    [0.5,0.5,198,4,RobotoB14,Green,"MAP"],
    [0.5,0.5,245,4,RobotoB14,Green,"RADIO"],
    [0.5,0.5,68,23,Roboto12,Green,"STATUS"],
    [0.5,0.5,114,23,Roboto12,Mid_Green,"SPECIAL"],
    [0.5,0.5,158,23,Roboto12,Mid_Green,"PERKS"],
    [0.5,0.5,131,191,Roboto10,Green,"18"], # Ammo
    [0.5,0.5,182,191,Roboto10,Green,"10"], # Armor
    [0.5,0.5,200,191,Roboto10,Green,"20"], # Energy
    [0.5,0.5,217,191,Roboto10,Green,"10"], # Rads
    [0.5,0.5,40,214,Roboto10,Dark_Green,"STIMPAK (0)"],
    [0.5,0.5,102,214,Roboto10,Dark_Green,"RADAWAY (0)"],
    [0.5,0.5,48,231,RobotoB14,Green,"HP 115/115"],
    [0.5,0.5,105,231,Roboto10,Green,"LEVEL 50"],
    [0.5,0.5,279,231,RobotoB14,Green,"AP 90/90"],
    ]

for label in labels:
    my_text = bitmap_label.Label(label[4], color=label[5], text=label[6])
    my_text.anchor_point = (label[0],label[1])
    my_text.anchored_position = (label[2],label[3])
    group_2.append(my_text)

# Glitch the GUI at load a bit
with open("/gfx/Static_Screen2.bmp", "rb") as bitmap_file:
    bitmap = displayio.OnDiskBitmap(bitmap_file)
    bitmap_tile = displayio.TileGrid(bitmap, pixel_shader=displayio.ColorConverter())
    bitmap_tile.y = 0
    group_1.append(bitmap_tile)
    # Wait for the image to load.
    display.refresh(target_frames_per_second=FPS)
    time.sleep(0.05)
    bitmap_tile.y = 160
    time.sleep(0.05)
    group_1.remove(bitmap_tile)

display.show(group_2)

# Cleanup group 1
while len(group_1):
    group_1.pop()
gc.collect()


# Animate!
FRAMES = [0,1,2,3,4,5,6,7]
while True:
    for frame in FRAMES:
        vault_boy_grid[0] = frame
        time.sleep(0.15)

time.sleep(60)
group_2.remove(my_shape)
while len(group_2):
    group_2.pop()
gc.collect()
time.sleep(5)

print(gc.mem_free(), "Bytes free in the end")

#Blink LED forever
while True:
    now = time.monotonic()  # Store the current time to refer to later.
    if not led.value:
        if now >= LAST_BLINK_TIME + BLINK_OFF_DURATION:  # Is it time to turn on?
            led.value = True
            LAST_BLINK_TIME = now
    if led.value:
        if now >= LAST_BLINK_TIME + BLINK_ON_DURATION:  # Is it time to turn off?
            led.value = False
            LAST_BLINK_TIME = now
 
Last edited:

Don't want to see this ad? Sign up for anRPF Premium Membershiptoday. Support the community. Stop the ads.

Inquisitor Peregrinus

Master Member
No shade thrown here. Programming languages are a closed book to me, beyond the most BASIC. As usual, I am in awe of your will and ability to learn. I'm still banging my head against Blender in a desperate bid to join the 21st century.
 

rworne

Member
This is fascinating to read. I worked with teslabe on a Pip-boy retrofit and did this exact same thing. There's a bunch more you can do with some tools to edit the Unity files in the app too. There you can extract all the 70 some-odd audio files.
 

zapwizard

Sr Member
I extracted the audio files from the full game years ago. About 300 files, including all the radio stations. When I did the video I actually had to edit them a bit as the timing wasn't exactly the same of course.
 

zapwizard

Sr Member
I have updated the python code in the post above. Before I was faking much of the final screen with a bitmap, now it is all generated with text and rectangles. That way with more code the values or graphics could be updated if needed.
 

zapwizard

Sr Member
*&^$%!!!!! These displays are ticking me off!

So the display I ordered almost two months ago finally arrived. I also ordered a breakout board and 60 pin 0.5mm pitched connector.

I spent about an hour just soldering the tiny pins. I had to flood solder, and then wick as I don't have a micro-soldering station and scope at home.
After verifying each of the 60 pins was both connected, and not shorted, I proceeded to wire up the display.

When I went to try powering the backlight, way too much current was being drawn... the problem: The breakout board is numbered backwards!
Hopefully I didn't just fry one of the two displays.

I finally get it all wired up to a Raspberry Pi on the SPI lines. That is when I finally figure out, the display is not SPI exclusive. It is SPI+RGB. I didn't read the datasheet carefully enough. It uses SPI for control, but DSI RGB for the actual video data. You can wire a DSI display to a Pi, if you want to use up every single pin on the Pi. I may try seeing if I can wire it for 8-bit mode, which should require fewer lines, maybe the display will even work with just green connected. After all, I only need like 4 to 6 shades of green for the Pip-Boy.

The only driver I have found for this chipset was written in Rust, a programming language I never even heard of. And even then, it would have to be tweaked for 8-bits.

If only the damn Pi foundation would document the MIPI display interface, it would make wiring modern high res displays much easier.

All that, and I also found out that there was a 4" 720x720 ready to use display on the market last year, the HyperDisplay 4.0 Square. It uses most the pins, but keeps i2c open, so it may be the next one I try out (if it ever comes back onto the market)
 

Don't want to see this ad? Sign up for anRPF Premium Membershiptoday. Support the community. Stop the ads.

Your message may be considered spam for the following reasons:

  1. Your new thread title is very short, and likely is unhelpful.
  2. Your reply is very short and likely does not add anything to the thread.
  3. Your reply is very long and likely does not add anything to the thread.
  4. It is very likely that it does not need any further discussion and thus bumping it serves no purpose.
  5. Your message is mostly quotes or spoilers.
  6. Your reply has occurred very quickly after a previous reply and likely does not add anything to the thread.
  7. This thread is locked.

Don't want to see this ad? Sign up for anRPF Premium Membershiptoday. Support the community. Stop the ads.

Top