Asynchronous play with the wave shield

Post here about your Arduino projects, get help - for Adafruit customers!

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
1rulon1
 
Posts: 3
Joined: Sun Jun 01, 2014 1:53 am

Asynchronous play with the wave shield

Post by 1rulon1 »

Hello all and thank you for your help.

I have spent hours trying to figure out how to play a song while having an RGB fade through colors. I have tried all sorts of things. I have a pretty neat project planned and am pretty disheartened at this point.

Heres my Loop, Im pretty sure that is where my problem is. The RGB works on its own, the wave works on its own, if I play this loop it just plays the wave. I am a beginner, this is my first project but I have put ~100 hrs into learning and researching so far...

Code: Select all

void loop() {
  byte i;
  static byte playing =-1;
    
    if (playing != 0) {
      playing = 0;
      playfile("1.WAV");
      
    }
 
  
    
    
    if (timeout(&count1, led1time )) {
    switch (led1State) {
    case 0: 
      { led1State = 1;               // next step
        led1time = 2000UL;           // for however
        fadeToColor(ledAnalogOne, YELLOW, GREEN, 5);                              // begin the sequence
        break; 
      }

    case 1: 
      {
        led1State = 2;               // next step
        led1time = 2000UL;           // for however
        fadeToColor(ledAnalogOne, GREEN, BLUE, 5);  // switch it off
        break; 
      }

    case 2: 
      {
        led1State = 3;
        led1time = 2000UL;
        fadeToColor(ledAnalogOne, BLUE, INDIGO, 5); // switch it on
        break; 
      }

    case 3: 
      {
        led1State = 4;
        led1time = 2000UL;
        fadeToColor(ledAnalogOne, VIOLET, CYAN, 5);  // switch it off
        break; 
      }
    case 4:
       {
        led1State = 5;
       led1time = 2000UL;
       fadeToColor(ledAnalogOne, MAGENTA, WHITE, 5);
       break; 
       }
    case 5:
       {
        led1State = 0;
       led1time = 2000UL;
       fadeToColor(ledAnalogOne, MAGENTA, WHITE, 5);
       break;   
    }
      
    }}}

Thank you all!

1rulon1
 
Posts: 3
Joined: Sun Jun 01, 2014 1:53 am

Re: Asynchronous play with the wave shield

Post by 1rulon1 »

Here is the whole code

Code: Select all

#include <FatReader.h>
#include <SdReader.h>
#include <avr/pgmspace.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 play

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

//=============================================================================
int ledAnalogOne[] = {6, 9, 11}; //the three pins of the first analog LED 3 = redPin, 5 = greenPin, 6 = bluePin
                                //These pins must be PWM

//Defined Colors (different RGB (red, green, blue) values for colors
//(to add your own ie. fuscia experiment and then add to the list)
const byte RED[] = {255, 0, 0}; 
const byte ORANGE[] = {83, 4, 0}; 
const byte YELLOW[] = {255, 255, 0}; 
const byte GREEN[] = {0, 255, 0}; 
const byte BLUE[] = {0, 0, 255}; 
const byte INDIGO[] = {4, 0, 19}; 
const byte VIOLET[] = {23, 0, 22}; 
const byte CYAN[] = {0, 255, 255}; 
const byte MAGENTA[] = {255, 0, 255}; 
const byte WHITE[] = {255, 255, 255}; 
const byte PINK[] = {158, 4, 79};
const byte TEST[] = {255, 255, 255 };
const byte BLACK[] = {0, 0, 0};

int led1State = 0;

long int led1time = 10UL;

unsigned long count1 = 0;

boolean timeout(unsigned long *marker, unsigned long interval) {
  if (millis() - *marker >= interval) { 
    *marker += interval;    // move on ready for next interval
    return true;       
  } 
  else return false;
}
//===================================================================================


// this handy function will return the number of bytes currently free in RAM, great for debugging!   
int freeRam(void)
{
  extern int  __bss_end; 
  extern int  *__brkval; 
  int free_memory; 
  if((int)__brkval == 0) {
    free_memory = ((int)&free_memory) - ((int)&__bss_end); 
  }
  else {
    free_memory = ((int)&free_memory) - ((int)__brkval); 
  }
  return free_memory; 
} 

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

void setup() {
 //================================================================
  led1time = 1UL;
  led1State = 0; 
  
  for(int i = 0; i < 3; i++){
   pinMode(ledAnalogOne[i], OUTPUT);   //Set the three LED pins as outputs
  }
  setColor(ledAnalogOne, BLACK); 
  //==================================================================
  byte i;
  
  // set up serial port
  Serial.begin(9600);
  putstring_nl("WaveHC with ");

  putstring_nl("buttons");
  
  putstring("Free RAM: ");       // This can help with debugging, running out of RAM is bad
  Serial.println(freeRam());      // if this is under 150 bytes it may spell trouble!
  
  // 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);
 
  // 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!
  }
  
  // enable optimize read - some cards may timeout. Disable if you're having problems
  card.partialBlockRead(true);
 
// Now we will look for a FAT partition!
  uint8_t part;
  for (part = 0; part < 5; part++) {     // we have up to 5 slots to look in
    if (vol.init(card, part)) 
      break;                             // we found one, lets bail
  }
  if (part == 5) {                       // if we ended up not finding one  :(
    putstring_nl("No valid FAT partition!");
    sdErrorCheck();      // Something went wrong, lets print out why
    while(1);                            // then 'halt' - do nothing!
  }
  
  // Lets tell the user about what we found
  putstring("Using partition ");
  Serial.print(part, DEC);
  putstring(", type is FAT");
  Serial.println(vol.fatType(),DEC);     // FAT16 or FAT32?
  
  // Try to open the root directory
  if (!root.openRoot(vol)) {
    putstring_nl("Can't open root dir!"); // Something went wrong,
    while(1);                             // then 'halt' - do nothing!
  }
  
  // Whew! We got past the tough parts.
  putstring_nl("Ready!");
  


  }

