rMP3 Spectrum Analyzer Demonstration

The rMP3 has (as of firmware version 100.02-b002) a command to retrieve values from a built-in spectrum analyzer. You can select the number of, and the frequency of the bands you want to monitor).

You can read more about the firmware update here: rMP3 Beta Firmware

Components

Libraries

You'll need the following Arduino libraries:

Video

The Adobe Flash Plugin is needed to display this content.

Coding Details

Spectrum Analyzer Data

Setting and retrieving the values from the rMP3 is the easy part.

First, you need to set the bands you want to work with. I did this in the playTrack() function:

void playTrack(void)
{
  char mp3path[128];
 
// ...
 
  rmp3.playfile(mp3path);
 
  rmp3.setspectrumanalyzer(bandfreqs, 10);
 
  Serial.println("Playing");
}

Then, to retrieve the values (while the rMP3 is playing the file):

void doLCDSpec(void)
{
  // prepare for up to 23 bands
  uint8_t v[23];
 
  rmp3.getspectrumanalyzer(v);

Displaying on the LCD

The tough part is getting it displayed on the LCD.

Luckily I wrote some functions to make vertical bars get displayed on the SerLCD controlled LCD.

First you need to prepare all of the “custom characters” on the LCD - we need to have the 8 different levels because each character on the LCD has 8 rows.

void lcdCustomChars(void)
{
  // sets up the custom chars
  byte chars[] = {
    0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b11111,
    0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b11111, 0b11111,
    0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b11111, 0b11111, 0b11111,
    0b00000, 0b00000, 0b00000, 0b00000, 0b11111, 0b11111, 0b11111, 0b11111,
    0b00000, 0b00000, 0b00000, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111,
    0b00000, 0b00000, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111,
    0b00000, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111,
    0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111
  };
 
  for (int i = 0; i < 8; i++)
    lcdSetCustomChar(i, chars + i*8);
 
  delay(100);
}

Now for the weird and strange looking math. We need to translate a value into a vertical bar to be displayed on the LCD. It's a bit tricky, but not all that difficult.

The function below maps the value to match the number of bars (i.e. how tall? if you have a 2 line LCD, you can either use 1 or 2 bars). Then it draws the bar as tall as it needs based on the value. FYI: x refers to which column you are drawing.

void lcdSpecMap(int x, int value, int numBars)
{
  int8_t i, val;
 
  // map value of 0 - maxSpecValue -> 0->7, 0->15, 0->23, 0->31
  if (value > maxSpecValue)
    value = maxSpecValue;
 
  value = map(value, 0, maxSpecValue, 0, 8*numBars);
 
  for (i = 0; i < numBars; i++)
  {
    lcdGotoXY(x, i);
    val = value - (8 * (numBars - 1 - i));
 
    if (val <= 0)
      val = ' ';
    else if (val > 8)
      val = 7;
    else
      val -= 1;
    LCD.print(val, BYTE);
  }
}

Full Source

rMP3_Spectrum_Analyzer_Demo
#include <RogueMP3.h>
#include <RogueSD.h>
#include <NewSoftSerial.h>
 
NewSoftSerial LCD(255, 4);
NewSoftSerial rmp3_s(6, 7);
 
RogueMP3 rmp3(rmp3_s);
RogueSD filecommands(rmp3_s);
 
uint16_t bandfreqs[] = { 50, 120, 200, 500, 1000, 2000, 5000, 8000, 10000, 20000 };
 
uint16_t numfiles = 0;
 
#define MP3PATH "/mp3/"
// you need to put the two double quotes ("") in the middle below,
// because the Arduino IDE looks for unclosed comments.
#define MP3FILTER "/mp3/""*.mp3"
 
 
#define lcdHeight 4
#define lcdWidth 20
#define maxSpecValue 20
 
void lcdClear()
{
   LCD.print(0xFE, BYTE);      //command flag
   LCD.print(0x01, BYTE);      //clear command.
}
 
void lcdBacklightOn(uint8_t level)
{  //turns on the backlight
    LCD.print(0x7C, BYTE);     //command flag for backlight stuff
    LCD.print(level, BYTE);    //light level.
}
 
void lcdBacklightOff()
{  //turns off the backlight
    LCD.print(0x7C, BYTE);     //command flag for backlight stuff
    LCD.print(0x80, BYTE);     //light level for off.
}
 
void lcdGotoXY(int x, int y)
{
  int pos;
 
  if (x >= lcdWidth)
    x = lcdWidth-1;
  if (y >= lcdHeight)
    y = lcdHeight-1;
 
  pos = x + ((y % 2) * 0x40);
 
  if (y >= 2)
    pos += lcdWidth;
 
  LCD.print(0xFE, BYTE);
  LCD.print(0x80 + pos, BYTE);
}
 
 
void lcdSetCustomChar(byte pos, byte values[])
{
  LCD.print(0xFE, BYTE);
  LCD.print(0x40 + pos * 8, BYTE);
  for (int i = 0; i < 8; i++)
    LCD.print(values[i], BYTE);
}
 
 
void lcdCustomChars(void)
{
  // sets up the custom chars
  byte chars[] = {
    0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b11111,
    0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b11111, 0b11111,
    0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b11111, 0b11111, 0b11111,
    0b00000, 0b00000, 0b00000, 0b00000, 0b11111, 0b11111, 0b11111, 0b11111,
    0b00000, 0b00000, 0b00000, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111,
    0b00000, 0b00000, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111,
    0b00000, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111,
    0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111
  };
 
  for (int i = 0; i < 8; i++)
    lcdSetCustomChar(i, chars + i*8);
 
  delay(100);
}
 
void lcdSpecMap(int x, int value, int numBars)
{
  int8_t i, val;
 
  // map value of 0 - maxSpecValue -> 0->7, 0->15, 0->23, 0->31
  if (value > maxSpecValue)
    value = maxSpecValue;
 
  value = map(value, 0, maxSpecValue, 0, 8*numBars);
 
  for (i = 0; i < numBars; i++)
  {
    lcdGotoXY(x, i);
    val = value - (8 * (numBars - 1 - i));
 
    if (val <= 0)
      val = ' ';
    else if (val > 8)
      val = 7;
    else
      val -= 1;
    LCD.print(val, BYTE);
  }
}
 
void doLCDSpec(void)
{
  // prepare for up to 23 bands
  uint8_t v[23];
 
  rmp3.getspectrumanalyzer(v);
 
  for (uint8_t i=0; i<10; i++)
  {
//    lcdSpecMap(i, v[i], 4);
    // we are displaying each band in two columns.
    // so, band 0 goes on columns 0 and 1, band 1 on 2 and 3, band 2 on 4 and 5, etc...
    lcdSpecMap(2*i, v[i], 4);
    lcdSpecMap(2*i+1, v[i], 4);
  }
}
 
 
void setup(void)
{
  Serial.begin(9600);
  Serial.println("Started");
 
  LCD.begin(9600);
 
  for(int i = 0; i < 10; i++)
  {
    LCD.print(18, BYTE);
    delay(20);
  }
 
  LCD.print(124, BYTE);
  LCD.print(16, BYTE);
  delay(20);
 
  LCD.begin(38400);
  rmp3_s.begin(38400);
 
  pinMode(2, INPUT);
  pinMode(3, INPUT);
 
  lcdCustomChars();
  lcdClear();
 
  Serial.println("Starting sync");
  rmp3.sync();
  filecommands.sync();
  Serial.println("Done sync");
 
  lcdGotoXY((lcdWidth - 5)/2, 0);
  LCD.print("Ready");
}
 
 
void playTrack(void)
{
  char mp3path[128];
 
  numfiles = filecommands.filecount(MP3FILTER);
 
  Serial.print("MP3 count: ");
  Serial.println(numfiles, DEC);
 
  // play a file (random)
  strcpy(mp3path, MP3PATH);
  filecommands.entrytofilename(mp3path + strlen(mp3path), 127, MP3FILTER, random(0, numfiles));
 
  Serial.println(mp3path);
  rmp3.playfile(mp3path);
 
  rmp3.setspectrumanalyzer(bandfreqs, 10);
 
  Serial.println("Playing");
}
 
 
void loop(void)
{
  int i;
  static char status = 'S';
 
  status = rmp3.getplaybackstatus();
 
  while (status == 'P')
  {
    doLCDSpec();
 
    status = rmp3.getplaybackstatus();
  }
 
  if (status == 'S')
  {
    lcdGotoXY((lcdWidth - 7) / 2, 0);
    LCD.print("Stopped");
    if (filecommands.status() == 0)  // card is inserted and waiting
      playTrack();
    status = rmp3.getplaybackstatus();
  }
}

Please, if you have any questions, don't hesitate to ask. Make comments below.

Discussion

test189.38.206.226, 2012/07/16 22:47

Friend, where to buy! and most impotante this spectrum allows the code changes, putting graphic effects in the program through the arduino. the code of this graph is open to change? ex: ten effect http://www.youtube.com/watch?v=9M5OOPE06x4&feature=related

test189.38.206.226, 2012/07/16 22:47

Friend, where to buy! and most impotante this spectrum allows the code changes, putting graphic effects in the program through the arduino. the code of this graph is open to change? ex: ten effect http://www.youtube.com/watch?v=9M5OOPE06x4&feature=related

You could leave a comment if you were logged in.
  • Bookmark at
  • Bookmark "rMP3 Spectrum Analyzer Demonstration" at del.icio.us
  • Bookmark "rMP3 Spectrum Analyzer Demonstration" at Digg
  • Bookmark "rMP3 Spectrum Analyzer Demonstration" at Google
  • Bookmark "rMP3 Spectrum Analyzer Demonstration" at StumbleUpon
  • Bookmark "rMP3 Spectrum Analyzer Demonstration" at Technorati
  • Bookmark "rMP3 Spectrum Analyzer Demonstration" at Facebook
  • Bookmark "rMP3 Spectrum Analyzer Demonstration" at Twitter
  • Bookmark "rMP3 Spectrum Analyzer Demonstration" at Slashdot
  • Bookmark "rMP3 Spectrum Analyzer Demonstration" at Yahoo! Bookmarks
  • Bookmark "rMP3 Spectrum Analyzer Demonstration" at Furl
  • Bookmark "rMP3 Spectrum Analyzer Demonstration" at Reddit
  • Bookmark "rMP3 Spectrum Analyzer Demonstration" at Ask
  • Bookmark "rMP3 Spectrum Analyzer Demonstration" at BlinkList
  • Bookmark "rMP3 Spectrum Analyzer Demonstration" at blogmarks
  • Bookmark "rMP3 Spectrum Analyzer Demonstration" at Ma.gnolia
  • Bookmark "rMP3 Spectrum Analyzer Demonstration" at Netscape
  • Bookmark "rMP3 Spectrum Analyzer Demonstration" at ppnow
  • Bookmark "rMP3 Spectrum Analyzer Demonstration" at Rojo
  • Bookmark "rMP3 Spectrum Analyzer Demonstration" at Shadows
  • Bookmark "rMP3 Spectrum Analyzer Demonstration" at Simpy
  • Bookmark "rMP3 Spectrum Analyzer Demonstration" at Socializer
  • Bookmark "rMP3 Spectrum Analyzer Demonstration" at Spurl
  • Bookmark "rMP3 Spectrum Analyzer Demonstration" at Tailrank
  • Bookmark "rMP3 Spectrum Analyzer Demonstration" at Live Bookmarks
  • Bookmark "rMP3 Spectrum Analyzer Demonstration" at Wists
  • Bookmark "rMP3 Spectrum Analyzer Demonstration" at Yahoo! Myweb
  • Bookmark "rMP3 Spectrum Analyzer Demonstration" at BobrDobr
  • Bookmark "rMP3 Spectrum Analyzer Demonstration" at Memori
  • Bookmark "rMP3 Spectrum Analyzer Demonstration" at Faves
  • Bookmark "rMP3 Spectrum Analyzer Demonstration" at Favorites
  • Bookmark "rMP3 Spectrum Analyzer Demonstration" at Newsvine
  • Bookmark "rMP3 Spectrum Analyzer Demonstration" at myAOL
  • Bookmark "rMP3 Spectrum Analyzer Demonstration" at Fark
  • Bookmark "rMP3 Spectrum Analyzer Demonstration" at RawSugar
  • Bookmark "rMP3 Spectrum Analyzer Demonstration" at LinkaGoGo
  • Bookmark "rMP3 Spectrum Analyzer Demonstration" at Mister Wong
  • Bookmark "rMP3 Spectrum Analyzer Demonstration" at Wink
  • Bookmark "rMP3 Spectrum Analyzer Demonstration" at BackFlip
  • Bookmark "rMP3 Spectrum Analyzer Demonstration" at Diigo
  • Bookmark "rMP3 Spectrum Analyzer Demonstration" at Segnalo
  • Bookmark "rMP3 Spectrum Analyzer Demonstration" at Netvouz
  • Bookmark "rMP3 Spectrum Analyzer Demonstration" at DropJack
  • Bookmark "rMP3 Spectrum Analyzer Demonstration" at Feed Me Links
  • Bookmark "rMP3 Spectrum Analyzer Demonstration" at funP
  • Bookmark "rMP3 Spectrum Analyzer Demonstration" at HEMiDEMi
projects/rmp3/spectrum_analyzer_demonstration.txt · Last modified: 2010/08/16 01:06 by bhagman
Valid CSS Recent changes RSS feed Valid XHTML 1.0