Possible to combine shields?

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
FSUDAL
 
Posts: 28
Joined: Sat Jan 14, 2012 7:04 pm

Possible to combine shields?

Post by FSUDAL »

I have an Arduino UNO with an Adafruit data logger shield. I would like to add high quality audio that will play when triggered by a sensor (same song is restarted each time sensor is triggered). The data logger will capture the sensor levels and how often the audio is triggered. Is it possible to add another shield (wave shield) with the data logger shield? If not, can you think of any way that I could add audio that is triggered by a sensor (wire up a standalone mp3 player somehow)?

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

Re: Possible to combine shields?

Post by adafruit_support_bill »

Both the Wave Shield and the VS1053 have SD cards interfaces, so you do not really need the one on data logger. A better combination would be the Wave Shield or VS1053 with an DS1307 RTC breakout (if you need the real-time clock functionality).

FSUDAL
 
Posts: 28
Joined: Sat Jan 14, 2012 7:04 pm

Re: Possible to combine shields?

Post by FSUDAL »

Thank you for the quick reply. I am just a notch above novice level but was able to assemble and program the data logger to work with the Arduino UNO. It sound like what your saying is that I do not need the data logger shield if using a different shield with an SD interface? If I used the wave shield with the SD interface and the DS1307 RTC breakout for the clock could I use the same code that worked for the data logger to capture data or would all of that need to be changed? If not, what code would I use to capture the data in the same what that I have been doing it with the data logger? Thanks again for your time and support. This community is what makes it possible for people like me to have success with your products. Thanks again!

User avatar
adafruit_support_rick
 
Posts: 35092
Joined: Tue Mar 15, 2011 11:42 am

Re: Possible to combine shields?

Post by adafruit_support_rick »

The same code for writing to the SD should work with the WaveShield.
The only thing to do is to make sure that the chipSelect line is set to Pin 10 to use the SD card on the WaveShield

FSUDAL
 
Posts: 28
Joined: Sat Jan 14, 2012 7:04 pm

Re: Possible to combine shields?

Post by FSUDAL »

Thanks again. I have bought several items from your store over the years and can't express enough how much I appreciated the help and support (along with the great product and tutorials). I just ordered the real time clock in hopes that I will not need to stack my adafruit data logger (I'll put it to use elsewhere)! I was looking for an mp3 player and did not find one available on your site yet. I know this is not your product but did you think that I could use the SD card on this shield with the arduino UNO and your RTC to capture data in the same way your data logger shield did? Thanks again.

http://www.elechouse.com/elechouse/inde ... ts_id=2193

User guide; http://www.elechouse.com/elechouse/imag ... 0Guide.pdf

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

Re: Possible to combine shields?

Post by adafruit_support_bill »

We do not have an MP3 in shield form, but the VS1053 breakout board I mentioned in my first post includes MP3 and much more. It will playback MP3, AAC, Ogg Vorbis, WMA, MIDI, FLAC, WAV (PCM and ADPCM). As well as record both PCM (WAV) and compressed Ogg Vorbis.

See the tutorial here:
http://learn.adafruit.com/adafruit-vs10 ... c-tutorial

The SD card should be compatible with any shield or breakout that has an SD interface.
Image

FSUDAL
 
Posts: 28
Joined: Sat Jan 14, 2012 7:04 pm

Re: Possible to combine shields?

Post by FSUDAL »

I was reading more about this board and watched the new product video on it; however, I did not see an example of the audio quality. I would like to use it to play cd quality music through powered speakers. Is there a youtube video available so that I can hear an example of the music quality? If not, what is the quality of the audio/music when played from the sd card? Thanks again.

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

Re: Possible to combine shields?

Post by adafruit_support_bill »

I would like to use it to play cd quality music through powered speakers.
MP3's and other lossy compression formats are not going to be CD quality on this or any other device. The output can only be as good as the source material. But the VS1053 sound quality is as good as any MP3 device I have heard. Playing lossless formats such as FLAC, the sound is excellent.

