element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet & Tria Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • About Us
    About the element14 Community
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      •  Japan
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      •  Vietnam
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
Spring Clean!
  • Challenges & Projects
  • Project14
  • Spring Clean!
  • More
  • Cancel
Spring Clean!
Spring Clean Projects 2026 Meet Bowie! The Printed Circuit Bowtie
  • News and Projects
  • Forum
  • Members
  • More
  • Cancel
  • New
Join Spring Clean! to participate - click to join for free!
  • Share
  • More
  • Cancel
Group Actions
  • Group RSS
  • More
  • Cancel
Engagement
  • Author Author: Oday
  • Date Created: 31 May 2026 10:48 PM Date Created
  • Views 83 views
  • Likes 3 likes
  • Comments 2 comments
  • Spring Clean 2026
Related
Recommended

Meet Bowie! The Printed Circuit Bowtie

Oday
Oday
31 May 2026
Meet Bowie! The Printed Circuit Bowtie

Where It All Began

Imagine you're at a career fair, suited up, resume in hand, and you've got about 45 seconds before a recruiter moves on to the next student. Your resume has a QR code linking to a video of your best project, but nobody has time to watch it. You can't bring your robot arm. You can't lug a laptop running your firmware demo. So how do you show what you can do, in a room full of engineers in dress clothes, in under a minute?

That question is what started this project.

The answer had to be wearable, something that goes wherever you go, requires no setup, and fits the formality of a career event. At nearly every professional event I attend, I wear a bowtie, they're stylish, sleek, and they stand out as they're not commonly worn. So the idea came together naturally: why not make the bowtie itself the project? But not just any bowtie, one that lights up, listens to you, and talks back!

image

Introducing the PCB: the Printed Circuit Bowtie. A fully custom 4-layer PCB, designed in the shape of a bowtie, powered by an ESP32-S3, acting as a wearable AI personal assistant named Bowie. Ask Bowie a question out loud, and Bowie answers through a speaker built right into the bowtie. This project brings together everything I love about electrical and computer engineering: PCB design, embedded firmware, IoT architecture, and audio systems. All wrapped up in one of the classiest pieces of clothing ever made!


Section 1: Project Background & The Spring Clean Story

image

Bowie V1 in action on the way to a networking event! :)

The story of Bowie goes all the way back to December 2024. At that point I was a junior Engineer working on this as a personal project and it was just a very simple breadboard. A microphone, an ESP32, and a cloud backend that could record a voice prompt, send it to a language model, and return an audio response saved to an SD card. The absolute bare bones concept worked, but the execution was nowhere close to done.

A busy semester of engineering school put the project on hold, and it sat untouched until September 2025 which was my last semester. With my senior design project done the semester prior, I picked Bowie back up with a clear mission: design the hardware properly and turn this breadboard proof-of-concept into an actual wearable device.

From September to October, the breadboard had evolved, now including Neopixels, potentiometers, haptic feedback, but most important of all audio output! So from October to November, the full hardware design came together in Altium Designer, an ESP32-S3 as the brain surrounded by all peripherals considered on breadboard but now with additional features that I couldn't breadboard like LiPo battery management, onboard charging, programming through USBC and more. All packed into a 4-layer PCB which I ordered from in late November arriving in January 2026.

And that's where the real work began.

The first version of the board was about 80% successful, but it had a critical flaw: the audio output circuit failed entirely. This was not a small fix and it prevented the bowtie from doing its primary task, talking! So from January through March, it was back to the datasheets, diagnosing what went wrong, correcting the failure, and cleaning up the layout. New boards arrived in March 2026. This time, everything worked: audio, peripherals, battery management, USB-C programming. I had full hardware validation across the board.

Spring Clean 2026 became the deadline to finish what the hardware had been waiting for: a complete, working software stack. From voice capture to Bowie speaking back.


Section 2: System Architecture

