Arduino Uno R3, WS2812B, 1 полоса из 60 светодиодов, разделенная на 4

Arduino Uno R3, WS2812B, 1 полоса из 60 светодиодов, разделенная на 4.

Проблема: требуется, чтобы в любой момент времени выполнялся только один сегмент /fx_mode.


#include <WS2812FX.h>

#define LED_COUNT 60

#define LED_PIN 13

WS2812FX ws2812fx = WS2812FX(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);

void setup() {

ws2812fx.init();

ws2812fx.setBrightness(85);

// разделить полосу из 60 светодиодов на 4 сегмента

ws2812fx.setSegment(0,  0, 14, FX_MODE_COMET, BLUE,  3000, false); 

ws2812fx.setSegment(1, 15, 29, FX_MODE_SCAN, RED, 3000, true); 

ws2812fx.setSegment(2, 30, 44, FX_MODE_SCAN, BLUE,  3000, false); 

ws2812fx.setSegment(3, 45, 60, FX_MODE_SCAN, RED, 3000, true); 

ws2812fx.start(); 
}

void loop() {

ws2812fx.service();
}

, 👍0

Обсуждение

и не так ли? ... какой у Вас вопрос?, @jsotola

разве они не индивидуально адресуемые светодиоды?, @jsotola

посмотрите пример кода в IDE arduino, @jsotola

ваш пост ничего не говорит о том, что вы пытаетесь сделать ... код примера находится прямо в Arduino IDE на вашем компьютере., @jsotola

Пожалуйста, позвольте мне объяснить это подробнее. У меня есть 1 полоска из 60 светодиодов, разделенная на 4 части с 4 разными FX_MODES и цветами. Я хочу, чтобы только 1 сегмент или FX_MODE были включены в любой момент времени... Сегмент (0, чтобы быть включенным, а остальные выключены. Следующий сегмент (1, включен, а остальные выключены). Следующий сегмент (2, включен а остальные выключены.Следующий сегмент(3, ВКЛ и все остальные выключены., @New2This

Вы можете помочь, добавив дополнительную информацию в вопрос, отредактировав его. Как и сейчас, ваш вопрос состоит только из неформатированного кода без описания того, что с ним не так или чего вы пытаетесь достичь. Вряд ли на это ответят так., @StarCat

Вы должны посмотреть на библиотеку *ws2812fx*, чтобы увидеть, что делает код. Я думаю, что это довольно хорошо описано [здесь] (https://github.com/kitesurfer1404/WS2812FX/blob/master/extras/WS2812FX%20Users%20Guide.md), включая то, как работает функция setSegment. Вы можете пропустить ws2812fx.setSegment(1,...) to (3,...), чтобы прекратить использование этого сегмента. Вы можете изменить количество светодиодов в сегменте с помощью второго и третьего параметров, т.е. ws2812fx.setSegment(0, 0, 4, ...) зажгутся только первые 5 светодиодов (0..4). Просто поэкспериментируйте немного с параметрами., @StarCat

Я всего лишь неоплачиваемый волонтер, который пытается помочь вам в свободное время, что я перестану делать после вашего комментария. *Я не могу читать твои мысли*. Вам нужно указать всю эту информацию в вопросе. А как насчет "пауза/задержка/время/счетчик"? Это не в вашем вопросе. Откуда мне было знать, что вы уже изменили количество светодиодов в каждом сегменте? Вы нигде об этом не упомянули., @StarCat

Я пытался прочитать все, что мог, здесь и в примерах библиотек, на YouTube и в Google. Наконец, задайте вопрос здесь в 3 часа ночи, так как я думал, что проблема будет очевидна для профессионала. Сейчас 5 утра, и уже давно пора спать, лол, спокойной ночи, @New2This

Ваш вопрос звучит так: «Проблема: я хочу испечь торт. Вот рецепт». Вы не говорите, что на самом деле происходит, когда вы следуете рецепту. Даже профессионал не может ответить на этот вопрос., @Nick Gammon


1 ответ


1

Используемая библиотека не дает вам прямой возможности автоматизировать изменения сегмента. Поэтому вам нужно написать этот код самостоятельно.

В настоящее время вы настраиваете все сегменты в setup() и запускаете их вместе с помощью start(). Вместо этого вы должны добавить соответствующий сегмент только тогда, когда он должен быть включен, и удалить все сегменты, которые не должны запускаться. В следующем я не удаляю и не добавляю сегмент, но я заменяю предыдущий сегмент (описанный ниже).

Я предлагаю код, подобный следующему, чтобы каждый элемент загорался один за другим в течение определенного времени (не тестировался).:

#include <WS2812FX.h>

#define LED_COUNT 60

#define LED_PIN 13

#define SEGMENT_INTERVAL    3000
unsigned long segment_timestamp;
uint8_t current_segment = 0;
#define SEGMENT_N   4

WS2812FX ws2812fx = WS2812FX(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);

void setup() {
    ws2812fx.init();
    ws2812fx.setBrightness(85);
    ws2812fx.start(); 
}

void loop() {
    if(millis()-segment_timestamp > SEGMENT_INTERVAL){
        segment_timestamp += SEGMENT_INTERVAL;
        switch(current_segment){
            case 0:
                ws2812fx.setSegment(0,  0, 14, FX_MODE_COMET, BLUE,  3000, false);
                break;
            case 1:
                ws2812fx.setSegment(0, 15, 29, FX_MODE_SCAN, RED, 3000, true);
                break;
            case 2:
                ws2812fx.setSegment(0, 30, 44, FX_MODE_SCAN, BLUE,  3000, false);
                break;
            case 3:
                ws2812fx.setSegment(0, 45, 60, FX_MODE_SCAN, RED, 3000, true);
                break;
        }
        current_segment = (current_segment + 1) % SEGMENT_N;
    }
    ws2812fx.service();
}

Что здесь происходит? Сначала мы используем функцию millis() в шаблоне примера BlinkWithoutDelay для определения времени смены сегментов на каждые 3 секунды (3000 мс), не блокируя выполнение другого кода (здесь процедура обслуживания светодиодной анимации). Я не буду здесь вдаваться в подробности, поскольку этот принцип описан во многих местах в Интернете и на этом сайте. Просто найдите что-то вроде "Arduino millis" или "Arduino Мигает без задержки". Теперь важно только то, что код внутри оператора if будет выполняться каждые 3 секунды (может быть изменен с помощью SEGMENT_INTERVAL).

В операторе if мы используем оператор switch для установки соответствующего сегмента, который должен быть активирован в это время. Здесь мы всегда устанавливаем сегмент 0, так как в любой момент активен только один сегмент. Вместо того чтобы удалять предыдущий сегмент и добавлять новый, мы просто меняем предыдущий сегмент на данные нового сегмента.

С помощью строки

current_segment = (current_segment + 1) % SEGMENT_N;

мы переходим к следующему сегменту, одновременно переходя от сегмента 3 к сегменту 1 с помощью оператора по модулю %. Это необходимо для перебора сегментов.

Вызов ws2812fx.service() по-прежнему необходим, поскольку он обрабатывает фактическую анимацию текущего сегмента.


Обратите внимание, что приведенный выше код все еще может быть улучшен. Вы можете сохранить все данные сегмента в массиве структур и заменить оператор switch одной строкой, используя current_segment'й элемент массива. Я оставлю это улучшение на ваше усмотрение.

,