Использование массивов и светодиодов для представления фортепианных гамм

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

int MajorScale[] = {2,2,1,2,2,2,1}; //представляет полуноты в мажорной гамме
int t= 8 //представляет номер светодиода, который представляет первую C на клавиатуре

Должны загореться следующие светодиоды —

(8, 8+2, 8+2+2, 8+2+2+1, 8+2+2+1+2, 8+2+2+1+2+2, 8+2+ 2+1+2+2+2 , 8+2+2+1+2+2+2+1) // Это первая гамма до мажор на фортепиано

так.. (8,10,12,13,15,17,19) // Это первая гамма до мажор на фортепиано, где 8 — первая до

Затем зажгите все остальные гаммы до мажор, доступные на фортепиано, ограниченные количеством клавиш на фортепиано, в данном случае 76 клавиш

Поскольку на каждую октаву приходится 12 нот, добавьте это в массив

если я возьму только ноту C

8, 8+12, 8+12+12, 8+12+12+12, 8+12+12+12+12 и т. д.

Мой код пока просто подсвечивает полутон, который я установил в массиве

enter code here
#include "FastLED.h"
#define DATA_PIN 5
#define NUM_LEDS 76
#define BRIGHTNESS 10
CRGB leds[NUM_LEDS];
int MajorScale[] = {2,2,1,2,2,2,1};
int delayValue = 1000;

void setup() {
Serial.begin(9600); // открываем последовательный порт на скорости 9600 бит/с:
FastLED.addLeds<WS2812B, DATA_PIN, GRB>(leds, NUM_LEDS);
FastLED.setBrightness(BRIGHTNESS);
FastLED.clear();
}

void loop() {
for(int i = 0; i <=6; i++)
{  
    leds[MajorScale[i]] = CRGB::BlueViolet;  
    FastLED.show();          
     delay(delayValue);

}

FastLED.clear();
}

, 👍0

Обсуждение

А какой у тебя вопрос? Какова конкретная проблема, которая у вас есть с кодированием остального?, @chrisl

Как мне это сделать.. От начального массива {2,2,1,2,2,2,1} до первого набора светодиодов (8,10,12,13,15,17,19). Я не могу представить себе формулу, которая добавляет каждый элемент массива к следующему элементу. Похоже на текущую сумму с добавлением константы, @Subash


1 ответ


1

Ваш текущий код не будет отображать все ноты гаммы. Будут светиться только ноты 1 и 2, так как вы не суммируете числа, которые вы сохранили в MajorScale. Но я думаю, что не очень хорошая идея суммировать их программно, так как это константа, и вы не выиграете много, представляя данные таким образом. Вместо этого вы должны напрямую инициировать переменную MajorScale с суммированными значениями:

int MajorScale[] = {0, 2, 4, 5, 7, 9, 11};

Затем вы можете объединить свой цикл for с другим циклом for, который добавляет смещение, соответствующее октаве:

for(int j=0; j<NUM_LEDS; j+=12){
    for(int i=0; i<=6 && MajorScale[i]+j<NUM_LEDS;i++){
        leds[8+MajorScale[i]+j] = CRGB::BlueViolet;
        FastLED.show();
        delay(delayvalue);
    }
}

Итак, мы устанавливаем номер светодиода 8+MajorScale[i]+j. 8 для смещения до C, MajorScale[i] как положение ноты в текущей октаве и j для смещения текущей октавы относительно C.

Обратите внимание, что это никак не проверяется.

,

Боязнь, что вы забыли суммировать значения MajorScale. например, светодиоды[MajorScale[0]+j] == светодиоды[MajorScale[1]+j] указывают на один и тот же светодиод. И также должно быть смещение 6 для каждого j. ИМХО ;-), @Peter Paul Kiefer

Ах, ты прав. У меня это смешалось в голове. я изменю ответ, @chrisl

Когда я увидел редактирование, я понял, что тоже сделал ошибку. Идея изменить массив MajorScale лучше, чем смещение 6 (хорошая идея). Я был неправ, когда сказал, что для каждого j требуется смещение 6. Этот первый MajorScale начинается со светодиода № 8, а вторая шкала начинается со следующего ВЕЛ; Наверное. Итак, если первая C находится на светодиоде 8, начните с j=8 и добавьте 0. Следующий светодиод - это D -> добавьте 2, затем E добавьте 2, затем F добавьте 1 ... следующая октава j++ the , 11} необходимо удалить, потому что j++ переходит к следующей октаве C, где вы добавляете 0. и так далее. Извините за это "за каждого". Вечеринка не удалась ;-), @Peter Paul Kiefer

Позиция 11 соответствует ноте B, которая все еще на 1 полтона ниже следующей октавы C. После этого число i больше не имеет значения, так как внутренний цикл for завершится. Но я предполагаю, что я должен инициализировать i нулем в цикле for., @chrisl

Если вы видели мой последний комментарий. Я удалил его, потому что это был полный бред. Вы правы, код правильный., @Peter Paul Kiefer

@chris, спасибо, это сработало. Я хочу, чтобы эта программа зажигала необходимые светодиоды, а затем останавливалась. Оставьте их включенными. Я обновил цикл for, и когда я это сделал, светодиод перестал мигать. Я добавил 8 в цикл for for(int i=0; i<=6 && MajorScale[i]+j+8<=NUM_LEDS;i++) Я не совсем понимаю, почему это сработало?, @Subash