Что-то сбрасывается при окончании самого длинного millis

anatonokao
anatonokao аватар
Offline
Зарегистрирован: 23.08.2021

Здравствуйте!

Помогите пожалуйста кое-что.

Написал код с использованием FastLED. Пытаюсь контролировать три куска адресной ленты параллельно отдельно. Проблема вот в чем. Когда самая длинная лента заканчивает свой цикл, остальные сбрасывают свой цвет в начало.

Вот код. Максимально откомментировал, чтобы было проще, если нужен будет видос проблемы, скину:

#include <FastLED.h>

//Количество светодиодов на каждой ленте
#define NUM_LEDS_1 3
#define NUM_LEDS_2 6
#define NUM_LEDS_3 45

//Цвета
CRGB redLeds[NUM_LEDS_1];
CRGB greenLeds[NUM_LEDS_2];
CRGB blueLeds[NUM_LEDS_3];

//Переменные для получения номера светодиодов
byte counter1 = 0;
int counter2 = 0;
int counter3 = 0;

//Переменные для таймеров
unsigned long timing1 = 0;
unsigned long timing2 = 0;

void setup() {
  //Инициализировал три ленты отдельно по пинам
  FastLED.addLeds<NEOPIXEL, 6>(redLeds, NUM_LEDS_1);
  FastLED.addLeds<NEOPIXEL, 5>(greenLeds, NUM_LEDS_2);
  FastLED.addLeds<NEOPIXEL, 7>(blueLeds, NUM_LEDS_3);
}

void loop() {
  //Таймер 1
  if (millis() - timing1 > 20) {
    timing1 = millis();
    ledFirst();
  }
  //Таймер 2
  if (millis() - timing2 > 50) {
    timing2 = millis();
    ledSecond();
  }
}

//Функция для первых двух лент (Радуга)
void ledFirst() {
  for (int i = 0; i < NUM_LEDS_1; i++ ) {
    redLeds[i] = CHSV(counter1 + i * 2, 255, 50);
  }
  for (int i = 0; i < NUM_LEDS_2; i++ ) {
    greenLeds[i] = CHSV(counter2 + i * 2, 255, 50);
  }
  counter1++;
  counter2++;
  FastLED.show();
}

//Функция для третьей ленты (бежит точка с хвостом)
void ledSecond() { 
  blueLeds[counter3] = CHSV(counter3 * 255 / NUM_LEDS_3, 255, 100);
  blueLeds[counter3 - 1] = CHSV(counter3 * 255 / NUM_LEDS_3, 255, 50);
  blueLeds[counter3 - 2] = CHSV(counter3 * 255 / NUM_LEDS_3, 255, 30);
  blueLeds[counter3 - 3] = CHSV(counter3 * 255 / NUM_LEDS_3, 255, 15);
  blueLeds[counter3 - 4] = CHSV(counter3 * 255 / NUM_LEDS_3, 255, 0);
  counter3++;
  if (counter3 >= NUM_LEDS_3) {
    counter3 = 0;
  };
  FastLED.show();
}

Заранее спасибо!

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Как Вы думаете, blueLeds[counter3 - 4] при counter3 == 0 - это где?

b707
Offline
Зарегистрирован: 26.05.2017

Anatonokao, а нафига вторая такая же ветка? Тех отвнтов, что были вчера - недостаточно?

anatonokao
anatonokao аватар
Offline
Зарегистрирован: 23.08.2021

b707 пишет:
Anatonokao, а нафига вторая такая же ветка? Тех отвнтов, что были вчера - недостаточно?

Я в душе не понимаю, что произошло(что админ сделал). У меня еще вчера при публикации ветка сдублировалась, после чего в одной из них я попросил удалить одну, в другой соответственно были ответы. Гляньте на время публикации.

anatonokao
anatonokao аватар
Offline
Зарегистрирован: 23.08.2021

С этой проблемой разобрался. Спасибо большое всем, кто отвечал. Теперь вылезла другая.

Написал еще пару эффектов для этих трех кусков. Выпихал эти функции в отдельный .h и пытаюсь switch их по кнопке(ее тоже пихнул в отдельный .h). Первые два кейса, четвертый и дефолт отрабатывают хорошо, а при переключении на третий происходит вакханалия(явно не то, что я имею в виду). При этом отдельной прошивкой он тоже хорошо отрабатывает. На всякий случай приложу весь имеющийся код, потому что не знаю, где конкретно проблема. Опять же максимально все откомментировал, чтобы было проще.

Вот основной файл с кейсами:

#include <FastLED.h>
#include "button.h"
#include "FastLEDcase.h"

//Переменные для таймеров
unsigned long timing1 = 0;
unsigned long timing2 = 0;
unsigned long timing3 = 0;

// кнопка
button btn1(4);
byte caseLED = 4;

