Cheap Yellow Display Window
by jonathanr4242 in Circuits > Arduino
320 Views, 1 Favorites, 0 Comments
Cheap Yellow Display Window
I built a “window” using ESP32 Cheap Yellow Displays (CYDs) as the glass panels.
The setup uses:
- 16 CYDs arranged in a 4×4 grid
- A Raspberry Pi Zero with a camera on a servo pan-tilt
- The Pi captures video, splits it into tiles, and streams each tile to a display
Each screen shows a portion of the image, so together they act like a digital window.
Touching a screen moves the camera, so you can “look around” like a real window.
The full code is here:
https://github.com/jonathanrandall/CYD_window
How It Works (Quick Overview)
- The Raspberry Pi captures video
- It splits the image into a grid (default 4×4)
- Each display subscribes to a specific tile. For example, the display at position (0,0) receives the top-left image.
- Touch input from a CYD sends a command back to the Pi
- The Pi moves the camera using the servos
Supplies
Supplies
You will need:
- Raspberry Pi Zero WH (WiFi + headers required)
- Raspberry Pi Camera
- 2 × Servos (MG996R is preferred but SG90 should also work)
- Servo pan-tilt bracket
- PCA9685 servo driver (I2C)
- 16 × Cheap Yellow Displays (ESP32)
- Adjustable buck converter (~6V for servos)
- 3 X 5V regulators (for Pi and CYDs)
- Batteries (2S or 3S LiPo)
- Switch
- WAGO connectors
- Wire (12–16 AWG for power)
- Jumper wires
- Wood (or other material) for frame
Note: There are many ways to power and build this. For example, the Pi can run from a power bank, and the frame can be wood, aluminium, or 3D printed.
Setup the Raspberry Pi
Install dependencies:
Enable I2C:
Clone the repo:
Getting the Camera Streaming
In this step we get the Raspberry Pi camera streaming sub-images over the network. We test that everything is working on the Pi before connecting the ESP32 Cheap Yellow Display. This step is important. It allows you to debug networking and streaming issues before adding the ESP32 displays.
Place these files on your Pi:
Run the stream:
Open in your browser:
Using the .local hostname avoids issues where the Pi’s IP address changes. This is important because the ESP32 code uses a hard coded address.
Expected Result
- A 4×4 grid of live camera images. You can change the grid_size parameter in the python code to vary this.
- Smooth updates (not necessarily high FPS)
If It Doesn’t Work
- Try using the IP instead:
- Check WiFi connection
- Make sure port 7123 is reachable
You should see the camera stream to a 4x4 grid (16 images). The grid size is set to 4 in the python code.
Building the Servo Pan-Tilt
In this step we assemble the servo pan-tilt mechanism and mount the raspberry pi, raspberry pi camera and pca9685 servo driver on it. The freecad file and STL files shown in the images are in the git repo for this project (directory print_files_3D). In the next step, we will set up the power/battery connections for the pan-tilt mechanism.
Assemble:
- Pan-tilt bracket with 2 servos and (optional) 3d printed base mount.
- Camera mount (3d printed mount also holds raspberry pi)
- Raspberry Pi + camera
- PCA9685
Important
Center the servos before assembling (use a servo tester or script).
Wiring (PCA9685 → Pi)
- SDA → GPIO2
- SCL → GPIO3
- VCC → 3.3V
- GND → GND
Powering the Raspberry Pi Zero and the Servos
In this step, we set up the battery connection for the pi zero WH and the servos. For this step I use two voltage converters, a variable buck converter set at 6V for the servos, and a fixed 5V converter for the pi. While it is possible to run both off the 5V converter, its not recommended because the current draw from the servos can cause ripple on the pi voltage. The pi needs a good quality voltage signal.
Use:
- 5V regulator → Raspberry Pi
- ~6V buck converter → servos
Why separate supplies?
Servos draw high current spikes, which can cause voltage drops and instability on the Pi.
Wiring Overview
- Battery → switch → WAGO
- WAGO → regulators
- 5V → Pi
- 6V → PCA9685 (V+)
- Servos → PCA9685
Expected Result
- Pi boots normally
- Servos don’t jitter or reset the Pi
Other power options are possible. For example, a power bank may work for the pi zero W, but the servos will still require a separate supply.
At this point we should have:
- the servo driver and the pi connected to the battery
- the servos connected to the servo driver
- the servo driver connected to the i2c of the pi.
Test the Servos
In this step we get the servos up and running.
Run:
Observe direction:
- Note which way the camera moves when duty cycle value increases
Now test via browser:
Expected Result
- Camera moves diagonally to face bottom right
This is intentional: touching a part of the “window” moves the camera in the direction you would naturally look.
For example touch00 is the command the top-left touchscreen tile will send to the Raspberry Pi when it is pressed. We want the top-left screen to move the camera diagonally down and to the right, because that corresponds to the direction you would look if this were a real window. The code is set up, so if you touch one of the corner CYDs, the servos move in the opposite diagonal from that corner, if you touch the top (not corner) the servos move down and if you touch the right side, the servos move left.
Try:
If Direction Is Wrong Adjust the servo direction (if needed)
If the servo moves in the wrong direction, you can reverse it by editing the stream_server7.py file: Change the + or - signs for SERVO_STEP in the function:
This allows you to match the servo movement to your specific servo orientation.
Run at Startup (Optional)
It's a bit of a drag to have to remote into the pi every time it turns on and off and restart the python script. In this step, we get the pi to start the streaming server at start up. So, all we have to do is power on the pi and the program will start. This is achieved with a systemd service.
First create the service file:
Then enter the following text into the file. Don't forget to change the directory path "/hom/jonny/rnt_stream/" to match the location of your python file.
Now enable the service with the following commands. Don't forget to restart.
Note:
To stop the service you can type
To disable the service type
Setup the Cheap Yellow Displays
In this step we will get the ESP32 Cheap Yellow Display displaying the video stream from the raspberry pi. The code for this step is in the esp32_tft_side_v2 directory of the github repo. Each display automatically requests a different tile based on its configured position.
Use Arduino IDE:
- Board: ESP32 Dev Module
- Library: TFT_eSPI
Update:
Set WiFi credentials in the .ino.
Upload to all 16 CYDs.
Expected Result
- Each screen shows part of the image
Note:
I'm using Bodmer's TFT_eSPI library for the display on the Arduino IDE. The library should be installed in your Arduino/libraries directory. On my machine the full path is:
/home/jonny/Arduino/libraries/TFT_eSPI/
You will need to update the User_Setup.h file. For most cheap yellow displays, the User_Setup.h in the github repo should work.
Building the Frame
Parts for this step:
- Six wooden beads, approximately 60cm (24 inches) each: four for the horizontal crossbars and two for the vertical crossbars. I used 12mm X 12mm square timber beads. Tip: Measure out the placement of the CYDs before cutting the beads down.
- Paint. I'm using red spray paint.
- 32 X M3 screws and nylon standoffs. The CYD has an M3 mounting hole. I'm using 20mm M3 screws and 15mm standoffs.
- Wood screws to join the frame together. You will need to choose your screw length according to your bead dimension.
- Drill.
Steps for Making the frame:
- Paint and/or decorate the wooden beads or before putting together.
- Take the top (horizontal) bead and drill the holes for the CYDs. I drilled the right hole for the first CYD (top right), and then used the CYD to measure the correct distance between the holes. I've left around 35mm (1.4 inches) between adjacent CYDs measuring from mount to mount. In retrospect, I probably would've made the spacing bit smaller.
- Drill smaller crossbar attachment holes on the left and right hand side of the bead. These will be used to attach the vertical crossbars.
- With the next three horizontal wooden beads, stack them with the top bar on top, so that you can use the top bar as a stencil to drill the remaining holes. This will ensure all holes are lined up..
- On each of the two vertical crossbars, drill four holes about 70mm (2.8 inches) apart.
- Attach to vertical crossbars at the left and right ends of the horizontal crossbars with wood screws, making sure that everything is lined up neatly.
- Attach the nylon standoffs to the frame, so that it is ready to mount the CYDs on.
Powering the Cheap Yellow Displays
Each CYD uses:
- GND
- VCC (5V)
The I2C cable can be used for power:
- Red = VCC
- Black = GND
- SDA/SCL not used
Wiring Strategy
- Split into rows
- Use WAGO connectors
- Feed from 5V regulators
Important Note
You may need:
- Multiple regulators
- Separate batteries
If you see:
- flickering
- slow startup
- random resets
→ this is almost always a power issue
Now, get the screens receiving the image.
Power up the raspberry pi and servos. The pi should be configured to run the python code at startup.
Switch on the battery that is connected to the CYDs. The CYDs should start receiving the images. It may look jumbled because the positions are not configured.
Configure the Screens
On startup, each CYD shows a colored grid.
You have ~2 seconds to select its position.
Process
- Tap the correct tile in the grid that corresponds to the screen position
- Repeat for all screens
Notes
- You may need to restart a few times
- Configuration is saved after so there is no need to reconfigure unless you move one of the screens
Final Setup
Steps:
- Mount the frame
- Place the camera
- Power on Pi first
- Wait for stream
- Power on CYDs
Expected Result
- Full “window” image
- Touching screens moves the camera
Common Problems
Screens glitching
→ Power issue (most common)
Can’t access .local
→ Use IP address instead
Servos moving wrong way
→ Adjust SERVO_STEP
Slow startup
→ Normal with multiple displays + WiFi
Final Notes
- Works best with strong WiFi
- You can change grid size in code
- Frame design is flexible — wood, aluminium, or 3D print