Bowie is an IoT device at its core. The bowtie handles all the user-facing hardware, like the microphone, speaker, buttons, Neopixels, while a server running on Digital Ocean handles the heavy processing. This split was a deliberate call as the ESP32-S3 has limited memory and isn't well-suited to running LLM inference or making complex API calls directly, so the device stays lean and offloads intelligence to the cloud.

image

The end-to-end flow:

  1. User presses the button to initiate a prompt
  2. The ICS43434 MEMS microphone captures audio over I2S
  3. Audio is written chunk-by-chunk to the SD card over SPI
  4. WAV file is streamed to the Digital Ocean backend over WebSocket
  5. The backend runs it through AssemblyAI speech-to-text
  6. The transcript goes to the Claude API, configured with Bowie's persona
  7. Claude's response goes through ElevenLabs text-to-speech
  8. The resulting MP3 is sent back to the bowtie over WebSocket
  9. The ESP32-S3 stores the response on the SD card over SPI
  10. Two MAX98357A I2S amplifiers play it through two speakers


Section 3: Hardware Design

image

No way! It's actually a circuit board shaped like a bowtie!!

3.1 Why 4 Layers?

image

One look and the answer is pretty obvious Sweat smile

The simplest reason is that the bowtie form factor is unforgiving. Every IC, connector, button, and Neopixel had to fit within the outline of a standard bowtie. With almost 200 components on the board, a 2-layer board simply couldn't route cleanly.

The 4-layer stack up also allowed me to provide a dedicated power and ground plane in the inner layers which helped greatly with routing as well as keeping high speed digital signals well maintained. Even with 4 layers though, routing was challenging to ensure no cross overs, solid ground planes under SPI and I2C signals, and maintaining a critical keep out underneath the ESP32-S3 antenna.

3.2 Embedded Protocols

One of the design challenges of packing this much into a bowtie-sized PCB was managing multiple communication protocols simultaneously. Nearly every pin on the ESP32-S3 is allocated:

Protocol Peripheral Purpose
I2S (RX) ICS43434 Microphone Digital audio capture
I2S (TX) MAX98357A Amplifiers Digital audio playback
SPI Micro SD Card WAV write / MP3 read
Native USB USB-C Port Programming and debug (USB Serial/JTAG)
GPIO Button, Neopixels, Pots, Haptic Motors, etc User Interface

3.3 Schematic Overview

image

Here's an overview of the schematic with PDF below to take a closer look in HD, I will dive deeper into the main elements that make bring Bowie together in this section

imagePDF

Power Management

LiPo batteries were the natural choice for a wearable. They're lightweight, rechargeable, and energy-dense enough to power the ESP32-S3, audio circuits, and 20 NeoPixels comfortably. Two 1000mAh cells wired in parallel double the capacity while keeping the voltage at 3.7V nominal, which feeds cleanly into the onboard LDO.

image

But LiPo batteries demand respect. Overcharge them and they swell. Over-discharge them and you permanently damage the cell. To handle both, the DW01A battery protection IC monitors the battery continuously, controlling a dual N-channel FS8205 MOSFET sitting in the battery's negative path. If the DW01A detects an over-charge or over-discharge condition, it opens the appropriate FET and cuts current in that direction, protecting both the battery and anything connected to it.

image

Each battery also has its own dedicated Resettable Polyfuse (F1, F2) right at the connector. The polyfuses act as a first line of defense, if current draw spikes beyond a safe threshold, they trip and self-reset once the fault clears, no replacement needed. 

Charging is handled by the TP4056, with a 1.2kΩ PROG resistor setting the charge current, and green/red status LEDs indicating standby and active charging states.

image

The more interesting design challenge was power selection. The rule for LiPo safety is simple: never let the battery charge and power the load through the same path simultaneously. So my circuit enforces this elegantly using a Schottky diode (D7) and a P-Channel MOSFET (Q2).

When USB is plugged in, VCC is present. The Schottky diode conducts, pulling Q2's gate up toward VCC which is higher than Bat+, bringing VGS close to zero and turning Q2 off. The battery is completely disconnected from the load path. USB powers the device directly, and the TP4056 charges the battery independently on its own path.

