This tutorial shows you how to build your own globe of persistence of vision.
First, what is a globe of persistence of vision? The idea is to rotate a column of LEDs fast enough for giving the impression of an entire globe of pixels (typically more than 10 rounds per second). If we can change the colour of the LEDs in synchronization with the rotation, we display neat columns of pixels.
This device was designed by two students of Télécom Bretagne (Brest, FRANCE) and was selected in the Digilent Design Contest 2015. The project is still ongoing so this tutorial might evolve in the future months. The current state of the project is summed up in the video above.
For building the device using this tutorial, you'll need the following material:
- The Zybo board from Digilent
- The Neopixel LED strip from Adafruit
- A 12 wires slip ring like this one from Adafruit
- The GP1A57HRJ00F Sparkfun photo interrupter breakout board and the GP1A57HR photo interrupter that you can find here and here
- A 12V DC motor
- A micro SD card
- A cross-compiler for ARM processors
This tutorial follows the same path than the project and is divided in the following steps:
- Using the globe VHDL architecture
- Building the extension board
- Installing Linux on the globe
- Preparing the micro SD card
- Building the globe mechanical structure
- Welding the wires
- Using the globe
Step 1: Using the Globe VHDL Architecture
First, get and install Vivado webpack:
- Go to http://www.xilinx.com/support/download.html
- Go to Vivado and sdk standalone web install client
- Select your OS
- Download the file
- Install Vivado webpack and the SDK by following the instructions given
Then, download the base system design for your board and use it with Vivado:
In this example, we will use the ZYBO from Digilent.
- Go to https://www.digilentinc.com/Products/Detail.cfm?P...
- Download the ZYBO Base System Design
- Extract the file
- Launch Vivado
- Click on open file
- Open the file zybo_bsd.xpr which is in the folder: zybo_base_system\source\vivado\hw\zybo_bsd
- Select Automatically upgrade to the current version (if offered)
- Then click on Report IP Status and choose Upgrade Selected and OK
- Close the warning window (don’t worry about it) and go to Tools/Create and Packages IP
Create the IP for the globe:
We will now use the IP packager of Vivado to insert the globe as an IP in the global system.
- When you see the window above you have to click on next and then Create a new AXI4 peripheral
- Then name the peripheral as you want (you can add a little description)
- For the AXI interface you have to let the name S00_AXI and select the type Lite and the mode Slave. Data width should be 32 and the rest doesn’t matter
- Finally you can click on next and select Edit IP then Finish
Integrate the source code in the IP:
We have now the IP packager opened; we will insert the source code in this IP in order to the correct system.
- First download the archive file
- Delete the file present in the IP and import all the file from the archive folder (right click/add sources/create or add design source)
- Then click on the tab Package IP and do everything asked for each part and finally click on Re-Package IP
- You are now back to the main window of Vivado
- Do a right click on the diagram and choose Add IP then select your IP (your IP is now added to the system you will have to connect your IP to it)
- For all the external ports (LED0-5, PWM_OUT and INFRA_SENSOR) do a right click on it and choose Make External (you will have now all the external port of the globe created)
- Then double click on the AXI Interconnect and add one Master interface
- Now connect this new Master interface to your S00_AXI
- Then connect M08_ACLK and M08_ARESETN to the other one
- Then connect your s00_axi_aclk and s00_axi_aresetn to the previous one
- In the tab Address Editor and right click on your IP and select Auto Assign Address
- In the Sources tab right click on the system_i and select Generate Output Products
- And then click again on it and select Create HDL Wrapper
- Finally update the constraint file base.xdc (the following pictures is an example)
- You can now generate the Bitstream
Generate the FSBL:
You have now the system_wrapper.bit generated. You will now generate the FSBL file.
- At the end of the Bitstream generation a window appears: close it and go to the File/Export/Export hardware and select include bitstream then click on OK
- Go to File/Launch SDK (and follow the different steps)
- Once the SDK launches go to File/New/Board Support Package and click on Finish then select the library xilffs, xilrsa and xilmfs and then OK
- Go to File/New/Application Project give it a name click on use existing (select the board package you just created) and Next
- The FSBL is generated!
If you have any difficulty during the process, you should see the pdf which shows some pictures to help you.
Step 2: Building the Extension Board
For connecting the Zybo to the globe, we need to build an extension board that will fullfill the following functions:
- Converting the 3.3V signals from the FPGA to 5V signals for the LEDs
- Controlling the motor rotation
- Supplying power to the whole system
The electronic scheme of the board is shown above.
For designing this board, you will need to download and install Eagle. It is a free software for designing electronic boards. After setting it up, you can download the two files analog_v3.sch and analog_v3.brd. You will need the library perso.lbr to find some customized components.Those are the scheme of the board and its layout. You can use the layout if you have the facility to print it. Otherwise, you will only need the scheme to design your own layout.
Here is a list of special components you need for building the board:
- 2 logic converters TXB0104, you can find them here
- Voltage regulator PTR08100WVD of Texas Instrument
- An optocoupler MOC3041M
The result is shown above. It is advised to use a right-angle connector for connecting the extension board to the Zybo.
Step 3: Installing Linux on the Globe
It is time to set up Linux on the ARM processor of the Zynq. For practical reasons, we want the system to be on a micro SD card. This step must be completed on a Linux based operative system.
For this step, you will need the First Stage BootLoader and the globe bitstream compiled in step 1.
But before getting started, let's give some explanations.
The bitstream you compiled contains the configutaion of the programmable logic of the Zynq. As we want to use the ARM processor of the Processing System of the Zynq, we also need to configure it as to launch a Linux based operative system when booting. The First Stage BootLoader will be the first program executed and will initialize the processor's resources (clocks and memory) so that a larger bootloader can be loaded. This second and larger bootloader is U-Boot, it is responsible for loading and executing the Linux kernel. The Linux kernel will need its file system to work. For the sake of simplicity, this file system will be loaded on the RAM of the Zynq.
To compile U-Boot, download the sources on github using the following commands:
- git clone https://github.com/Xilinx/u-boot-xlnx.git
- git checkout e2d21cedaa70356fa2f45729d9401933c9c0cfd4
- Enter the U-Boot folder and type:
- make zynq_zybo_defconfig
To compile the linux kernel, download the sources first:
- git clone https://github.com/Xilinx/linux-xlnx.git
- git checkout 7ad8e6023d969336961312ef751228cbb8874752
- Before compiling, you'll need to replace the file .config by the file linux-config. After, you type the following commands:
- make menuconfig
To generate the initramfs (compressed image of the Linux file system), you will need Buildroot:
- git clone git://git.buildroot.net/buildroot
- git checkout b8a8ecd43b81fc2fda90ce24be8914a074fa5fd5
- You need to replace the file busybox-config by the one given. You also need to replace the file .config by the file buildroot-config given. This new .config file must be modified as to correspond to your environment. Those two lines may have to be replaced:
- For the first line, enter the path of the folder containing the ARM cross compiler.
- For the second line, enter the path which lead to the busybox-config file of the buildroot folder.
This part is optional. It will enable Linux to automatically mount your applications and drivers and configure them.
- You go in the Buildroot folder, you enter the /target/ folder, you should see the generated file system.
- You can modify the etc/init.d/rcS file and add those few lines at the end:
- mount /dev/mmcblk0p2 /mnt
- source /mnt/load.sh
Now we will generate the boot files. You will need to download the file Makefile-bootgen and rename it in Makefile. In the same folder, you will download the files zynq-zybo.dts and bootimage.bif. Copy the FSBL in your working directory and rename it in zynq_fsbl.elf. Copy the u-boot file from your u-boot directory and rename it in u-boot.elf. Copy the file zImage from your git linux folder (arch/arm/boot/zImage). Copy the ramfs from your buildroot directory (it is output/images/rootfs.cpio.uboot) and rename it in uramdisk.image.gz. After you launch the boot files generation with a "make". Then you just have rename the file output.bin in BOOT.bin and uImage.bin in uImage.
Step 4: Preparing the Micro SD Card
We want the system to boot on the micro SD card. We need to prepare our micro SD card as to contain both the boot files and the applications.
We will create two partitions on our micro SD card: the first in FAT32 to contain the boot files and the second one in ext2 to contain the applications. The following instructions tell you how to do it (the bold instructions are command to type):
- cd /dev
- plug in the micro SD card
- check the name of the last device plugged, the micro SD card, let's suppose it is sdc
- fdisk sdc
- command, type "o" to create a new partition table
- command, type "p" and check no partition are on the micro SD card
- partition type, type "p" for primary
- type "1" for the partition number, type "+32M" for the size
- command, type "t" to change the format of the partition, choose W95 FAT32
- command, type "n"
- partition type, type "p" for primary, type "2" for partition number, let the default size
- command, type "w" to save the partitions
- mkfs.fat /dev/sdc1
- mkfs.ext2 /dev/sdc2
Those instructions need to be done only one time.
If you have not successfully compiled the boot files or if you don't want to, just download the boot files and extract them.
After, you can mount the two partitions. In the first, you copy the boot files:
In the second, you can copy the compiled applications, the drivers and the load script. The files are given:
- custom_module.ko (contains the drivers of the globe)
- load.sh (script used to load the custom module)
- jo (an application that displays the olympics' flag on the globe and make it rotate)
- word (an application that displays "hello world!" in the colour given)
- long_word (an application that displays a very long text on the globe)
- speed_control (set the rotating speed of the globe to the value given)
Step 5: Building the Globe Mechanical Structure
You can see the whole mechanical structure in the pictures above.
For this part, you will need the following materials:
- A motor able to rotate fast (the one used in the design can be found here)
- Wood or plastic boards
- The presses around the motor shall be in metal as to optimize the motor cooling
- Two pulleys and a belt
- Two ball bearings on the hollow axis
- One ball bearing above the motor
Our design was entirely based on the chosen motor and on the materials we had.
However, we strongly advise you to keep the structure: the hollow axis to enable the wires to connect the globe to the slip ring, the system to hold the motor and align it with the hollow axis.
You can see pictures of the different parts of the globe. You can find the design sources, Solidworks files if you have Solidworks installed, STL files that could be used directly by a 3D printer for example and the drawings of the different pieces.
Once you have made all the pieces, you need to fix the small part of the slip ring in the hollow axis; you fix its big part on the block below. Do not forget to pass the wires of the small part of the slip ring through the entire axis. After, you just need to cut the LED strip in 6 strips of 16 LEDs. You stick them on the ring symmetrically considering the rotation axis. To stick the LEDs’ ring on the hollow axis, you should screw it on the adaptation piece. To stick the ball bearings on their structure or the adaptation piece on the hollow axis, you should use threaded pins. Then you can assemble the structure holding the LEDs’ ring and its axis. Next, you should jam the motor in the metallic presses (let the aeration in open-air), and assemble all the rest. At the end, you set the driving belt tension and vertical alignment (the driving belt must be just a little loose, if the motor cannot rotate the globe, you should relax the belt).
Step 6: Welding the Wires
Now, you should have a complete globe of persistence of vision.
However, the slip ring is useless if we do not use it to connect electrically the rotating part of the globe (the LEDs) to the extension board.
You must build a connector for the extension board with the wires of the steady part of the slip ring. You can connect them in any order you want to the extension board. Nevertheless, you should keep the same order to connect the wires from the other part of the slip ring to the LED' strips. The LED' strips must be connected to the extension board in the right order, which is shown on the scheme above.
You can also use the same order we used. You can see it on the picture and in the pdf.
You should connect the data pin of each LED' strip to its corresponding slip ring wire. For the power supply, just keep in mind that one pair of slip ring wires (GND and 5V) must connect two different strips.
To connect the infrared barrier to the extension board correctly, check on the second step.
To supply power to the FPGA, you will need to have a jack connector that fits and connect it to the extension board after checking the sense (make sure to not reverse GND and 5V).
Step 7: Using the Globe
Now it's time for fun !
You can use two power sources (12V and 5V) or only one (12V). The 12V power sources must be able to supply at least 10A. If you use two power sources, the 5V one must be able to supply 6A. You must set the power jumpers accordingly:
- The FPGA jumper must be set as to connect the FPGA power supply to the right power supply (5V in the Zybo case)
- If you use two sources, the other two jumpers mustn't be put. If not, place the jumpers as they are on the picture step 2
For each power supply, you can use two types of connectors: jack or block connector.
Before connecting any external component (including the FPGA), check the indicator lights on the board.
If it is right, switch the power supplies off and connect all the components (slip ring connector, infrared barrier, motor and FPGA). Fpr booting on the micro SD card, do not forget to set the boot jumper
Switch the power supplies back on (the FPGA power switch must be off).
Connect the UART USB port of the FPGA to your PC. Launch putty or any other program able to make a serial communication, set the correct port (COM21 on Windows) and speed (115200 bauds).
Then, you can turn on the FPGA and the serial communication. If it works, you should see Linux booting on the putty window. Wait until Linuw asks for login/password (root/root) and type them.
Now you can enter the "/mnt" folder, you should see the content of the second partition of the card (drivers and applications). You can test the applications:
- jo: display the olympics flag and make it rotate on the globe
- word <color>: display "HELLO WORLD!" in the given color and make it rotate
- long_word <color>: display a very long text in the given color by making it appear on the globe using a sliding window
- speed_control <speed>: set the speed to the given value (between 0 and 255)
The applications start the globe rotation but they do not stop it at the end, you must use speed_control to stop the rotation.
If the texts are displayed backwards, just invert the two motor wires.
If you wish to go further and make your own applications, you can download the sources below. It contains the application sources and the drivers (custom_module.c). It also contains a Makefile. Before using it, do not forget to change the KERNEL_DIR for the path leading to the folder containing the linux you compiled earlier. Your application to compile is named app.c.