You want a desk light, an exhibit or a classroom object to respond when someone speaks or plays music. The first prototype lights up. Then you try a quieter room: some LEDs never go out, and louder music barely changes the display. The question is no longer whether a microphone can control a light. It is whether the response makes sense to the person using it.
That is a common starting point. In a January 2025 Arduino forum discussion, someone using a MAX9814 microphone and an LED ring reported lights staying on in quiet conditions and little response at the loud end. The circuit differs from ours, but the design problem is the same: decide what the light should communicate before treating its output as a measurement.
On our bench we built a sound-reactive light from GraftSense modules: a microphone, an eight-segment light bar and a Raspberry Pi Pico on a GraftPort carrier, powered from a small battery and mounted in a clear acrylic case, with a button to pause and resume. This note follows that build and what it does and does not show.
Build one understandable input-to-output path
The input is a MAX9814 electret-microphone module. It produces an analog signal, a changing voltage that the controller reads through its ADC (analog-to-digital converter). The output is an eight-segment LED bar driven by a PCF8574 I/O expander over I2C. The firmware changes how many segments are lit; this is not an addressable color LED strip.
We connected the microphone to the carrier's ADC0 connector and the light bar to I2C0. A second control line on the microphone module sets its gain. If you move the design to another controller, translate the connector mapping to real pins rather than assuming the same label means the same pin.
The MAX9814 has automatic gain control. As the Analog Devices product page explains, its amplification changes with signal level. That helps the light respond across different rooms, but it also means the output is not a fixed-scale reading of loudness. Treat the bar as an interactive response, not a calibrated sound-level meter.
That choice changes what you test. A classroom object might need a clear response when a child speaks nearby. A music ornament might need a lively range during normal listening. Those are different thresholds and behaviors to evaluate, and our build has not been through a user trial for either.
Keep the wiring and the enclosure in the story
A battery charge and discharge module supplies the board, and the parts sit on a perforated acrylic base on M3 plastic standoffs, with M3 screws holding the side panels. The microphone and light bar sit beside the controller, with the power module and battery in the same case.
One detail from our build is worth repeating: on one of our power cables, red was ground and black was the positive supply. Never wire by color. Check the module labels, connector orientation and continuity with power disconnected before connecting a supply.
Mounting the parts makes the object easier to handle, and it raises a new question: can the microphone still hear the sound you care about? A case opening, a nearby speaker or a vibrating panel all change the response. We have not tested the acoustic behavior of the final enclosure.
Keep the button and the power connector reachable if the object is going to someone else. A prototype that has to be opened just to stop the effect makes it hard to learn whether people like the interaction.
One board-specific check: on this carrier, when the external watchdog module is not fitted, the RUN switch 2 position has to be connected or the board will not start. Check that before blaming the microphone or the code.
Follow the value that actually controls the bar
At startup the application initializes the microphone and light-bar drivers, scans the I2C bus and starts a scheduled task. Our run found one I2C device at 0x20; check the address on your own module rather than assuming every PCF8574 board is set the same way.
Each time the task runs, an analyzer takes a block of microphone readings, filters and windows them, and calculates an energy value. The task takes the integer part of that energy, caps it at eight and lights that many segments. So values below one light nothing, and anything at eight or above fills the bar. If your normal sounds all land near one end of that range, changing the mapping will help more than adding LEDs.
The analyzer also calculates frequency-related results, but this task does not use them. Describe the build as sound-reactive, not as beat detection or separate bass, mid and treble bands.
There is a timing caveat if you extend the analysis. Our main program requested a 10 ms task interval with a 5 ms scheduler tick, while earlier diagrams and comments gave other numbers. The analyzer has a sample-rate parameter, but its sampling loop does not pace each reading to that rate. None of these settings is a measured sampling rate or response time. Measure the actual acquisition timing before making any claim based on the frequency output.
Run it, pause it, and look at the result
We developed on MicroPython 1.23.0. In the demonstration, changing the sound near the microphone moved the light bar. We used no calibrated sound source, distance measurement or decibel scale, so the result is a working sound-to-light loop, nothing more.
Pressing the board button pauses the task, and pressing it again resumes. Pausing does not clear the bar. That is an interaction choice to notice: a frozen bar can look like a steady reading to someone who does not know the task has stopped. If pause should mean dark, make that change explicitly and test it.
The console also printed memory-collection messages. They show what the program was doing; they do not show that it is free of memory leaks or that it has run for days. Long operation is a separate test.
Choose the response before adding spectacle
Try the assembled object in the setting you have in mind. Compare a quiet-room baseline, normal speech or music, and a louder sound nearby. Watch whether the bar spends most of its time empty or full, whether brief sounds are noticeable, and whether pause and resume are obvious. Repeat after moving the microphone into its final position in the case.
Aim for a behavior you can state, for example "ordinary speech moves the bar through several levels, and the button visibly pauses the effect". Once that works for your users, decide whether to keep the simple bar, change the visual pattern or use a different audio front end.