User avatar
adafruit_support_rick
 
Posts: 35092
Joined: Tue Mar 15, 2011 11:42 am

Re: Possible to combine shields?

Post by adafruit_support_rick »

Audio quality depends on the compression of the original data and the quality of the reproduction system (amplifier, speakers, etc.). The VS1053 combines a compression-format decoder and an 18-bit oversampling DAC.
The DAC itself is capable of producing a CD-quality signal, therefore the VS1053 itself will have no impact, positive or negative, on overall sound quality.

FSUDAL
 
Posts: 28
Joined: Sat Jan 14, 2012 7:04 pm

Re: Possible to combine shields?

Post by FSUDAL »

Thanks for the good information. I just ordered the board. While I also have the data logger shield I will put that in my closet for now and will be working with; the Arduino UNO, the VS1053 Codec + MicroSD Breakout and the DS1307 RTC. Combining these three can I play music while logging data to the SD card on the VS1053 breakout board? If not how can I either combine the data logger shield or another breakout board so that I can play music and log data? Thanks again for your support. While I purchased the MP3 board from elechouse it wound up being a disaster since there is no meaningful support from them. I will be sticking with adafruit from now on (learned my lesson)!

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

Re: Possible to combine shields?

Post by adafruit_support_bill »

You might get that to work, but it is asking a lot from an Arduino. Memory is one issue. The Uno only has 2K of SRAM for file buffers, stack & heap. Contention for SD card access is another issue. When logging events and audio buffer updates collide, your audio quality will suffer.

FSUDAL
 
Posts: 28
Joined: Sat Jan 14, 2012 7:04 pm

Re: Possible to combine shields?

Post by FSUDAL »

Thanks Bill. What hardware would you suggest that I use to get this to work (log data and play quality music at the same time)? Should I scrap the UNO for another model? Could I add the data logger to what I already have and use two SD Cards (one on the data logger for data and the other on the audio card for playing music)?

User avatar
adafruit_support_rick
 
Posts: 35092
Joined: Tue Mar 15, 2011 11:42 am

Re: Possible to combine shields?

Post by adafruit_support_rick »

If it were me, I'd first see whether it works with one SD card. The buffering scheme might smooth over any SD data writes.

FSUDAL
 
Posts: 28
Joined: Sat Jan 14, 2012 7:04 pm

Re: Possible to combine shields?

Post by FSUDAL »

I received my VS1053 MP3 breakout board and attempted to play music while data logging. I am a bit of a newbie so please state the obvious. I am able to play mp3 files (the quality is perfect!) while using the "player_interupts" example sketch. I can also data log using my custom sketch based off your "datalogger" sketch; however, when I try to combine the two sketches so that I can play mp3 files while data logging, the datalogger prints one line, there is a beep and then the I get an SD Failed or not present warning and everything stops. When I deleted the "while (1); // don't do anything more" line from the "player_interupts" portion of the combined sketch the warning appears but then it says "SD OK!" logs one time and starts playing the music without any further data logging. Would you please take a peek at the combined sketch below and offer a solution? Thank you so much for your continued help and support!

Code: Select all

    const int sensorpin = A0;                // select the input pin for the sensor
    const int alarmpin = 7;                  // select the pin for the buzzer
    float sensorvalue = 0;                   // variable to store the value coming from the sensor
    float microvolts = 0;                    // stores microVolt readings
    float tempmicrovolts = 0;                // stores sensorValue
    float summicrovolts = 0;                 // sum sensorValue readings
    float averagemicrovolts = 0;
    unsigned long lastSecond = 0;
    int seconds = 0;
    int minutes = 0;
    int hours = 0; 
    int offcounter = 0;                      // sets offcounter to zero

