Управление светодиодной лентой ws2812b с помощью ик-модуля HX1838

Тема в разделе "Arduino & Shields", создана пользователем szxcxzc, 18 май 2019.

  1. szxcxzc

    szxcxzc Нуб

    Я хочу сделать на светодиодной ленте ws2812b гирлянду(мигалку). Эффекты должны переключаться с помощью пульта. Проект уже собран, программа с тремя простыми эффектами написана и работает. Проблема заключается в том, что эффект длиться всего один раз. Мне нужно что бы эффект длился бесконечно до тех пор, пока не придет сигнал ик-датчика на arduino (пока не нажму на пульте кнопку). Т.е. на каждый эффект своя кнопка на пульте. Сделать я думаю можно с помощью цикла while, но так как я в программировании новичок и с циклами не работал (не писал программы) как сделать это я не знаю. Нужна помощь. Пробовал сделать так:
    Код (C++):
    while (true) {
    //Эффект
    }
    эффект идет бесконечно и не переключается.
    Т.е. нужно дописать программу, что бы эффект длился бесконечно пока не нажму на кнопку (на пульте) со следующим эффектом.
    Программа выглядит так:
    Код (C++):
    #include <IRremote.h>
    IRrecv irrecv(2);
    decode_results results;
    #include <Adafruit_NeoPixel.h>
    #define PIN 6
    #define count_led 60
    #define DELAYVAL 25
    Adafruit_NeoPixel pixels = Adafruit_NeoPixel(count_led, PIN, NEO_GRB + NEO_KHZ800);
    void setup() {
      pixels.begin();
      pixels.show();
      pixels.setBrightness(50);
      irrecv.enableIRIn();
    }
    void loop() {
      if ( irrecv.decode( &results )) { // если данные пришли
    switch ( results.value ) {
    case 0xE318261B :
    //==========================ПЕРВЫЙ ЭФФЕКТ==================================
    for (int i = 0; i < count_led; i++)
      {
        pixels.setPixelColor(i, pixels.Color(255, 0, 0)); // Красный цвет.
      }
      // Передаем цвета ленте.
      pixels.show();
      // Ждем 500 мс.
      delay(500);
      // Выключаем все светодиоды.
      for (int i = 0; i < count_led; i++)
      {
        pixels.setPixelColor(i, pixels.Color(0, 0, 0)); // Черный цвет, т.е. выключено.
      }
      // Передаем цвета ленте.
      pixels.show();
      // Ждем 500 мс.
      delay(500);
    //==========================КОНЕЦ ПЕРВОГО ЭФФЕКТА=============================
    break;
    case 0x511DBB:
    //==========================ВТОРОЙ ЭФФЕКТ====================================
    pixels.clear();
      for(int i=0; i<count_led; i++) {
        pixels.setPixelColor(i, pixels.Color(255, 0, 0));
        pixels.show();
        delay(DELAYVAL);
      }
    //==========================КОНЕЦ ВТОРОГО ЭФФЕКТА=============================
    break;
    case 0xEE886D7F:
    //==========================ТРЕТИЙ ЭФФЕКТ======================================
    pixels.clear();
      for(int i=0; i<count_led; i++) {
        pixels.setPixelColor(i, pixels.Color(0, 255, 255));
        pixels.show();
        delay(DELAYVAL);
      }
    //==========================КОНЕЦ ТРЕТЬЕГО ЭФФЕКТА=========================================================
      break;
    }
    irrecv.resume();
      }
    }
    [​IMG]
     
    Последнее редактирование: 19 май 2019
  2. Daniil

    Daniil Гуру

    Процедура loop и есть тот бесконечный цикл.
    Проблема в том, что вы постоянно читаете что пришло с пульта и выполняете соответствующий эффект.
    Лучше сделать через флаги.
    Пришел код эффекта1, установить флаг1, пришел код эффекта2, установить флаг2(и сбросить флаг1).

    Ещё момент. У вас эффект включается только когда есть входящий код.
    Я бы сделал так:
    Код (C++):
    Void loop()
    {
    if что-то пришло
      {
      код=пришедший код
      }
    switch (код)
      {
      case эффект1: что-то делать1 break;
      case эффект2: что-то делать2 break;
    и т.д.
      }
    }
    т.е. ваш код почти готов)
     
  3. parovoZZ

    parovoZZ Гуру

    Этак никакой памяти не напасёшься. Лучше сделать переменную - вектор таблицы состояния конечного автомата. Одна такая переменная вместит 255 эффектов.
     
  4. Daniil

    Daniil Гуру

    Реализация мною рекомендованных флагов "очень похожа" на состояния конечного автомата
     
  5. szxcxzc

    szxcxzc Нуб

    Не понимаю момент код = пришедший код как это? Можете пожалуйста подробно расписать программу? Просто я не программист и не знаю что такое флаги и как с ними работать.
     
    Последнее редактирование: 19 май 2019
  6. Daniil

    Daniil Гуру

    "код пришедший" - это то, что оказывается в results.value у вас. То, что пришло на ИК приемник. То, что вы отправляете, нажимая кнопку на пульте.
    К сожвлению, нет. Мне проверять не на чем.
    Вам нужно ваш блок switch вытащить из под if.
    Чтобы понять как работает код, советую на листочке расписать чему равны переменные за несколько циклов.
     
  7. b707

    b707 Гуру

    Идею вам расписали в сообщении #2. Вам остается только подставить в эту схему ваш код. "Подробно расписывать вашу программу" вам никто не будет. Если вы не программист - значит придется научиться.

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

    Чтобы решить две проблемы разом - чтоб эффекты уверенно переключались и работали до следующей команды - этот код нужно практически полностью переписывать.
     
  8. parovoZZ

    parovoZZ Гуру

    Начинать надо с алгоритмизации. Даже если алгоритм верно переложен на код, но сам алгоритм не верен - Программа скомпилируется и даже будет работать, но совсем не так, как ожидается.
    Вымучивал конечный автомат. Взял блокнотик программиста и разрисовал все состояния. Сразу же в коде нашёл пару ошибок. Да и дальше код пошёл, как по маслу. 1843A847-7E25-4445-8E8B-C2E226AEDF2F.jpeg
     
  9. ostrov

    ostrov Гуру

    С этой лентой есть проблема. Пока на нее передаются данные, не работает ничего другое, даже прерывания. То есть, если эффект происходит в вечном цикле, шанс поймать команду от пульта будет только между этими отправками. Не знаю насколько это стабильно, скорее всего нет. Лучше всего использовать два МК: один крутит эффекты, второй ловит сигналы и передает простые ни команды на первый, с подтверждением их приема.
     
  10. parovoZZ

    parovoZZ Гуру

    Это не проблема ленты. Это кривая Программа. Или не подходящий МК.
     
  11. Daniil

    Daniil Гуру

    Или размазать эффекты во времени) не использовать делеи. Или проблема аж в библиотечных ф-иях?
     
  12. ostrov

    ostrov Гуру

    Понятно, что без делеев в любом случае надо делать. Остальное зависит от эффекта, если он постоянно меняет картинку, то время на все остальное есть только между "кадрами". Сделать иначе никак, пакет отправляется одним куском частотой 800КГц, малейшая задержка и на ленте фигня. Если МК не многоядерный, конечно, и здесь с т не работают. "ядра" разносят на несколько МК, по 100 руб за штуку. )
     
    Последнее редактирование: 19 май 2019
  13. parovoZZ

    parovoZZ Гуру

  14. ostrov

    ostrov Гуру