Управление двумя RGB

vitmish
Offline
Зарегистрирован: 06.02.2017

Никак не могу решить, в какую сторону идти для управления двумя RGB-лентами с разных пинов.

Для одной ленты все просто и понятно - прописать три пина цветов и вперед, навстречу радуге.

А если указать пины другой ленты, то наступает коллапсец.

Изначально идея была как работа двух RGB-лент в одинаковом режиме плавного изменения цветов.

Затем при включении определенных пинов режимы работы меняются, в зависимости от пина у каждой ленты свой режим.

Вообще хотел прописать каждый режим функциями и для кажого пина подставлять свой набор функций.

Но с самого начала не пошло. Нашел библиотеку под плавное изменение цвета, решил прописать туда несколько пинов, потом решил вписать массив, потом.... стал искать револьвер )

Догадываюсь, что задача достаточно проста, но вот уже несколько часов топчусь на одном месте.

vitmish
Offline
Зарегистрирован: 06.02.2017

Жуть. перечитал себя.

К ардуино подключаются две RGBленты к выводам с ШИМ-управлением.

Режимы работы как синхронные (самое простое), но и различные, в зависимости от сигналов на других пинах.

Думал, что найду подобное в сети - ан нет, либо плохо искал либо случай клинический.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Чего. Это достаточно простая задача. Но все скетчи написаны в дебильном (зачеркнуто) "традиционом" для ардуино стиле. Вот херню вы и видили.

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

vitmish, Ккой библиотекой Вы пользуетесь, не знаю. Но общий подход таков: для каждой ленты описываете свою переменную (объект, экземпляр класса) и указываете ей, с какими пинами работать.

vitmish
Offline
Зарегистрирован: 06.02.2017

Библиотеку нашел на просторах. Подкупила достаточной компактностью и результатом. Немножко отредактировал (в меру своих возможностей) по свои нужды, но...

Сама библиотека ниже.

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

#include "rgb.h"
#include <Arduino.h>

rgb::rgb(int redPin, int greenPin, int bluePin) {
    pinRed = redPin;
    pinGreen = greenPin;
    pinBlue = bluePin;
    red = 0;
    redTarget = 0;
    green = 0;
    greenTarget = 0;
    blue = 0;
    blueTarget = 0;
	timeToChangeColor = millis();
	timeIntervalToNextColor = 10;

}
void rgb::SetTarget(uint8_t red, uint8_t green, uint8_t blue) {
    redTarget = red;
    greenTarget = green;
    blueTarget = blue;
}

void rgb::SetRandomColors(void) {
	    do {
            redTarget   = random(255);
            greenTarget = random(255);
            blueTarget  = random(255);
        } while (((abs)(redTarget - greenTarget) < 140) && ((abs)(greenTarget - blueTarget) < 140) && ((abs)(blueTarget - redTarget) < 140 ) );

        i++;														// Счетчик смены цветов;
        if (15 == i) { redTarget = 255; greenTarget = 0; blueTarget = 0; }
        if (30 == i) { redTarget = 0; greenTarget = 255; blueTarget = 0; }
        if (45 == i) { redTarget = 0; greenTarget = 0; blueTarget = 255; }
        if (60 == i) { redTarget = 255; greenTarget = 255; blueTarget = 0; }
        if (75 == i) { redTarget = 0; greenTarget = 255; blueTarget = 255; }
        if (90 == i) { redTarget = 255; greenTarget = 0; blueTarget = 255; }
        if (105 == i) { redTarget = 255; greenTarget = 255; blueTarget = 255;
            i = 0;
        }
}

void rgb::SetTimeIntervalToNextColor(unsigned long interval) {
	timeIntervalToNextColor = interval;
}

void rgb::SwitchOnNow(void){        // Включаем ленту на всю дурь
    red = redTarget = green = greenTarget = blue = blueTarget = 255;
    SwitchColorNow(red,green,blue);
}

void rgb::SwitchOffNow(void) {      // Гасим ленту
    red = redTarget = green = greenTarget = blue = blueTarget = 0;
    SwitchColorNow(red,green,blue);
}

