How to do start playing audio with the wave shield and do other things

Adafruit Ethernet, Motor, Proto, Wave, Datalogger, GPS Shields - etc!

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
User avatar
KOefficient
 
Posts: 14
Joined: Sat Apr 04, 2009 12:48 pm

How to do start playing audio with the wave shield and do other things

Post by KOefficient »

I'm working with the wave shield and want to add lights to my project. What I'd like to do is start playing audio based on input and then control the digitally addressable LED strand with tons of for loops. Is it possible to start playing audio and exit a function then go into another function and control the LEDs with the audio still playing all on the same arduino?

I've attached the pieces of my code that matter. Essentially I'm going to have multiple LEDs patterns and multiple wave files to choose from but I am testing the basics with just 2 switches until I get my order in.

Code: Select all

void loop() {
  byte led_choice, music_choice, r_index, r_middle, r_ring, r_pinky, 
       l_index, l_middle, l_ring, l_pinky, r_hand, l_hand;
      
      r_index = digitalRead(right_index);
      r_middle = digitalRead(right_middle);
      r_ring = digitalRead(right_ring);
      r_pinky = digitalRead(right_pinky);
      l_index = digitalRead(left_index);
      l_middle = digitalRead(left_middle);
      l_ring = digitalRead(left_ring);
      l_pinky = digitalRead(left_pinky);
      
      r_hand = r_index + 2 * r_middle + 4 * r_ring + 8 * r_pinky;
      l_hand = l_index + 2 * l_middle + 4 * l_ring + 8 * l_pinky;
      
      if(r_index)
      {
        Serial.println("Start playing Mr. Roboto");
        playcomplete("mrroboto.wav");
        Serial.println("Out of the placomplete function");
      }
      
      if(r_middle)
      {
        Serial.println("Start playing CylonLoop");
        CylonLoop(Cylon_Wait);
        Serial.println("Done playing CylonLoop");
      }
}
  
  void CylonLoop(unsigned int CylonWait)
  {
    Serial.println("Cylon Loop");
    int i, j, temp;
    
    // Start by turning all pixels off:
    for(i=0; i<strip.numPixels(); i++) strip.setPixelColor(i, 0);
    
    for (i=0; i<LedPerStrand; i++)
    {
      for(j = 0; j < nStrand; j++)
      {
        temp = i + (j*LedPerStrand);
        strip.setPixelColor(temp, strip.Color(127, 0, 0)); // Set new pixel 'on'
      
        if(i-1 >= 0)
        {
          temp = temp - 1;
          strip.setPixelColor(temp, strip.Color(64, 0, 0)); // Set training pixel to 50%
        }
        
        if(i-2 >= 0)
        {
          temp = temp - 1;
          strip.setPixelColor(temp, strip.Color(16, 0, 0)); // Dim trailing pixel
        }
        if(i-3 >= 0)
        {
          temp = temp - 1;
          strip.setPixelColor(temp, strip.Color(0, 0, 0)); // Turn off trailing pixel
        }
      }
      
      strip.show();              // Refresh LED states
      
      delay(CylonWait);
    }
    
    strip.setPixelColor(i-1, strip.Color(0, 0, 0)); // Set last training pixel off
   
    for (i=(LedPerStrand-1); i>=0; i--)
    {
      for(j = 0; j < nStrand; j++)
      {
        temp = i + (j*LedPerStrand);
        strip.setPixelColor(temp, strip.Color(127, 0, 0)); // Set new pixel 'on'
      
        if(i+1 < LedPerStrand)
        {
          temp = temp + 1;
          strip.setPixelColor(temp, strip.Color(64, 0, 0)); // Set training pixel to 50%
        }
        
        if(i+2 < LedPerStrand)
        {
          temp = temp + 1;
          strip.setPixelColor(temp, strip.Color(16, 0, 0)); // Dim trailing pixel
        }
        if(i+3 < LedPerStrand)
        {
          temp = temp + 1;
          strip.setPixelColor(temp, strip.Color(0, 0, 0)); // Turn off trailing pixel
        }
      }
      
      strip.show();              // Refresh LED states
      
      delay(CylonWait);
    }
  }
  
// Plays a full file from beginning to end with no pause.
void playcomplete(char *name) {
  // call our helper to find and play this name
  playfile(name);
 // while (wave.isplaying) {
  // do nothing while its playing
  //}
  // now its done playing
}

void playfile(char *name) {
  // see if the wave object is currently doing something
  if (wave.isplaying) {// already playing something, so stop it!
    return;
    //wave.stop(); // stop it
  }
  // look in the root directory and open the file
  if (!f.open(root, name)) {
    putstring("Couldn't open file "); Serial.print(name); return;
  }
  // OK read the file and turn it into a wave object
  if (!wave.create(f)) {
    putstring_nl("Not a valid WAV"); return;
  }
  
  // ok time to play! start playback
  wave.play();
}

User avatar
KOefficient
 
Posts: 14
Joined: Sat Apr 04, 2009 12:48 pm

Re: How to do start playing audio with the wave shield and do other things

Post by KOefficient »

I think I've got the code working. I'm still having problems with the LED strip not lighting up. I'm unable to initialize the correct number of LEDs per strip.

