В данной статье мы расскажем об опыте сборки куба 4x4x4 на RGB-светодиодах, а также о разработке программного обеспечения, необходимого для использования куба в качестве визуализатора звука. Используется микроконтроллер Arduino Uno.

image


Подготовка


Куб

При исследовании подобных проектов была обнаружена реализация под названием «Чарликуб» («Charliecube») за авторством Эшера Глика (Asher Glick) и Кевина Бэйкера (Kevin Baker). Данный вариант примечателен тем, что, в отличие от других реализаций, не предусматривает наличие счётчиков, регистров сдвига либо каких-либо других компонентов для построения куба с целью его последующего программирования и задействует только 16 выводов микроконтроллера (позволяя при этом адресовать 64 светодиода). В основе этой реализации лежит конструкция светодиодной индикации под названием «Чарлиплексинг».

Чарлиплексинг

Цифровые выводы микроконтроллеров имеют трёхзначную логику: присоединён к питанию, присоединён к «земле» и не посоединён ни к чему. Если нам надо зажечь светодиод, необходимо подать "+" на X и "-" на «Y», только в таком случае он будет гореть. Если на Y ничего не подавать, до светодиод не загорится. Подробнее о методе можно почитать в одноимённой статье на Википедии, ниже приведено описание работы конкретно в нашем случае.

image

схема столбика светодиодов

Предположим, что мы хотим зажечь LED1 зелёным цветом. Если проследить по синей линии, видно, что необходимо подать "+" на вход 1. Проследив за красной линией, понимаем, что нужно подать "-" на вход 3. На остальные входы ничего не подаётся.

Визуализация

Было решено, что весь анализ музыки будет производится на подключённом к кубу ПК. Основная идея: ПК анализирует канал записи звука, преобразует звук в информацию о частотах и передаёт данные о ритме музыки в Arduino.Далее микроконтроллер на основе этой информации подсвечивает определённые светодиоды.

Поскольку у авторов проекта большой опыт работы с Ruby, в рамках проекта хотелось прибегнуть именно к этому языку программирования. Была обнаружена статья Дэвида Гутмана (David Guttman), описывающая визуализацию звука на JRuby с помощью гема ruby-processing и java-библиотеки Minim. Найденная статья была взята за основу для написания визуализатора.

Сборка


Собираем столбик

image


Перед соединением светодиодов в столбец необхобходимо в каждом из четырёх светодиодов выгнуть ноги так, чтобы каждая нога составляла с с соседней 90°.

imageimage

Затем каждый из светодиодов нужно вращать поочерёдно на 90° (каждый последующий должен быть повёрнут на 90° по часовой стрелке по отношению к предыдущему). Предварительно одну из ног можно пометить (у нас она помечена зелёным лаком), чтобы не запутаться.

imageimage

Соединяем наши светодиоды в столбик. После соединения светодиодов обрезаем выступающие концы ног.

imageimageimage

image image

Размещаем столбики

Оставшиеся 15 столбиков собираются аналогичным образом.

image


Столбики расставляются на плате на одинаковом расстоянии друг от друга, формируя таким образом куб со стороной, равной 4 светодиодам. Все столбики должны быть повёрнуты в одинаковом направлении (тут очень пригодится предварительная маркировка «опорной» ноги).

image image

image image

Соединяем столбики между собой

Переворачиваем конструкцию и начинаем присоединять провода. Всего проводов 16, соединение проводилось в 4 этапа.

imageimage

imageimage

imageimage

imageimage

image


Осталось подключить к Arduino — и можно приступать к программированию.

Подключаем к Arduino

Авторы Чарликуба предусмотрели библиотеку cubeplex для удобного программирования куба с Arduino. Для того, чтобы данную библиотеку можно было использовать без модификаций, необходимо подключать наши провода в следующем порядке (нумерация соответствует проводам на изображениях из предыдущего раздела):

image image

Программируем Arduino


Базовый функционал

Как было сказано выше, авторы воспользовались библиотекой charlieplex, которая предоставляет функцию drawLed(), принимающая цвет и позицию светодиода в координатах XYZ.
Подсветить весь кубик красным цветом
#include "cubeplex.h"

const int cubeSides = 4;

void setup() {
  initCube();
}

void loop() { 
  for (int xpos = 0; xpos < cubeSides; xpos++) {
    for (int ypos = 0; ypos < cubeSides; ypos++) {
      for (int zpos = 0; zpos < cubeSides; zpos++) {
          drawLed(red, xpos, ypos, zpos);
      }
    }
  }
}


Обмен сообщениями с ПК