void setup() {
  Serial.begin(9600);
  //Инициилизировал три ленты отдельно по пинам
  FastLED.addLeds<NEOPIXEL, 6>(redLeds, NUM_LEDS_1);
  FastLED.addLeds<NEOPIXEL, 5>(greenLeds, NUM_LEDS_2);
  FastLED.addLeds<NEOPIXEL, 7>(blueLeds, NUM_LEDS_3);
}

void loop() {
  if (btn1.click()) caseLED++; //если кнопка нажата прибавить 1 к caseLED
  switch (caseLED) { //в зависимости от числа caseLED включить соответствующий кейс
    case 1:
      //Таймер 1
      if (millis() - timing1 > 20) {
        timing1 = millis();
        ledFirstRGBD();
      }
      //Таймер 2
      if (millis() - timing2 > 35) {
        timing2 = millis();
        ledSecondRGBD();
      }
      break;
    case 2:
      //таймер 1
      if (millis() - timing1 > 20) {
        timing1 = millis();
        ledFirstRGBS();
      }
      break;
    case 3:
      //таймер 1
      if (millis() - timing1 > 40) {
        timing2 = millis();
        ledFirstRGBDBlue();
      }
      //Таймер 3
      if (millis() - timing2 > 40) {
        timing3 = millis();
        ledSecondRGBDBlue();
      }
      break;
    case 4:
      ledSecondRGBBlack();
      break;
    default:
      caseLED = 1;
      break;
  }
}

Вот .h с функциями:

//Количество светодиодов на каждой ленте
#define NUM_LEDS_1 3
#define NUM_LEDS_2 6
#define NUM_LEDS_3 45

//Цвета
CRGB redLeds[NUM_LEDS_1];
CRGB greenLeds[NUM_LEDS_2];
CRGB blueLeds[NUM_LEDS_3];

//Переменные для получения номера светодиодов
byte counter1 = 0;
int counter2 = 0;
int counter3 = 0;
byte colorPick;

//--------------------------функции первого кейса------------------------------
//функция для первых двух лент
void ledFirstRGBD() {
  static int dir = 1;
  static int bright = 0;
  for (int i = 0; i < NUM_LEDS_1; i++ ) {
    redLeds[i] = CHSV(counter1 + i * 5, 255, bright);
  }
  for (int i = 0; i < NUM_LEDS_2; i++ ) {
    greenLeds[i] = CHSV(counter2 + i * 5, 255, bright);
  }
  counter1++;
  counter2++;
bright += dir * 2;

  if (bright > 150) {
    bright = 150;
    dir = -1;
  }
  if (bright < 0) {
    bright = 0;
    dir = 1;
  }
  FastLED.show();
}

//функция для третьей ленты
void ledSecondRGBD() {
  if (counter3 <= NUM_LEDS_3) {
    blueLeds[counter3] = CHSV(colorPick + counter3 * 10, 255, 255);;
    counter3++;
  Serial.println(colorPick);
  }
  if (counter3 >= NUM_LEDS_3) {
    blueLeds[counter3 - 45] = CRGB::Black;
    counter3++;
  }
  if (counter3 >= NUM_LEDS_3 * 2) {
    counter3 = 0;
    colorPick = random(100, 300);
  }
  FastLED.show();
}

//--------------------------функция второго кейса------------------------------
//функция для всех трех лент
void ledFirstRGBS() {
  for (int i = 0; i < NUM_LEDS_1; i++ ) {
    redLeds[i] = CHSV(counter1 + i * 5, 255, 50);
  }
  for (int i = 0; i < NUM_LEDS_2; i++ ) {
    greenLeds[i] = CHSV(counter2 + i * 5, 255, 50);
  }
  for (int i = 0; i < NUM_LEDS_3; i++ ) {
    blueLeds[i] = CHSV(counter3 + i * 5, 255, 200);
  }
  counter1++;
  counter2++;
  counter3++;
  FastLED.show();
}

//--------------------------функции третьего кейса------------------------------
//функция для первых двух лент
void ledFirstRGBDBlue() {
  static int dir = 1;
  static int bright = 0;
  for (int i = 0; i < NUM_LEDS_2; i++ ) {
    greenLeds[i] = CHSV(160, 255, bright);
    redLeds[i] = CHSV(160, 255, bright);
  }
  if (counter2 < NUM_LEDS_2) {
    counter2++;
  }
  bright += dir * 5;

  if (bright > 150) {
    bright = 150;
    dir = -1;
  }
  if (bright < 0) {
    bright = 0;
    dir = 1;
  }
  FastLED.show();
}

//функция для третьей ленты
void ledSecondRGBDBlue() {
  blueLeds[counter3] = CRGB::Blue;
  if (counter3 > 2) {
    blueLeds[counter3 - 3] = CRGB::Black;
  }
  counter3++;
  if (counter3 >= NUM_LEDS_3) {
    counter3 = 0;
  };
  FastLED.show();
}

