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

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

    Русскоязычный форум
    1
    1
    6.5k
    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
      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
      • First post
        Last post