Обмен сообщениями реализуется посредством последовательного ввода-вывода в порт, через который контроллер соединяется с машиной. Работа с такими событиями реализована в Arduino через SerialEvent.
Выборочная подсветка куба с вводом пользователя
#include "cubeplex.h"

String inputString = "";         
boolean stringComplete = false;

// Ввод каждого символа в порт сопровождается вызовом SerialEvent, который накапливает введённые символы в строку inputString.
// Как только пользователь вводит Enter, меняется значение флага inputComplete и выполняется дальнейший код из loop().

int color = red;

void setup() {
  Serial.begin(9600);
  inputString.reserve(200);
  initCube();
}

void loop() {
  if (stringComplete) {
      Serial.println(inputString);
      drawString(inputString);
      resetBuffer();
      inputString = "";
      stringComplete = false;
    }
  }
}

void serialEvent() {
  while (Serial.available()) {
    char inChar = (char)Serial.read();
    inputString += inChar;
    if (inChar == '\n') {
      stringComplete = true;
    }
  }
}

// Очистка буфера куба; перед последующей подсветкой диодов куб полностью погаснет.
void resetBuffer() {
  flushBuffer();
  clearBuffer();
}

// Закодируем три кординаты светодиода трёмя цифрами.
// Каждая координата - каждые три символа из строки, которая пришла в порт.
// То есть строка "000001002003" подсветит столбик с координатами { x: 0, y: 0 }.

void drawString(String inputString) {
  int xpos = -1;
  int ypos = -1;
  int zpos = -1;

  for (int i = 0; inputString[i + 3]; i += 3) {
    xpos = charToInt(inputString[i]);
    ypos = charToInt(inputString[i + 1]);
    zpos = charToInt(inputString[i + 2]);

    drawLed(color, xpos, ypos, zpos);
  }
}

void charToInt(char value) {
  return (value - '0');
}


Программирование для светомузыки

Предполагается, что куб будет мигать в такт музыке. Соответственно, можно упростить формат сообщения до одной цифры. Алгоритм такой: как только анализатор музыки «ловит» такт, кубик должен полностью загореться. После этого кубик будет медленно (слой за слоем) гаснуть. Как только анализатор словит следующий такт, кубик снова загнорается полностью. То есть кубику достаточно передать одну цифру: сколько слоёв необходимо подсветить в данный момент. Также при каждой итерации будем случайным образом определять новый цвет.
Подсветка заданного количества слоёв
void drawBeat(String inputString) {
  int height = charToInt(inputString[0]);
  int color = random(red, white);

  for (int xpos = 0; xpos < cubeSides; xpos++) {
    for (int ypos = 0; ypos < cubeSides; ypos++) {
      for (int zpos = 0; zpos < height; zpos++) {
          drawLed(color, xpos, ypos, zpos);
      }
    }
  }
}


Анализ звука на JRuby


В набор библиотеки Minim входит класс BeatDetect, который предоставляет инструменты для определения ритма музыки. Вообще с помощью этой библиотеки предельно просто подключиться к каналу приёма звука и произвести его частотный анализ. Для наших целей подошёл частотный метод определения ритма.
Код тестировался на Ubuntu 15.10; версия JRuby, использованная авторами — jruby 9.0.5.0. Для запуска скрипта необходимо установить Processing и подключить библиотеку Minim.
Анализ ритма
require 'ruby-processing'

require_relative 'translator'
require_relative 'serial_writer'

class SoundProcessor < Processing::App
  load_library "minim"
  import "ddf.minim"
  import "ddf.minim.analysis"

  def setup
    @minim = Minim.new self
    @input = @minim.get_line_in
    @beat = BeatDetect.new @input.mix.size, 44100
    @beat_value = 0.001
    @beat.set_sensitivity 300
  end

  def draw
    process_beat
    SerialWriter.instance.write(Translator.instance.translate(@beat_value))
  end

  private

  def process_beat
    @beat.detect @input.mix
    @beat_value = @beat.is_kick ? 1 : @beat_value * 0.95
  end
end

SoundProcessor.new



Демонстрация работы




Средствами PulseAudio визуализатору в качестве audio input был присвоен audio output, т.е. получаем визуализацию всего звука, который у нас идёт из динамиков. После записи на видео был наложен звук, который воспроизводился в момент создания ролика.

Посесловие


Нам удалось получить визуализатор звука в связке с пк. В дальнейшем можно улучшить алгоритм определения ритма (стандартные средства определения ритма библиотеки Minim далеки от идеала), также на куб можно выводить информацию о частотах. Как видите, куб несложен в построении и программировании; кроме того, он задействует минимум компонентов.

Ссылки:


Авторы
Макоед Виктор и Евгений Куница, студенты 3 курса БГУиР ВМСиС
Поделиться с друзьями
-->

Комментарии (13)


  1. DeleteOne
    21.06.2016 20:21

    Отличный проект!
    В идеале подключить это все к NodeMCU, чтобы получить внешний визуализатор. Кроме того, вроде сама плата способна справиться с анализом звука, судя по этому посту https://m.geektimes.ru/post/277276/.

    А вообще, давно мечтаю собрать подобный куб, только опыта в пайке недостаточно.
    Кстати, из чего делались ножки, которыми соединяли светодиоды?


    1. ekunitsa
      22.06.2016 11:20

      вообще это медная проволока, мы использовали кабель ВВГ 3*1,5


  1. kedobear
    21.06.2016 20:44
    +5

    Астрологи объявили неделю БГУИРа. Количество постов про светодиодные кубы на Geektimes увеличено вдвое.
    https://geektimes.ru/post/268166/
    https://geektimes.ru/post/269162/
    https://geektimes.ru/sandbox/3678/


    1. Samal
      28.06.2016 11:21

      Да, ладно, вам. Два куба зимой, один летом…
      Скоро наиграются… :)

      Кстати последняя ваша ссылка — и не про куб вообще… https://geektimes.ru/sandbox/3678/


  1. ilyaplot
    22.06.2016 09:53

    Возможностей у этого куба куда больше, чем просто визуализация звука. Я собирал на обычных светодиодах куб 5х5 и выводил на нем текст с анимацией, введенный в программе на ноутбуке. В качестве визуализации звука хорошо смотрелся эффект «дождь»


  1. cdmlex
    22.06.2016 11:06

    Если ножки сделать до потолка куба и там их как-нибудь закрепить, столбики будут стоять ровнее. А так, это самый аккуратный вариант куба.


    1. ekunitsa
      22.06.2016 11:20

      мы его после подклеили, и столбики стояли ровно, просто видео уже не переснимали.


  1. madf
    22.06.2016 15:50

    Вот меня всегда удивляли люди, которые делают что-то 3D, а потом пытаются "это" передать путем простой записи на видео (где естественно "вау эффект" не передаётся), потому как снимать надо в динамике угла…
    В общем, потрачено было уйму сил, а лично для меня так и остаётся загадкой ради чего это всё делалось. (


  1. roboq6
    22.06.2016 16:55
    -2

    Это визуализация музыки? Как любитель Anime Music Video (AMV), а также прочих музыкальных видеороликов, фи и ещё раз фи.
    Для меня музыка, как правило, должна иметь какую-то историю и/ли идею. Видеоряд как раз эту функцию и выполняет, он в той или иной степени визуализирует музыку раскрывая идею, историю. Может этот кубик передать идею/историю музыки? Нет и ещё раз нет.

    Вот примеры того как выглядит настоящая визуализация музыки:

    https://www.youtube.com/watch?v=_9FKoD1K6Yw

    https://www.youtube.com/watch?v=PJvPyH8WnMw


    1. madf
      22.06.2016 18:04

      чот ваши видео — не о чем, какое отношение они имеют вообще к этой теме, я ещё понимаю, если дать ссылку на нечто подобное: https://youtu.be/4ldsFIbf8aU?t=1m28s
      основная идея вся сводится к цветомузыке, а когда цветомузыка умела передавать "какую-то историю"? никогда)


      1. roboq6
        22.06.2016 18:27
        -1

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

        Цвет для передачи настроения музыки (и настроения вообще) я видет в диснеевском мультфильме «Алладин». Например сцена где Джафар приказывает Джину сделать его султаном насыщена фиолетовым цветом.


        1. madf
          22.06.2016 18:31

          вы видели постановку, свет носил вспомогательную суть к атмосфере
          здесь, да, кубик даже к цветомузыки не имеет никакого отношения, слабовато (соглашусь), но вот к творчеству руками и усидчивости — тоже немаловажно :D


          1. roboq6
            23.06.2016 06:33
            -1

            Думаю кубик всё-таки можно было бы использовать для визуализации музыки в двух случаях:

            1.Некий ИИ (скорее всего нейросеть) путём анализа тэгов, частот и прочей информации пытается угадать какое настроение передаёт музыка и соответствующим образом меняет цвет и яркость кубика. В случае неудачи получает feedback от пользователя.

            2.Вместе со звуковым файлом плэйер читает специальный файл в котором расписано какой цвет и яркость должен иметь кубик в том или ином месте мелодии. Файл создаётся вручную автором музыки либо кем-нибудь из фанатов.