//--------------------------функции четвертого кейса------------------------------
//функция для всех лент
void ledSecondRGBBlack() {
  for (int i=0; i <= 36; i++) {
  blueLeds[i] = CRGB::Black;
  redLeds[i] = CRGB::Black;
  greenLeds[i] = CRGB::Black;
  }
  FastLED.show();
}

И .h кнопки на всякий случай:

class button {
  public:
    button (byte pin) {
      _pin = pin;
      pinMode(_pin, INPUT_PULLUP);
    }
    bool click() {
      bool btnState = digitalRead(_pin);
      if (!btnState && !_flag && millis() - _tmr >= 100) {
        _flag = true;
        _tmr = millis();
        return true;
      }
      if (!btnState && _flag && millis() - _tmr >= 500) {
        _tmr = millis ();
        return true;
      }
      if (btnState && _flag) {
        _flag = false;
        _tmr = millis();
      }
      return false;
    }
  private:
    byte _pin;
    uint32_t _tmr;
    bool _flag;
};

Помогите пожалуйста, люди добрые! Битый час сижу!

Заранее спасибо!

sadman41
Offline
Зарегистрирован: 19.10.2016

Если бы в той теме Вам сразу бы не показали проблему, то Вы бы научились дебажить свой код и локализовать ошибки.

Поэтому снова без вызываемой в case 3 функции все работает? Если её заменить на простую типа fill() // не помню, как там в фастледе заливка страйпа // все работает нормально?

b707
Offline
Зарегистрирован: 26.05.2017

> с этой проблемой разобрался, теперь вылезла другая.....
Anatonokao, вы совсем идиот? С чем вы разобрались, какая "другая проблема"?
Ошибка та же что вчера, только теперь в другой функции

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

Неужели я дождался переполнения millis()? Пипец...

 

b707
Offline
Зарегистрирован: 26.05.2017

mykaida пишет:

Неужели я дождался переполнения millis()? Пипец...

 


че, там еще и переполнение?:)

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

b707 пишет:
че, там еще и переполнение?:)

А нахера тогда сбрасывать?

b707
Offline
Зарегистрирован: 26.05.2017

Да у него просто мк перенружается...

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

b707 пишет:
Да у него просто мк перенружается...

Я тут себе win10 поставил. Просто автокад на линуксе не пашет. Похоже, что его писали тоже "пинововцы"

anatonokao
anatonokao аватар
Offline
Зарегистрирован: 23.08.2021

b707 пишет:
> с этой проблемой разобрался, теперь вылезла другая..... Anatonokao, вы совсем идиот? С чем вы разобрались, какая "другая проблема"? Ошибка та же что вчера, только теперь в другой функции

Дядь, Вы зачем такой агрессивный? Мб Вы >идиот, учитывая Вашу гениальную идею заходить в песок и токсичить на людей из-за их непонимания?))

anatonokao
anatonokao аватар
Offline
Зарегистрирован: 23.08.2021

sadman41, спасибо. Попробую.

mykaida, я понимаю, что надо обнулять, просто не совсем понимаю где это делать, по клику кнопки?

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

anatonokao пишет:

mykaida, я понимаю, что надо обнулять, просто не совсем понимаю где это делать, по клику кнопки?

Не - Вы меня не поняли. Не надо обнулять, а надо перезаписывать oldmillis. Переменная так называется.

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

Если Вы хотите получить реальное тактирование - посмотрите в "проектах" мой "термостат". Там я исходил из реального времени. (сейчас забросают)

anatonokao
anatonokao аватар
Offline
Зарегистрирован: 23.08.2021

mykaida пишет:

Если Вы хотите получить реальное тактирование - посмотрите в "проектах" мой "термостат". Там я исходил из реального времени. (сейчас забросают)

Спасибо, гляну обязательно.

Всем большое спасибо за ответы. Опытным путем понял, где ошибка и исправил.

b707
Offline
Зарегистрирован: 26.05.2017

anatonokao пишет:

Опытным путем понял, где ошибка и исправил.


"понял и исправил" как в прошлый раз ? А завтра снова придешь с той же проблемой?
Давай рассказывай что понял

anatonokao
anatonokao аватар
Offline
Зарегистрирован: 23.08.2021

 

Цитата:
"понял и исправил" как в прошлый раз ? А завтра снова придешь с той же проблемой? Давай рассказывай что понял

Дядь, там помимо выхода за границу массива, была ошибка с таймингами из-за которой вообще не было видно этого самого выхода, и соответственно проблема, которую я не понимал была именно в них, а не в массиве.

      if (millis() - timing1 > 40) {
47
        timing2 = millis();
48
        ledFirstRGBDBlue();
49
      }
50
      //Таймер 3
51
      if (millis() - timing2 > 40) {
52
        timing3 = millis();
53
        ledSecondRGBDBlue();
54
      }

Откисай))