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

