ADAFRUIT Data Logger Shield and Music Maker Shield Conflict

General project help for Adafruit customers

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
tomcolllins
 
Posts: 7
Joined: Fri Jul 25, 2014 2:17 pm

ADAFRUIT Data Logger Shield and Music Maker Shield Conflict

Post by tomcolllins »

Running standard data logger (with RTC) for gathering accelerometer data and a Music shield playing a single mp3.
Only collects data for a few seconds, to a few minutes before an interference noise comes out of the headset and from then on only plays music.

Code: Select all

#include <SPI.h>
#include <Adafruit_VS1053.h>
#include <SD.h>
#include <Wire.h>
#include "RTClib.h"
#define LOG_INTERVAL  20 // mills between entries (reduce to take more/faster data)

// how many milliseconds before writing the logged data permanently to disk
// set it to the LOG_INTERVAL to write each time (safest)
// set it to 10*LOG_INTERVAL to write all data every 10 datareads, you could lose up to 
// the last 10 reads if power is lost but it uses less power and is much faster!
#define SYNC_INTERVAL 1000 // mills between calls to flush() - to write data to the card
uint32_t syncTime = 0; // time of last sync()
// the digital pins that connect to the LEDs
#define redLEDpin 2

// The analog pins that connect to the sensors
#define xInput 0                 // analog 0
#define yInput 1                 // analog 1
#define zInput 2                 // anaolg 2 

#define aref_voltage 3.3         // we tie 3.3V to ARef and measure it with a multimeter!
// These are the pins used for the music maker shield
#define SHIELD_RESET  -1      // VS1053 reset pin (unused!)
#define SHIELD_CS     7      // VS1053 chip select pin (output)
#define SHIELD_DCS    6      // VS1053 Data/command select pin (output)

#define CARDCS 4     // Card chip select pin
#define MusicPlayer_CS 4
#define DREQ 3       // VS1053 Data request, ideally an Interrupt pin

// Define music Player
Adafruit_VS1053_FilePlayer musicPlayer = 
 Adafruit_VS1053_FilePlayer(SHIELD_RESET, SHIELD_CS, SHIELD_DCS, DREQ, CARDCS);
// Calibrated Accelerometer Ranges:
// ****************************************************************
// Determine the values for each axis at +/- 1g using AccelCalib
int xNeg = 490;
int xPos = 530;

int yNeg = 490;
int yPos = 531;

int zNeg = 489;
int zPos = 529;
// ****************************************************************
RTC_DS1307 RTC; // define the Real Time Clock object

DateTime now ;
uint32_t m;
int xReading=0;
int yReading=0;
int zReading=0;
long xScaled ;
long yScaled ;
long zScaled ;
int nowSecond, nowMinute, nowHour, nowUnix, nowDay, nowMonth, nowYear; 
float xAcc;
float yAcc ;
float zAcc ;

char filename[] = "LOGGER00.CSV";

// for the data logging shield, we use digital pin 10 for the SD cs line
const int chipSelect = 10; 

// the logging file
File logfile;

// call back for file timestamps
void dateTime(uint16_t* date, uint16_t* time) {
  DateTime now = RTC.now();

  // return date using FAT_DATE macro to format fields
  *date = FAT_DATE(now.year(), now.month(), now.day());

  // return time using FAT_TIME macro to format fields
  *time = FAT_TIME(now.hour(), now.minute(), now.second());
}


