Программирование светодиодных лент WS2818 через MegaD

Использование системы в различных ситуациях, вопросы программирования сценариев.

Модератор: immortal

Ответить
aleksey_nsk
Сообщения: 3
Зарегистрирован: Пн фев 26, 2018 3:09 pm
Благодарил (а): 1 раз
Поблагодарили: 0

Программирование светодиодных лент WS2818 через MegaD

Сообщение aleksey_nsk » Пн фев 26, 2018 3:40 pm

Добрый день,
я использую у себя контроллеры megad-2561, а в качестве подсветки - ленты на базе чипов ws2818. Подробнее механизм описан https://ab-log.ru/smart-house/ethernet/megad-ws-2018

В качестве обьектов сделал новый класс RGB_WS2818 на базе SRGB
свойства:

Код: Выделить всё

Chip                          //Количество чипов в ленте (Ключевые данные)     
MegaD_IP                 //IP Мегадевайса (Ключевые данные)     
MegaD_Password    //Пароль от меги (Ключевые данные)     
MegaD_Port             //Порт управления, на котором висит лента (Ключевые данные)        
и переписанный метод colorUpdated:

Код: Выделить всё

$megad_ip=$this->getProperty("MegaD_IP");
$megad_port=$this->getProperty("MegaD_Port");
$megad_pass=$this->getProperty("MegaD_Password");
$chip=$this->getProperty("Chip");
$color=$this->getProperty("Color");
$red="";
$green="";
$blue="";
   if ($color[0] == '#') {
        $color = substr($color, 1);
    };   
$red=substr($color,0,2);
$green=substr($color,2,2);
$blue=substr($color,4,2);
$color=$blue.$red.$green;
$url = "http://".$megad_ip."/".$megad_pass."/?pt=".$megad_port."&chip=".$chip."&ws=".$color;
file_get_contents($url);
В моей ленте RGB не RGB, а BRG, поэтому строка разбирается.

В общем в меню управления блок выбора цвета, привязанный обьект и свойство. Собственно все работает, но вот как мне запрограммировать эффект для ленты? Суть, что надо "где-то отдельно" запустить бесконечный цикл, который будет обрабатывать эффект, еще нужно как-то удобно этот эффект включать и выключать. Я немного "недогоняю" глобальное устройство MD, из-за этого мои "бесконечные циклы" вешают всю систему. Подскажите как организовать это дело?

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

Вот пример скрипта для "гирлянды" (с сайта производителя):

Код: Выделить всё

$url = "http://192.168.4.30/sec/?pt=35&chip=160&ws=";
$url2 = "http://192.168.4.30/sec/?pt=34&chip=160&ws=";

    $loop_cnt = 0;
    $color = "ff0000";
    while(true)
    {

        $cmd = "";
        for ( $i = 0; $i < 6; $i++ )
        {
            if ( $i == $cnt )
            //$cmd .= $cmd_list[$color].$cmd_list[$color];
            $cmd .= $color.$color;
            else
            $cmd .= "000000000000";
        }
    
        if ( $cmd == "000000000000000000000000000000000000000000000000000000000000000000000000" )
        $cmd = $color.$color."000000000000000000000000000000000000000000000000000000000000";

        $cnt++;

        if ( $cnt == 12 )
        {
            $cnt = 0;
            $r = 0;
            $g = 0;
            $b = 0;
            for ( $i = 0; $i < 3; $i++ )
            {
                $r = dechex(rand(0, 50));
                $g = dechex(rand(0, 50));
                $b = dechex(rand(0, 50));

                if ( strlen($r) == 1 )
                $r = "0".$r;
                if ( strlen($g) == 1 )
                $g = "0".$g;
                if ( strlen($b) == 1 )
                $b = "0".$b;
                $color = $r.$g.$b;

            }
            //$color = rand(0,3);
        }
        file_get_contents($url.$cmd);
        file_get_contents($url2.$cmd);

        usleep(50000);

        $loop_cnt++;
        if ( $loop_cnt == 200 )
        return;
    }
 
получается эффект бегущих с разным цветом огней. В данном случае работает две ленты с одним эффектом.

