Search the Community

Showing results for tags 'mp3'.

  • Search By Tags

    Type tags separated by commas.
  • Search By Author

Found 1 result

  1. Задача: реализовать работу с mp3-плеером (включить/выключить/следующая песня/регулировка громкости) композиций в mp-3 плеере используя одну кнопку. Логика работы с кнопкой такая: Один раз кликнули - начала воспроизводиться песня Второй раз кликнули - песня поставлена на паузу Третий раз кликнули - продолжили воспроизведение Двойной клик по кнопке - переход к следующей песне Долго давим на кнопку - постепенное нарастание громкости. Если достигли максимума - сбрасываем на минимум. И так по кругу. Реализация: В качестве mp3-плеера был взят DFPlayer Mini Почему то в нем не работала функция mp3_next(). Вернее она работала, но после переключения плеер останавливался, и приходилось еще раз нажать на кнопку, чтобы его запустить. По этому решил переключать композиции по номерам (но это надо знать заранее сколько будет песен на флешке, что для моей задачи вполне подходило). #include <SoftwareSerial.h> #include <DFPlayer_Mini_Mp3.h> // Объявляем переменные и константы const int buttonPin = 2; // Пин с кнопкой int currentButtonStatus = 0; // 0 - Кнопка не нажата // 1 - Кнопка нажата первый раз // 2 - Кнопка отжата после нажатия // 3 - Кнопка нажата во второй раз // Настройки MP3-плеера const int mp3_fileCount = 3; // Общее количество файлов (в обход глючной mp3_next) int mp3_currentFile = 1; // Текущий трек для проигрывания int mp3_currentStatus = 0; // Текущий статус проигрывания // 0 - Ничего не проигрывается // 1 - Проигрывается очередная композиция // 2 - На паузе int currentValue = 10; // Текущее значение громкости int prevValue = currentValue; // Значение громкости в предыдущей итерации const int maxValue = 30; // Максимальное значение громкости const int minValue = 5; // Минимальное значение громкости const int delayChangeValue = 100; // Длительность времени, в течении которого не увеличиваем громкость на следующий уровень, в мс unsigned long currentChangeValueStart; // Кол-во милисекунд от начала работы программы, когда последний раз изменили громкость const int delayChangeValueMax = 3000; // Длительность времени, в течении которого значение громкости находится на максимуме unsigned long currentMaxValueStart; // Кол-во милисекунд от начала работы программы, когда значение громкости было выставлено в максимум const int delayPause2Stop = 10000; // Кол-во милисекунд, по прошествии которых пауза переходит в остановку песен unsigned long timePauseStart; // Кол-во милисекунд от установки плеера на паузу // Настройки кнопки const int delayFalse = 10; // Длительность, меньше которой не регистрируется единоразовый клик const int delayLongSingleClick = 1000; // Длительность зажатия кнопки для выхода в режим увеличения громкости const int delayDeltaDoubleClick = 800; // Длительность между кликами, когда будет зафиксирован двойной клик unsigned long currentButtonStatusStart1; // Кол-во милисекунд от начала работы программы, когда начался статус 1 unsigned long currentButtonStatusStart2; // Кол-во милисекунд от начала работы программы, когда начался статус 2 unsigned long currentButtonStatusStart3; // Кол-во милисекунд от начала работы программы, когда начался статус 3 void setup() { // Прописываем пины pinMode(buttonPin, INPUT); // Вывод Serial.begin(9600); // Настройка MP3 mp3_set_serial (Serial); delay(1); mp3_set_EQ(4); mp3_set_volume (currentValue); currentChangeValueStart = millis(); } void loop() { // Определяем текущий статус кнопки int event = changeButtonStatus(); if(event > 0) { // Если поменялся статус switch(event) { case 1: // Единоразовый клик switch(mp3_currentStatus) { case 0: // Ничего не играло - начинаем играть с начала mp3_play(mp3_currentFile); mp3_currentStatus = 1; Serial.println("Step 1: play new"); break; case 2: // Было на паузе - начинаем играть с прошлого места mp3_play(); mp3_currentStatus = 1; Serial.println("Step 1: play"); break; case 1: // Играло - на паузу mp3_pause(); mp3_currentStatus = 2; timePauseStart = millis(); Serial.println("Step 1: pause"); break; } break; case 2: // Двойной клик if(mp3_currentStatus == 1) { // Срабатывает только если сейчас идет проигрывание mp3_currentFile++; if(mp3_currentFile > mp3_fileCount) mp3_currentFile = 1; mp3_play(mp3_currentFile); Serial.println("Step 1: next"); } break; case 3: // Давим кнопку увеличения громкости if(millis() - currentChangeValueStart > delayChangeValue) { // На текущей громкости давим уже больше времени, чем стоит задержка нахождения на одном уровне громкости if(currentValue < maxValue) { // Громкость еще не достигла своего максимального уровня // Обнуляем счетчик нахождения на максимальном уровне currentMaxValueStart = millis(); } currentValue++; // Прибавляем громкость currentChangeValueStart = millis(); // Ограничение по максимальному значению if(currentValue > maxValue) { // Громкость достигла своего максимального уровня // Проверяем, сколько времени мы находимся в этом состоянии if(millis() - currentMaxValueStart > delayChangeValueMax) { // В максимуме мы былу уже достаточно времени // Скидываем громкость в минимум currentValue = minValue; } else { currentValue = maxValue; } } if(currentValue != prevValue) { // Отправляем новое значение громкости в плеер delay(1); mp3_set_volume (currentValue); prevValue = currentValue; } } break; case 4: // Отпустили кнопку с громкостью // Обнуляем время currentChangeValueStart = millis(); currentMaxValueStart = millis(); break; } } if(mp3_currentStatus == 2) { // Если проигрывание стоит на паузе // Проверяем как долго стоит на паузе if(millis() - timePauseStart > delayPause2Stop) { // На паузе уже стоим давно // Пора стопится mp3_stop(); mp3_currentStatus = 0; Serial.println("Step 1: stop"); } } } /** * Смена текущего статуса * @return = 0 - ничего не произошло * 1 - простой клик * 2 - двойнок клик * 3 - зажата кнопка * 4 - отжата кнопка после долгого зажатия */ int changeButtonStatus() { // Событие int event = 0; // Текущее состояние кнопки int currentButtonClick = digitalRead(buttonPin); // Текущее время unsigned long timeButton = millis(); switch(currentButtonStatus) { case 0: // В настоящий момент кнопка не нажималась if(currentButtonClick) { // Зафиксировали нажатие кнопки currentButtonStatus = 1; currentButtonStatusStart1 = millis(); } else { // Кнопка не нажата // Ничего не происходит } break; case 1: // В настоящий момент кнопка на этапе первого нажатия if(currentButtonClick) { // Кнопка все еще нажата if(timeButton - currentButtonStatusStart1 >= delayLongSingleClick) { // Кнопка в нажатом состоянии уже дольше времени, после которого фиксируем длительное одинарное нажатие на кнопку // Событие длительного давления на кнопку - продолжаем давить event = 3; } } else { // Кнопку отжали обратно if(timeButton - currentButtonStatusStart1 < delayFalse) { // Время, которое была кнопка нажата, меньше минимального времени регистрации клика по кнопке // Скорее всего это были какие то флюктуации // Отменяем нажатие currentButtonStatus = 0; event = 0; } else if(timeButton - currentButtonStatusStart1 < delayLongSingleClick) { // Время, которое была кнопка нажата, меньше времени фиксации долгого нажатия на кнопку // Значит это первое одноразовое нажатие // Дальше будем ожидать второго нажатия currentButtonStatus = 2; currentButtonStatusStart2 = millis(); } else { // Время, которое была нажата кнопка, больше времени фиксации долгого единоразового нажатия // Значит это завершение длительного нажатия currentButtonStatus = 0; event = 4; } } break; case 2: // Мы находимся в фазе отжатой кнопки в ожидании повторного ее нажатия для фиксации двойного нажатия // или, если не дождемся - значит зафиксируем единичное нажатие if(currentButtonClick) { // Если кнопку снова нажали // Проверяем, сколько времени кнопка находилась в отжатом состоянии if(timeButton - currentButtonStatusStart2 < delayFalse) { // Кнопка была в отжатом состоянии слишком мало времени // Скорее всего это была какая то флюктуация дребезга кнопки // Возвращаем обратно состояние на первичное нажатие кнопки currentButtonStatus = 1; } else { // Кнопка была достаточно долго отжата, чтобы зафиксировать начало второго нажатия // Фиксируем currentButtonStatus = 3; currentButtonStatusStart3 = millis(); } } else { // Если кнопка все еще отжата // Проверяем, не достаточно ли она уже отжата, чтобы зафиксировать разовый клик if(timeButton - currentButtonStatusStart2 > delayDeltaDoubleClick) { // Кнопка в отжатом состоянии слишком долго // Фиксируем одинарный клие currentButtonStatus = 0; event = 1; } } break; case 3: // Мы на этапе второго нажатия // Для подтверждения факта двойного нажатия if(currentButtonClick) { // Кнопка все еще зажата // Ничего не происходит, ждем, когда отожмут } else { // Кнопку отжали // Проверям, действительно ли отжали, или это дребезг кнопки if(timeButton - currentButtonStatusStart3 < delayFalse) { // Кнопку отжали слишком рано // Скорре всего это дребезг // Гинорируем его } else { // Кнопка была в нажатом состоянии уже достаточно длительное время // Это завершение цикла фиксации двойного нажатия // Сообщаем такое событие event = 2; currentButtonStatus = 0; } } break; } return event; }