Play .wav File From SD Card But No Sound

Hello there.
I have trying to resolve a playback issue when trying to play a .wav file from an SD card. I have some lightsaber voices. I made the connections of the SD card as in the attached diagram but I only hear meaningless rhythmic sounds.

How can i solve this? Thank you so much and may the Force be with you!

Here my code:

// ---------------------------- AYARLAR -------------------------------
#define NUM_LEDS 30         // LED şerit üzerindeki WS2811 mikro devre sayısı (not: bir WS2811 3 LED'i kontrol eder!)
#define BTN_TIMEOUT 800     // düğmeyi basılı tutma süresi (ms cinsinden)
#define BRIGHTNESS 255      // LED parlaklığı (0 - 255)

#define SWING_TIMEOUT 500   // salınımlar arasındaki zaman aralığı
#define SWING_L_THR 150     // dönüş açısı hız eşiği
#define SWING_THR 300       // hızlı dönüş açısı hız eşiği
#define STRIKE_THR 150      // hızlanma eşiğine ulaşma
#define STRIKE_S_THR 320    // sert vuruş hızlanma eşiği
#define FLASH_DELAY 80      // vurulduğunda çıkan parlama süresi

#define PULSE_ALLOW 1       // kılıç titreşimi (1 - açık, 0 - kapalı)
#define PULSE_AMPL 20       // darbe çokluğu
#define PULSE_DELAY 30      // darbeler arasındaki gecikme

#define R1 100000           // gerilim bölücü gerçek direnç
#define R2 51000            // gerilim bölücü gerçek direnç
#define BATTERY_SAFE 1      // açlışta pil seviyesi gösterme (1 - açık, 0 - kapalı)

#define DEBUG 1             // port ekranın hata bilgileri görme (1 - açık, 0 - kapalı)
// ---------------------------- AYARLAR -------------------------------

#define LED_PIN 6
#define BTN 3
#define IMU_GND A1  //Bu çıkış GND'ye bağlı fakat düzgün çalışmayacağından boş pinleri çıkış gösterdim.
#define SD_GND A0   //Bu çıkış GND'ye bağlı fakat düzgün çalışmayacağından boş pinleri çıkış gösterdim.
#define VOLT_PIN A6
#define BTN_LED 4

// -------------------------- KULLANILAN KÜTÜPHANELER ---------------------------
#include <avr/pgmspace.h>   // PROGMEM kütüphanesi
#include <SD.h>
#include <TMRpcm.h>         // SD kütüphanesinde ses
#include "Wire.h"
#include "I2Cdev.h"
#include "MPU6050.h"
#include <toneAC.h>         // Hum sesi oluşturma kütüphanesi
#include "FastLED.h"        // adreslenebilir LED kütüphanesi
#include <EEPROM.h>
//Araçlar>Kütüphaleri Yönet  menüsünden yukarıdaki kütüphaneleri yüklemeniz gerek. Aksi takfirde kodu arduinoya atamazsınız.
CRGB leds[NUM_LEDS];
#define SD_ChipSelectPin 8
TMRpcm tmrpcm;
MPU6050 accelgyro;
// -------------------------- KULLANILAN KÜTÜPHANELER ---------------------------


// ------------------------------ DEĞİŞKENLER ---------------------------------
int16_t ax, ay, az;
int16_t gx, gy, gz;
unsigned long ACC, GYR, COMPL;
int gyroX, gyroY, gyroZ, accelX, accelY, accelZ, freq, freq_f = 20;
float k = 0.2;
unsigned long humTimer = -9000, mpuTimer, nowTimer;
int stopTimer;
boolean bzzz_flag, ls_chg_state, ls_state;
boolean btnState, btn_flag, hold_flag;
byte btn_counter;
unsigned long btn_timer, PULSE_timer, swing_timer, swing_timeout, battery_timer, bzzTimer;
byte nowNumber;
byte LEDcolor;  // 0 - kırmızı, 1 - yeşil, 2 - mavi, 3 - mor, 4 - sarı, 5 - buz mavisi
byte nowColor, red, green, blue, redOffset, greenOffset, blueOffset;
boolean eeprom_flag, swing_flag, swing_allow, strike_flag, HUMmode;
float voltage;
int PULSEOffset;
// ------------------------------ DEĞİŞKENLER ---------------------------------