void rgb::SwitchColorNow(uint8_t red, uint8_t green, uint8_t blue) {
    analogWrite(pinRed, red);
    analogWrite(pinGreen, green);
    analogWrite(pinBlue, blue);
}

 

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016
class Cl_RGB_led {
  private:
    byte R_pin;
    byte G_pin;
    byte B_pin;
    byte R_on;
    byte G_on;
    byte B_on;
    byte R_off;
    byte G_off;
    byte B_off;
    bool led; // 1 горит / 0 нет
    bool stat_blink; //1 разрешено мигание / 0 нет
    uint16_t time_blink;// период мигания
    uint32_t past = 0;
  public:
    Cl_RGB_led(byte R_pin, byte G_pin, byte B_pin);
    void setup();
    void loop();
    void write(byte R, byte G, byte B);
    void writeON(byte R, byte G, byte B);
    void writeOFF(byte R, byte G, byte B);
    void ON();
    void OFF();
    void blink(uint16_t time = 500); // мигать
    void Noblink(); // немигать
};
Cl_RGB_led::Cl_RGB_led(byte _R_pin, byte _G_pin, byte _B_pin) {
  R_pin = _R_pin;
  G_pin = _G_pin;
  B_pin = _B_pin;
}
void Cl_RGB_led::setup() {
  writeOFF(255, 255, 255);
  writeON(0, 0, 0);
  stat_blink = 0;
  ON();
}
void Cl_RGB_led::loop() {
  if (!time_blink) return;
  if (millis() - past > time_blink) {
    past = millis();
    (!led) ? ON() : OFF() ;
  }
}
void Cl_RGB_led::blink(uint16_t time = 500) { // мигать
  time_blink = time;
  stat_blink = 1;
  ON();
  past = millis();
}
void Cl_RGB_led::write(byte R, byte G, byte B) {
  analogWrite(R_pin,  R);
  analogWrite(G_pin, G);
  analogWrite(B_pin, B);
}

void Cl_RGB_led::writeON(byte R , byte G , byte B ) {
  R_on = R;
  G_on = G;
  B_on = B;
}
void Cl_RGB_led::ON() {
  write(R_on, G_on, B_on );
  led = 1;
}
void Cl_RGB_led::writeOFF(byte R , byte G , byte B ) {
  R_off = R;
  G_off = G;
  B_off = B;
}
void Cl_RGB_led::OFF() {
  write(R_off, G_off, B_off );
  led = 0;
}

Cl_RGB_led RGB[] = {
  Cl_RGB_led(3, 5, 6), // первая гирлянда на выв 3,5,6
  Cl_RGB_led(9, 10, 11) // вторая гирлянда на выв 9,10,11
};
void setup() {
  for (byte i = 0; i > 2; i++) {
    RGB[i].setup();
    RGB[i].blink(1000);
  }
}

void loop() {
  for (byte i = 0; i > 2; i++) RGB[i].loop();
}

 

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

И где же Вы пытаетесь прописать вторую ленту?

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

andriano пишет:

И где же Вы пытаетесь прописать вторую ленту?

class Cl_RGB_led {
  private:
    byte R_pin;
    byte G_pin;
    byte B_pin;
    byte R_on;
    byte G_on;
    byte B_on;
    byte R_off;
    byte G_off;
    byte B_off;
    bool led; // 1 горит / 0 нет
    bool stat_blink; //1 разрешено мигание / 0 нет
    uint16_t time_blink;// период мигания
    uint32_t past = 0;
  public:
    Cl_RGB_led(byte R_pin, byte G_pin, byte B_pin);
    void setup();
    void loop();
    void write(byte R, byte G, byte B);
    void writeON(byte R, byte G, byte B);
    void writeOFF(byte R, byte G, byte B);
    void ON();
    void OFF();
    void blink(uint16_t time = 500); // мигать
    void Noblink(); // немигать
};
Cl_RGB_led::Cl_RGB_led(byte _R_pin, byte _G_pin, byte _B_pin) {
  R_pin = _R_pin;
  G_pin = _G_pin;
  B_pin = _B_pin;
}
void Cl_RGB_led::setup() {
  writeOFF(255, 255, 255);
  writeON(0, 0, 0);
  stat_blink = 0;
  ON();
}
void Cl_RGB_led::loop() {
  if (!time_blink) return;
  if (millis() - past > time_blink) {
    past = millis();
    (!led) ? ON() : OFF() ;
  }
}
void Cl_RGB_led::blink(uint16_t time = 500) { // мигать
  time_blink = time;
  stat_blink = 1;
  ON();
  past = millis();
}
void Cl_RGB_led::write(byte R, byte G, byte B) {
  analogWrite(R_pin,  R);
  analogWrite(G_pin, G);
  analogWrite(B_pin, B);
}

