Greetings to everyone, I am developing a project - a drum machine based on the Arduino MEGA 2560 and I have some difficulties.
The principle of operation of the device is that the Arduino Mega 2560 reads the signal from the touch buttons and plays sounds using the speaker stored on the SD card.
The key problem is that the speaker (universal speaker on the 4th) reproduces different generated sounds, the SD card is initialized, but for some unknown reason they do not interact with each other, although in Serial Monitor all processes proceed smoothly and there are no errors and plugs.
Files are stored on the memory card in wav resolution, 8 bits, 8khz, mono (I tried both 16 bits and 16 khz, removed file numbering). At the moment, the file is recorded as "sound" and it is stored on a formatted 2gb memory card.
P.S.this is my first Arduino-based project, so please treat my question with understanding, thank you in advance!
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <SD.h>
#include <SPI.h>
#include <TMRpcm.h>
#define SD_ChipSelectPin 53
#define SpeakerPin 3
#define ENCODER_S1 7
#define ENCODER_S2 8
#define ENCODER_KEY 6
TMRpcm audio;
LiquidCrystal_I2C lcd(0x27, 16, 2);
const int sensorPins[9] = {2, 3, 4, 5, 9, 10, 11, 12, 13};
int pattern = 0;
int bpm = 120;
int volume = 5;
bool adjustVolume = false;
volatile long lastEncoderPosition = 0;
void listFiles() {
File root = SD.open("/");
while (true) {
File entry = root.openNextFile();
if (!entry) {
// no more files
break;
}
Serial.print("File: ");
Serial.println(entry.name());
entry.close();
}
}
void playSound(int soundNum) {
String soundFile = "sound" + String(soundNum) + ".wav";
Serial.print("Attempting to play sound: ");
Serial.println(soundFile);
if (SD.exists(soundFile)) {
Serial.println("File exists, playing...");
audio.play(soundFile.c_str()); // Преобразование String в const char*
} else {
lcd.setCursor(0, 1);
lcd.print("File Missing ");
Serial.println("File Missing");
}
}
void setup() {
Serial.begin(9600); // Для отладки
lcd.begin(16, 2); // Укажите количество столбцов и строк
lcd.backlight();
lcd.print("DIY Drum Machine");
for (int i = 0; i < 9; i++) {
pinMode(sensorPins[i], INPUT);
}
pinMode(SpeakerPin, OUTPUT);
audio.speakerPin = SpeakerPin;
lcd.setCursor(0, 1);
lcd.print("Initializing SD");
Serial.println("Initializing SD card...");
// Попытка инициализации SD карты с несколькими попытками
bool sdInitSuccess = false;
for (int attempt = 0; attempt < 5; attempt++) {
if (SD.begin(SD_ChipSelectPin)) {
sdInitSuccess = true;
break;
}
delay(500); // Задержка перед повторной попыткой
}
if (!sdInitSuccess) {
lcd.setCursor(0, 1);
lcd.print("SD Init Fail ");
Serial.println("SD Initialization Failed");
return;
}
lcd.setCursor(0, 1);
lcd.print("SD Init Success");
Serial.println("SD Initialization Success");
// Дополнительные настройки для TMRpcm
audio.setVolume(volume); // Установить начальный уровень громкости
audio.quality(1); // Повышенное качество звука
// Список файлов на SD карте для отладки
listFiles();
// Настройка энкодера
pinMode(ENCODER_S1, INPUT);
pinMode(ENCODER_S2, INPUT);
pinMode(ENCODER_KEY, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(ENCODER_S1), updateEncoder, CHANGE);
attachInterrupt(digitalPinToInterrupt(ENCODER_S2), updateEncoder, CHANGE);
}
void loop() {
// Обработка сенсорных кнопок
for (int i = 0; i < 9; i++) {
if (digitalRead(sensorPins[i]) == HIGH) {
Serial.print("Sensor pin ");
Serial.print(sensorPins[i]);
Serial.println(" activated.");
playSound(i + 1);
lcd.setCursor(0, 1);
lcd.print("Sound: ");
lcd.print(i + 1);
delay(1000); // Задержка для предотвращения слишком частого считывания
}
}
// Обработка нажатия кнопки энкодера
if (digitalRead(ENCODER_KEY) == LOW) {
adjustVolume = !adjustVolume; // Переключение между режимами регулировки громкости и BPM
if (adjustVolume) {
lcd.setCursor(0, 0);
lcd.print("Volume: ");
lcd.print(volume);
lcd.print(" "); // Очищаем остаточные символы
} else {
lcd.setCursor(0, 0);
lcd.print("BPM: ");
lcd.print(bpm);
lcd.print(" "); // Очищаем остаточные символы
}
delay(300); // Задержка для устранения дребезга кнопки
}
// Обновление значения BPM или громкости в зависимости от текущего режима
if (adjustVolume) {
audio.setVolume(volume);
} else {
int newBpm = map(lastEncoderPosition, -1023, 1023, 60, 180);
if (newBpm != bpm) {
bpm = newBpm;
lcd.setCursor(0, 0);
lcd.print("BPM: ");
lcd.print(bpm);
lcd.print(" "); // Убираем возможные остаточные символы
Serial.print("Updated BPM: ");
Serial.println(bpm);
}
}
delay(100); // Задержка для улучшения читаемости
}
void updateEncoder() {
int s1State = digitalRead(ENCODER_S1);
int s2State = digitalRead(ENCODER_S2);
if (s1State != s2State) {
lastEncoderPosition++;
if (adjustVolume && volume < 7) {
volume++;
Serial.print("Volume increased to: ");
Serial.println(volume);
lcd.setCursor(0, 0);
lcd.print("Volume: ");
lcd.print(volume);
lcd.print(" "); // Очищаем остаточные символы
}
} else {
lastEncoderPosition--;
if (adjustVolume && volume > 0) {
volume--;
Serial.print("Volume decreased to: ");
Serial.println(volume);
lcd.setCursor(0, 0);
lcd.print("Volume: ");
lcd.print(volume);
lcd.print(" "); // Очищаем остаточные символы
}
}
if (!adjustVolume) {
lcd.setCursor(0, 0);
lcd.print("BPM: ");
lcd.print(bpm);
lcd.print(" "); // Очищаем остаточные символы
}
}