My code:

Code: Select all

#include <LPD8806.h>
#include <SPI.h>
#include <WaveUtil.h>
#include <WaveHC.h>

SdReader card;    // This object holds the information for the card
FatVolume vol;    // This holds the information for the partition on the card
FatReader root;   // This holds the information for the filesystem on the card
FatReader f;      // This holds the information for the file we're playing

WaveHC wave;      // This is the only wave (audio) object, since we will only play one at a time

// Number of RGB LEDs in strand:
int nLEDs = 160;
int nStrand = 10;
int LedPerStrand = 16;
unsigned int Cylon_Wait = 15;
unsigned int BlockDelta = 10;
unsigned int ChaseSpeed = 10;

// Chose 2 pins for output; can be any valid output pins:
int dataPin  = 8;
int clockPin = 9;
int right_index = 6;
int right_middle = 7;
int right_ring = 14;
int right_pinky = 15;
int left_index = 16;
int left_middle = 17;
int left_ring = 18;
int left_pinky = 19;

// First parameter is the number of LEDs in the strand.  The LED strips
// are 32 LEDs per meter but you can extend or cut the strip.  Next two
// parameters are SPI data and clock pins:
LPD8806 strip = LPD8806(nLEDs, dataPin, clockPin);

void sdErrorCheck(void)
{
  if (!card.errorCode()) return;
  PgmPrint("\r\nSD I/O error: ");
  Serial.print(card.errorCode(), HEX);
  PgmPrint(", ");
  Serial.println(card.errorData(), HEX);
  while(1);
}

// You can optionally use hardware SPI for faster writes, just leave out
// the data and clock pin parameters.  But this does limit use to very
// specific pins on the Arduino.  For "classic" Arduinos (Uno, Duemilanove,
// etc.), data = pin 11, clock = pin 13.  For Arduino Mega, data = pin 51,
// clock = pin 52.  For 32u4 Breakout Board+ and Teensy, data = pin B2,
// clock = pin B1.  For Leonardo, this can ONLY be done on the ICSP pins.
//LPD8806 strip = LPD8806(nLEDs);

void setup() {
  // Start up the LED strip
  strip.begin();

  // Update the strip, to start they are all 'off'
  strip.show();
  
  Serial.begin(9600);           // set up Serial library at 9600 bps for debugging

 putstring_nl("\nWave test!");  // say we woke up!
  
  putstring("Free RAM: ");       // This can help with debugging, running out of RAM is bad
  Serial.println(FreeRam());
  Serial.print("Number of pixels: ");
  Serial.println(strip.numPixels(), DEC);
  Serial.print("nLEDs = ");
  Serial.println(nLEDs, DEC); 
  
  strip.updateLength(nLEDs);
  Serial.print("Number of pixels: ");
  Serial.println(strip.numPixels(), DEC);
  
  // Set the output pins for the DAC control. This pins are defined in the library
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(right_index, INPUT);
  pinMode(right_middle, INPUT);
  pinMode(right_ring, INPUT);
  pinMode(right_pinky, INPUT);
  pinMode(left_index, INPUT);
  pinMode(left_middle, INPUT);
  pinMode(left_ring, INPUT);
  pinMode(left_pinky, INPUT);
 
  // pin13 LED
  pinMode(13, OUTPUT);
 
  //  if (!card.init(true)) { //play with 4 MHz spi if 8MHz isn't working for you
  if (!card.init()) {         //play with 8 MHz spi (default faster!)  
    putstring_nl("Card init. failed!");  // Something went wrong, lets print out why
    sdErrorCheck();
    while(1);                            // then 'halt' - do nothing!
  }
The output of the code is:
Wave test!
Free RAM: 336
Number of pixels: 0
nLEDs = 160
Number of pixels: 0
Using partition 1, type is FAT32
Ready!
I can't figure out why I am unable to initialize the correct number of pixels.

User avatar
adafruit_support_bill
 
Posts: 88093
Joined: Sat Feb 07, 2009 10:11 am

Re: How to do start playing audio with the wave shield and do other things

Post by adafruit_support_bill »

You may be running out of RAM and overwriting the variable. The pixel array takes up quite a bit. Try with a smaller number of pixels and see if it initializes properly.

User avatar
KOefficient
 
Posts: 14
Joined: Sat Apr 04, 2009 12:48 pm

Re: How to do start playing audio with the wave shield and do other things

Post by KOefficient »

it looks like if I lower the number then it appears to be working correctly so you nailed it. Thanks for the help. Is there any way for me to optimize the code to free up enough RAM or am I going to have to move to a second Arduino? Even with the smallest array I need (64) I see some undesired behavior from the pixels.

User avatar
adafruit_support_bill
 
Posts: 88093
Joined: Sat Feb 07, 2009 10:11 am

Re: How to do start playing audio with the wave shield and do other things

Post by adafruit_support_bill »

There are some tips here: http://itp.nyu.edu/~gpv206/2008/04/maki ... o_mem.html
And the current version of the Arduino IDE supports the "F()" macro to store literal strings in flash as described here: http://arduino.cc/playground/Learning/Memory

Locked
Please be positive and constructive with your questions and comments.

Return to “Arduino Shields from Adafruit”