Skip to content

Project Development

My final project master piece is a web-radio lamp. It’s shape is inspired by Pixar’s mascot, Luxo Jr., which in turn was inspired by Jac Jacobsen’s 1937 Luxo L-1 architect’s table lamp.

!Fab Speaker Bestial Design

This page tracks progress of the work on my final project. I split progress in the different parts of the project, and update each as it advances. Development is not linear, as some choices influence other elements, and many aspects went back and forward during progress.

Work Calendar

Week # Date Weekly Assignment Reviews Final Project Tasks
Week 1 Jan 24 Principles and Practices Ideation
Week 2 Jan 31 Computer Aided Design Design Development
Week 3 Feb 07 Computer-controlled Cutting Lamp Body Prototyping
Week 4 Feb 14 Electronics Production Electronics acessment
Week 5 Feb 21 3D Scanning and Printing Lamp Head Prototyping
Week 6 Feb 28 Embedded Programming Light Control Program
Week 7 Mar 06 Computer-Controlled Machining Light Dynamics
Week 8 Mar 13 Electronics Design Electronics Design
week 9 Mar 20 Output Devices Audio Output
Week 10 Mar 27 Mechanical Design, Machine Design Electronics Design
Week 11 Apr 03 Fake Break, Midterm Review Electronics Design
Week 12 Apr 10 Input Devices Electronics Design and Production
Week 13 Apr 17 Molding and Casting Electronics Production
Week 14 Apr 24 Networking and Communications Electronics Production
Week 15 May 01 Interface and Application Programming Electronics Production and Assembly
Week 16 May 08 Wildcard Week Electronics Production and Assembly
Week 17 May 15 Applications and Implications & Project Development Electronics Testing
Week 18 May 22 System Integration Final Project Testing and Validation
Week 19 May 29 Invention, Intellectual Property, and Income Update Video, Slide and Documentation
Week 20 Jun 05 Project Presentation

In designing the lamp’s head, I used 3d modeling, as described in Computer Aided Design week. I used Rhino 3D for this task.

!Fab Speaker Bestial Design

After some iterations, the head part was 3d printed on a Prusa i3 MK3, in Galaxy Black PLA.

!Fab Speaker Bestial Design

As everything is interconnected, restrictions on some elements determine the design of other parts, so I had to adapt the design over several iterations.

I found that the weight of the Dayton Audio RS100-4 3d driver was too high for the springs I found that fit the body of the lamp, at nearly 0.5Kg. I decided to use a smaller driver, a Tang Bang mini sub-woofer that I had around and sounds good too. It’s not a full range driver, but it should work for this project.

Another element that determined the redesign was the lack of time to make an LED ring. My instructor has a parts bin, where he found a led ring I could use, but it was larger than the first head and wouldn’t fit, so I finally made a larger head.

That also meant the oculus (i never know what to call the ring element around the audio driver) had to be redrawn too. In this case, and because time was short, I decided to just measure the inner diameter of the new head and the outer diameter of the tang bang driver and just cut a piece of acrylic to fit the space.

The acrylic I had around is transparent, but I left the white protective film on for light dissipation and it kind of works. My plan is to eventually machine a bulged ring like the first design, but for now this will do.

So I 3d printed the new head, and despite some minor issues, it was mostly alright. An then, as it sometimes happens, the fitment of Filipe’s led ring was too tight, by a fraction of a millimeter, it didn’t fit. I would have to sand the print, the ring, or both to fit.

I remembered I had a bright led strip that might work. The light would shine inwards into the head, but enough of it would come out through the acrylic, so I tried it. It fit perfectly in the available width and also in length, so I glued it on, soldered power wires and connected them to a salvaged 12V power supply I’m using for my project, and they shone quite brightly. The light is expectedly not uniform across the acrylic, but it serves the effect until I find a better solution.

The leds got a bit warm, which may become an issue if the lamp is left on max for too long, but my electronics will have a PWM / potentiometer brightness control, so it can be adjusted.

All issues moderately solved for now. Had I thought to use the led strip before, I wouldn’t have had to make a larger head; but it looks goofier on the body I made, so it’s staying.

Articulated Body

As described in Computer Aided Design week, I remodeled the body parts in order to 2d laser cut them from acrylic left over stock I had. I adapted the design so I could use 8mm aluminium tube as connecting parts between the various acrylic pieces, and brass pipe fittings as connecting elements between the body and the head and base.

