I discovered the “Build A Simpsons TV” article in the Volume 79 issue of Make: magazine. The article is by Brandon Withrow and he did an excellent job documenting the build process in the article and on a dedicated web site: www.withrow.io/simpsons-tv-build-guide. As I embarked building my own Simpsons TV, I ran into issues being able to obtain the 2.8″ display specified in the build instructions as well as audio and OS issues. So, I thought I would take my learnings and present them here for others who might find them useful. In the end, I built my Simpsons TV using a 3.5″ display available on Amazon, fixed the audio issues, and enhanced the functionality of the project by adding play/pause, rewind, next video, change “channel”, exit python script, and safe power shutdown features.
Of particular note is the safe power shutdown feature. The Raspberry Pi OS features a journaling file system. This means that it can be writing to the SD card at any time. This can potentially be bad if you just remove power without executing a proper shutdown sequence. How bad can this be? Well, let’s just say that I’ve completely ruined several SD cards on Raspberry Pis before I learned this lesson (they had to be thrown away – nonrecoverable). To address this, I created a simple circuit using an Atmega ATtiny microcontroller to monitor the power switch, send a signal to the Pi to shutdown, monitor the activity LED signal on the Pi, then safely remove power from the Pi once all activity has ceased. There are other options to address the safe power shutdown needed by the Pi without using a dedicated microcontroller, which I’ll also cover in this Instructable.
This Instructable is rather long due to me including a lot of low-level details about all the steps required to build this project. My intent is to provide a fun learning experience on topics such as 3D printing, ATtiny microcontrollers, Raspberry Pi, Python, some Arduino, and soldering. I hope you enjoy!
Now, let’s get started…
Supplies
Most of the supplies are the same as those called out on Brandon’s website. I’ve copied them here for completeness with modifications based on my build.
3D Printed Parts (https://www.thingiverse.com/thing:5257326):
- TV Housing
- TV Front
- VCR
- Antennae Balls (2x)
- Power Switch Actuator
- Power Switch Base
- Volume Knob
- Volume Knob Base
- TV Foot (4x – Front Left, Front Right, Rear Left, Rear Right)
- Front Grille
Electronic Parts:
- AC to DC power adapter – 5VDC @3A with micro USB output connector
- Raspberry Pi Zero 2 W
- iUniker 3.5-inch Raspberry Pi Zero display, 480 x 320 resolution (Amazon)
- Adafruit mono 2.5W class D audio amplifier board (Amazon)
- 64GB Ultra Micro SDHC memory card (Amazon)
- ATtiny25 microcontroller (NOTE: ATtiny45 or ATtiny85 will work as well – they have the same pinout and functionality, just more memory – any variant will work, just get the DIP package version: Amazon)
- 8-pin IC DIP socket (Amazon)
- 1k Ohm potentiometer (I bought a kit of multiple values: Amazon)
- 6mm x 6mm x 6mm push micro momentary push button (2x – kit of switches: Amazon)
- 7mm x 7mm push-on/off push button (included in the kit of switches above)
- Micro USB to DIP adapter (Amazon)
- Gikfun 4 Ohm 40mm diameter 3W speaker (Amazon)
- IRF4905 P-FET power transistor or similar (Amazon)
- 40-pin, 2 x 20, extended pin socket header (Amazon)
- PC Board
- 100 Ohm, 1/4 W resistor (included in resistor assortment kit: Amazon or similar)
- 220 Ohm, 1/4 W resistor (included in resistor assortment kit)
- 330 Ohm, 1/4 W resistor (2x) (included in resistor assortment kit)
- 0.1uF 50V ceramic capacitor (2x) (Amazon)
- 1N4148 rectifier diode (2x) (Amazon)
- 1 pin header (snap off larger header – crimp sockets and header pin kit: Amazon or similar)
- 2 pin header, 0.1″ spacing (2x) (snap off larger header from header kit above)
- 1 pin DuPont socket with female crimp pin (3x) (included with crimp socket kit above)
- 2 pin DuPont socket with female crimp pins (4x) (included with crimp socket kit above)
- 3 pin DuPont socket with female crimp pins (included with crimp socket kit above)
- Signal Wire (included with crimp socket kit above – usually 28 AWG)
- 22 AWG Wire – about 2 feet (half red/half black or similar: Amazon)
- ~1″ / 25mm of 30AWG solid wire (Amazon).
Tools & Misc Supplies:
- Soldering Iron
- Solder (I prefer Kester 0.020″ diameter 24-7068 lead-free as 60/40 Sn/Pb lead-based solders are toxic).
- Hot Melt Glue Gun
- Hot Melt Glue
- Super Glue (cyanoacrylate)
- Crimpers (for socket crimps – included with the crimp sockets and header pin kit mentioned above)
- Wire cutters
- Wire strippers
- Mini file set (with round and flat files – used to clean up 3D printed parts)
- Rustoleum Universal Paint and Primer gloss black spray paint or whatever paint you want to use to paint the bezel.
- Painter’s tape (for masking off the bezel area for painting)
- Cotton swabs
- Isopropyl alcohol
- Programmer for ATtiny (Arduino UNO or dedicated programmer such as AVRISP mkII or similar)
- 10uF capacitor (for Arduino UNO if it is used to program the ATtiny)
- USB keyboard (to set up Pi)
- USB micro to USB B converter (if needed to connect keyboard and USB thumb drive to Pi)
- HDMI mini to HDMI converter (if needed to connect HDMI monitor to Pi)
- Breadboard (used to aid in programming the ATtiny microcontroller)
- DuPont wires (used to connect programmer to ATtiny on breadboard for programming) (Amazon)
- 1/4″ diameter x 1/16″ thick (6mm x 1.5mm) neodymium magnets (4x) (Amazon). Other similar sizes can be used, but you may have to modify the TV housing and TV front 3D model files to fit.
- #6 x 3/8″ machine screws (2x)
Step 1: 3D Design
The 3D STL files Brandon provided were for a 2.8″ screen version. Unfortunately, STL files are not ideal for the significant modifications I needed to make to fit my 3.5″ screen version. So, I went searching on Thingiverse for possible alternates that would fit my 3.5″ screen. I did not find anything that fit it directly. However, I found the next best thing! On Thingiverse, I found that highping had remodeled the 3D design for Brandon’s Simpsons TV from the ground up for a 4″ HDMI screen – and – he was kind enough to include the Fusion 360 source files for his design. Also, his design featured two buttons on the VCR box that sits on top of the TV, so I was able to make use of those to implement the play/pause, rewind, next video, change “channel”, and exit Python script features (more on these later).
For my project, I made the following modifications to the Fusion 360 files from highping:
- Changed the display bezel area to accommodate my 3.5″ display
- Added screw holes to the VCR box and TV case to make it easy to service the buttons in the VCR should the need arise. This allows you to mount the VCR using two #6 x 3/8″ screws to the TV instead of gluing it.
- Changed the volume knob, volume knob base, power switch actuator, and power switch base to be compatible with the volume knob and power switch from Brandon’s original design.
- Extended the top front alignment edge to traverse the entire front – this acts as a light block to prevent the display’s backlight from bleeding out around the top gap between the TV housing and the TV front.
- Resized the circular holes for the speaker and the four magnets to fit the parts I had on hand.
- Added “foot stop” feature at the four bottom corners of the housing to act as secure stops and glue points for the four feet.
I have posted STLs, Fusion360, Autodesk 123D Design, and STEP file variants on Thingiverse (https://www.thingiverse.com/thing:5257326) to make it easy for most anyone to modify for their purposes.
Step 2: 3D Printing
A total of (14) 3D printed parts are needed (reference 3D Printed Parts in the Supplies section). I printed everything using a 0.4mm nozzle, 0.2mm layer height, and 30% infill out of black, light blue, and purple PLA plastic (I used 3D Solutech plastic from Amazon – but most any PLA will do – use what works best for you and your 3D printer).
The picture shows the print orientation and color I used for each part. I didn’t use any supports on the TV Housing, TV Feet, or Antennae Balls. I used minimal supports on everything else. I did not use any rafts, but printed multiple parts at the same time (or multiple copies) for smaller parts to allow some cooling time for each part in between printing layers – this helps improve print quality for the smaller parts (i.e. TV Feet, Knobs/Bases, Front Grille, and Antennae Balls).
After 3D printing, some light filing is usually needed around the base (where the part made contact with the 3D printer bed) or where support material meets a side edge of some of the parts (knobs/bases, front grille, VCR button holes, and antennae feet) in order for them to fit correctly with mating parts. I used a set of small files to do this. You can use a hot-air rework station after filing to remove the “whiting” effect of filing; Use minimal heat and quick passes of the hot air to prevent warping of the part. If you’ve never done this before, I suggest trying this on a piece of scrap 3D printed plastic to perfect your technique.
Step 3: Electronic Parts
The picture above Provides a visual reference of all the electronic parts used in this build variant of The Simpsons TV.
Step 4: Raspberry Pi Zero 2 W Pinout & Resource Usage
As you can see from the figure above, most of the Pi’s GPIO pins are used by the LCD screen.
The usage entries with the shaded backgrounds indicate DuPont socket connectors used to connect power, audio, VCR buttons, and the safe shutdown signal (Pi pins 2, 4, 6, 10, 22, 23, 35, 37, and 39 are used) . Additionally, the Status LED signal will be used; but, it must be accessed via a test point on the back of the board.
Step 5: Wire Audio Amplifier Circuitry
The audio output on the Raspberry Pi Zero 2 W is generally provided via PWM signals on GPIO18 and GPIO19. This project only uses one channel of audio, so it only uses GPIO19 and a mono audio amplifier. The original design uses this same approach, but I changed the audio circuit to:
- Reposition the 1k Ohm volume potentiometer from the output side of the audio amplifier to the input side. This is because these small potentiometers can be damaged by the larger current that they can be exposed to on the audio output side (at high volume / low resistance). Moving the volume potentiometer to the input side of the amplifier greatly reduces the current to which the volume potentiometer may be exposed.
- Added a Volume Knob circuit to address the “tinny” and scratchy audio issue. This circuit is comprised of a 100 Ohm resistor, 220 Ohm resistor, and 0.1uF capacitor (Note: The 1k Ohm volume potentiometer was added to the output of this circuit to provide the volume control on the input side of the audio amplifier). These components create a filter for the harsh PWM audio signal to smooth it out before feeding it into the audio amplifier. This greatly improves the audio quality.
The picture above shows the six steps to build the audio circuit. Steps one through five show the construction of the volume knob circuit while step 6 shows how to wire the complete audio circuit (volume control knob circuit, audio amplifier, speaker, and Raspberry Pi connectors). Details for each step are as follows:
- Step 1 – Cut a piece of the PC Board so that it is 3 holes wide by 5 holes high as shown in Step 1. This PC Board will be used to build the volume knob circuit.
- Step 2 – Position the 1k Ohm potentiometer on the 3 x 5 piece of PC Board. The orientation of the potentiometer matters as the knob is NOT centered top-to-bottom (but it IS centered side-to-side); note the position of the notched end of the potentiometer shown in Step 2.
- Step 3 – Flip the PC Board over, make sure the pins of the potentiometer are positioned as shown in the Step 3 picture, then solder the three pins.
- Step 4 – Solder the 220 Ohm resistor across the two outermost pins of the potentiometer on the bottom side of the PC Board. Then, solder one end of the 100 Ohm resistor to the right pin of the potentiometer/220 Ohm resistor junction. Insert the other end of the 100 Ohm resistor in the 4th hole as shown in the Step 4 picture – solder in place. Trim all component leads using flush-cut wire cutters.
- Step 5 – Solder the 0.1uF capacitor across the 220 Ohm resistor leads as shown in the Step 5 picture. Trim the capacitor leads.
- Step 6 – Use 28 AWG signal wire to wire the speaker, audio amplifier board, volume knob circuit and Raspberry Pi connectors as shown in the Step 6 picture:
- Wire the speaker to the amplifier with two signal wires about 4″ long (Purple and Blue). Solder all ends.
- Solder one end of a ~1/2″ piece of 30AWG solid wire (small blue wire) to the audio amplifier’s Audio IN(-) connection. Place the other end in of the 30AWG wire into the GND hole on the audio amplifier (BUT DO NOT SOLDER YET! – two more wires will need to be inserted into this hole before soldering).
- Solder three signal wires (Green, Yellow, and Orange) about 6″ long to the volume knob circuit board; one wire to the GND connection (Green), one wire to the Audio OUT connection (Yellow), and one wire to the Audio IN(+) connection (Orange). Crimp a female crimp pin on the other end of the Audio IN(+) wire (Orange) and then insert it into position 3 of a 3-position socket connector as shown in the picture.
- Solder the other end of the Audio OUT wire (Yellow) from the volume knob circuit to the Audio IN(+) connection on the amplifier board.
- Cut two more signal wires (Red and Brown) about 6″ long and solder one (Red) into the +5V power connection on the audio amplifier board. Crimp a female crimp pin on other other end of this wire and insert the female crimp pin into a 1-position socket connector. Insert the other wire (Brown) into the audio amplifier board’s GND connection hole along with the existing 30AWG solid wire (small blue wire) previously inserted there and the GND wire from the volume knob circuit (Green) – solder all three wires in this hole. On the other end of the audio amplifier GND wire (Brown), crimp a female crimp pin and insert it into position 1 of the 3-position socket as shown in the picture above.
NOTE: Of course, you can use whatever colors you like for the wiring scheme. The colors are mentioned here to match the pictures so that it’s easier to keep track of what wire goes where.
Step 6: Getting Ready to Program the ATtiny for Safe Shutdown Circuit
The ATmega ATtiny microcontroller can be programmed using the Arduino IDE. But, The Arduino IDE does not have this capability natively. So, this must be set up first. If you don’t have the Arduino IDE, install it by going to Arduin.CC.
- Step 1 – Open the Arduino IDE and select File -> Preferences. In the “Additional Manager URLs:” field, copy/paste the following URL: https://raw.githubusercontent.com/damellis/attiny/ide-1.6.x-boards-manager/package_damellis_attiny_index.json as shown in the first picture above.
- Step 2 – Click “OK“. Next, click on Tools -> Board -> Board Manager as shown in the picture above.
- Step 3 – In the Board Manager, scroll down the list to where it says “attiny by Davis A. Mellis“. Click on that and then click “INSTALL“.
This should add new entries in the Tools -> Board menu. However, there is additional functionality needed that is not installed by the attiny package.
Step 7: Adding Programming Brownout Protection Capability to the Arduino IDE
Even though the attiny package provides the ability to program the ATtiny microcontroller, it’s abilities to program configuration options are limited to just selecting the system operating frequency of the microcontroller; it does not provide a way to set brownout protection options. If brownout protection is not enabled, it might be possible to corrupt the microcontroller’s memory if voltage powering it falls below required operating levels. An external voltage monitor could serve this function as well, but why add the cost when the functionality is provided within the ATtiny itself? Luckily, adding the required functionality to the attiny package is easily accomplished.
There are three Fuse Bytes within the ATtiny that configure different options such as system clock source, brownout detection enable/disable and level, watchdog timer enable/disable, external reset enable/disable, and self-programming enable/disable to name a few. To enable brownout protection, the proper value must be programmed into the Fuse High Byte of the ATtiny microcontroller. If you want, you can read more on the ATtiny system architecture by reading the datasheet.
The attiny package provides the ability to program these three Fuse Bytes using the “Burn Bootloader” command in the “Tools” menu. But, the options are limited to just specifying the system clock source. Fortunately, it is simple to add the ability to program brownout detection and its level by making a simple modification to the “boards.txt” file installed by the attiny package. To do this, navigate to the “boards.txt” file in the “…/Arduino15/pacakages/attiny/hardware/avr/1.0.2/” directory on your computer. On a windows PC, this is usually located at the following location:
“C:\Users\<user>\AppData\Local]Arduino15\packages\attiny\hardware\avr\1.0.2\”
where “<user>” is the user profile logged into the computer and “1.0.2” is the version of the attiny package installed.
Once you have located the “boards.txt” file, open it in a text editor such as Notepad, Wordpad, Notepad++ or other. Locate and replace the following text:
ATtinyX5.menu.clock.internal8=Internal 8 MHz ATtinyX5.menu.clock.internal8.bootloader.low_fuses=0xe2 ATtinyX5.menu.clock.internal8.bootloader.high_fuses=0xdf ATtinyX5.menu.clock.internal8.bootloader.extended_fuses=0xff ATtinyX5.menu.clock.internal8.build.f_cpu=8000000L
with the following text:
ATtinyX5.menu.clock.internal8a=Internal 8 MHz, No BOD ATtinyX5.menu.clock.internal8a.bootloader.low_fuses=0xe2 ATtinyX5.menu.clock.internal8a.bootloader.high_fuses=0xdf ATtinyX5.menu.clock.internal8a.bootloader.extended_fuses=0xff ATtinyX5.menu.clock.internal8a.build.f_cpu=8000000L ATtinyX5.menu.clock.internal8b=Internal 8 MHz, BOD = 1.8V ATtinyX5.menu.clock.internal8b.bootloader.low_fuses=0xe2 ATtinyX5.menu.clock.internal8b.bootloader.high_fuses=0xde ATtinyX5.menu.clock.internal8b.bootloader.extended_fuses=0xff ATtinyX5.menu.clock.internal8b.build.f_cpu=8000000L ATtinyX5.menu.clock.internal8c=Internal 8 MHz, BOD = 2.7V ATtinyX5.menu.clock.internal8c.bootloader.low_fuses=0xe2 ATtinyX5.menu.clock.internal8c.bootloader.high_fuses=0xdd ATtinyX5.menu.clock.internal8c.bootloader.extended_fuses=0xff ATtinyX5.menu.clock.internal8c.build.f_cpu=8000000L ATtinyX5.menu.clock.internal8d=Internal 8 MHz, BOD = 4.3V ATtinyX5.menu.clock.internal8d.bootloader.low_fuses=0xe2 ATtinyX5.menu.clock.internal8d.bootloader.high_fuses=0xdc ATtinyX5.menu.clock.internal8d.bootloader.extended_fuses=0xff ATtinyX5.menu.clock.internal8d.build.f_cpu=8000000L
Save the file and exit. If you notice, only the high_fuses value is changed in each of the four code groups added above (the low_fuses and extended_fuses values are all the same). These four groups of code replace the one “Internal 8 MHz” clock selection option in the menu tree with four new menu options as follows:
- Internal 8 MHz, No BOD – This is the same as the original “Internal 8 MHz” option
- Internal 8 MHz, BOD = 1.8V – This option selects the Internal 8 MHz option AND enables 1.8V Brownout detection
- Internal 8 MHz, BOD = 2.7V – This option selects the Internal 8 MHz option AND enables 2.7V Brownout detection
- Internal 8 MHz, BOD = 4.3V – This option selects the Internal 8 MHz option AND enables 4.3V Brownout detection
That’s it – we’re all done with this step. Moving on…
Step 8: Program the Arduino UNO As an In-system-programmer
There are multiple ways of programming the ATtiny microcontroller. Probably the least expensive and most accessible way is to use the Arduino IDE with an Arduino UNO as an In-System-Programmer (ISP). So, that is the approach I’m going to take in this instructable.
The first step is to set up an Arduino UNO as an ISP. To do this:
- Connect an Arduino UNO to your computer
- Open the Arduino IDE
- In the Arduino IDE, select File -> Examples -> ArduinoISP
- Upload to the Arduino using the “Upload” button on the menu bar or by selecting Sketch -> Upload in the Arduino IDE
At this point, the Arduino UNO is an ISP. Remove power (USB cable) from the Arduino UNO so that you can wire it up to the ATtiny microcontroller on a breadboard as detailed in the next step.