// --------------------------------- SESLER ----------------------------------
const char strike1[] PROGMEM = "SK1.wav";
const char strike2[] PROGMEM = "SK2.wav";
const char strike3[] PROGMEM = "SK3.wav";
const char strike4[] PROGMEM = "SK4.wav";
const char strike5[] PROGMEM = "SK5.wav";
const char strike6[] PROGMEM = "SK6.wav";
const char strike7[] PROGMEM = "SK7.wav";
const char strike8[] PROGMEM = "SK8.wav";

const char* const strikes[] PROGMEM  = {
  strike1, strike2, strike3, strike4, strike5, strike6, strike7, strike8
};

int strike_time[8] = {779, 563, 687, 702, 673, 661, 666, 635};

const char strike_s1[] PROGMEM = "SKS1.wav";
const char strike_s2[] PROGMEM = "SKS2.wav";
const char strike_s3[] PROGMEM = "SKS3.wav";
const char strike_s4[] PROGMEM = "SKS4.wav";
const char strike_s5[] PROGMEM = "SKS5.wav";
const char strike_s6[] PROGMEM = "SKS6.wav";
const char strike_s7[] PROGMEM = "SKS7.wav";
const char strike_s8[] PROGMEM = "SKS8.wav";

const char* const strikes_short[] PROGMEM = {
  strike_s1, strike_s2, strike_s3, strike_s4,
  strike_s5, strike_s6, strike_s7, strike_s8
};
int strike_s_time[8] = {270, 167, 186, 250, 252, 255, 250, 238};

const char swing1[] PROGMEM = "SWS1.wav";
const char swing2[] PROGMEM = "SWS2.wav";
const char swing3[] PROGMEM = "SWS3.wav";
const char swing4[] PROGMEM = "SWS4.wav";
const char swing5[] PROGMEM = "SWS5.wav";

const char* const swings[] PROGMEM  = {
  swing1, swing2, swing3, swing4, swing5
};
int swing_time[8] = {389, 372, 360, 366, 337};

const char swingL1[] PROGMEM = "SWL1.wav";
const char swingL2[] PROGMEM = "SWL2.wav";
const char swingL3[] PROGMEM = "SWL3.wav";
const char swingL4[] PROGMEM = "SWL4.wav";

const char* const swings_L[] PROGMEM  = {
  swingL1, swingL2, swingL3, swingL4
};
int swing_time_L[8] = {636, 441, 772, 702};

char BUFFER[10];
// --------------------------------- SESLER ---------------------------------

