Déjà VU


My nostalgic love for analog VU meters made me buy two of these little Chinese guys. They contain good old-fashioned incandescent bulbs and came in a kit with an analog control board. Build quality looks OK and everything works as expected, although the control board seems to be designed to power LEDs instead of incandescent bulbs.


While preparing to connect them to my VS1053 audio decoder breakout, I discovered that additional functionality can be added to the VS1053b chip by means of plugins. One of these extra plugin functions allows you to digitally read VU meter levels! This means that, instead of using the analog control board from the kit, I can let an Arduino (or other MCU) translate digital VU levels to PWM values for driving the meters directly from GPIO pins (these simple VU meters are basically just volt meters). This provides total programmatic control over the meters’ ballistics.

Plugin files for the VS1053b chip can be found on the VLSI Solution site. Documentation can be a bit confusing for beginners like me. It took some research before I understood the mechanism, but then it was easy to upload a plugin, enable the VU meter and actually read its values. Here’s some info that might help (when using Arduino or ESP boards):

  • Plugins are loaded into volatile (temporary) memory of the chip. This means that they won’t harm the chip in case you make mistakes. Just restart your VS1053.
  • Because of the above, plugins have to be loaded within sketches that use them.
  • From the VLSI site, get the ‘.plg’ file of the plugin that you want to use. This file contains a plugin array (RLE encoded) and a LoadUserCode function.
  • Put the plugin array from the .plg file on top of your sketch (or in a header file that you include on top of your sketch). You may add PROGMEM to the array’s declaration.
  • If not using Adafruit’s library: put the example LoadUserCode function from the .plg file inside your sketch. Note that this function contains two WriteVS10xxRegister calls. You’ll need to write your own WriteVS10xxRegister function for writing a 16-bit value to a VS1053 memory address.
  • If not using Adafruit’s library: After the line <your_player>.begin() in your sketch, add the line LoadUserCode();
  • In case you use the Adafruit VS1053 library, you don’t need to include and call a LoadUserCode function. Instead, add the following line after <your_player>.begin(): musicPlayer.applyPatch(plugin, PLUGIN_SIZE);
  • After writing the plugin to the VS1053’s memory, enable the VU meter by setting the 7th bit (from the left) of the VS1053’s status register (address 0x01) to 1.
  • After enabling the VU meter, you can read dB levels from the AICTRL3 register (0x0F). The high 8 bits represent the left channel, the low 8 bits the right channel.

After I posted an issue with the VU meter plugin on their forum, the VLSI support team were kind enough to release a new version that fixes it. Now I can read decibel levels directly from the VS1053b chip and control my stereo VU meters with two GPIO pins.

Update: the plugin turned out to provide ‘leaking peak’ levels instead of real time readings, forcing me to do some programmatical reconstruction work.

Here’s a video of The Swinging Needles.