Всем доброго времени суток. Сразу оговорюсь: это моя первая проба пера с ардуино, так что прошу сильно не ругать за возможно тупые вопросы. Итак, ближе к делу. Имеем arduino uno, music shield с карточкой на 2 гига и двумя треками на ней и кнопку, подключенную ко 2-у цифровому входу. Задача: при нажатой кнопке в цикле воспроизводить один трек, при отпущенной - второй. Набросал пару скетчей которые как мне кажется Код (Text): // Подключаем все 3 предоставленные библиотеки #include <Fat16util.h> #include <NewSPI.h> #include "MusicPlayer.h" // Создаём объект для управления плейером MusicPlayer myplayer; bool State = 0; void setup() { Serial.begin(9600); myplayer.begin(); myplayer.keyDisable(); //отключаем встроенное управление воспроизведением myplayer.digitalControlEnable(); //включаем возможность слушать цифровые входы myplayer.attachDigitOperation(2, opened, LOW); myplayer.attachDigitOperation(2, closed, HIGH); myplayer.setPlayMode(MODE_REPEAT_ONE); myplayer.creatPlaylist(); myplayer.playList(); } void loop() { } void opened() { Serial.println("OPENED"); myplayer.playSong(1); delay(50); } void closed() { Serial.println("CLOSED"); myplayer.playSong(2); delay(50); Код (Text): // Подключаем все 3 предоставленные библиотеки #include <Fat16util.h> #include <NewSPI.h> #include "MusicPlayer.h" // Создаём объект для управления плейером MusicPlayer myplayer; int buttonState = 0; const int buttonPin = 4; void setup() { myplayer.begin(); myplayer.keyDisable(); //отключаем встроенное управление воспроизведением Serial.begin(9600); } void loop() { myplayer.setPlayMode(MODE_REPEAT_ONE); myplayer.creatPlaylist(); myplayer.playList(); buttonState = digitalRead(buttonPin); if ((buttonState==LOW)){ myplayer.playSong(1); Serial.println("opened"); } if ((buttonState==HIGH)){ myplayer.playSong(2); Serial.println("closed"); } } Имеем воспроизводящийся в цикле 1-й трек замолкающий при нажатии на кнопку и продолжающийся при отпускании. примерно вот так это выглядит в консоли Код (Text): 1.MP3 2.MP3 Song 0 opened реакция на нажатие кнопки: Код (Text): CLOSED error: open file failed при отпусканни кнопки ничего не выводится. Помимо всего прочего это сопровождается периодическими самопроизвольными перемотками и остановками воспроизведения. Собственно вопрос что я не так делаю и как нужно. Буду благодарен любым советам
Возможно ардуино путается когда читает треки просто потомучто они у вас названы одинаково?? Могу ошибаться особо не вникал.
для начала - выкиньте инициализацию плеера и создание плейлиста из loop и повесьте подавление дребезга на кнопку, например, библиотекой Bounce
внёс изменения. Код (Text): // Подключаем все 3 предоставленные библиотеки #include <Fat16util.h> #include <NewSPI.h> #include "MusicPlayer.h" #include <Bounce.h> // Создаём объект для управления плейером int buttonState = 0; const int buttonPin = 2; Bounce bouncer = Bounce( buttonPin,5 ); MusicPlayer myplayer; void setup() { pinMode(buttonPin,INPUT); Serial.begin(9600); myplayer.begin(); myplayer.keyDisable(); myplayer.setPlayMode(MODE_REPEAT_ONE); myplayer.creatPlaylist(); } void loop() { bouncer.update ( ); buttonState = bouncer.read(); if ((buttonState==LOW)){ myplayer.playSong(1); Serial.println("opened"); } if ((buttonState==HIGH)){ myplayer.playSong(2); Serial.println("closed"); } } в таком виде в консоли видна реакция на кнопку, но выскакивает ошибка Код (Text): All songs in the root directory: 1.MP3 2.MP3 opened error: open file failed closed error: open file failed если использовать формат с названиями треков типа myplayer.playSong("1.MP3"); то включается первый трек и какая либо реакция на нажатие кнопки отсутствует
Правильно обрабатывать нажатие кнопки так: Код (Text): if(bouncer.update() && bouncer.read() == HIGH) { ... }
я в курсе. я пытаюсь передавать номер трека в плейлисте, т.к. передача имени файла вызывает какой то конфликт с уже занесённым в плейлист именем. кстати ещё почему то при подстановке нуля компилятор расценивает его как int и выдаёт ошибку компиляции, при передаче других значений корректно распознаётся как unsigned int. В любом случае задать нужный трек пока не удаётся. максимум добился перехода на следующий/предыдущий и то только при отпускании кнопки.
сейчас скетч выглядит так: Код (Text): // Подключаем все 3 предоставленные библиотеки #include <Fat16util.h> #include <NewSPI.h> #include "MusicPlayer.h" #include <Bounce.h> // Создаём объект для управления плейером int buttonState = 0; const unsigned int i=0; //номер первого трека const unsigned int j=1; //номер второго трека const int buttonPin = 2; Bounce bouncer = Bounce( buttonPin,100 ); bool State =0; MusicPlayer myplayer; void setup() { pinMode(buttonPin,INPUT); Serial.begin(9600); myplayer.begin(); myplayer.keyDisable(); myplayer.setPlayMode(MODE_REPEAT_ONE); myplayer.creatPlaylist(); } void loop() { if(bouncer.update() && bouncer.read() == LOW){ if (State){ Serial.println("opened"); myplayer.playSong(i); State=0; } } if(bouncer.update() && bouncer.read() == HIGH){ if (!State){ Serial.println("closed"); myplayer.playSong(j); State=1; } } } в консоли выглядит так: Код (Text): All songs in the root directory: 1.MP3 2.MP3 closed error: open file failed opened error: open file failed closed error: open file failed opened error: open file failed closed т.е. почти корректно обрабатывает нажатие/отпускание кнопки, но выдаёт ошибку воспроизведения. периодически начинают произвольно сыпаться сообщения.
Одна из playSong() принимает char*. Если передавать числовой терминал, это может быть воспринято компилятором как передача константного указателя. Передавайте номер трека через переменную или приводите аргумент к типу unsigned int явно.
ну судя по тому что условия выполняются он возвращает true сейчас вопрос то скорее в том как корректно выбирать нужный трек
Попробуйте сперва отладить код, который просто запускает воспроизведение одного трека. Затем добавьте переключение на другой трек - например, через n секунд после запуска первого трека. И так далее - добавляйте мелкие кусочки кода, так проще отследить, после чего начинаются глюки. Опять же можно попробовать переключать треки не по номеру или имени, а функциями opNextSong и opPreviousSong, если это приемлемо для логики Вашего скетча.
пошёл от обратного, набросал скетч со всем остальным функционалом. Код (Text): #include <Fat16util.h> #include <NewSPI.h> #include "MusicPlayer.h" #include <Bounce.h> // Создаём объект для управления плейером int doorState = 1; const unsigned int zero = 0; const int startButton = 2; const int doorButton = 3; const int yellowLED = 4; const int greenLED = 5; const int redLED = 6; const int relayPin = 7; Bounce startBounce = Bounce( startButton,20 ); Bounce doorBounce = Bounce( doorButton,20 ); MusicPlayer myplayer; void setup() { Serial.begin(9600); pinMode(startButton,INPUT); pinMode(doorButton,INPUT); pinMode(yellowLED,OUTPUT); pinMode(greenLED,OUTPUT); pinMode(redLED,OUTPUT); pinMode(relayPin,OUTPUT); // myplayer.keyDisable(); myplayer.begin(); myplayer.setPlayMode(MODE_REPEAT_ONE); myplayer.creatPlaylist(); } void loop() { myplayer.opPlay(); doorState=1; digitalWrite(greenLED,LOW); digitalWrite(redLED,LOW); digitalWrite(relayPin,LOW); digitalWrite(yellowLED,HIGH); if ( startBounce.update ( ) && startBounce.read ()){ digitalWrite(yellowLED,LOW); digitalWrite(relayPin,HIGH); // opPreviousSong(); // гудим while (!( startBounce.update ( ) && startBounce.read ())){ if (doorState){ if (doorBounce.read()==HIGH){ digitalWrite(greenLED,HIGH); digitalWrite(redLED,LOW); myplayer.opPreviousSong(); // гудим } if (doorBounce.read()==LOW){ digitalWrite(greenLED,LOW); digitalWrite(redLED,HIGH); myplayer.opNextSong(); // гудим и пищим } } doorState=doorBounce.update ( ); } } } пришлось поменять местами myplayer.keyDisable(); myplayer.begin(); т.к. похоже оно работает только в таком порядке, иначе диоды начинают светиться едва заметно. но с воспроизведением звука всё плохо. при использовании playList() начинается воспроизведение и больше ничего не происходит, при использовании playSong(номер трека) всё почти работает, но выкидывает в консоль ошибки при попытке открытия файла, при использовании opPlay, opNextSong(), opPreviousSong() всё работает, но на эти команды не реагирует. PS: удалось заставить выбирать трек при помощи doorButton и playSong("имя файла"), т.е. при нажатии startButton в зависимости от состояния doorButton включается 1-й или 2-й трек, но на этом какая либо реакция на кнопки прекращается (((
Сначала опросите все кнопки, а потом начинайте логику разворачивать. а то получается так: опросили одну кнопку и свалились в цикл ожидания нажатия другой кнопки. Не надо одну и ту же кнопку несколько раз опрашивать в одном месте - сохраните в переменную и пользуйтесь ей. Добавьте отладочный вывод во все сомнительные месте - отладка пойдет гораздо веселей
Вы уж определитесь. Не вижу каких то проблем с циклом, да и проблема совершенно не в нём. Что даст отладочный вывод, если при начале воспроизведения выполнение программы останавливается?