void Cl_RGB_led::writeON(byte R , byte G , byte B ) {
  R_on = R;
  G_on = G;
  B_on = B;
}
void Cl_RGB_led::ON() {
  write(R_on, G_on, B_on );
  led = 1;
}
void Cl_RGB_led::writeOFF(byte R , byte G , byte B ) {
  R_off = R;
  G_off = G;
  B_off = B;
}
void Cl_RGB_led::OFF() {
  write(R_off, G_off, B_off );
  led = 0;
}

Cl_RGB_led RGB[] = {
  Cl_RGB_led(3, 5, 6), // первая гирлянда на выв 3,5,6
  Cl_RGB_led(9, 10, 11) // вторая гирлянда на выв 9,10,11
};
void setup() {
  for (byte i = 0; i > 2; i++) {
    RGB[i].setup();
  };
  RGB[0].writeON(255,0,0); 
  RGB[0].writeOFF(0,255,0);
  RGB[0].blink(1000); // первая герлянда мигает красным на зеленое 1 сек вкл 1 сек выкл
  RGB[1].writeON(0,0,255);
  RGB[1].writeOFF(0,0,0);
  RGB[1].blink(600); // первая герлянда мигает синее вкл -выкл 0,6 сек вкл 0,6 сек выкл

}

void loop() {
  for (byte i = 0; i > 2; i++) RGB[i].loop();
}

ПС: Что бы управлять надо сначало сказать с помощью чего Вы собираетесь управлять. А так это всего лишь заготовка,шаблон.

vitmish
Offline
Зарегистрирован: 06.02.2017

78,79 строки, если не ошибаюсь.

Только данный вариант у меня отнимает возможность раздельного управления лентами, если я правильно понимаю весь скетч.

Уффф, ладно.

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

vitmish пишет:

78,79 строки, если не ошибаюсь.

Только данный вариант у меня отнимает возможность раздельного управления лентами, если я правильно понимаю весь скетч.

Уффф, ладно.

Единственный опубликованный Вами скетч (пост №4) имеет только 61 строку.

И то, что там приведено, никаких возможностей не отнимает.

vitmish
Offline
Зарегистрирован: 06.02.2017

сама лента работает по очень компактному скетчу, который без библиотеки ни о чем не скажет

#include <RGB.h>

bool gotAllColors = false;
rgb rgb (9,10,11);
 
void setup()
{
        rgb.SetTimeIntervalToNextColor(5);   
    rgb.SetTarget(0,0,0);           
}

void loop()
{                                          
    if(gotAllColors) {                     
        rgb.SetRandomColors();
        gotAllColors = 0;
    }
    else {
        gotAllColors = rgb.UpdateColors(); 
      
    }
}

 

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

И что вас устраивает, что цвета меняюся случайным образом?

vitmish
Offline
Зарегистрирован: 06.02.2017

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

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Плавно это тоже самое, что и резко, только медленно. Рандом приращение на каждый цвет с шагом - 25..+25 в течении 0,05-0,1 сек . Разумеется немного подобрать константы и все.

vitmish
Offline
Зарегистрирован: 06.02.2017

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

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

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Ну еще можно применить метод отскока. Цвет меняется от 0 до 255 и 255 до 0 . Как бы отскакивает от "стенок". При отскоке меняется шаг измения 5,10,15,20,25. Рандомно. Шаг длится 0,5 секунды. Так что переход от крайностей может длится 25-5 секунды.  Тогда классов будет не 2 , а !!! шесть. На каждый цвет каждой гирлянды свой класс. Код короче и проще.

Logik
Offline
Зарегистрирован: 05.08.2014

qwone пишет:

Плавно это тоже самое, что и резко, только медленно. 

))) В цитатник!

Logik
Offline
Зарегистрирован: 05.08.2014

qwone пишет:

Ну еще можно применить метод отскока. Цвет меняется от 0 до 255 и 255 до 0 . Как бы отскакивает от "стенок". При отскоке меняется шаг измения 5,10,15,20,25. Рандомно. Шаг длится 0,5 секунды. 

А визуально чего получится, чтото я не скомпилирую. Наверно пробовать надо. А не случится что вкакой момент все тухнет? Наверно случится, это плохо. 

vitmish
Offline
Зарегистрирован: 06.02.2017

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

К чему это я? Ах да... проблема у меня в другом - развести в программе две RGBленты для библиотеки, написанной для одной ленты.

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

Вообще я хотел всю прогу написать через вызов функций. есть сигнал на пине - вызываем функции А, В и С.

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

