Приветствую всех, разрабатываю проект - драм машину на базе Arduino MEGA 2560 и у меня возникли некоторые сложности.
Принцип работы устройства заключается в том, что Arduino Mega 2560 считывает сигнал с сенсорных кнопок и воспроизводит звуки с помощью динамика, хранящиеся на SD карте.
Ключевая проблема заключается в том, что динамик (универсальный динамик на 4ом) воспроизводит разные сгенерированные звуки, SD карта инициализируется, но они по какой-то невиданной причине не взаимодействуют друг с другом, хотя в Serial Monitor все процессы протекают ровно и никаких ошибок и затыков там нет.
Файлы хранятся на карте памяти в разрешении wav, 8 бит, 8кгц, моно (пробовал и 16 бит, и 16кгц, убирал нумерацию файлов). На данный момент файл записан как "sound" и он хранится на отформатированной карте памяти 2gb.
P.s.это мой первый проект на базе Arduino, поэтому отнеситесь пожалуйста к моему вопросу с пониманием, заранее благодарю вас!
Принцип работы устройства заключается в том, что Arduino Mega 2560 считывает сигнал с сенсорных кнопок и воспроизводит звуки с помощью динамика, хранящиеся на SD карте.
Ключевая проблема заключается в том, что динамик (универсальный динамик на 4ом) воспроизводит разные сгенерированные звуки, SD карта инициализируется, но они по какой-то невиданной причине не взаимодействуют друг с другом, хотя в Serial Monitor все процессы протекают ровно и никаких ошибок и затыков там нет.
Файлы хранятся на карте памяти в разрешении wav, 8 бит, 8кгц, моно (пробовал и 16 бит, и 16кгц, убирал нумерацию файлов). На данный момент файл записан как "sound" и он хранится на отформатированной карте памяти 2gb.
P.s.это мой первый проект на базе Arduino, поэтому отнеситесь пожалуйста к моему вопросу с пониманием, заранее благодарю вас!
C++:
#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(" "); // Очищаем остаточные символы
}
}