Possible to combine shields?
Moderators: adafruit_support_bill, adafruit
Please be positive and constructive with your questions and comments.
-
- Posts: 28
- Joined: Sat Jan 14, 2012 7:04 pm
Possible to combine shields?
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)?
- adafruit_support_bill
- Posts: 88093
- Joined: Sat Feb 07, 2009 10:11 am
Re: Possible to combine shields?
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).
-
- Posts: 28
- Joined: Sat Jan 14, 2012 7:04 pm
Re: Possible to combine shields?
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!
- adafruit_support_rick
- Posts: 35092
- Joined: Tue Mar 15, 2011 11:42 am
Re: Possible to combine shields?
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
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
-
- Posts: 28
- Joined: Sat Jan 14, 2012 7:04 pm
Re: Possible to combine shields?
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
http://www.elechouse.com/elechouse/inde ... ts_id=2193
User guide; http://www.elechouse.com/elechouse/imag ... 0Guide.pdf
- adafruit_support_bill
- Posts: 88093
- Joined: Sat Feb 07, 2009 10:11 am
Re: Possible to combine shields?
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.
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.
-
- Posts: 28
- Joined: Sat Jan 14, 2012 7:04 pm
Re: Possible to combine shields?
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.
- adafruit_support_bill
- Posts: 88093
- Joined: Sat Feb 07, 2009 10:11 am
Re: Possible to combine shields?
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.I would like to use it to play cd quality music through powered speakers.
- adafruit_support_rick
- Posts: 35092
- Joined: Tue Mar 15, 2011 11:42 am
Re: Possible to combine shields?
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.
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.
-
- Posts: 28
- Joined: Sat Jan 14, 2012 7:04 pm
Re: Possible to combine shields?
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)!
- adafruit_support_bill
- Posts: 88093
- Joined: Sat Feb 07, 2009 10:11 am
Re: Possible to combine shields?
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.
-
- Posts: 28
- Joined: Sat Jan 14, 2012 7:04 pm
Re: Possible to combine shields?
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)?
- adafruit_support_rick
- Posts: 35092
- Joined: Tue Mar 15, 2011 11:42 am
Re: Possible to combine shields?
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.
-
- Posts: 28
- Joined: Sat Jan 14, 2012 7:04 pm
Re: Possible to combine shields?
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");
}
- adafruit_support_bill
- Posts: 88093
- Joined: Sat Feb 07, 2009 10:11 am
Re: Possible to combine shields?
You are going to sit in this while loop until the music stops.
You should eliminate that loop and change your music start code to something like this:
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);
}
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;
}
}
Please be positive and constructive with your questions and comments.