RGBY-ROM reads ROM encoded as colors and executes the instructions on a custom CPU to control a RGB LED and LED array.
The RGBY-ROM end function is acting as a RGB LED controller and LED sequencer.
The front panel contains a RGB indicator and a mono-chrome 8 unit indicator representing port-out data.
The above video shows the RGBY-ROM reading the color encoded ROM and executing the instructors. The user input cycles through three LED array effects contained on the ROM: Knight Rider, binary counting, and sparkle (random).
ROM data is encoded red, green, blue, and yellow colors using a matrix of 0.290” acrylic squares. Each acrylic square, called nits as a play on words combining the terms bit and nibble, represents two bits of binary data. A ROM data cartridge contains 384 nits (equivalent to 96 bytes).
Although the ROM’s physical layout is a matrix, the logical layout is an array of 12bit words where each word represents an assembly instruction for 32 total instructions.
The ROM uses only four colors primarily because the demo programs do not require more than 32 instructions. A secondary reason is that the selected color detection sensor does not reliably distinguish colors with more than one primary color. This limitation could likely be overcome with a row of predetermined nit colors and a calibration routine doubling the ROM’s 32 instructions to 64 instructions.
COLOR Binary Representation Red 00 Green 01 Blue 10 Yellow 11
The indicators on top of the color sensor bar represent the column and color being scanned.
The data cartridge is constructed using two parts screwed together around the edges.
The data cartridge mounting frame contains embedded magnets attracting the screws of the data cartridge allow for quick change outs.
The video above demonstrates swapping two data cartridges.
The color sensor bar contains 12 TCS3200 color sensors converting red, green, blue color intensities into frequencies which are easily processed by the FPGA.
The frequency outputs of each sensor is selected using a de-multiplexor and four select lines from the FPGA’s Sensor Selector module. The detected color is determined by three select lines from the FPGA’s Color Detector module. Two additional multiplexors control the LED indicators.
The spirit of the project was to build a retro style computer with an eccentric memory implementation that could be reasonably created from discrete logic say from 7400-series ICs. Actually using TTL logic is unfathomable in terms of time dedication and using a microcontroller would have been cheating. A FPGA was the logical middle, therefore RGBY-ROM uses a TinyFPGA Bx to instantiate the logic for the CPU, RAM controller, motion controller, hardware ports, etc. The TinyFPGA Bx developed by Luke Valenty uses a Lattice ICE40LP8K and is programmed using Verilog with the Atom/APIO IDE.
Schematics and PCBs were designed in DipTrace using their free license for designs under 300 pins. The main board is simple due to using prefabricated modules for the DC-DC power converter, stepper driver, and FPGA. The ULN2003A darlington arrays are used to drive the LEDs because TinyFPGA pins have a low source/sink current of 4mA.
The CPU is custom designed to decode the ROM’s 12bit instructions and was inspired by the MIPs instruction set architecture. The above block diagram shows the logical separation of modules instantiated on the FPGA and the interactivity of data flow between the modules.
The PC Controller module has the odd added functionality of delaying incrementing the Program Counter when the delay instruction is processed. This functionality provides a software delay mechanism for creating LED visual effects without using precious instructions creating NOP loops.
There are 16 possible instructions with instruction types: register, immediate, and jump. Instructions are separated into three equal parts bitwise and the instruction type determines the purpose of each part.
|Instruction Type||Part 1 – Bits [11:8]||Part 2 – Bits [7:4]||Part 3 – Bits [3:0]|
|Register||OpCode||Resister A (Destination)||Register B (Source)|
|Immediate||OpCode||Value (decimal 0 – 255)|
|Jump||OpCode||Address (decimal 0 – 31)|
There are 16 registers with register types: read-only, cpu, hardware, and general.
|Read-only||Read-only, containing fixed or random values.|
|Cpu||Read-only, CPU writable only.|
|Hardware||Directly connected to hardware ports.|
|General||Read and write, user accessible for general purposes.|
The I/O provides two user input buttons labeled as Mode and Speed on the front panel. The I/O provides an output port 8 bits wide that is connected to eight LEDs on the PCB and the front panel’s eight LED indicator array. The I/O provides three PWM connected to the red, green, and blue LEDs on the PCB and the front panel’s RGB LED indicator.
An assembler was developed in QT/C++ to aid in converting assembly programs into data cartridges. The assembler features a crude text editor with syntax highlighting, error indication, program line numbers (memory addresses), and jump addresses. The assembler generates special files containing #defines of instruction and register indexes to keep the assembler and FPGA’s HDL synchronized. One of the special files is a RAM module containing hard-coded values of the assembled program that is copied over to the FPGA project files to aid in quicker develop and testing of the CPU and other modules. Instruction and register definitions are contained in a .csv file and loaded by the assembler which allowed for easy name changes during development.
The RGBY-ROM’s frame is constructed from 2020 aluminium extrusions providing a sturdy frame with multiple attachment locations for various brackets.
The electronics area is decently tidy.
RGBY-ROM uses an in house developed power distribution board.
The front tactile buttons are held in place using a custom 3D printed bracket.
The color sensor bar is belt driven by a dual shaft Nema 11 stepper motor 11HS20-0674D.
The Nema 11 stepper motor size and 36 teeth pulley combination holds the belt decently close the acrylic panel.
The opposite side of the belt is secured using a 3D printed idler and mounting bracket.
The color sensor bar’s home position, at the top of the frame, is determined by a limit switch. The image above shows the sensor mounting block connected to the drive belt using several 3D printed parts.
The color sensor bar is connected to the main board via a 11 position ribbon cable.
RGBY-ROM is mounted to the wall via a simple nail using this 3D printed bracket attached to the top of the frame.
Color sensor and motional controller tests were performed using a custom testing platform. The breadboard allowed for quickly connecting the TinyFPGA to the color sensor, stepper driver, and 8 channel digital logical analyzer. Sigrok’s PulseView GUI for the generic 8-channel logic analyzer was critical for debugging as the CPU and module waveforms became more complex. Sparkfun has tutorial for more information.
The testing platform shows the original intention of only using one color sensor. But, as development progressed on the frame and aesthetic design, creating a physical X/Y motion system in a confined space proved cumbersome at the time. The color sensor bar with 12 individual sensors works great and met the aesthetic goal.
The RGBY-ROM was an enthralling project diving into many languages, applications, technologies: ASM, C++, HDL/Verilog, schematic design, PCB design, AutoCAD, TinkerCad, QT Creator, Atom/APIO, PulseView, Diptrace, Cura, 3D printing, laser engraving, etc.
- A CRC (cyclic redundancy check) should of been added to the final 6 nits of the data cartridge to unsure ROM data was read correctly.
- A linear rail or linear rod system for the motion system would remove the need for the roller bearings on the color sensor bar.
- Adding a row of predetermined nit colors along with color sensor calibration methods could increase the color density of the nits from four to eight colors.
- The color sensor bar PCB should have jumpers to select output frequency scaling for potential code changes.
- The color sensor bar should have bypass caps near the multiplexors and sensors. The main board stepper driver should have a 100uF capacitor near the motor voltage pins.