!Work in progress assembled

Base

!Base in Slicer for Fusion

As usual, I modeled the base in Rhino. I was planning to place the electronics in the base of the lamp, an run cables to head from there.

That idea went through several iterations and much thought. Initially I wanted to machine it out of a recycled plastic block, but two sided machining was still a demanding process in terms of planning and time requirements.

I didn’t want to 3d print every part, so I decider to laser cut the base. I could iterate faster, and had plenty of leftover MDF and some acrylic to experiment with.

I took the first base design, exported it as STL, and imported it in Slicer for Fusion 360. This software has been deprecated by Autodesk, but at the time of writing, it was still available for windows and mac, as is, without support and buggy, but working.

In Slicer for Fusion, I prepared a preset for 3mm stock material, imported the STL file, making sure the Z axis was set as Up Direction. Then it’s important to set the object size to mm, as it was modeled, and original size, as the software tends to change it arbitrarily to some other scale. I then selected Radial Slices as the construction technique.

!Base in Slicer for Fusion

I adjusted the number of radial (horizontal) and axial (vertical) slices, and the heigh of each radial slice, in order to fortify the area where the base is connected to the body. I also planned to place the potentiometers in two of the formed shelves, so I iterated a few times to get the slices at a distance where the potentiometers would have enough vertical space to fit. The bottom was also placed to it had an area to fix my electronics board.

I exported the slices as a DXF file, in mm, and imported it to Inkscape, where I made measurements to make sure my parts fit where I wanted them. This took some iterations to get right (9 to be exact).

I added holes to fit the potentiometers and slots in the base to fit an internal enclosure for the electronics, for better system integration.

!Base Evolution in Inkscape

The electronics box I just designed in inkscape directly, using the KiCad SVG as a dimensions template.

Some design elements I could predict and correct beforehand, but some issues I discovered when I made the parts.

Acrylics

Acrylic sheets looks beautiful and straight until you have to fit parts with each other. Then you find out it’s thickness is really uneven, by fractions of a millimeter, but it’s enough for some joints to be lose and others to be so tight they don’t fit. If you try to force the connection, you risk braking the part, because acrylic is quite rigid (which makes it brittle) and does not compress at all. I tried sanding it, at that works, but it’s time consuming and tedious, and in the end it breaks as well. It drove me crazy and was quite frustrating, as acrylic is a fairly expensive material to experiment with, especially if it’s going to fail. Recently, though, I found out that I can melt it together and recycle it into new sheets with Precious Plastic techniques, so I feel a little less bad for the multiple broken iterations of my design.

After some iterations and repeat cuts due to broken parts, I decided MDF would be fine, as it is more compliant in the connections. I spray painted it matte black for aesthetics; that worked well and looks good with the clear plastic parts.

Here you can see it assembled, with the potentiometers and electronics in place.

I also designed and laser cut these round knobs that fit on the potentiometers, as well as 3d printed case to hide the potentiometers, underneath.

!Complete Base

Electronics

Disclaimer

Electronics design and production has been the most complicated part of Fab Academy for me, and I believe, for most students. It’s where I had the least prior knowledge, most difficulty, but also the subject I learned the most, failed the most, and learned again. I failed to complete Fab Academy at least 3 times because of it. When I decided to change to León Fab Lab as a remote student, I was motivated by the support I thought I would be able to get from instructors Ardián Torres and Pablo Nuñez, who I’d gotten to know through Saturdays’ Global Open Time, over the last few years. I wasn’t wrong, and their support and orientation made all the difference in completing my final project, in particular the electronics. Thank you guys!

I went through numerous iterations of the electronics board for my final project.

2022

In 2022, I had made a complicated sandwich of interconnected boards. The bottom was a Barduino adaptation with a commercial I2S audio board from adafruit, and the top one was a power management board with LED PWM fade controller, and a connection to a audio amplifier board.

!2022 Electronics Here you can see the bottom board, with long pins to connect with the top one.

!2022 Electronics Here you can see the whole pyramid of interconnected boards.

It probably sounds complicated, and it really was for me. It was meant to connect to an I2C screen, and a rotary encoder as well. My instructor Filipe Silvestre had helped me design the board, but I had too little experience to understand the total functionality, let alone debug properly. It failed for a few reasons I understand better now, and I failed with it.

2024

This year, Adrián wisely advised me to make it modular and simpler, one part at a time and make sure each part worked individually before joining everything together in a final board.