И еще второй вопрос:
допустим у меня в комнате четыре ленты, каждая сидит на отдельном порту меги, как включать из меню управления разом все ленты в один цвет?
Через вызов метода обьекта, контроллер (или MD???) тормозит нереально, в итоге на ленту вместо нужных данных приходит мусор и она "радугой" светится. Как я думаю, надо сначала получить из колорбокса меню цвет, из всех нужных объектов лент (которые надо зажеч) данные для меги и четыремя подряд командами file_get_contents() отправить скомпонованные команды контроллеру. Но как из сценария получить цвет из колорбокса меню?
Посоветуйте пожалуйста решение с минимальной нагрузкой на систему этими скриптами.
Chainik
Сообщения: 1465
Зарегистрирован: Вс янв 10, 2016 11:05 am
Благодарил (а): 262 раза
Поблагодарили: 455 раз

Re: Программирование светодиодных лент WS2818 через MegaD

Сообщение Chainik » Пн фев 26, 2018 8:58 pm

aleksey_nsk писал(а):Но как из сценария получить цвет из колорбокса меню?
Может быть имелось ввиду, как из меню передать в сценарий параметры цветов?
Если да, то можно использовать слайдеры (отдельный для каждого цвета), если цвета нужно плавно изменять. Если надо изменять цвета фиксированно, используя несколько предустановленных, думаю, можно воспользоваться элементом меню "radiobox".
После установки цветов (и записи их в свойства нужных объектов лент), наверное, надо нажать на выключатель, запускающий скрипты/методы.

Чтобы завершить бесконечный цикл (выключить ленты), надо еще подумать, как это сделать...
Вот нашел один из вариантов (viewtopic.php?f=4&t=4911).

Если у вас методами будут включаться ленты (что на мой взгляд самый правильный вариант), то можно в каждом объекте лент предусмотреть отдельное свойство для остановки (напр. "Activity"). Допустим, при запуске выставляем свойству "1", а когда переводим выключатель в состояние "выкл", выставляем "0". А внутри цикла делаем проверку свойства:

Код: Выделить всё

if ( $this->getProperty('Activity') == 0 ) return; 
Только может быть делать проверку 1 раз в 10 или в 100 итераций цикла, поскольку тут будет происходить операция чтения из БД, что занимает пусть небольшое, но время.
За это сообщение автора Chainik поблагодарил:
aleksey_nsk (Сб мар 03, 2018 9:50 am)
Рейтинг: 1.16%
aleksey_nsk
Сообщения: 3
Зарегистрирован: Пн фев 26, 2018 3:09 pm
Благодарил (а): 1 раз
Поблагодарили: 0

Re: Программирование светодиодных лент WS2818 через MegaD

Сообщение aleksey_nsk » Сб мар 03, 2018 9:47 am

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

Еще вопрос: из элемента меню упраления можно как-то считывать свойства напрямую? Или только надо связывать с другими объектами и обращаться уже к объектам?
aleksey_nsk
Сообщения: 3
Зарегистрирован: Пн фев 26, 2018 3:09 pm
Благодарил (а): 1 раз
Поблагодарили: 0

Re: Программирование светодиодных лент WS2818 через MegaD

Сообщение aleksey_nsk » Сб мар 03, 2018 9:51 am

По ссылочке именно то, что нужно, спасибо!
Chainik
Сообщения: 1465
Зарегистрирован: Вс янв 10, 2016 11:05 am
Благодарил (а): 262 раза
Поблагодарили: 455 раз

Re: Программирование светодиодных лент WS2818 через MegaD

Сообщение Chainik » Сб мар 03, 2018 10:40 am

aleksey_nsk писал(а):...
Еще вопрос: из элемента меню упраления можно как-то считывать свойства напрямую? Или только надо связывать с другими объектами и обращаться уже к объектам?
Я всегда связываю с другими Объектами.Свойствами. Как по-другому, не знаю (не программист).

К примеру, возьмем элемент управления "слайдер". Получается отличная обратная связь. С одной стороны, когда отпускаешь ползунок слайдера в новом положении, в связанное свойство записывается новое значение и (при необходимости) запускается связанный метод. С другой стороны, если из другого места (например, из скриптов, других методов и т.д.) изменяется значение свойства, с которым связан слайдер, то ползунок слайдера тут же перемещается в новое положение (в соответствии со значением свойства).
Ответить