Рандомное воспроизведение файлов DFplayer
- Войдите на сайт для отправки комментариев
Привет всем. Продолжаю рзбираться в премудростях дальше. Чуть вопроса такая: есть топик по наливатору http://arduino.ru/forum/proekty/nalivator-avtomatizirovannaya-mashina-kotoraya-budet-razlivat-alkogol-po-stopkam Это как бы вводная.. Есть такая штука как воспроизведение тостов. Вместо кучи кейсов, как вот тут, допустим, http://arduino.ru/forum/proekty/nalivator-avtomatizirovannaya-mashina-kotoraya-budet-razlivat-alkogol-po-stopkam?page=8#comment-481135 сделал так, чтобы не быть привязанным к количеству файлов на карте памяти.
#include "DFRobotDFPlayerMini.h"
int8_t files_tost = 0; // Не более 100 тостов. Да и куда их больше?
// Тосты
void Tost() {
randomSeed(analogRead(7));
lcd.clear();
lcd.setCursor(0, 1);
lcd.print(F(" БЕРИ РЮМКУ "));
delay (2000);
myDFPlayer.volume(vol_tost);
delay (100);
myDFPlayer.playFolder (2, random (files_tost));
}
void setup() {
files_tost = myDFPlayer.readFileCountsInFolder(2); // Считаем сколько треков в папке с тостами 02
}
void loop() {
Tost();
}
Все работает, воспроизводит и т.д., но... Суть вопроса в том, то рандом хиленький, то есть имеют место быть повторения. При чем могут следовать друг за другом. Подтолкните в нужную сторону, чтобы избежать этого. Бибоиотека для плеера эта https://github.com/DFRobot/DFRobotDFPlayerMini
а я в той теме писал, как сделать неповторяющийся random. Гдетта на 8 странице.
нет, вру, на 10-й
http://arduino.ru/forum/proekty/nalivator-avtomatizirovannaya-mashina-kotoraya-budet-razlivat-alkogol-po-stopkam?page=9#comment-481230
а я в той теме писал, как сделать неповторяющийся random. Гдетта на 8 странице.
нет, вру, на 10-й
http://arduino.ru/forum/proekty/nalivator-avtomatizirovannaya-mashina-kotoraya-budet-razlivat-alkogol-po-stopkam?page=9#comment-481230
Да, спасибо, читал конечно это. Как ниже написал Алексей, много незнакомых букв для меня, без комментариев тяжело.. И как в этом случае расположить файлы на карте памяти, чтобы не быть жестко привязанным к их количеству? Вместо
"Tost 1",03"Tost 2",04"Tost 3",05"Tost 4",написать ссылки на файлы на карте?
Дело-то еще в том, что все мп3 раскиданы по трем папкам 01, 02 и 03. В первой служебные, второй тосты, а третьей музыка для плеера. Поэтому и ищу что-то по проще, что было бы более понятно :))
Ну, первым делом, я бы все тосты в 1 папку закинул. это прям напрашивается.
короче, к вечеру грядки закончу формировать, да переделаю, пока трезвый, чтоб не тосты а индекс отдавал, если тебе не под силу.
Ну, первым делом, я бы все тосты в 1 папку закинул. это прям напрашивается.
Они у меня и так все в одной отдельной папке сидят. Остальное по своим.
И да, буду признателен если подмогЁте.
особенно если его неправильно использовать. Кто ж пишет randomSeed(analogRead(7)); при каждом вызове? Это надо один раз делать в начале.
Это абсолютно нормально. Более того, математически доказанный факт, что в идеальной бесконечной последовательности случайных объектов, обязательно встретится любая наперед заданная конечная подпоследовательность. Например, миллион нулей подряд - обязательно встретится.
Поэтому, если Вам нужна неповторяющаяся последовательность, то Вам нужен не random, а нечто другое.
сам проверяй, у мня на даче свободных Дуинов нету, все трудятся не смыкая глаз.
class TSongs { // класс песенки protected: uint8_t Count; uint8_t *SongsIdx; uint8_t Size; void Clear(void) { Count = Size; for (uint8_t i = 0; i < Size; i++) SongsIdx[i] = i; } void HideSong(const uint8_t ATostNum) { for (int8_t i = ATostNum; i < Count - 1; i++) SongsIdx[i] = SongsIdx[i + 1]; Count--; } TSongs() {}; // пустой каструктор не разрешен public: // ASongCount скока песенок надо воспроизвести // TSongs(const uint8_t ASongsCount) { SongsIdx = new uint8_t[Size = ASongsCount]; Clear(); }; ~TSongs() { delete[] SongsIdx; } // отдает случайный индекс следующей песенки // uint8_t getNext() { if (Count == 0) Clear(); uint8_t idx = random(Count); uint8_t result = SongsIdx[idx]; HideSong(idx); return result; } };обьявляешь переменную
TSongs Songs(количество песенок); // не более 255
и вызываешь потом там, где надо получить индекс след. песенки
uint8_t next = Songs.getNext();
DFPlayer.play(next);
в пределах количества песенок не повторится ни одна. Потом произвоцтвенный цыкал пойдет сначала.
@DetSimen
Спасибо за подсказку. Тоже озадачивался таким рандомом, но я тупо объявлял массив с количеством тостов, потом перемешивал в нём всё, что несколько увеличивало динамическую память в зависимости от количества тостов, например 255 тостов это 255 байт, как то жалко хранить номер тоста в одном байте))) . Тут как я понял динамическое выделение памяти и потом последующее её очищение, занятость динамической памяти не зависит от количества треков.
В Строка 13 опечатка, вроде не правильный тип переменной букву u забыли поставить, а то треки только до 127 выдаёт. Короче с Вашего позволения беру на вооружение)))
Рандом рандомный (по настоящему) может возникнуть только из аналога. Берем нечто шумящее ( типа диода шотки) и считываем из него периодически "0" или "1"
Аналоговый пин не подключенный никуда, сам по себе нечто шумящее)). Всеми тут ненавистный Гайвер делает так
unsigned long seed = 0; for (int i = 0; i < 16; i++) { seed *= 4; seed += analogRead(A0) & 3; } randomSeed(seed);Не плохо получается
особенно если его неправильно использовать. Кто ж пишет randomSeed(analogRead(7)); при каждом вызове? Это надо один раз делать в начале.
Теперь знаю. Спасибо!
Это абсолютно нормально. Более того, математически доказанный факт, что в идеальной бесконечной последовательности случайных объектов, обязательно встретится любая наперед заданная конечная подпоследовательность. Например, миллион нулей подряд - обязательно встретится.
Поэтому, если Вам нужна неповторяющаяся последовательность, то Вам нужен не random, а нечто другое.
Таки да, в любой последовательности будут повторения. Это нам вдолбили еще во времена универа на вышке. Но вот как-то сократить эти повторения можно же? Буду учиться...
сам проверяй, у мня на даче свободных Дуинов нету, все трудятся не смыкая глаз.
Эх, молчит плеер :(( Вставил в скетч перед сетапом, далее как написано объявил TSongs Songs(files_tost); так как количество считывается в сетапе. Даже если прописать там цифрами нужное количество, не хочет он играть. Хреново когда много не понимаешь... Да..
Если uint8_t next = Songs.getNext(); оставить в лупе, то молчит.
Если вынести после объявления
TSongs Songs(files_tost); // не более 255
Аналоговый пин не подключенный никуда, сам по себе нечто шумящее))
Там надо ловить не 0 -1, а между какими - то значениями. Хотя тоже рандом, но кислый ИМХО
В строке 13 да, читать uint8_t
А по работоспособности, только завтра в город паехаю, возьму еще несколько дуин, с плеером, проверю
Оно работает если в лупе, когда необходимо воспроизвести файл вставить все три строки
В таком случае да, воспроизводит как и положено из нужной папки. Но вот правильно ли это? Может тогда эти три строки обернуть в процедуру и вставлять уже ее? Чисто для эстетики и уменьшения количества строк.
Проверил поболее. В одном режиме воспроизводит после налива как надо, а в других может зависнуть на одной мелодии...
TSongs Songs(files_tost); объяви глобалом, а getNext() вызывай в лупе.
TSongs Songs(files_tost); объяви глобалом, а getNext() вызывай в лупе.
Так вообще глючно работает. Может раза два-три не воспроизвести вообще, а может зависнуть на одной мелодии. Что гораздо чаще, чем если вызывать каждый раз когда нужен тост. Если все три строчки в одном месте, то глючит меньше, но повторяется и может так же не воспроизвести что-то.
Я понял. Мой код тебе не поможет, забудь
Я понял. Мой код тебе не поможет, забудь
Вопрос у меня есть... Имеется ли в талмудах решение проблемы проверки валидности enum переменной при непоследовательных значениях членов enum-а?
Т.е. девайс мне шлёт коды возврата (байт), которые я преобразую к enum (ну, чтобы умным казаться). Однако коды эти непоследовательны: enum { code1 = 0x23, code2 = 0x41, code3 = 43 } codes_t. И вот я принял от девайса байт 0x35. Как бы мне без адова свича проверить, что 0x35 ошибочен или наоборот - валиден?
Я понял. Мой код тебе не поможет, забудь
Ок. Жаль :(( но и на том спасибо! Буду изучать дальше толмуты...