Over the next few months we spent many nights attempting to solve two problems:

  • Use a potentiometer to PWM fade a 12V LED strip.
  • Get audio playing from the ESP32 based board.

The first task was eventually solved with an external Mosfet board, based on this tutorial, which Adrián referenced. This went through a few iterations, mainly because I didn’t pay proper attention to R2, which was supposed to be a high resistance value of 100KΩ to 1MΩ. I had read wrong and placed a 220Ω resistor instead. I even had to make the board through-hole for that component as I didn’t have an SMD resistor of that value. In this case, as many others, it’s worth it to read the instructions carefully. It failed until I placed the right resistor in R2.

!Mosfet Board

The second task was to output good audio from the esp32. I knew this could be done, as I had it working in previous years, both in a commercial dev board, as well as in my barduino board. The only question was how. Would I try to make another KA-Radio32 compatible board or a simple Bluetooth receiver? Would I amplify the internal DAC signal with an external amplifier, or use another I2S board? Although Adrián begged me to make it simple, I was reluctant to give up on the idea of making a internet radio streamer.

KA-Radio was always something that I liked, but it troubled me because I had no control over the software. Even though it is open source, it’s not a simple arduino program I could try to understand, and as such it was as good as closed source to me.

Luckily, it’d been a couple of years since I last looked into it, and there are now other projects I could look into. It seems internet Radio is popular enough that someone developed an Arduino Library that works for my purposes. I will go more into it in the programming section. For know, I’ll mention that I found this tutorial, which made my life easier. In it, DroneBot Workshop Bill mentions three important things that I used in my project:

  • Wolle Schreibfaul’s ESP32-audioI2S Library for Arduino IDE
  • The MAX98357A I2S Amplifier Module
  • and even the code to implement a simple internet radio with potentiometer volume control.

I’ll be honest to mention I was relieved, as this helped me immensely on not only deciding my next steps, but also in implementing a simple internet radio with minimal functionality in the time I had left.

As such, I bought the MAX98357A I2S Amplifier Module and tested it on a commercial Esp32 Board. It really is an inexpensive yet surprisingly powerful audio amplifier module.

Having tested it successfully, I set out to design my final board, which should incorporate the two potentiometer inputs, for volume control and LED fading, as well as PWM output for the mosfet board and I2S output for the amplifier module. All this was meant to be fed with 12V from a power AC_DC converter I salvaged from my parts bin. I knew I needed 12V for the LED strip, at least, because the board would not feed enough voltage to light them up with 3.3V, so this was always a requirement. It was also part of what had gone wrong in 2022.

!the usual process

So I went back to KiCad, set the schematic and the board, based on Barduino, but with only the pins I needed; I exported the SVG, edited that in Inkscape, created the milling paths in Mods and ran them trough Candle to my 3018 cnc, as usual. I’ve become quite comfortable with this process.

!Schematic

!Board Design

After stuffing the board and uploading the code, the audio output seemed to work fine.

But when connecting the potentiometers and 12V power, the LEDs would not work at all. I pondered and looked, and couldn’t understand what was wrong. Can you see that the 12V ground wasn’t connected to the rest of the circuit? no common ground. Just as Neil warned the very same day, you need to make sure all grounds are common!

I frankensteined a shunt and finally the LEDs worked and faded!

I redesigned the board to fix this minor issue. But I didn’t realize then what the next issue would be. I had this board working, because I started it up and then connected the potentiometers and everything else. On my redesigned board, nothing worked again. When I tried programming it with the FTDI cable, I would get brown out messages in Arduino’s serial monitor. turns out, the two little pins (2 and 15) in the bottom right edge of the wroom processor, which I had used as input pins from the potentiometers, need to be low on startup. If the potentiometers were hooked up, these pins would possibly be high, and that would prevent a proper boot up. Crap!

So I went back to Kicad to redesign the board. At that point, I was already looking at System integration and wanted to merge the mosfet board with my main one. So I Integrated the mosfet and two resistors. While doing that, I messed up the circuit twice, but just due to being tired, so I’ll save you the screenshots, as not much was learned, other than working while tired is recipe for mistakes.

Spoiler Alert: This board is the penultimate one.

!Board Design I like to run the round tracks plugin; It’s good against interference, I was told, but to be honest, I just like it better for milling and I find it looks great, which the designer in me loves.