void setup(void)
{
  Serial.begin(9600);
  Serial.println();
  
  // initialise the music player
  if (! musicPlayer.begin()) { // initialise the music player
     Serial.println(F("Couldn't find VS1053, do you have the right pins defined?"));
     while (1); //hang here dont do anything else
  }

if (!SD.begin(CARDCS)) {
    Serial.println(F("Music SD or Data Logger card failed, or not present"));
    while (1);  // don't do anything more
  }
 
 // lower number = higher volume
  musicPlayer.setVolume(15,15);
  
  // Note that even if it's not used as the CS pin, the hardware SS pin 
  // 10 on most Arduino boards must be left as an output 
  // or the SD library functions will not work. 
  pinMode(10, OUTPUT);   
  pinMode(4, OUTPUT); 
  
  // connect to RTC
  Wire.begin();  
  if (!RTC.begin()) {
    logfile.println("RTC failed");
  }
  
//  ######################################################
    RTC.adjust(DateTime(__DATE__, __TIME__)); // *** uncomment to set RTC for first time ******
// #####################################################
 
 
   // set date time callback function
  SdFile::dateTimeCallback(dateTime); 
  // 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)) {
      // only open a new file if it doesn't exist
      logfile = SD.open(filename, FILE_WRITE); // only writing to one file in case of restarts while running.
      break;  // leave the loop!
    }
 }

  logfile.println("millis,stamp,datetime,x,y,z"); 
  logfile.flush();  // write first line header
  // If you want to set the aref to something other than 5v
  analogReference(EXTERNAL);
  
  // This option uses a pin interrupt. No timers required! But DREQ
  // must be on an interrupt pin. For Uno use Digital pin 3
  if (! musicPlayer.useInterrupt(VS1053_FILEPLAYER_PIN_INT)) //must stay pin 3 for music player
   Serial.println(F("DREQ pin is not an interrupt pin"));
}

void loop(void) 
{
  if ( musicPlayer.startPlayingFile("OneFile.mp3")) {  //do nothing its working
}  //had to merge all files to one to run longer than one song
  else if ( musicPlayer.startPlayingFile("TwoFile.mp3"))  {//do nothing its working
}
  else{
   Serial.println(F("Could not open music file"));
   while(1); // don’t do anything if music cant play
 }

while (musicPlayer.playingMusic) { 
   // delay for the amount of time we want between readings
  delay((LOG_INTERVAL -1) - (millis() % LOG_INTERVAL));
 musicPlayer.pausePlaying(true); //pause long enough to take data points and possibly write to SD
  // get data from accelerometer - put in log file - wont write until time.
   m = millis();
  logfile.print(m);           // milliseconds since start logfile is defined as: File logfile
   logfile.print(", ");    

  // fetch the time
  // log time
  now = RTC.now();
  logfile.print(now.unixtime()); // seconds since 1/1/1970
  logfile.print(", ");
   logfile.print(now.year(), DEC);
  logfile.print("/");
    logfile.print(now.month(), DEC);
  logfile.print("/");
   logfile.print(now.day(), DEC);
  logfile.print(" ");
  logfile.print(now.hour(), DEC);
  logfile.print(":");
  logfile.print(now.minute(), DEC);
  logfile.print(":");
  logfile.print(now.second(), DEC);
    
  analogRead(xInput);
  xReading = analogRead(xInput); 
  
  analogRead(yInput); 
  yReading = analogRead(yInput);
  
  analogRead(zInput); 
    zReading = analogRead(zInput);
    
    // Convert raw values to 'milli-Gs"
  xScaled = map(xReading, xNeg, xPos, -1000, 1000);
  yScaled = map(yReading, yNeg, yPos, -1000, 1000);
  zScaled = map(zReading, zNeg, zPos, -1000, 1000);
  
    // re-scale to fractional Gs
   xAcc = xScaled / 1000.0;
   yAcc = yScaled / 1000.0;
   zAcc = zScaled / 1000.0;
  
  logfile.print(", ");    
  logfile.print(xAcc);
  logfile.print(", ");    
  logfile.print(yAcc);
  logfile.print(", ");    
  logfile.print(zAcc);
  logfile.println();

  // Now we write data to disk! Don't sync too often - requires 2048 bytes of I/O to SD card
  // which uses a bunch of power and takes time
  if ((millis() - syncTime) < SYNC_INTERVAL) {
  }//continue just storing in the log file; else flush to file
  else {
     syncTime = millis();
     logfile.flush(); // actually write to file now
  }

musicPlayer.pausePlaying(false); // turn music back on right now 
// when noise is heard never get next line ******************* and no more data is logged.
  Serial.println();
  Serial.println((millis())); // so I see it come back from music
  
}// end of while playing music 
  
}// end of loop()
Last edited by adafruit_support_mike on Fri Jul 25, 2014 7:22 pm, edited 1 time in total.
Reason: added CODE tags to preserve formatting

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

Re: ADAFRUIT Data Logger Shield and Music Maker Shield Confl

Post by adafruit_support_rick »

At a guess, I'd say that you can't log to the SD and play music from it at the same time. I'm going to further guess that it's because the VS053 is reading the card at interrupt level, and there's something in the SD library that isn't interrupt-safe.