void loop() {
  byte i;
  static byte playing =-1;
  
 
  if (playing != 0) {
      playing = 0;
      playfile("1.WAV");
    }
    
    
    if (timeout(&count1, led1time )) {
    switch (led1State) {
    case 0: 
      {                              // begin the sequence
        led1State = 1;               // next step
        led1time = 2000UL;            // for half a second
        fadeToColor(ledAnalogOne, RED, ORANGE, 5); // switch it on
        break; 
      }

    case 1: 
      {
        led1State = 2;               // next step
        led1time = 2000UL;           // for however
        fadeToColor(ledAnalogOne, YELLOW, GREEN, 5);  // switch it off
        break; 
      }

    case 2: 
      {
        led1State = 3;
        led1time = 2000UL;
        fadeToColor(ledAnalogOne, BLUE, INDIGO, 5); // switch it on
        break; 
      }

    case 3: 
      {
        led1State = 4;
        led1time = 2000UL;
        fadeToColor(ledAnalogOne, VIOLET, CYAN, 5);  // switch it off
        break; 
      }
    case 4:
       {
        led1State = 5;
       led1time = 2000UL;
       fadeToColor(ledAnalogOne, MAGENTA, WHITE, 5);
       break; 
       }
    case 5:
       {
        led1State = 0;
       led1time = 2000UL;
       fadeToColor(ledAnalogOne, PINK, BLACK, 3);
       break;   
    }
      
    }}}
}
    //=================================================================================
    
     
 void setColor(int* led, byte* color){
 for(int i = 0; i < 3; i++){             //iterate through each of the three pins (red green blue)
   analogWrite(led[i], 255 - color[i]);  //set the analog output value of each pin to the input value (ie led[0] (red pin) to 255- color[0] (red input color)
                                         //we use 255 - the value because our RGB LED is common anode, this means a color is full on when we output analogWrite(pin, 0)
                                         //and off when we output analogWrite(pin, 255). 
 }
}

/* A version of setColor that takes a predefined color (neccesary to allow const int pre-defined colors */
void setColor(int* led, const byte* color){
 byte tempByte[] = {color[0], color[1], color[2]};
 setColor(led, tempByte);
}

/* Fades the LED from a start color to an end color at fadeSpeed
   led - (int array of three values defining the LEDs pins (led[0] = redPin, led[1] = greenPin, led[2] = bluePin))
   startCcolor - (byte array of three values defing the start RGB color (startColor[0] = start Red value, startColor[1] = start Green value, startColor[2] = start Red value
   endCcolor - (byte array of three values defing the finished RGB color (endColor[0] = end Red value, endColor[1] = end Green value, endColor[2] = end Red value
   fadeSpeed - this is the delay in milliseconds between steps, defines the speed of the fade
*/ 
void fadeToColor(int* led, byte* startColor, byte* endColor, int fadeSpeed){
  int changeRed = endColor[0] - startColor[0];                            //the difference in the two colors for the red channel
  int changeGreen = endColor[1] - startColor[1];                          //the difference in the two colors for the green channel 
  int changeBlue = endColor[2] - startColor[2];                           //the difference in the two colors for the blue channel
  int steps = max(abs(changeRed),max(abs(changeGreen), abs(changeBlue))); //make the number of change steps the maximum channel change
  
  for(int i = 0 ; i < steps; i++){                                        //iterate for the channel with the maximum change
   byte newRed = startColor[0] + (i * changeRed / steps);                 //the newRed intensity dependant on the start intensity and the change determined above
   byte newGreen = startColor[1] + (i * changeGreen / steps);             //the newGreen intensity
   byte newBlue = startColor[2] + (i * changeBlue / steps);               //the newBlue intensity
   byte newColor[] = {newRed, newGreen, newBlue};                         //Define an RGB color array for the new color
   setColor(led, newColor);                                               //Set the LED to the calculated value
   delay(fadeSpeed);                                                      //Delay fadeSpeed milliseconds before going on to the next color
  }
  setColor(led, endColor);                                                //The LED should be at the endColor but set to endColor to avoid rounding errors
}

/* A version of fadeToColor that takes predefined colors (neccesary to allow const int pre-defined colors */
void fadeToColor(int* led, const byte* startColor, const byte* endColor, int fadeSpeed){
  byte tempByte1[] = {startColor[0], startColor[1], startColor[2]};
   byte tempByte2[] = {endColor[0], endColor[1], endColor[2]};
   fadeToColor(led, tempByte1, tempByte2, fadeSpeed);
}
//==========================================================================================
 

// 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!
    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
adafruit_support_bill
 
Posts: 88154
Joined: Sat Feb 07, 2009 10:11 am

Re: Asynchronous play with the wave shield

Post by adafruit_support_bill »

One problem is that the wave shield uses timer1. That is the same timer that controls PWM on pins 9 and 10. You can try moving to a different PWM pin.
Another approach is to use a PWM breakout board like this: https://www.adafruit.com/product/1455

1rulon1
 
Posts: 3
Joined: Sun Jun 01, 2014 1:53 am

Re: Asynchronous play with the wave shield

Post by 1rulon1 »

Thank you kindly!!

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

Return to “Arduino”