!Board Design Can you tell I was proud? FTDI connector and Reset button in the front

!Board Design Potentiometer plugs, I2S amplifier board connector, program/run switch, LED GND and PWM plug, and Barrel Plug for power in the back

Now, it was great! If only it could hold. It worked, music played, potentiometer faded the volume and light, and everything. But only for a short period. Then it would break up, like as if it had something interfering. The music would stop, the lights would go out, then restart, but quickly stop again and again.

Then I noticed that the power regulator was heating up a lot to the touch, something I never noticed before. Upon further research, I found out that power regulators have a thermal protection, that turns it off if it’s getting too hot. That made sense, considering it was breaking up. But what could be making it become hot?

I used a laser thermometer to measure the temperature at the power regulator. Each time it went close or over 77ºC (170ºF), the circuit would crash.

I used a multimeter to measure current consumption of the LEDs and that came to 0.74A. I tried measuring the current going to the speaker, but I measured 0.07A, which didn’t make much sense. Maybe I measured it wrong, it seemed too little current.

Nevertheless I could calculate, from Ohm’s Law, that if the Amplifier board was working at 3,3V and the Speaker was a 4Ω driver, the current necessary to power it at volume would be 0,825 amperes… Even if I used an 8Ω Speaker, which would need 0,4125 amperes. Now, the power regulator has a maximum current of 0.95A! It finally made sense why it was getting hot and cutting off. I was asking too much of it, as the sum of what I required was above it’s rated limit. Ok, so now I had to figure out how to power my board.

After much remote back and forth, troubleshooting and sharing ideas, Adrián told me it was valid to integrate the LM2596 commercial buck converter to power my board, since I already had one. Testing powering my board with it, everything seemed to be working fine and the power regulator was happily chugging along at cool 30ish ºC

I’d just have to make another board to integrate the buck converter. So I set out to adapt my design once again :)

!Board Design I didn’t have a schematic symbol for the buck converter, so I had to make one, just a simple rectangle with the ins and outs

!Board Design I also made a footprint with the right measurements, paying attention to the fact that I was going to solver it from the under side of the board, so it was important that the polarity of inputs and outputs was correct for this use. Other than that, I removed the power regulator and decoupling capacitors, as I was just going to use the external board as a 12V to 3.3V converter, for all the 3.3V circuit, and a direct 12V line to the LEDs.

!Board Design

!Board Design

Here it’s finally complete and working

Funnily the radio station was always playing such epic oldies XD I was happy and relieved!

Programming

Programming is where I have the least merit. I mashed together the web radio code from DroneBot Workshop Bill, and Adrián’s LED PWM control. I installed Wolle Schreibfaul’s ESP32-audioI2S Library for Arduino IDE, adapted the code a little bit to suit my needs, but no major transformations.

Here is the whole program, and a brief explanation of what it does.

/*
  Internet Radio with Volume Demo, adapted to also PWM Fade an LED Strip in 2024
  esp32-i2s-radio-volume.ino
  ESP32 I2S radio with volume control
  Uses two MAX98357 I2S Amplifier Modules, strapped for Left and Right channel
  Uses ESP32-audioI2S Library - https://github.com/schreibfaul1/ESP32-audioI2S

  DroneBot Workshop 2022
  https://dronebotworkshop.com

  Adapted by Marius Araújo 2024 for his Fab Academy Final Project
  https://fabacademy.org/2020/labs/fct/students/marius-araujo/

  with help and support by Adrián Torres
  https://fabacademy.org/2020/labs/leon/students/adrian-torres/

  https://fablableon.org/
*/

// Include required libraries
#include "Arduino.h"
#include "WiFi.h"
#include "Audio.h"

// Define I2S connections
#define I2S_DOUT  33
#define I2S_BCLK  25
#define I2S_LRC   26

// Define volume control pot connection
// ADC3 is GPIO 39
const int volControl = 39;

// Integer for volume level
int volume = 10;

// Create audio object
Audio audio;

// Wifi Credentials
String ssid =    "YOUR WIFI SSID";
String password = "YOUR WIFI PASSWORD";


// Variables for LED control with potentiometer
int BRIGHTNESS = 0;
int pinPot = 34; // IN Pin potentiometer
int pinLed = 12;  // OUT Pin to LED Strip
const int frequency = 1000;
const int channel = 0;
const int resolution = 10;