When USB is removed, Q2's gate is pulled to ground through R9, making VGS sufficiently negative to turn Q2 on, and the battery takes over powering the device.

The result: plug in USB and the bowtie is simultaneously powered, programmable via USB Serial/JTAG, and charging its batteries. All three happen at once, with no risk of the battery and USB fighting each other on the load path.

Audio Output

imageimage

V1 Audio Output Design

The first version's audio schematic originally had a separate DAC and Audio amplifier which from the datasheets looked promising, but it effectively failed due to two reasons. First the compact design of the PCB made it difficult to isolate analog and digital grounds with so many other signals running between layers and all over the board, so noise filtering was basically inexistent. Secondly, the DAC I selected was an obsolete component and I simply had not known because I was testing it out on breadboard where it had it's own breakout board, but the IC by itself was nowhere to be found. (I proceeded to order the PCBs knowing the part was obsolete hoping I could desolder the IC from the breakout board and resolder it to my board, but that also failed so it was a hopeless case) The redesign fixed it by having the DAC and Amplifier all in one IC (eliminating the need to struggle with separate grounds) and of course it's a much more popular chip that was in stock.

image

V2 Audio Output Design

Now on V2, playback runs through two MAX98357A filterless Class D I2S amplifiers (one per speaker) with built in DAC that take digital audio directly from the ESP32-S3. They each output up to 3.2W and need very few external components which was perfect for a limited board space like this bowtie.

Audio Input

image

The ICS43434 is a high-performance I2S MEMS microphone chosen specifically for its omnidirectional pickup pattern. On a bowtie, the user isn't holding the mic up to their mouth, so the microphone needed to pick up voice reliably from chest height in a noisy room. Keeping the signal in the I2S digital domain all the way to the ESP32 also avoids the noise floor problems that come with analog mic routing across a dense board.

3.4 PCB Layout

image

Top Layer: Primary Signal and Power routing; A dense layer with MCU, I2S, SPI, and power management traces

image

Inner Layer 1: Dedicated ground plane, left unbroken under high speed traces when possible as well as connecting battery grounds together

image

Inner Layer 2: Dedicated power plane for clean 3.3V distribution as well as 5V rail distribution for Neopixels and Audio Amplifiers

image

Bottom Layer: Secondary signal routing and ground fills; Sparser than top layer but handles overflow and assists in getting signals from point to point

The stackup wasn't arbitrary. Having dedicated ground and power planes on the two inner layers means every signal trace on the outer layers has a reference plane immediately adjacent on both sides. This keeps trace impedance controlled, reduces crosstalk between sensitive signals, and gives the audio circuits a clean ground reference throughout.

3.5 General Bill of Materials

Component Part Number Function Qty
MCU ESP32-S3 Central MCU, WiFi 1
Audio Amplifier MAX98357A I2S Class D amplifier 2
Microphone ICS43434 I2S MEMS microphone 1
LiPo Charger TP4056 Battery charging via USB-C 1
Battery Protection DW01A Over-charge/discharge protection 1
LiPo Batteries Liter 102535 2× 1000mAh 3.7V in parallel 2
Micro SD Slot TF-01A Audio storage 1
Speaker 4Ω 3W Speaker Audio output 2
NeoPixels WS2812B 20x RGB LEDs, state animations 20


Section 4: The Audio Pipeline

Getting audio to flow reliably end-to-end on a memory-constrained device was the most challenging part of this project. The ESP32-S3 has limited RAM, which means you can't just record audio into a buffer, hold it in memory, and send it as the recording alone would overflow. Everything had to be designed around streaming to and from the SD card, with the RAM acting only as a small in-flight buffer at any given time.

image

4.1 Recording — Chunk by Chunk

When the button is held, the firmware reads raw I2S samples from the ICS43434 microphone in 1024-byte chunks and writes them directly to the SD card. Nothing accumulates in RAM. The WAV header is written with a placeholder size first, then patched at the end once the final byte count is known:

// Record directly to SD — never holds full audio in RAM
uint32_t dataSize = 0;
while (digitalRead(BTN_PIN) == HIGH && (millis() - startTime) < 10000) {
    size_t bytesRead = 0;
    i2s_read(I2S_MIC_PORT, buffer, BUFFER_SIZE, &bytesRead, pdMS_TO_TICKS(100));
    if (bytesRead > 0) {
        f.write(buffer, bytesRead);
        dataSize += bytesRead;
    }
    recordingAnimation();
    readPots();
}
// Patch WAV header with final size
f.seek(0);
writeWAVHeader(f, dataSize);
f.close();

4.2 Sending — Streaming Off the SD Card

Rather than reading the entire WAV into memory before sending, the firmware reads it back off the SD card in 1024-byte chunks and sends each one immediately over the WebSocket. Memory usage stays flat regardless of recording length:

// Stream WAV from SD card — 1KB at a time, never loads full file into RAM
File f = SD.open("/rec.wav");
while (f.available()) {
    webSocket.loop();
    size_t bytesRead = f.read(buffer, BUFFER_SIZE);
    if (bytesRead > 0) {
        webSocket.sendBIN(buffer, bytesRead);
        totalSent += bytesRead;
    }
    sendingAnimation();
}
f.close();
webSocket.sendTXT("AUDIO_COMPLETE");

4.3 Backend — Assembling and Processing the Audio

On the server side, the audio arrives as a stream of binary WebSocket chunks. The backend accumulates them into a bytearray until the AUDIO_COMPLETE signal arrives, then runs the full AI pipeline:

async for message in websocket:
    # Accumulate binary audio chunks as they arrive
    if isinstance(message, bytes):
        audio_buffer.extend(message)
        received_bytes += len(message)

    elif isinstance(message, str) and message == "AUDIO_COMPLETE":
        # Write assembled audio to disk
        with open("user_audio.wav", "wb") as f:
            f.write(audio_buffer)

        # STT → LLM → TTS pipeline
        transcript = transcriber.transcribe("user_audio.wav")
        user_text = transcript.text
        conversation_log.append({"role": "user", "content": user_text})

        response = clientA.messages.create(
            model="claude-haiku-4-5-20251001", max_tokens=100, system=system_prompt, messages=conversation_log ) bowie_response = response.content[0].text conversation_log.append({"role": "assistant", "content": bowie_response}) audio = client11.text_to_speech.convert( text=bowie_response, voice_id="XrExE9yKIg1WjnnlVkGX", model_id="eleven_turbo_v2_5", output_format="mp3_44100_128", ) with open("response.mp3", "wb") as f: for chunk in audio: f.write(chunk) # Send MP3 back in 4KB chunks with open("response.mp3", "rb") as f: mp3_data = f.read() for i in range(0, len(mp3_data), 4096): await websocket.send(mp3_data[i:i+4096]) await websocket.send("MP3_COMPLETE") 

Note that conversation_log is maintained across turns so Bowie remembers the conversation context, not just the most recent prompt.

4.4 Receiving and Playing — Non-Blocking Decode

Audio is sent back as an MP3 rather than WAV to reduce the time it takes to send. When the MP3 arrives back on the device, chunks are written to the SD card as they come in via the WebSocket callback. Once MP3_COMPLETE is received, playback begins, but critically, it's non-blocking. The Helix MP3 decoder processes one small chunk per loop iteration via copier.copy(), which means the main loop stays responsive and the full MP3 is never loaded into RAM at once:

// Non-blocking MP3 playback — one decode chunk per loop iteration
if (isPlaying) {
    if (!copier.copy()) {
        // copier.copy() returns false when the file is exhausted
        audioFile.close();
        decoder.end();
        isPlaying = false;
        enableRecordingMode();  // Switch I2S back to mic mode
    } else {
        processFFT();        // Run FFT on decoded samples
        updatePlaybackLEDs(); // Drive VU meter LEDs from FFT data
    }
    return;
}

The FFT runs on the decoded audio samples in real time during playback, driving the 20 Neopixels to animate the bowtie visually by pulsing to Bowie's voice.

4.5 Bowie's Persona

Bowie isn't a generic voice assistant,  it has a specific character defined through the Claude API system prompt. It knows it's a bowtie, knows it was invented by me, keeps responses short and conversational, and always has real-time context injected: current time, date, location, and even my iCloud calendar events. This means Bowie can answer "what's on my schedule today?" accurately, every time, even if I update my calendar between prompts!

system_prompt = f"""You are Bowie, a smart bowtie assistant. You speak in short,
natural responses like a real conversation. I am your inventor — you are a PCB
bowtie I (Oday) invented.

Match your response length to the question:
- Simple questions (time, weather, yes/no): 1 sentence max.
- Casual chat or quick facts: 2-3 sentences max.
- Only give longer responses when truly needed.

{current_context}"""
# current_context includes: time, date, location, and live iCloud calendar events

Section 5: The Spring Clean

To put the scope in perspective, here's what the project looked like before and after:

Before (January 2026):

  • V1 PCB in hand with a completely broken audio output
  • No working firmware beyond the original breadboard proof-of-concept
  • No WebSocket backend (Originally managed by MQTT which was a great start, but much much slower as chunks were smaller)
  • No end-to-end audio pipeline

After (May 2026):

  • V2 PCB fully validated: Audio, peripherals, battery management, programming all working
  • Complete ESP32-S3 firmware: I2S capture, WebSocket streaming, response playback
  • Digital Ocean backend: AssemblyAI STT → Claude API → ElevenLabs TTS pipeline live always
  • Conversation history maintained across turns
  • iCloud calendar integration working
  • Designed and 3D printed a small mechanical enclosure to house the speakers and allow the bowtie to be worn comfortably around the neck
  • End-to-end: ask Bowie a question, hear Bowie answer :)


Section 6: Demo

You don't have permission to edit metadata of this video.
Edit media
x
image
Upload Preview
image

Here's a link to the demo on YouTube in case the embedded link doesn't work ;)
Bowie the Printed Circuit Bowtie in Action!


Section 7: What's Next

The hardware is solid. The core pipeline works. But there's a long list of things Bowie still can't do yet, and that's part of what makes this project worth continuing.

  • Wake word: Hands-free activation without pressing a button, so Bowie can be summoned naturally at an event
  • Faster response time: There's still latency to squeeze out of the WebSocket pipeline; MQTT was tried first and was too slow, WebSockets improved it, but there's more to do
  • More integrations: The architecture is set up for additional API connections; calendar is working, but there's more to come (think Jarvis from Ironman!!)
  • Neopixel animations: The 20 NeoPixels already run a live FFT animation during playback; more states and animations planned
  • I2C Devices use: There are two I2C devices on the board not in use yet, an IMU and a battery level IC; the IMU will help with gesture-based activation and orientation-aware behavior and the battery level IC will of course be there for better UI design.

The bowtie is done, but Bowie is just getting started!

  • Sign in to reply
  • Oday
    Oday 15 hours ago in reply to kmikemoo

    Thank you so much, really appreciate it! The lag is real and it’s next on the list. The biggest win for this Spring Clean was honestly on the hardware side: getting a fully validated 4-layer custom PCB working end-to-end after a rough first revision. The software has a lot of room to grow and faster response time is at the top of the roadmap. Excited to keep building, and yes! One day maybe! :)

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • kmikemoo
    kmikemoo 15 hours ago

     Oday I give you props for innovative and creative.  Nice project.  While it seems a bit laggy in the video, it is unique and I think it's a differentiator.  Well done!  Keep designing.  You could be the next Rom Popeil.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2026 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube