Адресная лента

Тема в разделе "Arduino & Shields", создана пользователем sanya0017, 25 ноя 2020.

  1. sanya0017

    sanya0017 Нуб

    Задача такая.
    Нужно, чтобы при нажатии на кнопку, лента "дорожкой" загоралась и продолжала вся светиться, пока не отпущу кнопку, тогда она обратной дорожкой должна погаснуть.
    Тыкался много часов, лучшее, что я добился, это тот или иной эффект, но совместить их не получилось. загорается вся и в итоге обратно не тухнет.. Может кто помочь скетчем?
     
  2. a1000

    a1000 Гуру

    Ну так покажите чего добитлись.
     
  3. b707

    b707 Гуру

    500 руб :)
     
  4. parovoZZ

    parovoZZ Гуру

  5. sanya0017

    sanya0017 Нуб

    Вот код, который у меня работает "наполовину"
    Код (C++):
    #define STRIP_PIN 10
    #define NUMLEDS 40
    #include <microLED.h>
    microLED< NUMLEDS, STRIP_PIN, LED_WS2815, ORDER_GRB, CLI_AVER> strip;
    const int buttonPin = 6;
    int buttonState = 0;
    void setup() {
      strip.setBrightness(255);
      pinMode(buttonPin, INPUT);
    }
    void loop() {
       buttonState = digitalRead(buttonPin);
      if (buttonState == HIGH) {  
    up();
      }

      if (buttonState == LOW) {  
    down();
    }
      strip.show();
      delay(30);
    }
    void up() {
      static int counter = 0;
      strip.clear();
      strip.fill(0, counter, mRed);
      counter++;
      if (counter >= NUMLEDS) counter = NUMLEDS;
    }

    void down() {
      static int counter = NUMLEDS;
      strip.clear();
      strip.fill(0, counter, mWhite);
      counter--;
      if (counter <=0) counter = -1;
    }
     
     
  6. a1000

    a1000 Гуру

    Я с библиотекой microLED не работал. Сейчас ознакомился с ней бегло. Глядя на ваш код я не понимаю, про какую "половину" вы говорите? Оно не должно работать вообще. Опустим инициализацию ленты, наверное там правильно. Переходим в основной цикл. При нажатии кнопки вы вызываете функцию up.
    Код (C++):
    void up() {
      static int counter = 0;
      strip.clear();
      strip.fill(0, counter, mRed);
      counter++;
      if (counter >= NUMLEDS) counter = NUMLEDS;
    }
    В ней вы обнуляете counter, очищаете буфер, и командой strip.fill(0, counter, mRed) записываете в буфер - залить красным цветом светодиоды с номера 0 по counter. Потом инкреминируете counter, проверяече, что-бы counter не вышел за пределы числа светодиодов в ленте и возвращаетесь в основной цикл. Там вы командой strip.show() запуливаете содержимое буфера в ленту, ждёте 10 милисекунд и снова в начало loop. Кнопка по прежнему нажата, по этому снова в up. А там снова
    Код (C++):
    static int counter = 0;
    Так-что далее светодиода под номером ноль вы не сдвинетесь.
    В функцию down я даже не заглядывал.
     
  7. sanya0017

    sanya0017 Нуб

    Не должно, но полуработает. Код взял из примера алекса гайвера и попытался его адаптировать под себя. Не получилось. Буду тыкаться далее))
     
  8. Feofan

    Feofan Нерд

    static...
     
    parovoZZ нравится это.
  9. b707

    b707 Гуру

    не обнуляет
     
  10. b707

    b707 Гуру

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

    Угадал?
     
  11. sanya0017

    sanya0017 Нуб

    да, должно работать так, но по факту работает не до конца. с отключенной кнопкой белым с конца в начало уходит, как и должно, при нажатии так же красным до заполнения, как и должно, НО: по какой-то причине на этом происходит затык, если дать красному дойти до последнего диода, то больше на нажатие-отпускание кнопки ардуинка не реагирует. А если не дать красному всё заполнить и отпустить раньше, то всё работает как надо, пока не заполнится всё красным..
    PS если кому интересно - это подсветка плинтуса, когда основной свет включают, сигнал пойдёт на ардуинку (вместо кнопки), лента зажжется заполнением полностью, а когда выключат свет, лента обратным заполнением погаснет.
    PSS кнопка к земле разумеется подтянута
     
    Последнее редактирование: 26 ноя 2020
  12. a1000

    a1000 Гуру

    Возможно я что-то недопонимаю. Но разве после строки
    Код (C++):
    static int counter = 0;
    переменная counter не должна стать равной нулю? Что-то я начинаю сильно путаться в Си.
    Я тут как раз с такой лентой эксперементирую на самоизоляции. Для общего развития набросал на ASM зажигание и гашение ленты как хотел ТС, но без кнопок.

     
  13. sanya0017

    sanya0017 Нуб

    Кстати, если сюда в конце if добавить через запятую "loop()", то всё работает, но белый соответственно бегает циклично. За то нет затыка на красном))

    Код (C++):
    void down() {
      static int counter = NUMLEDS;
      strip.clear();
      strip.fill(0, counter, mWhite);
      counter--;
      if (counter <=0) counter = -1,loop();
    }
     
  14. sanya0017

    sanya0017 Нуб

    я сам не очень, вернее очень не, соображаю в си, в частности в ардуино иде, только поверхностно, но мне кажется, не даёт снова обнулиться каунтеру именно "static" int
     
  15. sanya0017

    sanya0017 Нуб

    Сел, подумал и решил проблему подумав логически, но почему так происходит, я так и не понял.
    Вот тут если сравнивать counter не с NUMLEDS, а отнять от него единицу (NUMLEDS-1), то всё начинает работать так, как и задумано. Почему - мне не ясно, но всё заработало)
    Код (C++):
    void up() {
      strip.clear();
      strip.fill(0, counter, mWhite);
      counter++;
      if (counter >= NUMLEDS-1) counter = NUMLEDS;
    }
    **********************

    Если кому ещё захочется сделать "такое", вот код с подробным описанием, как смог


    Код (C++):
    // Sanya0017, за основу взят код из примера описания библиотеки microLED от AlexGyver
    #define STRIP_PIN 10 // пин, к которому подключена лента
    #define NUMLEDS 40  // количество светодиодов
    #include <microLED.h> // подключение библиотеки microLED (3 версия)
    microLED< NUMLEDS, STRIP_PIN, MLED_NO_CLOCK, LED_WS2815, ORDER_GRB, CLI_AVER> strip; // инициализация ленты
    const int buttonPin = 6;  // пин, к которому подключена кнопка
    int buttonState = 0; // состояние кнопки
    int counter = 0; // счётчик
    int counteer = NUMLEDS; // второй счётчик
    void setup() {
      pinMode(buttonPin, INPUT); // настраиваем пин кнопки на "вход"
    }
    void loop() {
       buttonState = digitalRead(buttonPin); // слушаем кнопку
      if (buttonState == HIGH) { // если нажата, то делаем:
        counteer = NUMLEDS;  // закидываем во второй счётчик количество светодиодов
    up(); // переходим в void up()
      }
      if (buttonState == LOW) {   // если не нажата, то делаем:
        counter = 0; //закидываем в счётчик 0
    down(); // переходим в void down()
    }
    strip.setBrightness(50); // устанавливаем яркость
      strip.show(); // вывод изображения на ленту
      delay(30); // задержка (устанавливает fps)
    }
    void up() {
      strip.clear(); // очищаем ленту
      strip.fill(0, counter, mWhite); // заливаем ленту цветом (mWhite) с 0 диода по номеру диода, находящемуся в счётчике
      counter++; // добавляем к счётчику единицу
      if (counter >= NUMLEDS-1) counter = NUMLEDS; // если счётчик выше или равен значения NUMLEDS-1, то кидаем в него значение NUMLEDS, чтобы не пыталось считать дальше
    }
    void down() {
      strip.clear(); // очищаем ленту
      strip.fill(0, counteer, mWhite); // заливаем ленту с 0 диода по номеру диода, находящемуся в счётчике
      counteer--; // отнимаем от счётчика единицу
      if (counteer <=0) counter = -1; //если счётчик меньше либо равен 0, то кидаем в него значения -1 (со значением 0 будет гореть первый диод), чтобы не пыталось считать дальше
    }
     
     
    Последнее редактирование: 26 ноя 2020
  16. b707

    b707 Гуру

    Статические переменные инициализируются один раз - при первом заходе в функцию. Далее они сохраняют свое значение между запусками функции... на то они и "статические"
     
  17. b707

    b707 Гуру

    нелогичная фраза :)
    "Подумав логически" и "так и не понял" - несовместимо.
    То что вы сделали, называется иначе - "поменял наобум - а оно и заработало" :)

    Кстати, я вижу что вы не только поменяли NUMLEDS на NUMLEDS-1, но и сделали переменную counter общей в обоих процедурах. Это, кстати, могло иметь решающее значение.

    Причина, почему смена NUMLEDS на NUMLEDS-1 могла сказаться на работе - в кривости Гайверовской либы microled
    Когда вы используете процедуру
    Код (C++):
    strip.fill(0, counter, mWhite);
    - микроЛЕД не проверяет, лежат ли заданные индексы "внутри" ленты. Поскольку в ленте длиной NUMLEDS пикселей последний диод имеет индекс NUMLEDS-1 (индексы ведь считаются с нуля) - то когда вы пытаетесь запустить fill от 0 до NUMLEDS - вы попадаете за границу массива и "распахиваете" память.
    Кстати, правильнее будет поставить NUMLEDS-1 не только в условии, но и в присваивании счетчику::
    Код (C++):
    void up() {
      strip.clear(); // очищаем ленту
      strip.fill(0, counter, mWhite); // заливаем ленту цветом (mWhite) с 0 диода по номеру диода, находящемуся в счётчике
      counter++; // добавляем к счётчику единицу
      if (counter >= NUMLEDS-1) counter = NUMLEDS-1; // если счётчик выше или равен значения NUMLEDS-1, то кидаем в него значение NUMLEDS, чтобы не пыталось считать дальше
    }
    В либах Гайвера куча подобных ляпов, когда есть альтернатива - советую выбирать другие библиотекию Для вашего примера лучше было взять FastLED
     
    Последнее редактирование: 26 ноя 2020
  18. sanya0017

    sanya0017 Нуб

    Не совсем) я логическим путём понял, в какой именно момент происходит зависание и понял из-за чего, но почему - не понял, но вы объяснили про отсчёт не с 1, а с 0 и недоделку библиотеки, которая позволяет в этом случае всему крашиться, спасибо).
    Первый пример, который я нашёл, был как раз на микролед, а т.к. я что-то на фастледе делал с год-два назад, то я совсем забыл что там и как и решил остановиться на этом
    Пробую сижу бегущую радугу сделать, а не заливку, пока получилась только статичная радуга, но с заполнением xD
     
    Последнее редактирование: 26 ноя 2020
  19. a1000

    a1000 Гуру

    Чего только люди не придумают что-бы самим головой не думать.:):):):)
     
    parovoZZ нравится это.