/* This reads a wave file from an SD card and plays it using the I2S interface to a MAX08357 I2S Amp Breakout board. Circuit: * Arduino/Genuino Zero, MKRZero or MKR1000 board * SD breakout or shield connected * MAX08357: * GND connected GND * VIN connected 5V * LRC connected to pin 0 (Zero) or pin 3 (MKR1000, MKRZero) * BCLK connected to pin 1 (Zero) or pin 2 (MKR1000, MKRZero) * DIN connected to pin 9 (Zero) or pin A6 (MKR1000, MKRZero) created 15 November 2016 by Sandeep Mistry */ #include #include // filename of wave file to play const char filename[] = "castemere_mono.wav"; // SD_FAT_TYPE = 0 for SdFat/File as defined in SdFatConfig.h, // 1 for FAT16/FAT32, 2 for exFAT, 3 for FAT16/FAT32 and exFAT. #define SD_FAT_TYPE 2 // // Set DISABLE_CHIP_SELECT to disable a second SPI device. // For example, with the Ethernet shield, set DISABLE_CHIP_SELECT // to 10 to disable the Ethernet controller. const int8_t DISABLE_CHIP_SELECT = -1; // // Test with reduced SPI speed for breadboards. SD_SCK_MHZ(4) will select // the highest speed supported by the board that is not over 4 MHz. // Change SPI_SPEED to SD_SCK_MHZ(50) for best performance. #define SPI_SPEED SD_SCK_MHZ(24) //------------------------------------------------------------------------------ SdFat sd; // SD card chip select int chipSelect = 28; // variable representing the Wave File SDWaveFile waveFile(sd, filename); void setup() { // Open serial communications and wait for port to open: Serial.begin(9600); while (!Serial) { ; // wait for serial port to connect. Needed for native USB port only } if (!sd.begin(chipSelect, SPI_SPEED)) { if (sd.card()->errorCode()) { Serial.println("SD initialization failed."); // cout << F( // "\nSD initialization failed.\n" // "Do not reformat the card!\n" // "Is the card correctly inserted?\n" // "Is chipSelect set to the correct value?\n" // "Does another SPI device need to be disabled?\n" // "Is there a wiring/soldering problem?\n"); // cout << F("\nerrorCode: ") << hex << showbase; // cout << int(sd.card()->errorCode()); // cout << F(", errorData: ") << int(sd.card()->errorData()); // cout << dec << noshowbase << endl; return; } Serial.println("Card successfully initialized."); if (sd.vol()->fatType() == 0) { Serial.println("Can't find a valid FAT16/FAT32 partition."); return; } Serial.println("Can't determine error type."); return; } // check if the WaveFile is valid if (!waveFile) { Serial.println("wave file is invalid!"); while (1); // do nothing } // print out some info. about the wave file Serial.print("Bits per sample = "); Serial.println(waveFile.bitsPerSample()); long channels = waveFile.channels(); Serial.print("Channels = "); Serial.println(channels); long sampleRate = waveFile.sampleRate(); Serial.print("Sample rate = "); Serial.print(sampleRate); Serial.println(" Hz"); long duration = waveFile.duration(); Serial.print("Duration = "); Serial.print(duration); Serial.println(" seconds"); // adjust the playback volume AudioOutI2S.volume(5); // check if the I2S output can play the wave file if (!AudioOutI2S.canPlay(waveFile)) { Serial.println("unable to play wave file using I2S!"); while (1); // do nothing } // start playback Serial.println("starting playback"); AudioOutI2S.play(waveFile); } void loop() { // check if playback is still going on if (!AudioOutI2S.isPlaying()) { // playback has stopped Serial.println("playback stopped"); while (1); // do nothing } } /** * // ============================================ SD EXAMPLE // Quick hardware test for SPI card access. // #include #include "SdFat.h" #include "sdios.h" // SD_FAT_TYPE = 0 for SdFat/File as defined in SdFatConfig.h, // 1 for FAT16/FAT32, 2 for exFAT, 3 for FAT16/FAT32 and exFAT. #define SD_FAT_TYPE 2 // // Set DISABLE_CHIP_SELECT to disable a second SPI device. // For example, with the Ethernet shield, set DISABLE_CHIP_SELECT // to 10 to disable the Ethernet controller. const int8_t DISABLE_CHIP_SELECT = -1; // // Test with reduced SPI speed for breadboards. SD_SCK_MHZ(4) will select // the highest speed supported by the board that is not over 4 MHz. // Change SPI_SPEED to SD_SCK_MHZ(50) for best performance. #define SPI_SPEED SD_SCK_MHZ(24) //------------------------------------------------------------------------------ #if SD_FAT_TYPE == 0 SdFat sd; File file; #elif SD_FAT_TYPE == 1 SdFat32 sd; File32 file; #elif SD_FAT_TYPE == 2 SdExFat sd; ExFile file; #elif SD_FAT_TYPE == 3 SdFs sd; FsFile file; #else // SD_FAT_TYPE #error Invalid SD_FAT_TYPE #endif // SD_FAT_TYPE // Serial streams ArduinoOutStream cout(Serial); // input buffer for line char cinBuf[40]; ArduinoInStream cin(Serial, cinBuf, sizeof(cinBuf)); // SD card chip select int chipSelect = 28; void cardOrSpeed() { cout << F("Try another SD card or reduce the SPI bus speed.\n"); cout << F("Edit SPI_SPEED in this program to change it.\n"); } void reformatMsg() { cout << F("Try reformatting the card. For best results use\n"); cout << F("the SdFormatter program in SdFat/examples or download\n"); cout << F("and use SDFormatter from www.sdcard.org/downloads.\n"); } void setup() { Serial.begin(115200); // Wait for USB Serial while (!Serial) { SysCall::yield(); } cout << F("\nSPI pins:\n"); cout << F("MISO: ") << int(MISO) << endl; cout << F("MOSI: ") << int(MOSI) << endl; cout << F("SCK: ") << int(SCK) << endl; cout << F("SS: ") << int(SS) << endl; #ifdef SDCARD_SS_PIN cout << F("SDCARD_SS_PIN: ") << int(SDCARD_SS_PIN) << endl; #endif // SDCARD_SS_PIN if (DISABLE_CHIP_SELECT < 0) { cout << F( "\nBe sure to edit DISABLE_CHIP_SELECT if you have\n" "a second SPI device. For example, with the Ethernet\n" "shield, DISABLE_CHIP_SELECT should be set to 10\n" "to disable the Ethernet controller.\n"); } cout << F( "\nSD chip select is the key hardware option.\n" "Common values are:\n" "Arduino Ethernet shield, pin 4\n" "Sparkfun SD shield, pin 8\n" "Adafruit SD shields and modules, pin 10\n"); } bool firstTry = true; void loop() { // Read any existing Serial data. do { delay(10); } while (Serial.available() && Serial.read() >= 0); if (!firstTry) { cout << F("\nRestarting\n"); } firstTry = false; // cout << F("\nEnter the chip select pin number: "); // while (!Serial.available()) { // SysCall::yield(); // } // cin.readline(); // if (cin >> chipSelect) { // cout << chipSelect << endl; // } else { // cout << F("\nInvalid pin number\n"); // return; // } if (DISABLE_CHIP_SELECT < 0) { cout << F( "\nAssuming the SD is the only SPI device.\n" "Edit DISABLE_CHIP_SELECT to disable another device.\n"); } else { cout << F("\nDisabling SPI device on pin "); cout << int(DISABLE_CHIP_SELECT) << endl; pinMode(DISABLE_CHIP_SELECT, OUTPUT); digitalWrite(DISABLE_CHIP_SELECT, HIGH); } if (!sd.begin(chipSelect, SPI_SPEED)) { if (sd.card()->errorCode()) { cout << F( "\nSD initialization failed.\n" "Do not reformat the card!\n" "Is the card correctly inserted?\n" "Is chipSelect set to the correct value?\n" "Does another SPI device need to be disabled?\n" "Is there a wiring/soldering problem?\n"); cout << F("\nerrorCode: ") << hex << showbase; cout << int(sd.card()->errorCode()); cout << F(", errorData: ") << int(sd.card()->errorData()); cout << dec << noshowbase << endl; return; } cout << F("\nCard successfully initialized.\n"); if (sd.vol()->fatType() == 0) { cout << F("Can't find a valid FAT16/FAT32 partition.\n"); reformatMsg(); return; } cout << F("Can't determine error type\n"); return; } cout << F("\nCard successfully initialized.\n"); cout << endl; uint32_t size = sd.card()->sectorCount(); if (size == 0) { cout << F("Can't determine the card size.\n"); cardOrSpeed(); return; } uint32_t sizeMB = 0.000512 * size + 0.5; cout << F("Card size: ") << sizeMB; cout << F(" MB (MB = 1,000,000 bytes)\n"); cout << endl; cout << F("Volume is FAT") << int(sd.vol()->fatType()); cout << F(", Cluster size (bytes): ") << sd.vol()->bytesPerCluster(); cout << endl << endl; cout << F("Files found (date time size name):\n"); sd.ls(LS_R | LS_DATE | LS_SIZE); if ((sizeMB > 1100 && sd.vol()->sectorsPerCluster() < 64) || (sizeMB < 2200 && sd.vol()->fatType() == 32)) { cout << F("\nThis card should be reformatted for best performance.\n"); cout << F("Use a cluster size of 32 KB for cards larger than 1 GB.\n"); cout << F("Only cards larger than 2 GB should be formatted FAT32.\n"); reformatMsg(); return; } // Read any extra Serial data. do { delay(10); } while (Serial.available() && Serial.read() >= 0); cout << F("\nSuccess! Type any character to restart.\n"); while (!Serial.available()) { SysCall::yield(); } } */ /* * EXEMPLE 1 #include "Arduino.h" // the setup function runs once when you press reset or power the board void setup() { // initialize digital pin LED_BUILTIN as an output. pinMode(0, OUTPUT); SerialUSB.begin(9600); } // the loop function runs over and over again forever void loop() { digitalWrite(0, HIGH); // turn the LED on (HIGH is the voltage level) delay(1000); // wait for a second digitalWrite(0, LOW); // turn the LED off by making the voltage LOW delay(1000); // wait for a second SerialUSB.println("Hello, Arduino!"); } */