Мучаю умную ленту ws2811 aka проблема со скетчем

Тема в разделе "Arduino & Shields", создана пользователем moonlight1, 6 ноя 2016.

Метки:
  1. moonlight1

    moonlight1 Нерд

    Доброго дня. Потихоньку мучаю ленту чтобы сделать подсветку коридора. Можно было бы обойтись простой лентой без адресации, но есть такая, а на другую деньги тратить не хочется.
    Есть ардуино нано, 2 pir датчика, 5 метров ленты с адресацией.
    Необходимо чтобы при срабатывании первого датчика(501) светодиодная лента зажигается с 0 по n светодиоды. Когда время работы первого датчика заканчивается он посылает сигнал на выключение ленты, лента должна выключиться с n по 0 диода(т.е. в обратном порядке).
    Когда срабатывает второй датчик(502) лента зажигается с n по 0, а гаснет с 0 по n(опять же обратный порядок). у меня получается конфликт с тушением светодиодов.
    есть еще один вариант это плавное увеличение яркости, но как это сделать я не знаю. пробовал в цикле наращивать Brightness но нечего не выходило... Собственно схема и код ниже.
    [​IMG]
    Код (C++):
    #include "FastLED.h"
    int calibrationTime = 30;
    //Время, в которое был принят сигнал отсутствия движения(LOW)
    long unsigned int lowIn;
    //Пауза, после которой движение считается оконченным
    long unsigned int pause = 5000;
    //Флаг. false = значит движение уже обнаружено, true - уже известно, что движения нет
    boolean lockLow = true;
    //Флаг. Сигнализирует о необходимости запомнить время начала отсутствия движения
    boolean takeLowTime;

    #define NUM_LEDS 50 //кол-во пачек светодиодов по 3шт для ws2811; для ws2812 указывать общее кол-во светодиодов
    #define DATA_PIN 3 //пин куда подключен адресный вход ленты
    CRGB leds[NUM_LEDS];
    int pir1Pin = 2; //пин куда подключен первый пирометрический датчик
    int pir2Pin = 4; //пин куда подключен второй пирометрический датчик

    void setup()
    {
      Serial.begin(9600);
      FastLED.addLeds<WS2811, DATA_PIN, BRG>(leds, NUM_LEDS);
      LEDS.setBrightness((100 % 255)); //яркость ленты
      pinMode(pir1Pin, INPUT);//настраиваем датчики
      pinMode(pir2Pin, INPUT);//на вход
      FastLED.show();//гасим все светодиоды при первом запуске ленты
      //дадим датчику время на калибровку
      Serial.print("Calibrating");
      for (int i = 0; i < calibrationTime; i++)
      {
        Serial.print(".");
        delay(1000);
      }
      Serial.println(" done");
      Serial.println("SENSOR ACTIVE");
      delay(50);
    }

    void loop() {

      //1й датчик
      int pir1Val = digitalRead(pir1Pin); //1
      int pir2Val = digitalRead(pir2Pin); //2
      //Если обнаружили движение
      if (pir1Val == HIGH)
      {
        if (pir2Val == LOW)
        {
          for (int i = 0; i < NUM_LEDS; i++) //зажигаение светодиода с первого по последний
          {
            leds[i] = CRGB(0, 150, 0);
            FastLED.show();
            //leds[i] = CRGB::Black;
            delay(125);
          }
        }
      }
      else
      {
        if (pir1Val == LOW && pir2Val == LOW)
        {
          for (int i = NUM_LEDS - 1; i >= 0; i--) //гашение светодиодв с последнего по первый
          { //leds[i] = CRGB::Orange;
            FastLED.show();
            leds[i] = CRGB::Black;
            delay(100);
          }
        }
      }

      //2й датчик
      //Если обнаружили движение
      if (pir2Val == HIGH)
      {
        if (pir1Val == LOW)
        {
          for (int i =  NUM_LEDS - 1; i >= 0; i--) //зажигаение светодиода с последнего по первый
          {
            leds[i] = CRGB(0, 150, 0);
            FastLED.show();
            //leds[i] = CRGB::Black;
            delay(125);
          }
        }
      }
      else
      {
        if (pir1Val == LOW && pir2Val == LOW)
        {
          for (int i = 0; i < NUM_LEDS;  i++) //гашение светодиода с первого по последний
          {
            //leds[i] = CRGB::Orange;
            FastLED.show();
            leds[i] = CRGB::Black;
            delay(100);
          }
        }
      }
    }
    ЗЫ.: да на схеме лента ws2812b, но как говорится "я его слепила из того что было"
    Код конечно та еще дичь, но что имеем, то имеем
     

    Вложения:

  2. ostrov

    ostrov Гуру

    С такими лентами работаю готовыми пакетами. То есть в некоем массиве создаю то изображение какое надо на установленное кол-во пикселей, а уж его вывожу одной командой. И так по кругу. Остается лишь правильно формировать картинку в "массиве". А это, вроде бы не сложно.
     
    ДеКодер нравится это.
  3. moonlight1

    moonlight1 Нерд

    хм, спасибо попробую покопать в данном направлении
    а пример какой-нибудь дадите чтобы было яснее?
    просто если подавать с массив на ленту то все равно при "гашении" диодов с помощью отработки датчиков движения мне кажется такая же фигня будет как и у меня )
    будет срабатывать гашение диодов для первого датчика даже когда закончил работать второй.
     
    Последнее редактирование: 6 ноя 2016
  4. ostrov

    ostrov Гуру

    "Гашение" это подача на ленту нулевых сигналов, ничем не отличается от другого цвета. Так же управляется по вашему желанию.
     
  5. Tomasina

    Tomasina Сушитель лампочек Модератор

    при срабатывании датчик посылает 1 или 0?
    Вот для варианта, когда датчик посылает 1 при движении:
    Код (C++):
    #include "FastLED.h"                    // https://github.com/FastLED/FastLED

    #define DATA_PIN                8       // APA102(DI) / WS2812B(DI)
    #define CLOCK_PIN               4       // APA102(CI)
    #define SENSOR1                 3       // к датчику движения
    #define SENSOR2                 2       // к датчику движения

    #define NUM_LEDS                60      // количество светодиодов на ленте
    #define SPEED                   48      // скорость включения
    #define LED_TYPE                WS2811  // тип ленты
    #define COLOR_ORDER             GRB     // порядок распайки светодиодов на ленте
    #define OFFTIME                 20      // задержка перед выключением ленты, сек
    byte    ledBrightness =         64;     // яркость ленты (1...255)

    #define LEFT                    0
    #define RIGHT                   1
    #define OFF                     0
    #define ON                      1
    #define MOTION_DETECTED(SENSOR) (digitalRead(SENSOR))
    #define TIMEOUT(sensorTime)     ((millis() - sensorTime > OFFTIME * 1000UL))
    unsigned long timeSensor1, timeSensor2; // переменные для хранения времени начала сработки сенсора

    CRGB leds[NUM_LEDS];

    void setup()
    {
      Serial.begin(9600);
      pinMode(SENSOR1, INPUT);  // при сработке датчика (обнаружено движение) идет 1
      pinMode(SENSOR2, INPUT);
      FastLED.addLeds<LED_TYPE, DATA_PIN, COLOR_ORDER>(leds, NUM_LEDS);
      FastLED.setBrightness(ledBrightness);
      // testLEDstrip();  // проверка ленты
      // testDirection(); // проверка направления
      Serial.println("Ready");
    }


    void ledManager(boolean dir, boolean state)  // черный ящик с входными параметрами - направление (направо/налево) и действие (вкл/выкл)
    {
      for (byte i = dir * NUM_LEDS; i != NUM_LEDS - dir * NUM_LEDS;) // ленивый цикл, сам все формирует :)
      {
        leds[!dir ? i++ : --i] = CRGB(255 * state, 255 * state, 255 * state); // специально для ИгорьК - одна строка вместо 12 ;o)
        FastLED.show();
        if (state == OFF && MOTION_DETECTED(SENSOR1)) break;  // если подсветка гаснет, а обнаружено движение, то прекращаем гасить
        if (state == OFF && MOTION_DETECTED(SENSOR2)) break;
        delay(SPEED);
      }
    }


    void loop()
    {
      if (MOTION_DETECTED(SENSOR1))
      {
        Serial.println(F("Sensor 1: Motion detected"));
        timeSensor1 = millis();       // запоминаем время сработки датчика 1
        ledManager(LEFT, ON);         // включаем подсветку справа налево (от датчика 1)
        timeSensor2 = millis();
      }

      if (MOTION_DETECTED(SENSOR2))
      {
        Serial.println(F("Sensor 2: Motion detected"));
        timeSensor2 = millis();       // запоминаем время сработки датчика 2
        ledManager(RIGHT, ON);        // включаем подсветку слева направо (от датчика 2)
        timeSensor1 = millis();
      }

      if (TIMEOUT(timeSensor1))       // если с момента сработки датчика 1 прошло много времени
      {
        if (!MOTION_DETECTED(SENSOR1) && !MOTION_DETECTED(SENSOR2))  // И сейчас никакого движения нет
        {
          Serial.println(F("Sensor 1: Timeout"));
          ledManager(LEFT, OFF);      // отключаем подсветку справа налево (от датчика 1)
        }
      }

      if (TIMEOUT(timeSensor2))       // если с момента сработки датчика 2 прошло много времени
      {
        if (!MOTION_DETECTED(SENSOR1) && !MOTION_DETECTED(SENSOR2))  // И сейчас никакого движения нет
        {
          Serial.println(F("Sensor 2: Timeout"));
          ledManager(RIGHT, OFF);     // отключаем подсветку слева направо (от датчика 2)
        }
      }
    }


    void testDirection()
    {
      ledManager(LEFT, ON);       // включаем подсветку справа налево (от датчика 1)
      delay(3000);
      ledManager(LEFT, OFF);      // отключаем подсветку справа налево (от датчика 1)
      delay(3000);
      ledManager(RIGHT, ON);      // включаем подсветку слева направо (от датчика 2)
      delay(3000);
      ledManager(RIGHT, OFF);     //отключаем подсветку слева направо (от датчика 2)
      delay(3000);
    }


    void testLEDstrip()
    {
      while (1)  // бесконечный цикл
      {
        static boolean state = 0;
        state = !state;
        for (byte i = 0; i < NUM_LEDS; i++)
        {
          leds[i] = state ? CRGB::Red : CRGB::Black;
          FastLED.show();
          delay(SPEED);
        }
        for (byte i = 0; i < NUM_LEDS; i++)
        {
          leds[i] = CRGB::White;
          FastLED.show();
          delay(SPEED);
          leds[i] = CRGB::Blue;
          FastLED.show();
        }
      }
    }
     
    Последнее редактирование: 7 ноя 2016
    ИгорьК нравится это.
  6. moonlight1

    moonlight1 Нерд

    Да при движении датчик посылает 1. Ох, спасибо за такой код, то что надо и почти менять нечего не нужно.
    А можешь сказать откуда такой код? я инет переворачивал с ног на голову, на 10 страницу гугла заходил но ничего такого не видел.
     
  7. Tomasina

    Tomasina Сушитель лампочек Модератор

    Написан мною с нуля, скучно было, вот и сложилось. В гугле он появился три часа назад:D, первоисточник - именно эта тема. Теперь можно гуглить :p
     
    ZAZ-965 нравится это.
  8. moonlight1

    moonlight1 Нерд

    ого класс спасибо огромное, вы прямо маг :D осталось дождаться когда придет датчик освещенности и окончательно можно будет прикручивать и доделывать освещение коридора. еще раз спасибо!!
     
  9. alxndrlsn

    alxndrlsn Нерд

    меня сынок тоже просит ленту с разноцветными и под потолок комнаты, да на ИК-пульт... (без датчиков движения и освещенности)
    сильно изменится данный скетч?
     
  10. Tomasina

    Tomasina Сушитель лампочек Модератор

    с пультами не приходилось работать,но несложно - десяток готовых примеров эффектов есть в библиотеке, осталось назначить эффекты на кнопки пульта.
    Ну или купить ленту сразу с пультом и контроллером - довесок незначительный в цене.
     
  11. AlimovichPro

    AlimovichPro Нуб

    Спасибо добрый человек! Реально голову сломал пока дошло до меня как это сделать . Получалось только с плавным включением всех диодов . Пытаюсь кстате скрестить эти два скетча .. Что бы при поочередном включении диодов также плавно нарастала яркость . По без успешно ... сложно ли будет реализовать ?