Нужна помощь с градиентом

Артём Кудашев

✩✩✩✩✩✩✩
11 Сен 2020
11
0
Оформи код соответствующим тэгом
Здравствуйте! Имеется две матрицы 8*32, хотел вывести на них градиент из 2 цветов, зелëный и жëлтый, но он выводится как-то странно, код прилагаю, кто-то знает почему так?
Скетч:
#include <microLED.h>
#define M_PIN 6 // пин матрицы
#define P_PIN1 1 // пин потенциометра яркости
#define M_WIDTH 8 // ширина матрицы
#define M_HEIGHT 64 // высота матрицы
#define cur 5000 // max ток потребления в миллиаперах
#define NUM_LEDS (M_WIDTH * M_HEIGHT)
#define COLOR_DEBTH 3
microLED<NUM_LEDS, M_PIN, MLED_NO_CLOCK, LED_WS2818, ORDER_GRB, CLI_AVER> strip;
void setup() {
pinMode(P_PIN1, INPUT);
strip.setMaxCurrent(cur);
strip.setBrightness(20);
delay(100);
}
void loop() {
int Brightness = analogRead(P_PIN1);
Brightness = map(Brightness, 0, 1024, 0, 255);
strip.setBrightness(Brightness);
// заливка градиента
strip.fillGradient(0, NUM_LEDS, mGreen, mYellow);
strip.show();
delay(100);
}
IMG_20220717_224256.jpg
 

bort707

★★★★★★✩
21 Сен 2020
3,056
910
@Сотнег, не помогло, всё также
судя по картинке, тут две отдельные проблемы:
  • первое - неправильно описан порядок диодов в матрицах, поэтому вместо нижней матрицы зеленой и верхней желтой получается 4 цветных квадрата
  • и второе - собственно никакого градиента из зеленого в желтый нет, вместо этого есть резкий переход, как будто глубина цвета не 24 бита, а, скажем, 2 или 3.
Первое, думаю, легко поправить опциями "тип матрицы" А второе смахивает на косяк в библиотеке.

Чем разбираться, это проще самому написать, там логика элементарнейшая.
Посмотрите пример
 
Изменено:

poty

★★★★★★✩
19 Фев 2020
3,230
940
@Артём Кудашев,
во-первых, настройки, типа COLOR_DEBTH должны задаваться до #include < microLED.h > ;
во-вторых, не указана гамма-коррекция, которая в данном случае обязательна (думаю, CRT_PGM, но если нет серьёзной загрузки процессора, то CRT_CUBIC);
в-третьих, почему указана LED_WS2818, скорее всего, матрица из WS2812?
в-четвёртых, если у Вас матрица, то почему не определить её как матрицу?
в-пятых, скорее всего, формирование градиента происходит с помощью пространства HSV, в котором жёлтый цвет занимает крайне малый отрезок; в FastLED есть адаптированная раскладка HSV, увеличивающая (растягивающая) этот отрезок, не уверен, что эта фича сделана в microLED; отсюда - послушайте @bort707, сделайте градиент сами, тем более пример для этого в описании библиотеки имеется.

P.S. Формирование цвета через HSV не подтвердилось, но @Сотнег заставил посмотреть в библиотеку, есть неточность и в ней (см. ниже). Кроме того гамма коррекция для fillGradient не действует, что печально.
 
Изменено:

Сотнег

★★★★★★★
15 Янв 2020
4,365
1,494
@Артём Кудашев,
всё проще оказалось.

Библиотека microLED не универсальная.
Функция заливки градиента в ней не предусматривает, что на отрезке для заливки может оказаться более 256 пикселей.


Можете использовать эту функцию:
C-like:
void fixedFillGradient(uint32_t from, uint32_t to, mData color1, mData color2) {
    to -= from;
    for (uint32_t i = 0; i < to; i++) strip.leds[i + from] = strip.getBlend((i << 8) / to, 256, color1, color2);
}
или эту (в зависимости от того, куда вы её будете вставлять):
C-like:
void fillGradient(uint32_t from, uint32_t to, mData color1, mData color2) {
    to -= from;
    for (uint32_t i = 0; i < to; i++) leds[i + from] = getBlend((i << 8) / to, 256, color1, color2);
}
 
Изменено:

Артём Кудашев

✩✩✩✩✩✩✩
11 Сен 2020
11
0
Оформи код соответствующим тэгом
@Сотнег, возможно, что я сделал всё неправильно, но как использовать эти функции?
По ссылке переходил. Понял, что там описан fix, но как его применить - нет

#define COLOR_DEBTH 3
#include <microLED.h>
#define M_PIN 6 // пин матрицы
#define P_PIN1 1 // пин потенциометра яркости
#define M_WIDTH 8 // ширина матрицы
#define M_HEIGHT 64 // высота матрицы
#define cur 5000 // max ток потребления в миллиаперах
#define NUM_LEDS (M_WIDTH * M_HEIGHT)

microLED<NUM_LEDS, M_PIN, MLED_NO_CLOCK, LED_WS2811, ORDER_GRB, CLI_AVER> strip;
void setup() {
pinMode(P_PIN1, INPUT);
strip.setMaxCurrent(cur);
strip.setBrightness(20);
delay(100);
}

void loop() {
int Brightness = analogRead(P_PIN1);
Brightness = map(Brightness, 0, 1024, 0, 255);
strip.setBrightness(Brightness);
draw;
strip.show();

}


void draw(){
strip.fillGradient(0, NUM_LEDS, mGreen, mYellow);
for (int i = 0; i < NUM_LEDS; i++) leds = getBlend(i - 0, NUM_LEDS - 0, mGreen, mYellow);
}

выдаёт вот такое сообщение о ошибке:


'leds' was not declared in this scope
 

Сотнег

★★★★★★★
15 Янв 2020
4,365
1,494
@Артём Кудашев,
поправил код.
Верхний вариант - если вставлять в код вашего скетча,
нижний, если исправить глючную функцию прямо в библиотеке.

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

Сотнег

★★★★★★★
15 Янв 2020
4,365
1,494
@Артём Кудашев,
да.
void fillGradient
Если это словосочетание больше одного раза повторяется, в первом повторении нужно будет типы переменных поменять только,
а во втором целиком функцию заменить.
 

Артём Кудашев

✩✩✩✩✩✩✩
11 Сен 2020
11
0
Оформи код соответствующим тэгом
@Сотнег, Спасибо!!!! теперь получилось))
А есть вариант изменить функцию сложного градиента?
mGradient< 4 > myGrad; // создать градиент с именем myGrad на 4 точки
// указываем цвет каждой точки
myGrad.colors[0] = mBlack;
myGrad.colors[1] = mRed;
myGrad.colors[2] = mYellow;
myGrad.colors[3] = mWhite;
// создали градиент чёрный-красный-жёлтый-белый с одинаковым расстоянием между точками

// при помощи .get(позиция, размер) можно получить цвет в заданном месте градиента при указанной длине

// заливаем всю ленту
for (int i = 0; i < NUMLEDS; i++) {
strip.set(i, myGrad.get(i, NUMLEDS)); // получаем последовательно все цвета
}
strip.show();

чтобы он тоже работал больше чем 256 светодиодов
 

Сотнег

★★★★★★★
15 Янв 2020
4,365
1,494
Оформи код соответствующим тэгом
@Артём Кудашев,
Не проще вам 3 раза использовать fillGradient с разными диапазонами?
Типа,
strip.fillGradient(0, NUM_LEDS / 3, mBlack, mRed);
strip.fillGradient(NUM_LEDS / 3, NUM_LEDS * 2 / 3, mRed, mYellow);
strip.fillGradient(NUM_LEDS * 2 / 3, NUM_LEDS, mYellow, mWhite);