#include <SPI.h>
#include <Adafruit_VS1053.h> 
    #include <SD.h>
    #include <Wire.h>

    #define LOG_INTERVAL 1000                // mills between entries (reduce to take more/faster data)
    #define SYNC_INTERVAL 1000               // mills between calls to flush() - to write data to the card
    uint32_t syncTime = 0;                   // time of last sync()
    #define ECHO_TO_SERIAL 1                 // echo data to serial port
    #define WAIT_TO_START 0                  // Wait for serial input in setup()
    #define greenLEDpin 2
    const int chipSelect = 4;               // for the data logging shield, we use digital pin 10 for the SD cs line
    File logfile;                            // the logging file

#define RESET 9      // VS1053 reset pin (output)
#define CS 10        // VS1053 chip select pin (output)
#define DCS 8        // VS1053 Data/command select pin (output)
#define DREQ 3       // VS1053 Data request pin (into Arduino)
#define CARDCS 4     // Card chip select pin


Adafruit_VS1053_FilePlayer musicPlayer = Adafruit_VS1053_FilePlayer(RESET, CS, DCS, DREQ, CARDCS);
// Alternately, use 'soft SPI'. Requires Adafruit's flexible SD library
// Adafruit_VS1053_FilePlayer musicPlayer = Adafruit_VS1053_FilePlayer(MOSI, M

    void error(char *str)
    {
    Serial.print("error: ");
    Serial.println(str);
   
    digitalWrite(greenLEDpin, HIGH);         // LED indicates error

    while(1);
    }

void setup(void)
{
    pinMode(alarmpin, OUTPUT); 
    pinMode(greenLEDpin, OUTPUT);
    pinMode(10, OUTPUT);                     // make sure that the default chip select pin is set to output, even if you don't use it:

    Serial.begin(9600);
    Serial.println();
   
    #if WAIT_TO_START
    Serial.println("Type any character to start");
    while (!Serial.available());
    #endif //WAIT_TO_START
  
    Serial.print("Initializing SD card..."); // initialize the SD card
  
    if (!SD.begin(chipSelect))               // see if the card is present and can be initialized:
      {
      error("Card failed, or not present");
      }
 
    Serial.println("card initialized.");
  
    char filename[] = "LOGGER00.CSV";        // create a new file
    for (uint8_t i = 0; i < 100; i++) {
    filename[6] = i/10 + '0';
    filename[7] = i%10 + '0';

    if (! SD.exists(filename)) 
      {
      logfile = SD.open(filename, FILE_WRITE);// only open a new file if it doesn't exist
      break; // leave the loop!
      }
    }
  
    if (! logfile) 
      {
      error("couldnt create file");
      }
  
    Serial.print("Logging to: ");
    Serial.println(filename);
 
    Wire.begin();
  
    logfile.println("Time, uVolts, uVpm, uV SUM");
    #if ECHO_TO_SERIAL
    Serial.println("Time, uVolts, uVpm, uV SUM");
    #endif //ECHO_TO_SERIAL
  // initialise the music player
  if (!musicPlayer.begin()) {
    Serial.println("VS1053 not found");
    while (1);  // don't do anything more
  }

  musicPlayer.sineTest(0x44, 500);    // Make a tone to indicate VS1053 is working
 
  if (!SD.begin(CARDCS)) {
    Serial.println("SD failed!, or not present!");
//    while (1);  // don't do anything more
  }
  Serial.println("SD OK!");
  
  // Set volume for left, right channels. lower numbers == louder volume!
  musicPlayer.setVolume(20,20);

  /***** Two interrupt options! *******/ 
  // This option uses timer0, this means timer1 & t2 are not required
  // (so you can use 'em for Servos, etc) BUT millis() can lose time
  // since we're hitchhiking on top of the millis() tracker
  //musicPlayer.useInterrupt(VS1053_FILEPLAYER_TIMER0_INT);
  
  // This option uses a pin interrupt. No timers required! But DREQ
  // must be on an interrupt pin. For Uno/Duemilanove/Diecimilla
  // that's Digital #2 or #3
  // See http://arduino.cc/en/Reference/attachInterrupt for other pins
  // *** This method is preferred
  if (! musicPlayer.useInterrupt(VS1053_FILEPLAYER_PIN_INT))
    Serial.println("DREQ pin is not an interrupt pin");
}