void setup() {
  FastLED.addLeds<WS2811, LED_PIN, GRB>(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
  FastLED.setBrightness(100);  // ~LED şerit parlaklığının %40'ı
  setAll(0, 0, 0);             // ve kapatma

  Wire.begin();
  Serial.begin(9600);

  // ---- PİN AYARI ----
  pinMode(BTN, INPUT_PULLUP);
  pinMode(IMU_GND, OUTPUT);
  pinMode(SD_GND, OUTPUT);
  pinMode(BTN_LED, OUTPUT);
  digitalWrite(IMU_GND, 0);
  digitalWrite(SD_GND, 0);
  digitalWrite(BTN_LED, 1);
  // ---- PİN AYARI ----

  randomSeed(analogRead(2));    // rastgele oluşturucu için başlangıç noktası

  // IMU initialization
  accelgyro.initialize();
  accelgyro.setFullScaleAccelRange(MPU6050_ACCEL_FS_16);
  accelgyro.setFullScaleGyroRange(MPU6050_GYRO_FS_250);
  if (DEBUG) {
    if (accelgyro.testConnection()) Serial.println(F("MPU6050 Düzgün Çalışıyor"));
    else Serial.println(F("MPU6050 ÇALIŞMIYOR"));
  }

  // SD initialization
  tmrpcm.speakerPin = 9;
  tmrpcm.setVolume(5);
  tmrpcm.quality(1);
  if (DEBUG) {
    if (SD.begin(8)) Serial.println(F("SD Kart Düzgün Çalışıyor"));
    else Serial.println(F("SD Kart ÇALIŞMIYOR"));
  } else {
    SD.begin(8);
  }

  if ((EEPROM.read(0) >= 0) && (EEPROM.read(0) <= 5)) {  // ilk başlangıçta kontrol
    nowColor = EEPROM.read(0);   // rengi hatırlama
    HUMmode = EEPROM.read(1);    // modu hatırlama
  } else {                       // ilk başlangıç
    EEPROM.write(0, 0);          // varsayılana ayarla
    EEPROM.write(1, 0);          // varsayılana ayarla
    nowColor = 0;                // varsayılana ayarla
  }

  setColor(nowColor);
  byte capacity = voltage_measure();       // pil seviyesini al
  capacity = map(capacity, 100, 0, (NUM_LEDS / 2 - 1), 1);  // kılıç uzunluğuna dönüştür
  if (DEBUG) {
    Serial.print(F("Pil Seviyesi % "));
    Serial.println(capacity);
  }

  for (char i = 0; i <= capacity; i++) {   // pil seviyesini göster
    setPixel(i, red, green, blue);
    setPixel((NUM_LEDS - 1 - i), red, green, blue);
    FastLED.show();
    delay(25);
  }
  delay(1000);                         // pil seviyesini gösterme süresi (ms cinsinden)
  setAll(0, 0, 0);
  FastLED.setBrightness(BRIGHTNESS);   // parlak ayarla
}

// --- ANA DÖNGÜ---
void loop() {
  randomPULSE();
  getFreq();
  on_off_sound();
  btnTick();
  strikeTick();
  swingTick();
  batteryTick();
}
// --- ANA DÖNGÜ---

void btnTick() {
  btnState = !digitalRead(BTN);
  if (btnState && !btn_flag) {
    if (DEBUG) Serial.println(F("Buton Basma"));
    btn_flag = 1;
    btn_counter++;
    btn_timer = millis();
  }
  if (!btnState && btn_flag) {
    btn_flag = 0;
    hold_flag = 0;
  }
  // DÜĞME BASILI TUTULDUĞUNDA
  if (btn_flag && btnState && (millis() - btn_timer > BTN_TIMEOUT) && !hold_flag) {
    ls_chg_state = 1;                     // kılıç durumunu değiştirmek için (açık / kapalı)
    hold_flag = 1;
    btn_counter = 0;
  }
  // ZAMAN AŞIMINDAN ÖNCE DÜĞMEYE BİRKAÇ KEZ BASILMIŞSA
  if ((millis() - btn_timer > BTN_TIMEOUT) && (btn_counter != 0)) {
    if (ls_state) {
      if (btn_counter == 3) {               // 3 kez basılmışsa (renk değiştirmek için basma sayısı)
        nowColor++;                         // rengi değiştir
        if (nowColor >= 6) nowColor = 0;
        setColor(nowColor);
        setAll(red, green, blue);
        eeprom_flag = 1;
      }
      if (btn_counter == 5) {               // 5 kez basılmışsa mode değiştir (Jedi-Sith mod aralarında geçiş için)
        HUMmode = !HUMmode;
        if (HUMmode) {
          noToneAC();
          tmrpcm.play("HUM.wav");
        } else {
          tmrpcm.disable();
          toneAC(freq_f);
        }
        eeprom_flag = 1;
      }
    }
    btn_counter = 0;
  }
}

void on_off_sound() {
  if (ls_chg_state) {                
    if (!ls_state) {                 
      if (voltage_measure() > 10 || !BATTERY_SAFE) {
        if (DEBUG) Serial.println(F("KILIÇ AÇIK"));
        tmrpcm.play("ON.wav");
        delay(200);
        light_up();
        delay(200);
        bzzz_flag = 1;
        ls_state = true;               
        if (HUMmode) {
          noToneAC();
          tmrpcm.play("HUM.wav");
        } else {
          tmrpcm.disable();
          toneAC(freq_f);
        }
      } else {
        if (DEBUG) Serial.println(F("DÜŞÜK VOLTAJ!"));
        for (int i = 0; i < 5; i++) {
          digitalWrite(BTN_LED, 0);
          delay(400);
          digitalWrite(BTN_LED, 1);
          delay(400);
        }
      }
    } else {                         
      noToneAC();
      bzzz_flag = 0;
      tmrpcm.play("OFF.wav");
      delay(300);
      light_down();
      delay(300);
      tmrpcm.disable();
      if (DEBUG) Serial.println(F("KILIÇ KAPALI"));
      ls_state = false;
      if (eeprom_flag) {
        eeprom_flag = 0;
        EEPROM.write(0, nowColor);   // EEPROM'a renk yaz
        EEPROM.write(1, HUMmode);    // EEPROM'a mod yaz
      }
    }
    ls_chg_state = 0;
  }

  if (((millis() - humTimer) > 9000) && bzzz_flag && HUMmode) {
    tmrpcm.play("HUM.wav");
    humTimer = millis();
    swing_flag = 1;
    strike_flag = 0;
  }
  long delta = millis() - bzzTimer;
  if ((delta > 3) && bzzz_flag && !HUMmode) {
    if (strike_flag) {
      tmrpcm.disable();
      strike_flag = 0;
    }
    toneAC(freq_f,1);
    bzzTimer = millis();
  }
}

void randomPULSE() {
  if (PULSE_ALLOW && ls_state && (millis() - PULSE_timer > PULSE_DELAY)) {
    PULSE_timer = millis();
    PULSEOffset = PULSEOffset * k + random(-PULSE_AMPL, PULSE_AMPL) * (1 - k);
    if (nowColor == 0) PULSEOffset = constrain(PULSEOffset, -15, 5);
    redOffset = constrain(red + PULSEOffset, 0, 255);
    greenOffset = constrain(green + PULSEOffset, 0, 255);
    blueOffset = constrain(blue + PULSEOffset, 0, 255);
    setAll(redOffset, greenOffset, blueOffset);
  }
}

void strikeTick() {
  if ((ACC > STRIKE_THR) && (ACC < STRIKE_S_THR)) {
    if (!HUMmode) noToneAC();
    nowNumber = random(8);
    // PROGMEM'den parça adını oku
    strcpy_P(BUFFER, (char*)pgm_read_word(&(strikes_short[nowNumber])));
    tmrpcm.play(BUFFER);
    hit_flash();
    if (!HUMmode)
      bzzTimer = millis() + strike_s_time[nowNumber] - FLASH_DELAY;
    else
      humTimer = millis() - 9000 + strike_s_time[nowNumber] - FLASH_DELAY;
    strike_flag = 1;
  }
  if (ACC >= STRIKE_S_THR) {
    if (!HUMmode) noToneAC();
    nowNumber = random(8);
    // PROGMEM'den parça adını oku
    strcpy_P(BUFFER, (char*)pgm_read_word(&(strikes[nowNumber])));
    tmrpcm.play(BUFFER);
    hit_flash();
    if (!HUMmode)
      bzzTimer = millis() + strike_time[nowNumber] - FLASH_DELAY;
    else
      humTimer = millis() - 9000 + strike_time[nowNumber] - FLASH_DELAY;
    strike_flag = 1;
  }
}

void swingTick() {
  if (GYR > 80 && (millis() - swing_timeout > 100) && HUMmode) {
    swing_timeout = millis();
    if (((millis() - swing_timer) > SWING_TIMEOUT) && swing_flag && !strike_flag) {
      if (GYR >= SWING_THR) {      
        nowNumber = random(5);          
        // PROGMEM'den parça adını oku
        strcpy_P(BUFFER, (char*)pgm_read_word(&(swings[nowNumber])));
        tmrpcm.play(BUFFER);               
        humTimer = millis() - 9000 + swing_time[nowNumber];
        swing_flag = 0;
        swing_timer = millis();
        swing_allow = 0;
      }
      if ((GYR > SWING_L_THR) && (GYR < SWING_THR)) {
        nowNumber = random(5);            
        // PROGMEM'den parça adını oku
        strcpy_P(BUFFER, (char*)pgm_read_word(&(swings_L[nowNumber])));
        tmrpcm.play(BUFFER);              
        humTimer = millis() - 9000 + swing_time_L[nowNumber];
        swing_flag = 0;
        swing_timer = millis();
        swing_allow = 0;
      }
    }
  }
}

void getFreq() {
  if (ls_state) {                                               
    if (millis() - mpuTimer > 500) {                            
      accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);       

      // mutlak değeri bul ve 100'e böl
      gyroX = abs(gx / 100);
      gyroY = abs(gy / 100);
      gyroZ = abs(gz / 100);
      accelX = abs(ax / 100);
      accelY = abs(ay / 100);
      accelZ = abs(az / 100);

      // vektör toplamı
      ACC = sq((long)accelX) + sq((long)accelY) + sq((long)accelZ);
      ACC = sqrt(ACC);
      GYR = sq((long)gyroX) + sq((long)gyroY) + sq((long)gyroZ);
      GYR = sqrt((long)GYR);
      COMPL = ACC + GYR;
      /*
         // Hata Ayıklama IMU
         Serial.print("$");
         Serial.print(gyroX);
         Serial.print(" ");
         Serial.print(gyroY);
         Serial.print(" ");
         Serial.print(gyroZ);
         Serial.println(";");
      */
      freq = (long)COMPL * COMPL / 1500;                        // parabolik ton değişimi
      freq = constrain(freq, 18, 300);                          
      freq_f = freq * k + freq_f * (1 - k);                     // pürüzsüz filtre
      mpuTimer = micros();                                     
    }
  }
}

