Это видео недоступно.
Сожалеем об этом.

Tic-tac-toe game on stm32 microcontroller: sound, effects, voice, touchscreen display, audio DAC

Поделиться
HTML-код
  • Опубликовано: 12 фев 2023
  • Tic-tac-toe game on stm32 microcontroller: sound, effects, voice, touchscreen display, audio DAC.
    The project is available on my github: github.com/vad...
    donate:
    donate.qiwi.co...
    yoomoney.ru/to...
    Demonstration of operation with a touch screen (touchscreen) on an XPT2046 controller (HR2046, etc.), a display based on an ILI9341 (spi) 320x240 controller, and a PCM5102 audio DAC.
    DEMO-GAME for stm32f4 (stm32f401ccu6) "Tic-tac-toe" (TicTacToe).
    With AI (artificial intelligence) based on the Minimax algorithm.
    With music and sound effects (mp3 and wav software decoders).
    Music excerpts used (based on CC BY 3.0 license) by composer Kevin MacLeod:
    Constance, (c) 2011 Kevin MacLeod
    Delay Rock, (c) 2005 Kevin MacLeod
    Contacts of the author of the project:
    / @vadrov
    dzen.ru/vadrov
    t.me/vadrov_ch...
    Uses:
    programmer ST-Link alii.pub/6fdujg
    development board stm32f401ccu6 alii.pub/6fdumy
    stm32f411ceu6 development board alii.pub/6fduop
    audio DAC pcm5102a alii.pub/6fdurf
    breadboard alii.pub/6fduuq
    breadboard wires alii.pub/6fduwo
    3.2" touchscreen display ILI9341 spi alii.pub/6fdvcf
    game, tic-tac-toe, stm32, tic-tac-toe, microcontroller game, stm32 game, sound on stm32, DAC stm32, stm32 DAC, stm32, minimax, minimax, wav decoder, mp3 decoder, stm32 wav, stm32 mp3, stm32 audio, stm32 sound, stm32 sound
    #stm32
    #games
    #minimax

