Задать вопрос
Wolf_Yout
@Wolf_Yout

Esp8266 fastled в циклах for для заполнения всей ленты почему то иногда заполняется только первый светодиод, как решить?

5 файлов:
adress_strip_WiFi.ino(главный файл)
#define ssid_wf "" // SSID вайфай сети
#define pass_wf "" // Пароль сети, если нету то оставляем пустым.
#define PIN D3 // Пин куда подключена гирлянда
#define NUM_LEDS 50 // Кол-во светодиодов
bool debug = false; // Вкл/выкл отладку. true = вкл, false = выкл

// Значения во всех переменных ниже - ставятся по умолчанию, меняйте, если требуется
bool pwr = true; // Питание
int bright = 255; // Яркость
int effect = 0; // Эффект
bool auto_switch = 0; // Авто-смена эффекта
int time_switch = 5; // Время авто-смены эффекта в минутах
int speed = 10; // Скорость
int zoom = 10; // Масштаб
int color = 0; // Цвет

#include <FastLED.h> // import fastled
#include <GyverHub.h> // import GyverHub(UI interaction)
#include <ESP8266WiFi.h> // import WiFi lib
CRGB leds[NUM_LEDS];
GyverHub hub("MyDevices", "Гирлянда", "✹");

bool st_st;

void setup() {
  if (debug) Serial.begin(115200);
  FastLED.addLeds<WS2811, PIN, RGB>(leds, NUM_LEDS);
  FastLED.setBrightness(bright);
  FastLED.clear();
  WiFi.begin(ssid_wf, pass_wf);
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    for (int i=0;i<NUM_LEDS;i++) leds[i] = CHSV(91, 255, st_st ? 255 : 0);
    FastLED.show();
    st_st = !st_st;
    delay(300);
  }
  if (debug) {
    Serial.println();
    Serial.print("Connected! My IP: ");
    Serial.println(WiFi.localIP());
  }
  hub.onBuild(build);
  hub.begin();
}

void loop() {
  hub.tick();
  play();
}

actions.ino
void bright_sld() {
  FastLED.setBrightness(bright);
  FastLED.show();
}

autoswitch.ino
uint32_t tmr;

void changed_autosw() { // Функция, чтобы когда мы ВКЛЮЧАЕМ автосмену, таймер восстанавливается
  if (auto_switch and pwr) tmr = millis();
}

void check_autosw() { // Функция проверяющая что там с таймером
  if (millis() - tmr >= time_switch * 60000) {
    tmr = millis();
    effect++;
    if (effect > 4) effect = 0;
  }
}

builder.ino
void build(gh::Builder& b) {
  if (b.beginRow()) {
    b.Switch(&pwr).label("Питание").size(1).attach(changed_autosw);
    b.Slider(&bright).label("Яркость").size(4).range(1, 255, 1).attach(bright_sld);
  }
  b.endRow();
  b.Select(&effect).text("Радуга;Резкое мерцание;Плавное мерцание;Радужный Стробоскоп; Одноцветный стробоскоп;Шум перлина; Огонь").label("Выбор эффекта");
  if (b.beginRow()) {
    b.Switch(&auto_switch).label("Авто-смена эффектов.").size(1).attach(changed_autosw); // Вызываем восстановление таймера
    b.Slider(&time_switch).label("Время (минуты)").size(4).range(1, 240, 1).attach(changed_autosw); // тоже самое
  }
  b.endRow();
  if (b.beginRow()) {
    b.Slider(&speed).label("Скорость").range(1, 20, 1);
    b.Slider(&zoom).label("Масштаб(Для эффектов с поддержкой)").range(1, 20, 1);
  }
  b.endRow();
  b.Slider(&color).label("Цвет(Для эффектов с поддержкой)").range(0, 255, 1);
}

effects.ino
void play() {
  if (!pwr) {
    FastLED.clear();
    FastLED.show();
  } else {
    if (auto_switch) check_autosw(); // Вызов проверки таймера
    switch (effect) {
      case 0: movement_rainbow(); break;
      case 1: flash(); break;
      case 2: smooth_flash(); break;
      case 3: colored_stroboscope(); break;
      case 4: color_stroboscope(); break;
      case 5: perlin_noise(); break;
      case 6: perlin_fire(); break;
    }
  }
}

void movement_rainbow() {
  static byte counter;
  static uint32_t tmr;
  if (millis() - tmr >= speed) {
    tmr = millis();
    FastLED.clear();
    for (int i = 0; i < NUM_LEDS; i++) {
      leds[i] = CHSV(counter + i * zoom, 255, 255);
    }
    FastLED.show();
    counter++;
  }
}

void flash() {
  static bool status;
  static uint32_t tmr;
  if (millis() - tmr >= speed * 20) {
    tmr = millis();
    FastLED.clear();
    status = !status;
    if (status) {
      for (int i=0;i<NUM_LEDS;i++) {
        leds[i] = CHSV(color, 255, 255);
      }
      FastLED.show();
    } else {
      for (int i=0;i<NUM_LEDS;i++) leds[i] = CHSV(color, 255, 0);
      FastLED.show();
    }
  }
}

void smooth_flash() {
  static int val = 100;
  static bool dir;
  static uint32_t tmr;
  if (millis() - tmr >= speed) {
    tmr = millis();
    if (val <= 1 or val >= 255) dir = !dir;
    if (dir) val++;
    if (!dir) val--;
    for (int i=0;i<NUM_LEDS;i++) {
      leds[i] = CHSV(color, 255, val);
    }
    FastLED.show();
  }
}

void colored_stroboscope() {
  static byte color;
  static uint32_t tmr;
  static bool st;
  if (millis() - tmr >= speed * 3) {
    tmr = millis();
    st = !st;
    if (!st) color += zoom * 5;
    for (int i=0;i<NUM_LEDS;i++) leds[i] = CHSV(color, 255, st ? 255 : 0);
    FastLED.show();
  }
}

void color_stroboscope() {
  static bool st;
  static uint32_t tmr;
  if (millis() - tmr >= speed * 3) {
    tmr = millis();
    for (int i=0;i<NUM_LEDS;i++) leds[i] = CHSV(color, 255, st ? 255 : 0);
    FastLED.show();
    st = !st;
  }
}

void perlin_noise() {
  static uint32_t tmr;
  static int counter;
  if (millis() - tmr >= speed * 2) {
    tmr = millis();
    for (int i=0;i<NUM_LEDS;i++) leds[i] = CHSV(inoise8(i * zoom, counter), 255, 255);
    counter += 5;
    FastLED.show();
  }
}

void perlin_fire() {
  static uint32_t tmr;
  static int counter;
  if (millis() - tmr >= speed * 2) {
    tmr = millis();
    for (int i=0;i<NUM_LEDS;i++) {
      int val = inoise8(i * zoom * 2, counter);
      int h = color + map(val, 0, 255, 0, 21);
      int s = constrain(map(val, 0, 255, 255, 245), 0, 255);
      int v = constrain(map(val, 0, 255, 70, 255), 0, 255);
      leds[i] = CHSV(h, s, v);
    }
    counter += 10;
    FastLED.show();
  }
}


В вот этом цикле почему то чуть ли не постоянно мигает только первый светодиод, но иногда все таки заполняется вся лента:
while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    for (int i=0;i<NUM_LEDS;i++) leds[i] = CHSV(91, 255, st_st ? 255 : 0);
    FastLED.show();
    st_st = !st_st;
    delay(300);
  }

Тоже самое в этой функции, но уже почти всегда мелькает вся лента, но иногда мигает только первый светодиод
void flash() {
  static bool status;
  static uint32_t tmr;
  if (millis() - tmr >= speed * 20) {
    tmr = millis();
    FastLED.clear();
    status = !status;
    if (status) {
      for (int i=0;i<NUM_LEDS;i++) {
        leds[i] = CHSV(color, 255, 255);
      }
      FastLED.show();
    } else {
      for (int i=0;i<NUM_LEDS;i++) leds[i] = CHSV(color, 255, 0);
      FastLED.show();
    }
  }
}

как сделать, чтобы всегда мелькала вся лента? GyverHUB не знаю, причастен или нет своей синхронизацией, но я склоняюсь к тому что он не виноват, т.к. даже если на всех устройствах закрыть его, все равно иногда мелькает только первый светодиод...
  • Вопрос задан
  • 101 просмотр
Подписаться 2 Простой Комментировать
Пригласить эксперта
Ответы на вопрос 2
@kalapanga
Баг известный. Вот здесь вроде даже что-то придумали: Работает только первый светодиод ws2812 при подклю... (в суть решения я не вникал, просто случайно вспомнилось, что где-то я это уже видел)
Ответ написан
nava2002
@nava2002
Инженер
Я использую другой метод организации цикла.
Всегда работает.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы