Got my panda today and implemented the code needed to read the spectrum analyzer from www.bliptronics.com.
This is obviously my first application, any feedback is welcome
I had ported this form arduino to netduino … so it was an easy port to FEZ from there.
- Note: Edited - The original post will be updated with current code (as long as it be edited)
- Last Update: October 8th.
Overview
This shield is designed to pull 7 bands from music input. It uses an EQ chip designed for car stereos and works great. It has a built in multiplexer … so you can pull all seven bands using two Digital and one or two analog pins (stereo).
The Code
Edited
- Note I had used a loop and setup routine mapped from the arduino world in the original code, hence the initial comments and suggestion to use Timers.
/* Code to read the Spectrum Analyzer chip from bliptronics.com
*
* http://www.bliptronics.com/item.aspx?ItemID=116
*
* Author: Joseph Francis - based on code from bliptronics and arduino community assistance.
*
* Created: Oct 7, 2010
*
* Version 1.0: Oct 7, 2010 - Initial Version
* Version 1.1: Oct 8, 2010 - Updated to use timers and provide smoothed values / comments
*
*/
using System;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using GHIElectronics.NETMF.FEZ;
using GHIElectronics.NETMF.Hardware;
namespace FEZPandaBliptronicsAnalyzer
{
public class Program
{
//--- Strobe and Reset are hard wired on the board
//--- there are jumpers (jp1 - 2 holes) that allow other pins to be used (advanced)
static OutputPort spStrobe = new OutputPort((Cpu.Pin)FEZ_Pin.Digital.Di4, false);
static OutputPort spReset = new OutputPort((Cpu.Pin)FEZ_Pin.Digital.Di5, false);
//--- Stereo input means 2 chips and 2 analog reads (combined in this example)
static AnalogIn spReadL = new AnalogIn((AnalogIn.Pin)FEZ_Pin.AnalogIn.An0);
static AnalogIn spReadR = new AnalogIn((AnalogIn.Pin)FEZ_Pin.AnalogIn.An1);
//--- Stores music spectrum values and smoothing variables
static int[] Spectrum = { 0, 0, 0, 0, 0, 0, 0 };
const int EQ_SMOOTH_COUNT = 3;
static int[] SpectrumSmoothTots = {0, 0, 0, 0, 0, 0, 0};
static int SpectrumSmoothAt = 0;
static int[][] SpectrumSmoothVals = new int[][] {
new int[] { 0, 0, 0, 0, 0, 0, 0 },
new int[] { 0, 0, 0, 0, 0, 0, 0 },
new int[] { 0, 0, 0, 0, 0, 0, 0 }
};
//--- Variable to account for a humm.
// * Lower this until you get get output when off - then raise it some.
const int MUSIC_MIN = 190;
//--- Used to loop a value back to zero when count is hit (i.e. looping color).
// * The count is 1 based but the rest of the usage is zero based
static int incrToCount(int val, int amt, int count)
{
val += amt;
if (val > count - 1)
val -= count;
if (val < 0)
val += count;
return val;
}
//--- Used to loop a byte - commonly used value for color (256 levels)
static int increment(int val, int amt)
{
return incrToCount(val, amt, 256);
}
//--- Toggle the reset pin to activate the spectrum analyzer and reset to bass level (0)
static public void setupSpecrum()
{
spReset.Write(true);
Thread.Sleep(1);
spReset.Write(false);
Thread.Sleep(1);
}
//--- This toggles the strobe and reads the band values in a loop of 7 bands
//--- Also included is smoothing - but use the following line to get the smoothed value
// ------> int SpectrumVal = (SpectrumSmoothTots[i]) / EQ_SMOOTH_COUNT;
static public void readSpecrum()
{
byte Band;
for (Band = 0; Band < 7; Band++)
{
//--- Trigger strobe to make multiplexer jump
spStrobe.Write(true);
spStrobe.Write(false);
//--- Add the left and right values - then devide by 2
int cVal = spReadL.Read();
cVal += spReadR.Read();
cVal /= 2;
//--- Allow for a min hum
if (cVal < MUSIC_MIN)
{
cVal = 0;
}
//--- Set related bands (low to high = 0 through 6 for seven bands)
Spectrum[Band] = cVal;
int currTot = SpectrumSmoothTots[Band];
currTot += cVal;
currTot -= SpectrumSmoothVals[SpectrumSmoothAt][Band];
SpectrumSmoothVals[SpectrumSmoothAt][Band] = cVal;
SpectrumSmoothTots[Band] = currTot;
SpectrumSmoothAt = incrToCount(SpectrumSmoothAt, 1, EQ_SMOOTH_COUNT);
}
}
//--- Debug Routine: Shows the current results - real time
static public void showResults(Object o)
{
string strOut = "";
Boolean minHit = false;
for (byte i = 0; i < 7; i++)
{
int SpectrumVal = Spectrum[i];
if (!minHit && SpectrumVal > MUSIC_MIN)
minHit = true;
if (strOut != "")
strOut = strOut + " - ";
strOut = strOut + SpectrumVal.ToString();
}
strOut = "Direct Read: " + strOut + "\n";
if (minHit)
Debug.Print(strOut);
}
//--- Debug Routine: Shows the current results - smoothed
static public void showSmoothResults(Object o)
{
string strOut = "";
Boolean minHit = false;
for (byte i = 0; i < 7; i++)
{
int SpectrumVal = (SpectrumSmoothTots[i]) / EQ_SMOOTH_COUNT;
if (!minHit && SpectrumVal > MUSIC_MIN)
minHit = true;
if (strOut != "")
strOut = strOut + " - ";
strOut = strOut + SpectrumVal.ToString();
}
strOut = "Smooth: " + strOut + "\n";
if (minHit)
Debug.Print(strOut);
}
//--- Process that reads the spectrum analyzer in a timer
static public void readProcess(Object o)
{
readSpecrum();
}
public static void Main()
{
//--- Reset the spectrum analyzer
setupSpecrum();
//--- Setup a timer to read the music input, should be quick loop
Timer readTimer = new Timer(new TimerCallback(readProcess), null, 100, 50);
//--- Setup another demo timer that simply shows the results
Timer showTimer = new Timer(new TimerCallback(showResults), null, 1000, 50);
Timer showTimerSmooth = new Timer(new TimerCallback(showSmoothResults), null, 1000, 50);
//--- Just stop but do not end the program
Thread.Sleep(Timeout.Infinite);
}
}
}
When you turn off the music … you get nothing. When you turn on the music … you get this in debug (seven bands from low to high … left to right as you would expect).
,
Direct Read: 473 - 944 - 851 - 955 - 929 - 951 - 715
Smooth: 157 - 314 - 283 - 318 - 309 - 317 - 238
Direct Read: 777 - 1023 - 1023 - 1023 - 927 - 792 - 595
Smooth: 416 - 655 - 624 - 659 - 618 - 581 - 436
Direct Read: 626 - 1023 - 947 - 1023 - 907 - 657 - 500
Smooth: 625 - 996 - 940 - 1000 - 921 - 800 - 603
Direct Read: 696 - 1023 - 846 - 988 - 760 - 552 - 414
Smooth: 699 - 1023 - 938 - 1011 - 864 - 667 - 503
Direct Read: 637 - 1023 - 911 - 933 - 630 - 455 - 348
Smooth: 653 - 1023 - 901 - 981 - 765 - 554 - 420
Direct Read: 590 - 1023 - 1020 - 825 - 526 - 388 - 297
Smooth: 641 - 1023 - 925 - 915 - 638 - 465 - 353
Direct Read: 659 - 957 - 1023 - 771 - 440 - 1023 - 1023
Smooth: 628 - 1001 - 984 - 843 - 532 - 622 - 556
Direct Read: 617 - 932 - 1011 - 641 - 372 - 982 - 996
Smooth: 622 - 970 - 1018 - 745 - 446 - 797 - 772
Direct Read: 548 - 859 - 940 - 559 - 313 - 890 - 840
Smooth: 608 - 916 - 991 - 657 - 375 - 965 - 953
Direct Read: 526 - 890 - 840 - 466 - 305 - 747 - 694
Smooth: 563 - 893 - 930 - 555 - 330 - 873 - 843
…
- Edited to show new output from new version.