#1 2024-01-11 19:42:17

Alexxx
Учасник
Зареєстрований: 2024-01-11
Повідомлень: 2

Потрібна допомога з програмним кодом

Зробив підсвітку стельову з матриць на основі адресних LED діодів. В них по 7 штук стоїть на одній матриці. Чат GPT написав код для зміни кольору але я не можу від його добитись щоб зміна відбувалась плавно, десь на протязі трьох секунд, тобто щоб три секунди світились одним кольором, а потім щоб на протязі трьох секунд мінявся колір і далі цикл повторюється). Для профі це зробити як два пальця. Можете допомогти?

#include <FastLED.h>

#define NUM_LEDS 84
#define DATA_PIN 3
#define NUM_GROUPS 12
#define LEDS_PER_GROUP 7
#define MAX_BRIGHTNESS 255
#define COLOR_CHANGE_INTERVAL 3000 // 3 секунди

CRGB leds[NUM_LEDS];
CRGB groupColors[NUM_GROUPS];
uint32_t colorChangeTime;

void setup() {
  FastLED.addLeds<WS2812, DATA_PIN, GRB>(leds, NUM_LEDS);
  FastLED.setBrightness(MAX_BRIGHTNESS);
  randomSeed(analogRead(0));

  for (int i = 0; i < NUM_GROUPS; i++) {
    groupColors[i] = randomColor();
  }

  colorChangeTime = millis();
}

void loop() {
  if (millis() - colorChangeTime >= COLOR_CHANGE_INTERVAL) {
    for (int i = 0; i < NUM_GROUPS; i++) {
      groupColors[i] = randomColor();
    }
    colorChangeTime = millis();
  }

  fadeToColor(groupColors, leds, NUM_GROUPS, 5); // Зменшив швидкість зміни кольору до 5

  FastLED.show();
}

CRGB randomColor() {
  return CRGB(random(256), random(256), random(256));
}

void fadeToColor(CRGB *colorArray, CRGB *ledArray, int numGroups, int ledsPerGroup, uint8_t step) {
  for (int i = 0; i < numGroups; i++) {
    CRGB color = colorArray[i];
    for (int j = 0; j < ledsPerGroup; j++) {
      nblend(ledArray[i * ledsPerGroup + j], color, step);
    }
  }
}

Остання редакція Alexxx (2024-01-11 19:48:27)

Неактивний

#2 2024-01-13 08:34:41

vvr
Учасник
Зареєстрований: 2015-04-12
Повідомлень: 878

Re: Потрібна допомога з програмним кодом

Профі заробляють великі гроші та сюди не заходют .

Неактивний

#3 2024-01-14 07:02:57

dimich
Учасник
Зареєстрований: 2023-12-01
Повідомлень: 201

Re: Потрібна допомога з програмним кодом

nblend() просто оновлює кольорові компоненти відповідно до коефіцієнту перекриття за формулою: X=X*(1-k) + Y*k, де X - колір existing, Y - колір overlay, k = amountOfOverlay/255. Третій параметр - це не step, а коефіцієнт перекриття.

Після оновлення масиву його ще потрібно вивантажити в матрицю. Щоб зробити плавний перехід за 3 секунди, потрібно пробігтись по коефіцієнту перекриття від 0 до 255 з затримкою 3000мс/255, кожен раз оновлюючи масив.
Щось типу такого:

#include <FastLED.h>

#define NUM_LEDS 84
#define DATA_PIN 3
#define NUM_GROUPS 12
#define LEDS_PER_GROUP 7
#define MAX_BRIGHTNESS 255
#define COLOR_CHANGE_INTERVAL 3000 // 3 секунди

CRGB leds[NUM_LEDS];
CRGB groupColors_cur[NUM_GROUPS];
CRGB groupColors_new[NUM_GROUPS];
CRGB groupColors_tmp[NUM_GROUPS];

static CRGB randomColor()
{
    return CRGB(random(256), random(256), random(256));
}

static void updateLeds(CRGB colors[NUM_GROUPS])
{
    // заповнюєм масив
    for (int i = 0; i < NUM_GROUPS; i++) {
        for (int j = 0; j < LEDS_PER_GROUP; j++) {
            leds[i * LEDS_PER_GROUP + j] = colors[i];
        }
    }
    // вивантажуєм оновлені кольори в матрицю
    FastLED.show();
}

void setup()
{
    FastLED.addLeds<WS2812, DATA_PIN, GRB>(leds, NUM_LEDS);
    FastLED.setBrightness(MAX_BRIGHTNESS);
    randomSeed(analogRead(0));

    // початкові значення колорів
    for (int i = 0; i < NUM_GROUPS; i++) {
        groupColors_cur[i] = randomColor();
    }
}

void loop()
{
    // відображаєм статичні кольори 3 секунди
    updateLeds(groupColors_cur);
    delay(COLOR_CHANGE_INTERVAL);

    // кінцеві значення кольорів
    for (int i = 0; i < NUM_GROUPS; i++) {
        groupColors_new[i] = randomColor();
    }

    for (int k = 0; k <= 255; k++) {
        memcpy(groupColors_tmp, groupColors_cur, sizeof(groupColors_tmp));

        for (int i = 0; i < NUM_GROUPS; i++) {
            nblend(groupColors_tmp[i], groupColors_new[i], k);
        }

        updateLeds(groupColors_tmp);

        delay(COLOR_CHANGE_INTERVAL/255);   // весь цикл виконується приблизно за 3 с плюс час на виконання коду і вивантаження масиву в матрицю
    }

    // замінюєм поточні значення кінцевими для наступної ітерації
    memcpy(groupColors_cur, groupColors_new, sizeof(groupColors_cur));
}

Код не перевіряв, бо не маю такої матриці світлодіодів. Досить неоптимально і десь можуть бути помилки. Але основна ідея має бути зрозумілою.

Неактивний

#4 2024-01-14 19:22:41

Alexxx
Учасник
Зареєстрований: 2024-01-11
Повідомлень: 2

Re: Потрібна допомога з програмним кодом

dimich пише:

nblend() просто оновлює кольорові компоненти відповідно до коефіцієнту перекриття за формулою: X=X*(1-k) + Y*k, де X - колір existing, Y - колір overlay, k = amountOfOverlay/255. Третій параметр - це не step, а коефіцієнт перекриття.

Після оновлення масиву його ще потрібно вивантажити в матрицю. Щоб зробити плавний перехід за 3 секунди, потрібно пробігтись по коефіцієнту перекриття від 0 до 255 з затримкою 3000мс/255, кожен раз оновлюючи масив.
Щось типу такого:

#include <FastLED.h>

#define NUM_LEDS 84
#define DATA_PIN 3
#define NUM_GROUPS 12
#define LEDS_PER_GROUP 7
#define MAX_BRIGHTNESS 255
#define COLOR_CHANGE_INTERVAL 3000 // 3 секунди

CRGB leds[NUM_LEDS];
CRGB groupColors_cur[NUM_GROUPS];
CRGB groupColors_new[NUM_GROUPS];
CRGB groupColors_tmp[NUM_GROUPS];

static CRGB randomColor()
{
    return CRGB(random(256), random(256), random(256));
}

static void updateLeds(CRGB colors[NUM_GROUPS])
{
    // заповнюєм масив
    for (int i = 0; i < NUM_GROUPS; i++) {
        for (int j = 0; j < LEDS_PER_GROUP; j++) {
            leds[i * LEDS_PER_GROUP + j] = colors[i];
        }
    }
    // вивантажуєм оновлені кольори в матрицю
    FastLED.show();
}

void setup()
{
    FastLED.addLeds<WS2812, DATA_PIN, GRB>(leds, NUM_LEDS);
    FastLED.setBrightness(MAX_BRIGHTNESS);
    randomSeed(analogRead(0));

    // початкові значення колорів
    for (int i = 0; i < NUM_GROUPS; i++) {
        groupColors_cur[i] = randomColor();
    }
}

void loop()
{
    // відображаєм статичні кольори 3 секунди
    updateLeds(groupColors_cur);
    delay(COLOR_CHANGE_INTERVAL);

    // кінцеві значення кольорів
    for (int i = 0; i < NUM_GROUPS; i++) {
        groupColors_new[i] = randomColor();
    }

    for (int k = 0; k <= 255; k++) {
        memcpy(groupColors_tmp, groupColors_cur, sizeof(groupColors_tmp));

        for (int i = 0; i < NUM_GROUPS; i++) {
            nblend(groupColors_tmp[i], groupColors_new[i], k);
        }

        updateLeds(groupColors_tmp);

        delay(COLOR_CHANGE_INTERVAL/255);   // весь цикл виконується приблизно за 3 с плюс час на виконання коду і вивантаження масиву в матрицю
    }

    // замінюєм поточні значення кінцевими для наступної ітерації
    memcpy(groupColors_cur, groupColors_new, sizeof(groupColors_cur));
}

Код не перевіряв, бо не маю такої матриці світлодіодів. Досить неоптимально і десь можуть бути помилки. Але основна ідея має бути зрозумілою.

Не обов'язково перевіряти на матриці, можна перевірити на адресній стрічці WS2812B. Я взавтра завантажу і перевірю. Дякую за відповідь. Якщо цікаво - покажу результат і розповім де що замовляти. Поки чекав відповідь - трохи подіставав GPT і він написав новий код більщ-менш підходящий під мої потреби. Якщо цікаво - можу поділитись.

Неактивний

Швидке повідомлення

Введіть повідомлення і натисніть Надіслати

Підвал форуму