Wednesday, February 18, 2015

Victorian Steampunk Light Dress - Graphic Equalizer Function

Got the base function working with a shift register and two RGB LED's.

 Pinout is:

  • Datapin: 2 ->SR1(14)
  • Latchpin: 8->SR1(4)
  • Clockpin: 4 ->SR1(11)
  • SR1&2(16,10)->+5V
  • SR1&2(8) ->GND
  • SR1&2(13)->GND
  • SR1&2(15,1-7) LED's
  • SR1(9)->SR2(14)
  • SR1(4)->SR2(4)
  • SR1(11)->SR2(11)
  • Sound sensor VCC-5V
  • Sound Sensor GND->GND
  • Sound Sensor Out-> Analog 0
  • in/out 3 -> RGB1 Red pin
  • RGB1 GND->GND
  • in/out 5 -> RGB1 Green Pin
  • in/out 6 ->RGB1 Blue Pin
  • in/out 9 -> RGB2 Red pin
  • RGB2 GND->GND
  • in/out 10 -> RGB2 Green Pin
  • in/out 11 ->RGB2 Blue Pin

(photos to come)

Code below.  Please see references to LED, ShiftRegister and RGBColor class.

#include <LED.h>
#include <ShiftRegister.h>
#include <RGBColor.h>
// DO NOT COPY
RGBColor * color;
RGBColor * color2;
Led * c2;
Led * c1;
byte dataPin = 2;              // The Serial Data Pin to the Shift Register
byte latchPin = 8;             // The Latch Pin to the Shift Register
byte clockPin = 4;

ShiftRegister * sr=new ShiftRegister(clockPin,latchPin,dataPin,16,2);

// END DO NOT COPY

// Tracking SR variabes
byte trackVector=0;
byte oldTrackAvg=0;
byte trackCount=0;
int trackTotal=0;
byte newTrackAvg=0;
//Standard SR Variables
int soundPin=A0;
byte mus_peak=0;
int mus_peakAdj=0;
byte mus_avg=0;
int mus_colorCount=5000;
long mus_count=0;
long mus_total=0;


void setup()
{
  c1=new Led(3,5,6);
  c2=new Led(9,10,11);
  pinMode(3, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);
  pinMode(11, OUTPUT);
  
  pinMode(dataPin, OUTPUT);    // Configure Digital Pins
    
  pinMode(latchPin, OUTPUT);
    
  pinMode(clockPin, OUTPUT);  
  
  color=new RGBColor();
  color2=new RGBColor();
  Serial.begin(9600);
}

void loop()
{
  //Serial.println(analogRead(soundPin));
  //delay(40);
  musicBox(*c1,*c2);

}


void musicBox(Led &led1, Led &led2)
{
  // Bytes for the shift register
  byte SRPulse[]={B00000000,B00011000,B00111100,B01111110,B11111111};
// Turn off the Shift Register pins and LEDS


  // set the color
    // increment the music color count
  mus_colorCount=mus_colorCount+1;
  
  if (mus_colorCount>=5000)
  {
    color->SetRandom();
    color2->setColors(color->Compliment());
    mus_colorCount=0;

    
  }
  
  // collect the local sound value
  byte val=collectAnalogAVG(2);
  clearLed(led1);
  clearLed(led2);
  // add the value to the track total
  trackTotal=trackTotal+val;
  trackCount=trackCount+1;
  if (trackCount>=10)
  {
    oldTrackAvg=newTrackAvg;
    newTrackAvg=trackTotal/trackCount;
    int trackDifferent=newTrackAvg-oldTrackAvg;
    if (trackDifferent<0)
    {
      Serial.print(trackVector);
      // if we've picked up less noise, decrement the vector.
      if (trackVector>=1) trackVector=trackVector-1;
      Serial.print("=");
      Serial.print(trackVector);
    }
    else if (trackDifferent==0)
    {
      // if the sound value has not changed, trackvector should stay the same.
    }
    else if (trackDifferent>100)
    {
      // if the difference is great, increment by 2.
      if (trackVector<=2)  trackVector=trackVector+2;
      else if (trackVector<=3) trackVector=trackVector+1;
    }
    else {
    
      if (trackVector<=3) trackVector=trackVector+1;
    }
    Serial.print("=");
      Serial.println(trackVector);
    // reset SR tracking
    trackTotal=0;
    trackCount=0;
  }
  

  // if the current value is above the average...
  // TODO: Add an array of bytes that go from 0 up to to 255 in steps of 30.  If the sound goes up, pulse up every 2 (add counter.)  If it goes down, pulse down every 30.
  // weight the value against the peak
  if (val>mus_avg)
  {
  double perc=map(val,0,mus_peak,12,100)*.01;
  led1.SetRGB(color->Red()*perc,color->Green()*perc,color->Blue()*perc);
  led2.SetRGB(color2->Red()*perc,color2->Green()*perc,color2->Blue()*perc);
  fireLed(led1);
  fireLed(led2);
  
  delay(15);
  }
  fireLEDs(SRPulse[trackVector]);
}

