Introduction: Mini Retro SPY×FAMILY TV

This instructables shows how to build a SPY×FAMILY version of Mini Retro TV.

This is a simplified version of my previous project, Mini Retro TV. It only requires 5 components and some DuPont wires to make it.

This item is designed for simple assembly. STEAM students should be able to assemble it without issue.

Supplies

Step 1: Research

In SPY×FAMILY anime, there are 2 TV models.

The first TV model sit inside a cabinet at the first rental apartment. It only appear in episode 1, for some reason they rent another apartment afterward.

The second TV model stand on the living room corner of second rental apartment. The second TV model appears in many home scenes across season 1 to season 2 and should also in future seasons. So this project will build the second TV model.

Step 2: Model TV Panel

The TV panel have some minor variations in each scene and the design need to trade off some hardware limitations. There are 1 knob and 7 buttons on the TV panel, the knob become a clickable button and other 2 big buttons also become buttons. So it have 3 buttons.

Begin an ESP32-C3 dev device, it is better can operate boot and reset easily. So I assigned the biggest button as reset, the below 2 buttons assigned GPIO 0 and 9. The programmed function are up and down buttons for switching "channel".

The screen aspect ratio has a little bit difference but should be acceptable.

Step 3: Print 3D Model

Please download and 3D print the model at thingiverse:

https://www.thingiverse.com/thing:5759790

Note:

The antenna model have few versions, it depends on what type of antenna you want to build.

The legs model also have 2 versions. If you found the leg of normal version break easily, try the long version that have thicker legs.

Step 4: Prepare Media

Anya loves watching SPY WARS in the story, so I will collect the SPY WARS scenes for playing in this TV. There are 3 full screen scene in episode 5, 15 and 20. After conversion, it can just fit in the ESP32-C3 3MB flash file system. And the SPY WARS cover can be found at episode 1.

In previous projects research, ESP32-C3 is capable playing 288x240 MJPEG video in 12 FPS and playing mono 44100 sample rate MP3 audio at the same time. For the file size concern, the framerate is trimmed to 10 FPS.

Here are the shell scripts for the conversion:

#EP05
ffmpeg -i spy_family/EP05.mp4 -ss 07:25.70 -t 00:31.90 -vf "scale=320:264:flags=lanczos,crop=288:240:(in_w-288)/2:0" EP05.mpg
ffmpeg -i spy_family/EP05.mp4 -ss 07:25.70 -t 00:31.90 -ar 44100 -ac 1 -ab 32k -filter:a loudnorm -filter:a "volume=-5dB" EP05.mp3
ffmpeg -i spy_family/EP05.mp4 -ss 07:25.70 -t 00:31.90 -vf "fps=10,scale=320:264:flags=lanczos,crop=288:240:(in_w-288)/2:0" -q:v 11 EP05.mjpeg

#EP15
ffmpeg -i spy_family/EP15.mp4 -ss 20:00.00 -t 00:12.00 -vf "scale=320:264:flags=lanczos,crop=288:240:(in_w-288)/2:0" EP15.mpg
ffmpeg -i spy_family/EP15.mp4 -ss 20:00.00 -t 00:12.00 -ar 44100 -ac 1 -ab 32k -filter:a loudnorm -filter:a "volume=-5dB" EP15.mp3
ffmpeg -i spy_family/EP15.mp4 -ss 20:00.00 -t 00:12.00 -vf "fps=10,scale=320:264:flags=lanczos,crop=288:240:(in_w-288)/2:0" -q:v 11 EP15.mjpeg

#EP20
ffmpeg -i spy_family/EP20.mp4 -ss 17:02.00 -t 00:14.00 -vf "scale=320:264:flags=lanczos,crop=288:240:(in_w-288)/2:0" EP20.mpg
ffmpeg -i spy_family/EP20.mp4 -ss 17:02.00 -t 00:14.00 -ar 44100 -ac 1 -ab 32k -filter:a loudnorm -filter:a "volume=-5dB" EP20.mp3
ffmpeg -i spy_family/EP20.mp4 -ss 17:02.00 -t 00:14.00 -vf "fps=10,scale=320:264:flags=lanczos,crop=288:240:(in_w-288)/2:0" -q:v 11 EP20.mjpeg

Step 5: Software Preparation

Arduino IDE

Download and install Arduino IDE latest 1.x version if not yet:

https://www.arduino.cc/en/software

Arduino-ESP32

Follow installation step to add Arduino-ESP32 support if not yet:

https://docs.espressif.com/projects/arduino-esp32/en/latest/installing.html

Arduino_GFX Library

Open Arduino IDE Library Manager by selecting "Tools" menu -> "Manager Libraries...". Search "GFX for various displays" and press "install" button.

You may refer my previous instructables for more information about Arduino_GFX.

JPEGDEC

Open Arduino IDE Library Manager by selecting "Tools" menu -> "Manager Libraries...". Search "JPEGDEC" and press "install" button.

arduino-libhelix

This project use Helix decoder for playing MP3 audio. Download and import the arduino-libhelix library to Arduino IDE:

https://github.com/pschatzmann/arduino-libhelix.git

You may refer to Arduino Documentation for the details on how to import library to Arduino IDE

arduino-esp32fs-plugin

Follow installation step to add Arduino-esp32fs-plugin if not yet:

https://github.com/lorol/arduino-esp32fs-plugin

Step 6: Code Walk Through

Declare Constants

const char *jpeg_file = "/SPY_WARS.jpg";
const char *mp3_files[] = {
"/EP05.mp3",
"/EP15.mp3",
"/EP20.mp3"};
const char *mjpeg_files[] = {
"/EP05.mjpeg",
"/EP15.mjpeg",
"/EP20.mjpeg"};
#define FPS 10
#define MJPEG_BUFFER_SIZE (288 * 240 * 2 / 10)
#define UP_BTN_PIN 0
#define DOWN_BTN_PIN 9

Declare Display Class

You may find more Arduino_GFX data bus and display class details at Wiki.

#include <Arduino_GFX_Library.h>
#define GFX_BL 11
Arduino_DataBus *bus = new Arduino_ESP32SPI(6 /* DC */, 7 /* CS */, 2 /* SCK */, 3 /* MOSI */, GFX_NOT_DEFINED /* MISO */, FSPI /* spi_num */);
Arduino_GFX *gfx = new Arduino_ST7789(bus, 10 /* RST */, 1 /* rotation */, true /* IPS */, 240 /* width */, 288 /* height */, 0 /* col offset 1 */, 20 /* row offset 1 */, 0 /* col offset 2 */, 12 /* row offset 2 */);

Init Display

Start with data speed 80 MHz and fill in black color.

gfx->begin(80000000);
gfx->fillScreen(BLACK);

Init I2S Audio

esp_err_t ret_val = i2s_init(I2S_NUM_0, 44100, -1 /* MCLK */, 4 /* SCLK */, 5 /* LRCK */, 8 /* DOUT */, -1 /* DIN */);

Init Filesystem

if (!FFat.begin(false, "/root"))

Allocate Video Frame Buffer

For each video frame, first read from the video file and then pass it to the JPEG decoder. So it need a buffer memory in the middle.

mjpeg_buf = (uint8_t *)malloc(MJPEG_BUFFER_SIZE);

Display Cover

The cover is saved as JPEG image file. The decode method of JPEG and MJPEG files are the same, so it can reuse the MJPEG decoder for display a JPEG file.

mjpeg.setup(&jFile, mjpeg_buf, drawMCU, true /* useBigEndian */, 0 /* x */, 0 /* y */, gfx->width() /* widthLimit */, gfx->height() /* heightLimit */);
mjpeg.readMjpegBuf();
mjpeg.drawJpg();

Init Buttons

Set up the up and down button pins to input mode and pulled up. And then attach the interrupt functions for handling button pressed.

pinMode(UP_BTN_PIN, INPUT_PULLUP);
attachInterrupt(UP_BTN_PIN, up_btn_pressed, FALLING);
pinMode(DOWN_BTN_PIN, INPUT_PULLUP);
attachInterrupt(DOWN_BTN_PIN, down_btn_pressed, FALLING);

Loop Routine

  1. Check button pressed
  2. If button pressed, close previous opened files and open new file for playing
  3. If no button pressed, continue playing if any

Step 7: Upload Program

The program can be uploaded to the dev board before connect to any components. The uploaded program can help you test the connection once you connected to a component. So let's upload the program at the beginning.

Clone or download the source from GitHub:

https://github.com/moononournation/MiniTV

Then:

  1. Open ESP32_C3_SPYWARS/ESP32_C3_SPYWARS.ino in Arduino IDE
  2. Select ESP32C3 in "Tools -> Board"
  3. Select dev board serial port in "Tools -> Port"
  4. Press Upload button
  5. Select "Tools -> ESP32 Sketch Data Upload"
  6. select "FatFS" and press "OK" for upload data files

Step 8: Connections

Here are the connection summary:

ESP32-C3    LCD  MAX98357A  Buttons
======== === ========= =======
GND -> GND GND PCOM
3.3V -> VCC
5V -> Vin
GPIO 02 -> SCL
GPIO 03 -> SDA
GPIO 10 -> RES
GPIO 06 -> DC
GPIO 07 -> CS
GPIO 11 -> BLK
GPIO 05 -> LRC
GPIO 04 -> BCLK
GPIO 08 -> DIN
GPIO 09 -> 3rd button
GPIO 00 -> 2nd button
EN -> 1st button

Please follow the video for the connection and testing steps:

https://www.bilibili.com/video/BV1cg411s7nx/

Step 9: Case Assembly

Please follow the video for the case assembly steps:

https://www.bilibili.com/video/BV1YA411f7zd/

Step 10: Coloring

I like the full white version of the Retro TV, but it still better put on the color.

Coloring 3D model has various methods. The simpliest way is direct print with color filaments, but given that you have all required color filaments in hand. Coloring with water based marker on the white model is also a good choice.

Step 11: Antenna Variations

The TV antenna is too thin and has exceeded the limit of FDM 3D printing. So I use the T-pins act as the thinnest part. If you do not have T-pins in hand, you can using another variations. simply screw up the another version of antenna base then use some bent breadboard wires paperclips or even SIM card pins act as the antenna.

You can see the assembly steps of alternative antenna in color version assembly video:

https://www.bilibili.com/video/BV1SD4y1V796/

Step 12: Enjoy!

Anything Goes Contest

Runner Up in the
Anything Goes Contest