You could try not running the VS1053 from interrupts.
You could also try logging to the SD card on the logger shield.

tomcolllins
 
Posts: 7
Joined: Fri Jul 25, 2014 2:17 pm

Re: ADAFRUIT Data Logger Shield and Music Maker Shield Confl

Post by tomcolllins »

I changed the sketch to write to the Data Logger and Read music from the Music Maker Shield
I also changed to a Mega for more memory to open the data logger file ( was sometimes unable to open due to insufficient memory available).

I get a definite error in the data at approximately 4 seconds after starting the sketch and every 15 seconds.
millis unixtime x y z
1312 1407408451 -0.05 -0.122 1.1
1315 1407408451 -0.05 "-0.12E%¡!€ p!0@Iw!`p!u!è–L!"

and lose data.

Code shown here

Code: Select all

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


/* ***************************************************

This sketch will run on a Arduino Mega only
It will play files named 1.mp3, 2.mp3 and 3.mp3 in that order
the files themselves need to be randomized and put a readme on
the SD card to identify which is what beat per minute
It will error if the SD card on the logger cannot be written to 
A 5 second tone will be heard notifying user of error.
*/ //***************************************************


// how many milliseconds between grabbing data and logging it. 1000 ms is once a second
#define LOG_INTERVAL  20 // mills between entries (reduce to take more/faster data)
uint32_t syncTime = 0; // time of last sync()

// The analog pins that connect to the sensors
#define xInput 0                 // analog 0
#define yInput 1                 // analog 1
#define zInput 2                 // anaolg 2 
#define aref_voltage 3.3         // we tie 3.3V to ARef and measure it with a multimeter!

// These are the pins used for the music maker shield
#define SHIELD_RESET  -1      // VS1053 reset pin (unused!)
#define SHIELD_CS     7      // VS1053 chip select pin (output)
#define SHIELD_DCS    6      // VS1053 Data/command select pin (output)

#define CARDCS 4     // Card chip select pin
// DREQ should be an Int pin, see http://arduino.cc/en/Reference/attachInterrupt
#define DREQ 3       // VS1053 Data request, ideally an Interrupt pin

// Define music Player
Adafruit_VS1053_FilePlayer musicPlayer = 
 Adafruit_VS1053_FilePlayer(SHIELD_RESET, SHIELD_CS, SHIELD_DCS, DREQ, CARDCS);
  

// Calibrated Accelerometer Ranges:
// ****************************************************************
// Determine the values for each axis at +/- 1g using AccelCalib
const int xNeg = 490;
const int xPos = 530;

const int yNeg = 490;
const int yPos = 531;

const int zNeg = 489;
const int zPos = 529;
// ****************************************************************


RTC_DS1307 RTC; // define the Real Time Clock object

DateTime now ;
uint32_t m; // used to store milliseconds

int xReading, yReading, zReading;
long xScaled, yScaled, zScaled ;
int nowSecond, nowMinute, nowHour, nowUnix, nowDay, nowMonth, nowYear;
int rowCount; // used to store how many data lines are currently stored
float xAcc, yAcc , zAcc ;

char filename[] = "LOGGER00.CSV";
char buffer[9]; // used to convert long to string for accelerations

// for the data logging shield, we use digital pin 10 for the SD cs line
const int chipSelect = 10; 

// the logging file
File logfile;

// store data until writing  -- changed from logfile to change SD cards and not lose handle
String data = String();

// call back for file timestamps dont delete this or the files wont have a date time that is correct on creation
void dateTime(uint16_t* date, uint16_t* time) {
  DateTime now = RTC.now();

  // return date using FAT_DATE macro to format fields
  *date = FAT_DATE(now.year(), now.month(), now.day());

  // return time using FAT_TIME macro to format fields
  *time = FAT_TIME(now.hour(), now.minute(), now.second());
}

