This project stems from an idea I had early on in my embedded design course. I was trying to think of interesting potential systems that could be created from reasonably simple base components, and came up with the concept of what is essentially 'budget VR' - a single screen connected to a single frame of a virtual world, using an IMU to dynamically slice it into an image that fits within our simulated viewport.
It's a fun mixture of art and engineering and I am reasonably happy with the design!
HardwareThe core of this system is a PocketBeagle single-board-computer that allows us to run a full Linux system with a tremendous amount of GPIO and other hardware communication protocol access fairly easily. Our PocketBeagle is fed a steady 5V2A and in turn branches out to interface and power all the rest of our sensors and components.
The LED Matrix operates on 5V logic, but the PocketBeagle's GPIO can only support up to 3.3V - we use two parallel bidirectional level shifter boards to translate our GPIO pins to 5V logic!
User interaction is captured via four buttons, which use a simple 1kΩ pull-up resistor with a nice GPIO interface to connect back to the PocketBeagle.
The system also produces sound via the onboard buzzer, which is driven by one PWM pin (translated to 5V via the level shifter). This allowed me to add in simple sound effects and assist with the 'retro game console' sort of vibe i wanted to capture with some of the design elements.
The system also uses an I2C-connected MPU6050 IMU to determine its orientation, which it can provide via a nice abstracted interface to any of the onboard apps to allow fun gyroscope integration (like the Glass app, which generates and renders a zoomed-in slice of a panoramic image depending on the orientation of the device),
The software system itself is designed around a state machine that dynamically tracks which system the Window is running and hands off control & the abstract device interfaces between different applications without allowing any of them to control it at the same time. This lets us cleanly separate our applications into a neat filesystem, along with abstracting all of the hardware away at an application level.
This layer of abstraction is particularly useful for local development... I have a whole parallel pygame-driven simulator for the device that I can use to run and test my apps and see them behave identically to how they would run on the real machine.
Interfacing with the monitor took quite a bit of time, and required altering the device tree of the Pocketbeagle to use prussdrv instead of the PocketBeagle's default remoteproc,
The compiled installation of the pyledscape library we're using for this is also a bit of a black-box when it comes to source code and thus I have no way of figuring out how to allow it to run without sudo invocation (but it does need that!).
Another issue I ran into was that I initially modeled an entire 3D printed frame for a much smaller screen, and when I went to modify my design I ran into the issue of the printbeds being far too small to fit my new frame. Currently that issue has been solved by lasercutting an alternative frame.
I did my best to design the software for this tool such that the actual applications that run on it are fairly abstracted from the hardware and easy to add onto... in that regard, I have a programming project coming up involving a Conway's Game of Life style simulation of stellar life cycles in a gas cloud and I plan to port that over onto the Window! It should be fairly simple.


















_3u05Tpwasz.png?auto=compress%2Cformat&w=40&h=40&fit=fillmax&bg=fff&dpr=2)

Comments