void setPixel(int Pixel, byte red, byte green, byte blue) {
  leds[Pixel].r = red;
  leds[Pixel].g = green;
  leds[Pixel].b = blue;
}

void setAll(byte red, byte green, byte blue) {
  for (int i = 0; i < NUM_LEDS; i++ ) {
    setPixel(i, red, green, blue);
  }
  FastLED.show();
}

void light_up() {
  for (char i = 0; i <= (NUM_LEDS / 2 - 1); i++) {        
    setPixel(i, red, green, blue);
    setPixel((NUM_LEDS - 1 - i), red, green, blue);
    FastLED.show();
    delay(25);
  }
}

void light_down() {
  for (char i = (NUM_LEDS / 2 - 1); i >= 0; i--) {      
    setPixel(i, 0, 0, 0);
    setPixel((NUM_LEDS - 1 - i), 0, 0, 0);
    FastLED.show();
    delay(25);
  }
}

void hit_flash() {
  setAll(255, 255, 255);            
  delay(FLASH_DELAY);                
  setAll(red, blue, green);        
}

void setColor(byte color) { //Başka bir renk istiyorsanız aşağıdaki RGB değerlerini değiştirerek oluşturabilirsiniz. Ama led ayarlarını bozabileceğinden tavsiye edilmez.
  switch (color) {
    // 0 - kırmızı, 1 - yeşil, 2 - mavi, 3 - mor, 4 - sarı, 5 - buz mavisi
    case 0: //kırmızı renk için değer
      red = 255;
      green = 0;
      blue = 0;
      break;
    case 1: //yeşil renk için değer
      red = 0;
      green = 0;
      blue = 255;
      break;
    case 2: //mavi renk için değer
      red = 0;
      green = 255;
      blue = 0;
      break;
    case 3: //mor renk için değer
      red = 255;
      green = 0;
      blue = 255;
      break;
    case 4: //sarı renk için değer
      red = 255;
      green = 255;
      blue = 0;
      break;
    case 5: //buz mavisi renk için değer
      red = 0;
      green = 255;
      blue = 255;
      break;
  }
}