void setup(void)
{
  Serial.begin(115200);
  // initialise the music player
  if (! musicPlayer.begin()) { // initialise the music player
     Serial.println(F("Couldn't find VS1053, do you have the right pins defined?"));
     while (1); //hang here dont do anything else
  }

if (!SD.begin(CARDCS)) { // make sure SD card can talk
    Serial.println(F("Music SD or Data Logger card failed, or not present"));
    while (1);  // don't do anything more
  }
 data.reserve(512);
 // lower number = higher volume
  musicPlayer.setVolume(25,25);
  
  // Note that even if it's not used as the CS pin, the hardware SS pin 
  // 10 on most Arduino boards must be left as an output 
  // or the SD library functions will not work. 
  pinMode(10, OUTPUT);   
  pinMode(4, OUTPUT); 

  // connect to RTC
  Wire.begin();  
  if (!RTC.begin()) {
    data += "RTC failed";
#if ECHO_TO_SERIAL
    Serial.println(F("RTC failed"));
#endif  //ECHO_TO_SERIAL
  }
  else{
#if ECHO_TO_SERIAL
    Serial.println(F("RTC Started"));
#endif  //ECHO_TO_SERIAL

  }
  
//  ##########################################################################
   // RTC.adjust(DateTime(__DATE__, __TIME__)); // *** uncomment to set RTC for first time ******
// ##############################################################################
 SD.end();     // turn off SD for music card
 SD.begin(10); //need to switch cards make data logger ready for SD
 
   // set date time callback function
  SdFile::dateTimeCallback(dateTime); // makes the file date time correct on the SD card if RTC is correct
  // 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)) {
      // only open a new file if it doesn't exist
      logfile = SD.open(filename, FILE_WRITE); // only writing to one file in case of restarts while running.
      break;  // leave the loop!
    }
 }

  logfile.println("millis,stamp,x,y,z"); 
  logfile.flush();  // write first line header
  logfile.close();
  SD.end();    // finish with data logger
  SD.begin(4);  //need to switch back to music player so we can start
#if ECHO_TO_SERIAL
  Serial.println(F("millis,stamp,x,y,z"));
#endif //ECHO_TO_SERIAL

  // If you want to set the aref to something other than 5v
  analogReference(EXTERNAL);
  
  // This option uses a pin interrupt. No timers required! But DREQ
  // must be on an interrupt pin. For Uno use Digital pin 3
  if (! musicPlayer.useInterrupt(VS1053_FILEPLAYER_PIN_INT)) //must stay pin 3 for music player
   Serial.println(F("DREQ pin is not an interrupt pin"));
} // end of setup 

void loop(void) 
{
for (int i = 0; i < 3; i++) // loop needed to allow for different files to be loaded one after the other
{
  char* tracks[] = {"1.mp3", "2.mp3", "3.mp3"}; // change to whatever names you want 
  musicPlayer.startPlayingFile(tracks[i]) ; // play files in     
 while (musicPlayer.playingMusic) { // gather data from accelerometer once music player starts  
  delay((LOG_INTERVAL -1) - (millis() % LOG_INTERVAL));  // delay before taking an analog reading

 musicPlayer.pausePlaying(true); //pause long enough to take data points and possibly write to SD
   m = millis(); // milli seconds since this sketch started
  data += m;
  data += ",";

  // fetch the time
  now = RTC.now();
  data += now.unixtime(); // seconds since 1/1/1970
  data  += ",";
  xReading = analogRead(xInput);   
  yReading = analogRead(yInput);
  zReading = analogRead(zInput);
    
    // Convert raw values to 'milli-Gs"
  xScaled = map(xReading, xNeg, xPos, -1000, 1000);
  yScaled = map(yReading, yNeg, yPos, -1000, 1000);
  zScaled = map(zReading, zNeg, zPos, -1000, 1000);
  
    // re-scale to fractional Gs
   xAcc = xScaled / 1000.0;
   yAcc = yScaled / 1000.0;
   zAcc = zScaled / 1000.0;
  
  data  += dtostrf(xAcc, 6, 3, buffer); // convert long data to string 3 decimal places
  data += "," ;
  data  += dtostrf(yAcc, 6, 3, buffer);
  data +=  "," ;
  data  += dtostrf(zAcc, 6, 3, buffer);
  data +=  "\n";
  rowCount++;
  

   if (rowCount >= 1000 ) { // only write every 1000 data points 2000 too big errors before writing
   // 250 too often can hear delay when writing
   
     SD.end(); // turn off music SD and turn on Logger SD
     delay (10);
     SD.begin(10);
     
     File logfile2 = SD.open(filename, FILE_WRITE);
     if (!logfile2) {
       musicPlayer.sineTest(0x44, 50000);
       while (1); // Fail , play sound and hang if cant write to file.
     }
     logfile2.println(data);
     logfile2.flush();
     logfile2.close();
      data = "\0"; // empty the string after writing
      data = ""; // empty the string after writing
      
      SD.end();      
      delay(10);
      SD.begin(4);   // turn off Logger SD and turn on Music SD
    
     syncTime = millis();  // reset the syncTime to now
     rowCount=0;
     }// end of writing go back to collecting data

     musicPlayer.pausePlaying(false); // turn music back on right now
     Serial.println(millis()); // here so I can see millis when music errors happen 
     // when that interference happens I lose reco
}// end of while playing music 
} //end of for loop 
}// end of loop()
Last edited by adafruit_support_bill on Thu Aug 07, 2014 11:23 am, edited 1 time in total.
Reason: please use the </> button when submitting code. press </>, then paste your code between the [code] [/code] tags.

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