vitmish
Offline
Зарегистрирован: 06.02.2017

Logik пишет:

А визуально чего получится, чтото я не скомпилирую. Наверно пробовать надо. А не случится что вкакой момент все тухнет? Наверно случится, это плохо. 

Резкое изменение цветов (см выше)

Нет, не гаснет - плавное изменение цветов. Один цвет идет на максимум, второй где-то около, третий к минимуму. Так и живут.

без библиотеки rgb.h вряд ли скомпилится.

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

vitmish пишет:

сама лента работает по очень компактному скетчу, который без библиотеки ни о чем не скажет

#include <RGB.h>

bool gotAllColors = false;
rgb rgb (9,10,11);
 
void setup()
{
        rgb.SetTimeIntervalToNextColor(5);   
    rgb.SetTarget(0,0,0);           
}

void loop()
{                                          
    if(gotAllColors) {                     
        rgb.SetRandomColors();
        gotAllColors = 0;
    }
    else {
        gotAllColors = rgb.UpdateColors(); 
      
    }
}

Не знаю, как это понимает компилятор, но лично я не понимаю, в 4-й строке "rgb" - это имя класса или имя переменной?

Если Вы хотите работать с двумя лентами, то и опишите две ленты:

rgb RGB_0 (9,10,11); // это первая лента
rgb RGB_1 (6,7,8); // а это - вторая

И дальше работайте с кажлой так, как считаете нужным:

RGB_0.SetTimeIntervalToNextColor(5); // знал бы я еще, что это 
RGB_1.SetTimeIntervalToNextColor(6); // за функция, и что она делает

 

Logik
Offline
Зарегистрирован: 05.08.2014

vitmish пишет:

Logik пишет:

А визуально чего получится, чтото я не скомпилирую. Наверно пробовать надо. А не случится что вкакой момент все тухнет? Наверно случится, это плохо. 

Резкое изменение цветов (см выше)

Нет, не гаснет - плавное изменение цветов. Один цвет идет на максимум, второй где-то около, третий к минимуму. Так и живут.

Так резкое или плавное?

Но меняются все три цвета одновременно и независимо, с разными шагами. Потому должны быть моменты когда все три на минимуме. Так ведь?

 

vitmish пишет:

без библиотеки rgb.h вряд ли скомпилится.

У меня скомпилируется ;)

vitmish
Offline
Зарегистрирован: 06.02.2017

Выше была изложена библиотека (основная часть)

Выложил бы всю, да вижу только возможность указания кода

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

/*R_led.ino
*/
class Cl_R_led {
  private:
    byte pin;
    int R;
    byte step;
    int Dir;// +1  идет в + / -1 идет в -
    uint32_t past = 0;
    const uint16_t time = 300;
  public:
    Cl_R_led(byte R_pin);
    void setup();
    void loop();
};
Cl_R_led::Cl_R_led(byte _pin) {
  pin = _pin;
}
void Cl_R_led::setup() {
  analogWrite(pin,  R = 125);
  Dir = 1;
  step = (micros() / 4) % 5 * 5 + 5;
  past = millis();
}
void Cl_R_led::loop() {
  if (millis() - past > time) {
    past = millis();
    R += step * Dir;
    if (R > 255) {
      R = 255;
      Dir = -1;
    }
    if (R < 0) {
      R = 0;
      Dir = 1;
      step = (micros() / 4) % 5 * 10 + 20;
    }
    analogWrite(pin,  R);
  }
}
Cl_R_led R_led[] = {
  Cl_R_led(3), // первая гирлянда R
  Cl_R_led(5), // первая гирлянда G
  Cl_R_led(6), // первая гирлянда B
  Cl_R_led(9), // вторая гирлянда R
  Cl_R_led(10),// вторая гирлянда G
  Cl_R_led(11) // вторая гирлянда B
};
void setup() {
  for (byte i = 0; i < 6; i++) {
    R_led[i].setup();
  };
}

void loop() {
  for (byte i = 0; i < 6; i++) R_led[i].loop();
}

Это так на посмотреть константы подобрать.

vitmish
Offline
Зарегистрирован: 06.02.2017

Logik пишет:

Но меняются все три цвета одновременно и независимо, с разными шагами. Потому должны быть моменты когда все три на минимуме. Так ведь?

Библиотека не моя, я только использую в проекте (R)

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

Могу сказать одно - лента рядом светит, час светит, два.... может, когда отвернусь, она и гаснет )