byte SRNum(double perc)
{
  if (perc>.9)
  {
    return 255;
  }
  else if (perc>.7)
  {
    return 85;
  }
  else if (perc>.5)
  {
    return 68;
  }
  else {
    return 0;
  }
}

byte collectAnalogAVG(byte times)


  
  int total=0;
  for (int i=0;i<times;i++)
  {
    //total=total+map(analogRead(pin),0,500,0,255);
    byte val=map(analogRead(soundPin),0,255,0,255);
    // add it to the total
    mus_total+=val;
    // increment the count
    mus_count=mus_count+1;
    // calculate the average
    mus_avg=mus_total/mus_count;
    // If we've hit a musical peak
    if (val>=mus_peak)
    {
    trackCount=trackCount+5;
    mus_peak=val;
    // increment the color count; it goes up faster with loud noise!
    mus_colorCount=mus_colorCount+500;
    mus_peakAdj=0;
    // return right away!
    return mus_peak;
    }
    else {
    // increment the adjustment
    mus_peakAdj=mus_peakAdj+1;
    if (mus_peakAdj>=10000)
    {
      // if we've gone lower a hundred times, reduce the peak.
      mus_peak=mus_peak*.9;
      mus_peakAdj=0;
    }
    }
    total=total+val;
    delay(2);
    
  }
  return total/times;
}

void SRFireDiv(ShiftRegister &r, byte div)
{
     for (int i=0;i<r.NoPins();i++)
      {
        if (i%div==0) r.ActivatePin(i);
      }
      fireLED(r);
}
void clearLed(Led led)
{
    
    
    analogWrite(led.RPin(),0);
    analogWrite(led.GPin(),0);
    analogWrite(led.BPin(),0);
  
}

// STOP DO NOT COPY



void fireLed(Led led)
{
    
    
    analogWrite(led.RPin(),led.Red());
    analogWrite(led.GPin(),led.Green());
    analogWrite(led.BPin(),led.Blue());
  
}

    void fireLEDs(int data)
  {
        digitalWrite(latchPin,LOW);
        shiftOut(dataPin,clockPin,MSBFIRST,data);  
        shiftOut(dataPin,clockPin,MSBFIRST,data);   // Send the data byte 2
        digitalWrite(latchPin, HIGH);

  }
    void fireLED(ShiftRegister &r)
  {
     
       
        digitalWrite(r.LatchPin(),LOW);
       // for (byte i=0; i<r.NoRegs();i++)
        //{
          // if the current register is active, fire its pins
           // Serial.println(i);
            shiftOut(r.DataPin(),r.ClockPin(),MSBFIRST,r.ShiftNum(0));
            shiftOut(r.DataPin(),r.ClockPin(),MSBFIRST,r.ShiftNum(1));
          
        //}
         digitalWrite(r.LatchPin(), HIGH);
  }
  

No comments:

Post a Comment