Re: ADAFRUIT Data Logger Shield and Music Maker Shield Confl

Post by adafruit_support_rick »

Try it without running the music maker on interrupts

tomcolllins
 
Posts: 7
Joined: Fri Jul 25, 2014 2:17 pm

Re: ADAFRUIT Data Logger Shield and Music Maker Shield Confl

Post by tomcolllins »

commented out code for interrupt ( accelerations from ADXL326 on analog read )

// if (! musicPlayer.useInterrupt(VS1053_FILEPLAYER_PIN_INT)) //must stay pin 3 for music player
// Serial.println(F("DREQ pin is not an interrupt pin"));

No effect.
millis stamp x y z
1369 1407412891 -0.05 -0.122 1.1
1372 1407412891 -0.05 -0ÿõ*¸9Ãd‘!â@û)!`d!u!èHL!
6044 1407412895 -0.05 -0.122 1.1

Here I lost about 4 seconds of data or at least 200 data points

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

Re: ADAFRUIT Data Logger Shield and Music Maker Shield Confl

Post by adafruit_support_rick »

I think you've hit a brick wall. It looks like you can't do what you're trying to do.

One possibility - go with software SPI for the SD card. Connect it to a different set of pins. Make sure you're using the Adafruit SD library, which supports software SPI on any pins.

Go back to interrupts on the Music Maker.

tomcolllins
 
Posts: 7
Joined: Fri Jul 25, 2014 2:17 pm

Re: ADAFRUIT Data Logger Shield and Music Maker Shield Confl

Post by tomcolllins »

Which SD card, the one on the data logger or the one on the music maker?

I see a "low level" use of SPI but cant get it to work

Do I need to physically put jumpers on the music shield (or data logger) to get it to use different pins?

I tried using
Adafruit_VS1053_FilePlayer::Adafruit_VS1053_FilePlayer(
int8_t mosi, int8_t miso, int8_t clk,
int8_t rst, int8_t cs, int8_t dcs, int8_t dreq,
int8_t cardcs)

by defining
#define CLK 2 // SPI Clock, shared with SD card
#define MISO 8 // Input data, from VS1053/SD card
#define MOSI 9 // Output data, to VS1053/SD card
#define SHIELD_RESET 2 // VS1053 reset pin (unused!)
#define SHIELD_CS 7 // VS1053 chip select pin (output)
#define SHIELD_DCS 6 // VS1053 Data/command select pin (output)

#define CARDCS 4 // Card chip select pin
// DREQ should be an Int pin, see http://arduino.cc/en/Reference/attachInterrupt
#define DREQ 3 // VS1053 Data request, ideally an Interrupt pin

// Define music Player
Adafruit_VS1053_FilePlayer musicPlayer =
Adafruit_VS1053_FilePlayer(MOSI, MISO, CLK, SHIELD_RESET, SHIELD_CS, SHIELD_DCS, DREQ, CARDCS);

and when code gets to
if (! musicPlayer.begin()) { // initialise the music player
Serial.println(F("Couldn't find VS1053, do you have the right pins defined?"));
while (1); //hang here dont do anything else

it hangs and no music plays.

Turned on dumpRegs and Version code that was commented out in cpp file begin() and got all zeros Mode=0x0 Stat=0x0 clkF=0x0 Vol. = 0x0 Version = 0



Thanks

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

Re: ADAFRUIT Data Logger Shield and Music Maker Shield Confl

Post by adafruit_support_rick »

OK, so you're on a Mega, right? You will need to close the ICSP solder jumpers on the Music Maker (MISO, MOSI, SCK), and cut the traces on the adjacent #11, #12, and #13 jumpers. You've probably already done the solder jumpers, but you have to cut the traces on the other set of solder jumpers, too.

On the logger shield, pick an unused digital pin for the card Chip Select. Define it at CARDCS. Don't use 10, and don't use 4. Cut the trace between Pin 10 and the Pin 10 jumper pad. Solder a jumper between the CS pad and whatever pin you chose for a card chip select
Now, call SD.begin(CARDCS, 11, 12, 13);

So, the end result is that you'll be running the Music Maker via the ICSP header, and the logger card via software SPI on pins 11, 12, and 13. As such, they should no longer interfere with each other.
Logger_Mod.png
Logger_Mod.png (663.18 KiB) Viewed 797 times

tomcolllins
 
Posts: 7
Joined: Fri Jul 25, 2014 2:17 pm

Re: ADAFRUIT Data Logger Shield and Music Maker Shield Confl

Post by tomcolllins »

Quick question.

Cant see where to cut pin 10 on board. Put in jumper from 5 to CS on data logger so now pin 5 is jumped to 10.

Can you show me a blown up picture where to cut?

Thanks,

Tom

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

Re: ADAFRUIT Data Logger Shield and Music Maker Shield Confl

Post by adafruit_support_rick »

There should be a trace right between the '1' and the '0' in "10"

tomcolllins
 
Posts: 7
Joined: Fri Jul 25, 2014 2:17 pm

Re: ADAFRUIT Data Logger Shield and Music Maker Shield Confl

Post by tomcolllins »

I was able to cut connection to pin 10 (between the pin 10 and its jumper) on data logger and 11, 12 and 13 on music shield (by header)

#define LOGGERCS 8

pinMode( LOGGERCS, OUTPUT);

SD.begin(LOGGERCS, 11,12,13);

The serial output is great. The data in the file is bad.

8003 1407432131 -0.2 -0.22 1.1
8006 1407432131 -0.2 -0.220E*BANNED
Ep!4@M{!p!u!èšL!
12732 1407432135 -0.2 -0.22 1.1

Should I not use Strings? I tried keeping logfile.println (stuff), but nothing at all goes in the File.

Alternatives where Serial.println( x x x ) works but String += x x x fails when writing to the file using logfile.println(the String)?

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

Re: ADAFRUIT Data Logger Shield and Music Maker Shield Confl

Post by adafruit_support_rick »

Shouldn't make a difference whether you use strings or not.
Maybe if you posted your code I could spot something

tomcolllins
 
Posts: 7
Joined: Fri Jul 25, 2014 2:17 pm

Re: ADAFRUIT Data Logger Shield and Music Maker Shield Confl

Post by tomcolllins »

Here is the code. Somewhere there is an issue/difference between Serial.println and logfile.println. Data is good on visual, horrible in the file.

Code: Select all



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

// how many milliseconds between grabbing data and logging it. 1000 ms is once a second
#define LOG_INTERVAL  20 // mills between entries (reduce to take more/faster data)

// how many milliseconds before writing the logged data permanently to disk
// set it to the LOG_INTERVAL to write each time (safest)
// set it to 10*LOG_INTERVAL to write all data every 10 datareads, you could lose up to 
// the last 10 reads if power is lost but it uses less power and is much faster!
#define SYNC_INTERVAL 250 // mills between calls to flush() - to write data to the card
uint32_t syncTime = 0; // time of last sync()

#define ECHO_TO_SERIAL 0 // echo data to serial port

// the digital pins that connect to the LEDs
//#define redLEDpin 2


// The analog pins that connect to the sensors
#define xInput 0                 // analog 0
#define yInput 1                 // analog 1
#define zInput 2                 // anaolg 2 

#define aref_voltage 3.3         // we tie 3.3V to ARef and measure it with a multimeter!


// These are the pins used for the music maker shield
//#define CLK 2       // SPI Clock, shared with SD card
//#define MISO 8      // Input data, from VS1053/SD card
//#define MOSI 9      // Output data, to VS1053/SD card
#define SHIELD_RESET  -1      // VS1053 reset pin (unused!)
#define SHIELD_CS     7      // VS1053 chip select pin (output)
#define SHIELD_DCS    6      // VS1053 Data/command select pin (output)

#define CARDCS 4     // Card chip select pin
#define LOGGERCS 8
// DREQ should be an Int pin, see http://arduino.cc/en/Reference/attachInterrupt
#define DREQ 3       // VS1053 Data request, ideally an Interrupt pin

// Define music Player
Adafruit_VS1053_FilePlayer musicPlayer = 
 Adafruit_VS1053_FilePlayer(SHIELD_RESET, SHIELD_CS, SHIELD_DCS, DREQ, CARDCS);
  

// Calibrated Accelerometer Ranges:

// ****************************************************************
// Determine the values for each axis at +/- 1g using AccelCalib
const int xNeg = 490;
const int xPos = 530;

const int yNeg = 490;
const int yPos = 531;

const int zNeg = 489;
const int zPos = 529;
// ****************************************************************


RTC_DS1307 RTC; // define the Real Time Clock object

DateTime now ;
uint32_t m; // used to store milliseconds

int xReading, yReading, zReading;
long xScaled, yScaled, zScaled ;
int nowSecond, nowMinute, nowHour, nowUnix, nowDay, nowMonth, nowYear;
int rowCount; // used to store how many data lines are currently stored
float xAcc, yAcc , zAcc ;

char filename[] = "LOGGER00.CSV";
char buffer[9]; // used to convert long to string for accelerations

// for the data logging shield, we use digital pin 10 for the SD cs line
const int chipSelect = 10; 

// the logging file
File logfile;

// *************************** 
String data = String();


// call back for file timestamps dont delete this or the files wont have a date time that is correct on creation
void dateTime(uint16_t* date, uint16_t* time) {
  DateTime now = RTC.now();

  // return date using FAT_DATE macro to format fields
  *date = FAT_DATE(now.year(), now.month(), now.day());

  // return time using FAT_TIME macro to format fields
  *time = FAT_TIME(now.hour(), now.minute(), now.second());
}


void setup(void)
{
  Serial.begin(115200);

  // initialise the music player
  if (! musicPlayer.begin()) { // initialise the music player
     Serial.println(F("Couldn't find VS1053, do you have the right pins defined?"));
     while (1); //hang here dont do anything else
  }

if (!SD.begin(CARDCS)) { // make sure SD card can talk
    Serial.println(F("Music SD or Data Logger card failed, or not present"));
    while (1);  // don't do anything more
  }
 
 // lower number = higher volume
  musicPlayer.setVolume(25,25);
  
  // Note that even if it's not used as the CS pin, the hardware SS pin 
  // 10 on most Arduino boards must be left as an output 
  // or the SD library functions will not work. 
  pinMode(10, OUTPUT);   
  pinMode(4, OUTPUT); 
  pinMode( LOGGERCS, OUTPUT);

  // connect to RTC
  Wire.begin();  
  if (!RTC.begin()) {
    data += "RTC failed";
#if ECHO_TO_SERIAL
    Serial.println(F("RTC failed"));
#endif  //ECHO_TO_SERIAL
  }
  else{
#if ECHO_TO_SERIAL
    Serial.println(F("RTC Started"));
#endif  //ECHO_TO_SERIAL

  }
  
//  ##########################################################################
   // RTC.adjust(DateTime(__DATE__, __TIME__)); // *** uncomment to set RTC for first time ******
// ##############################################################################
 SD.end();     // turn off SD for music card
 SD.begin(LOGGERCS, 11,12,13); //need to switch cards make data logger ready for SD
 
   // set date time callback function
  SdFile::dateTimeCallback(dateTime); // makes the file date time correct on the SD card if RTC is correct
  // 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)) {
      // only open a new file if it doesn't exist
      logfile = SD.open(filename, FILE_WRITE); // only writing to one file in case of restarts while running.
      break;  // leave the loop!
    }
 }

  logfile.println("millis,stamp,x,y,z"); 
  logfile.flush();  // write first line header
  logfile.close();
  SD.end();    // finish with data logger
  SD.begin(4);  //need to switch back to music player so we can start
#if ECHO_TO_SERIAL
  Serial.println(F("millis,stamp,x,y,z"));
#endif //ECHO_TO_SERIAL

  // If you want to set the aref to something other than 5v
  analogReference(EXTERNAL);
  
  // This option uses a pin interrupt. No timers required! But DREQ
  // must be on an interrupt pin. For Uno use Digital pin 3
  if (! musicPlayer.useInterrupt(VS1053_FILEPLAYER_PIN_INT)) //must stay pin 3 for music player
   Serial.println(F("DREQ pin is not an interrupt pin"));

}

void loop(void) 
{
 
for (int i = 0; i < 3; i++) // loop needed to allow for different files to be loaded one after the other
{
  char* tracks[] = {"1.mp3", "2.mp3", "3.mp3"}; // change to whatever names you want 

  musicPlayer.startPlayingFile(tracks[i]) ; // play files in 
    
while (musicPlayer.playingMusic) { // gather data from accelerometer once music player starts
  
 // delay((LOG_INTERVAL -1) - (millis() % LOG_INTERVAL)); 

 musicPlayer.pausePlaying(true); //pause long enough to take data points and possibly write to SD
  
   m = millis(); // milli seconds since this sketch started
  data += m;
  data += ",";

  // fetch the time
  now = RTC.now();

  data += now.unixtime(); // seconds since 1/1/1970
  data  += ",";
  
  xReading = analogRead(xInput);   
  yReading = analogRead(yInput);
  zReading = analogRead(zInput);
    
    // Convert raw values to 'milli-Gs"
  xScaled = map(xReading, xNeg, xPos, -1000, 1000);
  yScaled = map(yReading, yNeg, yPos, -1000, 1000);
  zScaled = map(zReading, zNeg, zPos, -1000, 1000);
  
    // re-scale to fractional Gs
   xAcc = xScaled / 1000.0;
   yAcc = yScaled / 1000.0;
   zAcc = zScaled / 1000.0;
  
  data  += dtostrf(xAcc, 6, 3, buffer); // convert long data to string 3 decimal places
  data += "," ;

  data  += dtostrf(yAcc, 6, 3, buffer);
  data +=  "," ;

  data  += dtostrf(zAcc, 6, 3, buffer);
  data +=  "\n";
  rowCount++;
  

   if (rowCount >= 1000 ) { // only write every 1000 data points 2000 too big errors before writing
   // 250 too often can hear delay when writing
   
     SD.end(); // turn off music SD and turn on Logger SD
     SD.begin(LOGGERCS, 11,12,13);
     
     File logfile2 = SD.open(filename, FILE_WRITE);
     if (!logfile2) {
       musicPlayer.sineTest(0x44, 50000);
       while (1); // Fail , play sound and hang if cant write to file.
     }
     logfile2.println(data);
     logfile2.flush();
     logfile2.close();
      data = "\0"; // empty the string after writing
      data = ""; // empty the string after writing
     
      
      SD.end();      
      
      SD.begin(4);   // turn off Logger SD and turn on Music SD
    
     syncTime = millis();  // reset the syncTime to now
     rowCount=0;
     }// end of writing go back to collecting data

     musicPlayer.pausePlaying(false); // turn music back on right now
        }// end of while playing music 
} //end of for loop 
}// end of loop()




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

Re: ADAFRUIT Data Logger Shield and Music Maker Shield Confl

Post by adafruit_support_rick »

Instead of doing SD.end, SD.begin all the time, try creating an extra SD object for the log. Keep them both open all the time:

Code: Select all

// Define music Player
Adafruit_VS1053_FilePlayer musicPlayer = 
 Adafruit_VS1053_FilePlayer(SHIELD_RESET, SHIELD_CS, SHIELD_DCS, DREQ, CARDCS);

//Define an SD object for the data logger
SDClass SDLogger;l
Then, in setup():

Code: Select all

if (!SD.begin(CARDCS)) { // make sure Music SD card can talk
    Serial.println(F("Music SD card failed, or not present"));
    while (1);  // don't do anything more
  }
 
if (!SDLogger.begin(LOGGERCS, 11, 12, 13)) { // make sure Logger SD card can talk
    Serial.println(F("Data Logger card failed, or not present"));
    while (1);  // don't do anything more
  }
Then eliminate the code that switches between cards.

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

Return to “General Project help”