🤖Have you ever tried Chat.M5Stack.com before asking??😎
    M5Stack Community
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Register
    • Login

    Урок 19. LED панель + Микрофон. Светомузыка

    Scheduled Pinned Locked Moved Русскоязычный форум
    1 Posts 1 Posters 7.3k Views 1 Watching
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • DimiD Offline
      Dimi
      last edited by

      Цель урока

      Привет! Сегодня мы научимся зажигать многоцветные светодиодные панели (только в M5 FIRE), полагаясь на составляющие частоты звукового сигнала, полученные со встроенного (только в M5 FIRE) микрофона.

      Рисунок 1

      Этот урок научит: подключать и использовать на практике сторонние библиотеки для работы с быстрым преобразованием Фурье (FFT) и светодиодами SK6818.

      Краткая справка

      Цветомузыка - вид искусства, основанный на способности человека ассоциировать звуковые ощущения со световыми восприятиями; такое явление в неврологии получило название синестезия. Светомузыка как искусство, представляет собой производную от музыки и является её неотъемлемой частью. Её назначение — раскрытие сущности музыки посредством зрительных восприятий. Основной целью светомузыки как искусства — это изучение способности человека испытывать ощущения, навязываемые световыми образами при сопровождении музыки.

      Любители музыки уже давно подметили, что музыкальные инструменты звучат намного громче и отчетливее в хорошо освещённом помещении, чем в затемнённом. Поэтому при исполнении серьёзной музыки свет в зале обычно не гасят.

      Впервые связь между слухом и зрением очень убедительно показал русский физик и русский физиолог академик П. П. Лазарев.

      Подробно на Wiki: https://ru.wikipedia.org/wiki/Светомузыка

      Перечень компонентов для урока

      • PC/MAC;
      • M5STACK FIRE;
      • кабель USB-C из стандартного набора.

      Начнём!

      Шаг 1. Установка библиотеки для работы с LED BAR

      Переходим по ссылке Библиотека LED BAR в разделе Downloads и скачиваем пример с файлами библиотек (рис. 2).

      Рисунок 2

      Далее извлекаем архив в новую папку sketch и удаляем файл demo1.ino (рис. 3).

      Рисунок 3

      Шаг 2. Установка библиотеки FFT

      Переходим по ссылке Библиотека Arduino FFT в разделе Downloads и скачиваем пример с файлами библиотек (рис. 4).

      Рисунок 4

      Далее извлекаем содержимое и копируем папку в C:\Users\USER_NAME\Documents\Arduino\libraries с новым именем arduinoFFT вместо arduinoFFT-master (рис. 5).

      https://pp.userapi.com/c851016/v851016266/3d841/sySeWj6WcW4.jpg

      Рисунок 5

      Отлично! С библиотеками всё :)

      Шаг 3. Пишем скетч

      Создадим в Arduino IDE новый скетч и сохраним его в той папке, где лежат файлы библиотеки из шага 1 (рис. 6).

      Рисунок 6

      Сразу подключим необходимые библиотеки и создадим необходимые переменные:

      #include <M5Stack.h>
      #include "arduinoFFT.h"
      #include "esp32_digital_led_lib.h"
      arduinoFFT FFT = arduinoFFT();
      
      #define SAMPLES 256 //Must be a power of 2
      #define SAMPLING_FREQUENCY 10000 //Hz, must be 10000 or less due to ADC conversion time. Determines maximum frequency that can be analysed by the FFT.
      #define amplitude 50
      unsigned int sampling_period_us;
      unsigned long microseconds;
      byte peak[] = {0,0,0,0,0,0,0};
      double vReal[SAMPLES];
      double vImag[SAMPLES];
      unsigned long newTime, oldTime;
      strand_t m_sLeds = {.rmtChannel = 0, .gpioNum = 15, .ledType = LED_WS2812B_V3, .brightLimit = 32, .numPixels = 10, .pixels = nullptr, ._stateVars = nullptr};
      

      Для упрощенного обращения к LED BAR предлагаю использовать следующую функцию void ledBar(int R, int G, int B, int M). Где int R, int G, int B - яркость КРАСНОГО, ЗЕЛЕНОГО и СИНЕГО - соответственно (от 0 до 255); int M - режим: от 0 до 9 - номер светодиода, 10 - все светодиоды из левой панели, 11 - все светодиоды из правой панели, 12 - все светодиоды.

      Светодиоды расположены по часовой стрелке (рис. 7).

      Рисунок 7

      Рисунок 7.1

      void ledBar(int R, int G, int B, int M) {
        if ((M < 0) || (M > 13)) return;
        if (M == 11) // right
        {
          for (int i = 0; i < 5; i++)
          {
             m_sLeds.pixels[i] = pixelFromRGBW(R, G, B, 0);
          }
        }
        else if (M == 10) // left
        {
          for (int i = 5; i < 10; i++)
          {
             m_sLeds.pixels[i] = pixelFromRGBW(R, G, B, 0);
          }
        }
        else if (M == 12) // all
        {
          for (int i = 0; i < 10; i++)
          {
             m_sLeds.pixels[i] = pixelFromRGBW(R, G, B, 0);
          }
        }
        else
        {
           m_sLeds.pixels[M] = pixelFromRGBW(R, G, B, 0);
        }
        digitalLeds_updatePixels(&m_sLeds);
      }
      

      Основная часть. Не забывайте про void dacWrite(25, 0); чтобы динамик не издавал странных звуков и треска.

      void setup(){
        M5.begin();
        pinMode(25, OUTPUT);
        pinMode(34, INPUT);
        sampling_period_us = round(1000000 * (1.0 / SAMPLING_FREQUENCY));
        pinMode(15, OUTPUT);
        digitalWrite (15, LOW);
        if (digitalLeds_initStrands(&m_sLeds, 1)) {
          Serial.println("Can't init LED driver().");
        }
        digitalLeds_resetPixels(&m_sLeds);
      }
      

      Обратите внимание на pinMode(34, INPUT) - это аналоговый вход, к которому подключён встроенный микрофон (рис. 8) через усилитель, поэтому настроим его на INPUT.

      Рисунок 8

      void loop() {
        for (int i = 0; i < SAMPLES; i++) {
          newTime = micros() - oldTime;
          oldTime = newTime;
          vReal[i] = analogRead(34); // A conversion takes about 1mS on an ESP8266
          vImag[i] = 0;
          while (micros() < (newTime + sampling_period_us));  // do nothing to wait
        }
        
        FFT.Windowing(vReal, SAMPLES, FFT_WIN_TYP_HAMMING, FFT_FORWARD);
        FFT.Compute(vReal, vImag, SAMPLES, FFT_FORWARD);
        FFT.ComplexToMagnitude(vReal, vImag, SAMPLES);
        dacWrite(25, 0);
        
        for (int i = 2; i < (SAMPLES/2); i++){ // Don't use sample 0 and only first SAMPLES/2 are usable. Each array eleement represents a frequency and its value the amplitude.
          if (vReal[i] > 200) { // Add a crude noise filter, 4 x amplitude or more
            if (i<=5 )             displayBand(0,(int)vReal[i]/amplitude); // 125Hz
            if (i >5   && i<=12 )  displayBand(1,(int)vReal[i]/amplitude); // 250Hz
            if (i >12  && i<=32 )  displayBand(2,(int)vReal[i]/amplitude); // 500Hz
            if (i >32  && i<=62 )  displayBand(3,(int)vReal[i]/amplitude); // 1000Hz
            if (i >62  && i<=105 ) displayBand(4,(int)vReal[i]/amplitude); // 2000Hz
            if (i >105 && i<=120 ) displayBand(5,(int)vReal[i]/amplitude); // 4000Hz
            if (i >120 && i<=146 ) displayBand(6,(int)vReal[i]/amplitude); // 8000Hz
          }
        }
      }
      

      Зажигать светодиоды будем с помощью функции void displayBand(int band, int dsize). Где band - частота в сигнале; dsize - количество частоты в сигнале. Можете смело тут экспериментировать и добиваться лучших вспышек.

      void displayBand(int band, int dsize){
        if (band > 1) dsize += 100;
        if (dsize >= 150)
        {
          ledBar(0, 0, 0, 12);
          if (band == 0)
          {
            if (dsize >= 300)
            {
              ledBar(255, 0, 0, 0);
              ledBar(255, 0, 0, 1);
            }
          }
          else if (band == 1)
          {
            if (dsize >= 180)
            {
              ledBar(255, 255, 0, 3);
              ledBar(255, 255, 0, 4);
            }
          }
          else if (band == 2)
          {
            if (dsize >= 170)
            {
              ledBar(0, 255, 0, 5);
              ledBar(0, 255, 0, 6);
            }
          }
          else
          {
            ledBar(0, 0, 255, 8);
            ledBar(0, 0, 255, 9);
          }
        }
      }
      

      Завершающий шаг

      На этом всё :)

      Downloads

      • Библиотека LED BAR (GitHub): https://github.com/MartyMacGyver/ESP32-Digital-RGB-LED-Drivers/tree/master/arduino-esp32/demo1
      • Библиотека Arduino FFT (GitHub): https://github.com/kosme/arduinoFFT
      1 Reply Last reply Reply Quote 0

      Hello! It looks like you're interested in this conversation, but you don't have an account yet.

      Getting fed up of having to scroll through the same posts each visit? When you register for an account, you'll always come back to exactly where you were before, and choose to be notified of new replies (either via email, or push notification). You'll also be able to save bookmarks and upvote posts to show your appreciation to other community members.

      With your input, this post could be even better 💗

      Register Login
      • First post
        Last post