#include #include #ifdef __AVR__ #include #endif // Светодиодная лента подключена к пину 11 #define PIN 11 // Она состоит из 50 светодиодов #define NUMPIXELS 50 // Создаём объект для управления лентой Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800); // Создаём объект для связи по MIDI через Serial1 MIDI_CREATE_INSTANCE(HardwareSerial, Serial1, myMidi); // Вспомогательные переменные int r, g, b, pitchPot; // Функция, пересчитывающая оттенок в RGB. // Подробности: http://wiki.amperka.ru/projects:christmastree void f_HSV_to_RGB(int hue, int sat, int val) { int base; if (sat == 0) { r = val; g = val; b = val; } else { base = ((255 - sat) * val) >> 8; switch (hue / 60) { case 0: { r = val; g = (((val - base) * hue) / 60) + base; b = base; break; } case 1: { r = (((val - base) * (60 - (hue % 60))) / 60) + base; g = val; b = base; break; } case 2: { r = base; g = val; b = (((val - base) * (hue % 60)) / 60) + base; break; } case 3: { r = base; g = (((val - base) * (60 - (hue % 60))) / 60) + base; b = val; break; } case 4: { r = (((val - base) * (hue % 60)) / 60) + base; g = base; b = val; break; } case 5: { r = val; g = base; b = (((val - base) * (60 - (hue % 60))) / 60) + base; break; } case 6: { r = val; g = 0; b = base; break; } } } } // Обработчик события NoteOn. Эта функция будет вызвана автоматически при // при приёме сообщения NoteOn по MIDI-входу. // Подробнее: http://arduinomidilib.fortyseveneffects.com/a00022.html void handleNoteOn(byte channel, byte pitch, byte velocity) { // Velocity имеет значение от 0 до 127 // Чтобы не снижать диапазон значений оттенка цвета (0-255), // мы сдвигом влево умножаем силу нажатия на 2. byte doubleVelocity = velocity << 1; // Переводим оттенок в RGB f_HSV_to_RGB(doubleVelocity, 255, 255); // Номер ноты имеет значение от 0 до 127, // а светодиодов всего 50. Чтобы лента отображала ноты // в нужном интервале, подкрутим ленту под нужные ноты потенциометром. // Чтение значения с потенциометра происходит в loop(); int activePitch = pitch - pitchPot; // Устанавливаем цвет светодиода в нужную позицию... pixels.setPixelColor(activePitch, pixels.Color(r, g, b)); // ... и зажигаем ленту. pixels.show(); } // Обработчик события NoteOff. Эта функция будет вызвана автоматически при // при приёме сообщения NoteOff по MIDI-входу. // Подробнее: http://arduinomidilib.fortyseveneffects.com/a00022.html void handleNoteOff(byte channel, byte pitch, byte velocity) { // Гасим светодиод, который был зажжён от NoteOn int activePitch = pitch - pitchPot; pixels.setPixelColor(activePitch, pixels.Color(0, 0, 0)); pixels.show(); } void setup() { // Инициализируем светодиодную ленту... pixels.begin(); // ... и гасим все светодиоды pixels.show(); // Присоединяем обработчик события NoteOn myMidi.setHandleNoteOn(handleNoteOn); // Присоединяем обработчик события NoteOff myMidi.setHandleNoteOff(handleNoteOff); // Инициализируем MIDI-интерфейс на прослушку всех // MIDI-каналов. myMidi.begin(MIDI_CHANNEL_OMNI); } void loop() { // Здесь мы просто вызываем MIDI.read, // остальное библиотека сделает сама myMidi.read(); // Считаем значение с потенциометра. // Нам нужно значение в диапазоне (0-127), // его можно получить из диапазона (0-1024) сдвигом на 3 бита вправо pitchPot = analogRead(A4) >> 3; }