void batteryTick() {
  if (millis() - battery_timer > 30000 && ls_state && BATTERY_SAFE) {
    if (voltage_measure() < 15) {
      ls_chg_state = 1;
    }
    battery_timer = millis();
  }
}

byte voltage_measure() {
  voltage = 0;
  for (int i = 0; i < 10; i++) {    
    voltage += (float)analogRead(VOLT_PIN) * 5 / 1023 * (R1 + R2) / R2;
  }
  voltage = voltage / 10;           
  int volts = voltage / 3 * 100;    // 3 hücre!
  if (volts > 387)
    return map(volts, 420, 387, 100, 77);
  else if ((volts <= 387) && (volts > 375) )
    return map(volts, 387, 375, 77, 54);
  else if ((volts <= 375) && (volts > 368) )
    return map(volts, 375, 368, 54, 31);
  else if ((volts <= 368) && (volts > 340) )
    return map(volts, 368, 340, 31, 8);
  else if (volts <= 340)
    return map(volts, 340, 260, 8, 0);
}

And my scheme:

And a screenshot of the properties section of one of the sounds I want to play

Have you tried any simple test sketches from the sound library you are using?

1 Like

Sorry... "any simple test sketches" I don't understand

A standard example sketch that ships with the library that drives your sound device (without all the code that you produced, which also supports all the additional hardware, such as LEDs, etc).

Almost every library includes such sketches. They are accessible from the IDE menu after the library is installed.

It's the TMRpcm thing and the PAM8403 is probably some kind of AF amp.

so i will try to play a sound that comes by default first. is it correct?

So?

Muting.

Partially. I would say, "play a sound using the default software".

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.