void loop(void)
{
    int threshold = 25;                            // sets threshold sensor needs to exceed
    sensorvalue = analogRead(sensorpin);           // reads sensorPin to determine sensorValue
    microvolts = (sensorvalue/2.046);              // converts sensorValue into microvolts
    tempmicrovolts = summicrovolts;                // saves last sum
    summicrovolts = tempmicrovolts + microvolts;   // adds last sum with new number
    averagemicrovolts = ((summicrovolts/(millis()/60000)));     // calculates the average uVolts per minute
 
   if(millis() - lastSecond >= 1000)
   {
      lastSecond += 1000;
      seconds++;
   }
   if(seconds > 59)
   {
      seconds = 0;
      minutes++;
   }
   if(minutes > 59)
   {
      minutes = 0;
      hours++;
    }

   if(microvolts >= threshold)
      {
      digitalWrite(alarmpin, HIGH);                     // turn alarmPin on
      offcounter = 0;
      }
    
   if(microvolts < threshold)
      {
      offcounter++;
      } 
 
   if((microvolts < threshold) && offcounter >= 3)
      {
      digitalWrite(alarmpin, LOW);  
      }
 
     delay((LOG_INTERVAL -1) - (millis() % LOG_INTERVAL));// delay for the amount of time we want between readings
     digitalWrite(greenLEDpin, HIGH);
     uint32_t m = millis();                               // log milliseconds since starting

     logfile.print(hours);
     logfile.print(":");
     logfile.print(minutes);
     logfile.print(":");
     logfile.print(seconds);
     logfile.print(", ");
     logfile.print(microvolts);
     logfile.print(", ");    
     logfile.print(averagemicrovolts);
     logfile.print(", ");    
     logfile.println(summicrovolts);


     #if ECHO_TO_SERIAL
     Serial.print(hours);
     Serial.print(":");
     Serial.print(minutes);
     Serial.print(":");
     Serial.print(seconds);
     Serial.print(", ");
     Serial.print(microvolts);
     Serial.print(", ");  
     Serial.print(averagemicrovolts);
     Serial.print(", ");      
     Serial.println(summicrovolts);

     #endif
   
     digitalWrite(greenLEDpin, LOW);

     if ((millis() - syncTime) < SYNC_INTERVAL) return;
     syncTime = millis();
     logfile.flush();
  
  // Alternately, we can just play an entire file at once
  // This doesn't happen in the background, instead, the entire
  // file is played and the program will continue when it's done!
//  musicPlayer.playFullFile("track001.ogg");

  // Start playing a file, then we can do stuff while waiting for it to finish
  if (! musicPlayer.startPlayingFile("track001.mp3")) {
    Serial.print("Could not open file");
    return;
  }
  Serial.println("Started playing");

  while (musicPlayer.playingMusic) {
    // file is now playing in the 'background' so now's a good time
    // to do something else like handling LEDs or buttons :)
    Serial.print(".");
    delay(1000);
  }
  Serial.println("Done playing music");

}

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

Re: Possible to combine shields?

Post by adafruit_support_bill »

You are going to sit in this while loop until the music stops.

Code: Select all

  while (musicPlayer.playingMusic) {
    // file is now playing in the 'background' so now's a good time
    // to do something else like handling LEDs or buttons :)
    Serial.print(".");
    delay(1000);
  }
You should eliminate that loop and change your music start code to something like this:

Code: Select all

  if (!musicPlayer.playingMusic)  // if nothing is playing - start playing a track
  {
    if (! musicPlayer.startPlayingFile("track001.mp3")) 
    {
      Serial.print("Could not open file");
      return;
    }
  }

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

Return to “Arduino Shields from Adafruit”