void setup() {
  // Start Serial Monitor
  Serial.begin(115200);

  // Setup WiFi in Station mode
  WiFi.disconnect();
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid.c_str(), password.c_str());

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  // WiFi Connected, print IP to serial monitor
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
  Serial.println("");

  // Connect MAX98357 I2S Amplifier Module
  audio.setPinout(I2S_BCLK, I2S_LRC, I2S_DOUT);

  // Set the volume
  audio.setVolume(volume);

  // Connect to an Internet radio station (select one as desired)
  audio.connecttohost("0n-80s.radionetz.de:8000/0n-70s.mp3");

  // Potentiometer LED Control Configuration
  ledcSetup(channel, frequency, resolution);
  ledcAttachPin(pinLed, channel); // in order to use ledcAttachPin correctly
}

void loop() {
  // Run audio player
  audio.loop();

  // Get the volume level
  volume = map ((analogRead(volControl)), 0, 4095, 0 , 100);

  // Set the volume
  audio.setVolume(volume);

 // Potentiometer LED Control
  BRIGHTNESS = analogRead(pinPot);
  BRIGHTNESS = map(BRIGHTNESS, 0, 1023, 0, 255);
  ledcWrite(channel, BRIGHTNESS);
}

// Audio status functions
void audio_info(const char *info) {
  Serial.print("info        "); Serial.println(info);
}
void audio_id3data(const char *info) { //id3 metadata
  Serial.print("id3data     "); Serial.println(info);
}
void audio_eof_mp3(const char *info) { //end of file
  Serial.print("eof_mp3     "); Serial.println(info);
}
void audio_showstation(const char *info) {
  Serial.print("station     "); Serial.println(info);
}
void audio_showstreaminfo(const char *info) {
  Serial.print("streaminfo  "); Serial.println(info);
}
void audio_showstreamtitle(const char *info) {
  Serial.print("streamtitle "); Serial.println(info);
}
void audio_bitrate(const char *info) {
  Serial.print("bitrate     "); Serial.println(info);
}
void audio_commercial(const char *info) { //duration in sec
  Serial.print("commercial  "); Serial.println(info);
}
void audio_icyurl(const char *info) { //homepage
  Serial.print("icyurl      "); Serial.println(info);
}
void audio_lasthost(const char *info) { //stream URL played
  Serial.print("lasthost    "); Serial.println(info);
}
void audio_eof_speech(const char *info) {
  Serial.print("eof_speech  "); Serial.println(info);
}

Library Inclusions:

  • #include "Arduino.h": Includes the core Arduino functions
  • #include "WiFi.h": Includes the WiFi library for connecting to a network
  • #include "Audio.h": Includes Wolle’s Audio library for handling audio functions

I2S Connections

  • Defines the GPIO pins used for the I2S interface with the amp

Volume Control

  • const int volControl = 39;: Defines the GPIO pin connected to the potentiometer for volume control.

Volume Variable

  • int volume = 10;: Initializes the volume level variable

Audio Object

  • Audio audio;: Creates an instance of the Audio class

WiFi Credentials

  • Defines the WiFi SSID and password for connecting to the network

LED Control Variables

  • Variables for controlling an LED strip’s brightness using a potentiometer and PWM

Setup Function

  • void setup() { ... } initializes the serial monitor, sets up the WiFi connection, configures the I2S amplifier, connects to an internet radio station, and sets up the LED control

Loop Function

  • void loop() { ... } runs the audio player, reads the volume level from the potentiometer, updates the volume, reads the brightness level from another potentiometer, and adjusts the LED brightness

Audio Status Functions

  • Functions to print various audio statuses to the serial monitor for debugging and information purposes. This will allow me to output information to a screen in the future

This code sets up an ESP32 to stream internet radio, control the volume via a potentiometer, and adjust the brightness of an LED strip using another potentiometer.

System Integration

As I mentioned when designing the base, I was considering placing the electronics in it, so I created a case that would house the board, and label where the components that connect to it plug into.

!Board Design

!Board Design

In that sense, I do think some effort was made to integrate everything, from the electronics design, which accommodates the two daughter boards, to the cabling, the potentiometers, which was made to size and bundled in a neat cable wrap.

!Board Design

The potentiometers themselves are partially hidden in a 3d printed enclosure, have their own place in the base design, and are securely fastened with nuts, which are hidden by a laser cut knob.

!Board Design

Hero Shot

!Board Design

Files


Last update: June 11, 2024