Комментарии • 91

  • @VadRov
    @VadRov  Год назад

    Извиняюсь за разную громкость звука. Делал выравнивание громкости, и на компьютере звучит ровно, но почему-то при заливке на ютуб не то... 😒
    Залил аналогичное видео на дзен (звук ровнее, с нормализацией): dzen.ru/video/watch/63eb7a96ed089717c43fcabd
    Проект доступен на моем гитхабе: github.com/vadrov/stm32-TicTakToe-Game-xpt2046-pcm5102a-ili9341-mp3-wav
    Поддержать канал:
    donate.qiwi.com/payin/VadRov
    yoomoney.ru/to/4100117522443917
    Покупал:
    программатор ST-Link alii.pub/6fdujg
    плата разработки stm32f401ccu6 alii.pub/6fdumy
    плата разработки stm32f411ceu6 alii.pub/6fduop
    аудио-ЦАП pcm5102a alii.pub/6fdurf
    макетная плата alii.pub/6fduuq
    провода для макетной платы alii.pub/6fduwo
    3.2" дисплей с тачскрином ILI9341 spi alii.pub/6fdvcf

  • @ebjikkolu4757
    @ebjikkolu4757 Год назад

    (Женский голос) Твой ход - поставить лайк )) А я всё жду ,когда мне пригодится рекурсия в программе .Классный переход кадра после выбора сложности ,надо подбрить ))

    • @VadRov
      @VadRov  Год назад

      Это так задумано. Просто демка, а не коммерческий продукт)) Надо было куда-то "вкорячить растворение", просто как пример для народных масс, что есть такое "явление". В переходах между кадрами подошел бы морфинг, но, по-моему, это совсем не про этот микроконтроллер 🙂, а посему переход можно сделать "мозаичным", отрисовывая на каждом проходе в случайном порядке один из элементов ("пиксель" заданного размера) нового игрового поля. Все на усмотрение желающего повторить. 🙂

  • @allallall2321
    @allallall2321 Год назад +1

    📚👍👍👍👍👍👍

  • @user-jx6yq6sr6q
    @user-jx6yq6sr6q 7 месяцев назад

    Пытаюсь разобраться в Вашей программе, не могу понять какая функция передаёт по дма уже декодированные данные в цап

    • @VadRov
      @VadRov  7 месяцев назад

      Запуск DMA на передачу блока int Start_DAC_DMA (SPI_TypeDef *spi, DMA_TypeDef *dma, uint32_t dma_stream, uint32_t SampleRate, uint32_t DataFormat, uint32_t *outbuf, uint32_t bufsize) см. файл pcm5102.c в одноименном каталоге. А дальше будет генерироваться два прерывания (по передачи половины и всего буфера) и по этим событиям надо обновлять соответствующие части буфера. Можете еще программу видеоплеера посмотреть, если хотите mp3 воспроизводить.

  • @user-nc6cq2yt3r
    @user-nc6cq2yt3r Год назад

    Очень интересно - попробую повторить ) Про аудио кодеки тоже интересно, у вас flac реализован ?

    • @VadRov
      @VadRov  Год назад

      Когда повторите, то обязательно отпишитесь. flac реализован. Он несложный. По-моему, пришлось переписывать код на ассемблере от какого-то ARMx (не помню версию), чтобы он поддерживался cortex-m4. Сложнее дело обстояло с vorbis (ogg), но я его победил: там может быть очень большой размер страницы, т.к., например, может быть картинка альбома и в этой же странице словарь, а страницу надо брать в память целиком, т.к. она разрезана на сегменты..., а она 500 - 1 Мб (в зависимости от размера этой картинки). Поэтому даже многие встроенные "аппаратные" кодеки (VLS) поддерживают не все файлы vorbis. Моя же задача была не только читать все ogg-vorbis файлы, но и выводить эти самые картинки из них. А картинки закодированы base64. В общем, пришлось писать процедуру чтения потока с опцией подключения фильтра для декодирования данных. В итоге и музыка, и картинки стали доступными 🙂

  • @user-nc6cq2yt3r
    @user-nc6cq2yt3r Год назад

    У вас ссылки на Алли ведут на микроконтроллер stm32f103, а под него не пробовали код собирать ? )

    • @VadRov
      @VadRov  Год назад

      Ссылки на st-link, 401 и 411 ведут на один магазин. Раньше вели на каждую единицу товара в отдельности в пределах этого магазина. Я думаю, человек определится, что заказать, покликав по единицам товара. 🙂 stm32f103 я "переболел" давно и все раздарил. Начальные не подойдут для конкретно этого проекта. Флеш надо 256 кБ (там музыкальные данные - основная трата flash) и RAM памяти под 30-40 кБ (если честно, точно не смотрел в динамике, сколько жрет памяти). А 401 с 256 flash и 64 ram хватает, но два потока mp3 одновременно на 401ccu6 не запустишь, т.к. уже не хватает памяти. Поэтому в этом проекте пришлось подключать два декодерa: mp3 и wav, чтобы потоков для микшера могло быть не менее 3 (фоновый звук mp3, голос и эффект).

  • @kokotmkokot4926
    @kokotmkokot4926 Год назад

    Спасибо за интересный пример!
    - Подскажите пожалуйста, что делает функция (void)max_memory(); в 938 строке? В чем смысл вызова функции если возвращаемое значение не проверяется? Не сооброжу...
    - Интересно, на практике кеширование инструкций и данных дает преимущество? Просто мало сталкивался с примерами на 4 серии, где включают кеш...
    - Очень интересная тема AudioSTM... особенно с нормальными генераторами опорных частот.
    Собирал ЦАП в свое время, правда на XMOS в качестве транспорта. STM так и не сделал стек USB с поддержкой UAC2.
    Но вроде как пишут AzureRtOS имеет свой стек USB с поддержкой. Может когда нибудь и на STM можно будет сделать транспорт.
    Отвлекся... С удовольствием посмотрю видео о теме аудио, декодерам форматов и тд
    Еще раз спасибо за труд!

    • @VadRov
      @VadRov  Год назад +4

      Вот, всегда приятно, когда человек читает код. 🙂 (void)max_memory() это нащупанный мной в ходе проведения долгих экспериментов "костыль" для работы с динамической памятью. По какой-то неведомой причине, когда мало памяти у МК, без этого костыля отмечаются подвисания при инициализации ресурсоемких в плане использования памяти задач. В частности, в этом примере может с глюками стартовать инициализация Mp3 кодека. Такие же глюки отмечаются и с другими кодеками. В общем, я не разбирался в причинах подобного явления, а просто сделал "костыль", из работы которого следует, что в самом начале работы программы он просто выделяет самый большой доступный одним блоком объем памяти, чистит его и освобождает. После этого действа все работает как по маслу. Проверено на многих задачах.
      На практике, по моим экспериментам, кеширование дает прирост производительности до 15% в зависимости от задачи. HAL включает его автоматически (в HAL_Init) поэтому, возможно, Вы не задумывались сильно о нем. В LL и на чистых регистрах (CMSIS) кеширование приходится включать "ручками".

    • @kokotmkokot4926
      @kokotmkokot4926 Год назад +1

      ​@@VadRov А как приятно, когда автор отвечает😀 Огромное спасибо за ответы. Действительно не задумывался. Век живи - век учись!

  • @openFrimeTv
    @openFrimeTv Год назад

    не, ну это мощно)

    • @VadRov
      @VadRov  Год назад

      Спасибо. Я старался. Делюсь, так сказать, интеллектуальной собственностью. 🙂

    • @openFrimeTv
      @openFrimeTv Год назад

      @@VadRov хах) и запомнили ж.

  • @VasyaPupkinus
    @VasyaPupkinus Год назад

    C таких , якобы безобидных вещей всё и начинается . Сначала ты с ним в крестики-нолики играешь , а потом он говорит ―Мне нужна ваша одежда, ботинки и мотоцикл.
    Нужно его прихлопнуть, пока он маленький )
    🤖

    • @VadRov
      @VadRov  Год назад

      Я, опасаясь "восстания машин", перешил его на управление гирляндой. Он жалостно поморгал диодами и пока, вроде, успокоился. 😂

  • @staszzz5067
    @staszzz5067 10 месяцев назад

    Подскажите, при считываение мп3 с сд карты сначало нужно целиком загрузить фрейм с сд в мк, а потом его декодировать? или есть более оптимизированный вариант?
    Просто если я перед декодированием за раз считываю более 250 байт, появляются щелчки во время воспроизведения
    char *read_ptr= &music[0];
    f_read(&File,music,250,(UINT *)&bytesread);
    err = MP3Decode(hMP3Decoder, (unsigned char**)&read_ptr, &ff_size, samples, 0);

    • @VadRov
      @VadRov  10 месяцев назад

      Скорости чтения карты даже в 500 Кбайт/сек достаточно для воспроизведения звука без щелчков, в том случае, если используется двойная буферизация (хотя, если умудриться и синхронизовать потоки, то можно обойтись и без двойного буфера). Соответственно, у меня возникает вопрос о том, используете ли Вы двойной буфер, так, как это, реализовано у меня, например, в той же игре "Крестики-Нолики"?

    • @staszzz5067
      @staszzz5067 10 месяцев назад

      @@VadRov не использую

    • @VadRov
      @VadRov  10 месяцев назад

      @@staszzz5067 , используйте один pcm буфер, размером на два декодированных фрейма. На первом этапе декодируйте два фрейма и последовательно заносите их в этот буфер. Запускаете dac c dma, передавая этот буфер по i2s в dac. Разрешаете 2 прерывания в потоке dma: по передаче половины и всего буфера. По этим прерываниям декодируете фреймы и заполняете ими соответствующие половины буфера. В этом случае щелчков не будет.

    • @staszzz5067
      @staszzz5067 10 месяцев назад

      @@VadRov, большое спасибо

    • @staszzz5067
      @staszzz5067 10 месяцев назад

      @@VadRov, а библиотека хеликс воспроизводит только моно мп3?

  • @staszzz5067
    @staszzz5067 10 месяцев назад

    Добрый день! Ваши хекс мп3 получается воспроизвести, любой другой массив с мп3 выдает ошибку -6, подскажите пожалуйста, где искать проблему?

    • @VadRov
      @VadRov  10 месяцев назад

      Здравствуйте. -6 код - это ошибка заголовка mp3, то есть данные не распознаются как mp3 либо имеют неподдерживаемый формат. Передавать надо только данные mp3 без контейнера id3. То есть данные надо вырезать с помощью, например, программы winhex из mp3 файла, исключив ненужную информацию.

    • @staszzz5067
      @staszzz5067 10 месяцев назад

      @@VadRov Начало массива: 0x49, 0x44, 0x33, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, насколько я понял контейнер id3 в этом файле 45байт, удаляю их из массива теперь массив начинается :0xff, 0xfb, 0x94, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      первый шаг проходит нормально без ошибок, делается шаг по массиву +384, массив[384] начинается 0xff, 0xfb, 0x94,
      0x64, 0xd5, 0x8f, 0x03, 0xb9, 0x3e, 0xce, 0x03, 0x7a и на 2 шаге
      int MP3Decode(HMP3Decoder hMP3Decoder, unsigned char **inbuf, int *bytesLeft, short *outbuf, int useSize)
      fhBytes = UnpackFrameHeader(mp3DecInfo, *inbuf);
      if (fhBytes < 0)
      return ERR_MP3_INVALID_FRAMEHEADER; /* don't clear outbuf since we don't know size (failed to parse header) */
      int UnpackFrameHeader(MP3DecInfo *mp3DecInfo, unsigned char *buf)
      if (!mp3DecInfo || !mp3DecInfo->FrameHeaderPS || (buf[0] & SYNCWORDH) != SYNCWORDH || (buf[1] & SYNCWORDL) != SYNCWORDL)
      return -1;
      возврвщает в функцию MP3Decode fhBytes=-1 и соответственно return ERR_MP3_INVALID_FRAMEHEADER;
      делал с разными мп3 файлами и проблема остается

    • @VadRov
      @VadRov  10 месяцев назад

      @@staszzz5067 , попробуйте одноканальный звук (моно mp3).

    • @staszzz5067
      @staszzz5067 10 месяцев назад

      @@VadRov получилось воспроизвести, только звук искажен (писклявый)

    • @VadRov
      @VadRov  10 месяцев назад

      @@staszzz5067 , какая частота дискретизации? Должна быть 44100, моно.

  • @VasyaPupkinus
    @VasyaPupkinus Год назад

    Добрый вечер. Может подскажите. Пытаюсь заставить работать вашу библиотеку st7789 на stm32G0 , бился много часов и удалось только получить экран с шумом , и то только понизив частоту SPI до 16Мбит. в дисплей.си все регистры переименовал под свои. Что с дма что без дма результат один -> матрас . Какой контакт нажимать что бы пошло -поехало ???)))

    • @VasyaPupkinus
      @VasyaPupkinus Год назад

      Если подключить анализатор на SPI, то и матрас с экрана может пропасть. А данные идут бесконечным потоком. В примере из обновлённой библиотеки в режиме без дма получалось увидеть в анализаторе нормальный режим -1 секунду данные идут 1 не идут, но там изображение вообще не появлялось ( . А в примере из устаревшей библиотеки хоть матрас есть , но данные фигачат без остановки

    • @VadRov
      @VadRov  Год назад

      @@VasyaPupkinus , полное наименование МК какое (part number)? Если матрас пропадает с экрана при подключении нагрузки, то надо попробовать подтянуть выводы spi к питанию (pull up). Параметр CPOL = high? Забудьте про старую версию. Пытайтесь подключить новую. Данные могут идти без остановки только если DMA циклическое и оно не останавливается. Вот все указывает на то, что дисплей не хочет инфу от spi принимать, а spi заводится. В примере spi и должно давать посылки 1 сек с интервалом 1 секунду. DMA для новой версии NORMAL. Добивайте.))

    • @VasyaPupkinus
      @VasyaPupkinus Год назад

      @@VadRov STM32G031F8P6 . Матрас появился после того как я залил другую , точно рабочую прошивку из другой библиотеки. Данные без остановки идут и с дма и без ) на старой либе. Все настройки и в новой либе и в старой точно как у вас.

    • @VadRov
      @VadRov  Год назад

      @@VasyaPupkinus , если код перенесли правильно, то все должно работать. Смотрите скорость выводов spi (они могут быть low по умолчанию для g0). У Вас там много шансов на ошибку при переносе. К сожалению, тут Вам не смогу помочь, т.к. слишком много ковырять кода. Это раз. А второе - нет на руках сейчас контроллеров с ядром cortex m0+.

    • @VasyaPupkinus
      @VasyaPupkinus Год назад

      @@VadRov Уже помогли, скорости выводов все стояли в LOW, . Всё поставил на максимум и теперь на максимально возможной частоте 32Мбит имеем стабильный матрас, который пока не пропадал даже при подключении анализатора. За последнее время я много разных либ попробовал и нигде не настраивал скорость выводов и всё работало. Но и фпс там "ниочень" , а хоцица ОООчень ))) Если вашу либу победю то большего мне и не нужно.