rgb подсветка с условиями. (новичок просит помощи)

Тема в разделе "Arduino & Shields", создана пользователем Dimitry_, 14 май 2014.

  1. Dimitry_

    Dimitry_ Нерд

    Всем добрый день. Про ардуину узнал совсем недавно. Опыта програмирования крайне мало. Зато с паяльником дружу без проблем).
    И вот захотелось мне реализовать подсветку в машине на свой вкус, т.е. с лентой RGB. Первоначальный вариант был с контроллером за 100рэ с ебея. Там и цвет и яркость всё выбирается. Всякие режимы моргалки и пукалки меня не интересовали совсем.
    И тут на глаза попался набор ардуины, посмотрел инфу в нете, оказалось можно куда интереснее режимы организовать. И вот после долгих раздумий и подсчетов пришел к "проекту ( если так громко можно назвать).
    А точнее: 2 режима работы.
    Первый по кнопке перебор цветов по сине-зелено-красным диапазонам с градациями и регулировкой яркости. И сохранением последнего состояния в память ардуины ( и последующим чтением при включении).
    Второй - в зависимости от оборотов меняется цвет диодов. Так же от синего к красному через зеленый.

    Для подсчета Оборотов использую контакт с приборной панели. Идет он с мозгов машины. По расчетам выходит частота 300Гц при 6000 Об\мин. и для облегчения реализации можно приравнять кол-во импульсов с секунду к величине AnalogWrite. Т.е. при изменении оборотов от 0Гц до 256 ГЦ на входе будет меняться полностью спектр RGB диода. А чтоб не тратить оставшееся место в диапазоне высших оборотов - пусть при значениях на входе выше 256Гц мугет мигать красными ( последними в спектре) диодами. Получится что-то наподобии LightShift'a. Ну и соответсвенно с регулировкой яркости.
    Про неё отдельно. Как я понимаю нужно вводить переменную, на которую будет делится величина ШИМ выхода. Вполне достаточно 3-4 фиксированных положений. Потом можно и на датчик освещенности будет завести его).

    Вроде вкратце описал что хочу реализовать. Для регулировки цвета, яркости и режима можно подключить обычные кнопки, либо энкодер(понравился он мне).
    Сможет ли кто-то помочь в написании сего чуда? У меня уже есть готовый стенд с распаяным диодом и генератором импульсов на NE555 с частотами от 14Гц до 400Гц.


    Если нужна схема с контактами, то постараюсь нарисовать. Держу ее только в голове. Да и простая она.

    Заранее благодарю за любую помощь.


    куда что развел:

    int Gled = 9;
    int Rled = 10;
    int Bled = 11;
    int tacho = 2;
    int color = 4;
    int bright = 7;
    int mode =8;
    void setup()
    {
    pinMode(Rled, OUTPUT);
    pinMode(Gled, OUTPUT);
    pinMode(Bled, OUTPUT);
    pinMode(tacho, INPUT);
    pinMode(color, INPUT);
    pinMode(bright, INPUT);
    pinMode(mode, INPUT);
    }
     
    ИгорьК нравится это.
  2. lerik2703

    lerik2703 Гик

  3. Dimitry_

    Dimitry_ Нерд

    со считыванием разобрался через прерывания. но не понимаю никак каким образом привязть значение rpm к цветовому спектру и как сделать чтоб при rpm>255 моргали красные диоды.

    int Gled = 9;
    int Rled = 10;
    int Bled = 11;
    int color = 4;
    int bright = 7;
    int mode =8;
    volatile float time = 0;
    volatile float time_last = 0;
    volatile int rpm_array[5] = {0,0,0,0,0};
    void setup()
    {
    pinMode(Rled, OUTPUT);
    pinMode(Gled, OUTPUT);
    pinMode(Bled, OUTPUT);
    pinMode(color, INPUT);
    pinMode(bright, INPUT);
    pinMode(mode, INPUT);
    attachInterrupt(0, rpm_interrupt, FALLING);
    }
    void loop()
    {
    int rpm = 0;

    while(1){
    analogWrite(Bled, rpm );
    analogWrite(Rled, rpm + 128);
    analogWrite(Gled, 255 - rpm);
    delay(1000);
    if(time > 0)
    {
    //5 Sample Moving Average To Smooth Out The Data
    rpm_array[0] = rpm_array[1];
    rpm_array[1] = rpm_array[2];
    rpm_array[2] = rpm_array[3];
    rpm_array[3] = rpm_array[4];
    rpm_array[4] = 1000000 / time;
    //Last 5 Average RPM Counts Eqauls....
    rpm = (rpm_array[0] + rpm_array[1] + rpm_array[2] + rpm_array[3] + rpm_array[4]) / 5;

    }

    }
    }
    //Capture rpm
    void rpm_interrupt()
    {
    time = (micros() - time_last);
    time_last = micros();
    }
     
  4. lerik2703

    lerik2703 Гик

    а у вас максимальные обороты 255?
     
  5. Dimitry_

    Dimitry_ Нерд

    Эм, нет конечно). Поясню. По измерениям и расчетам получается при 6000 об.мин частота импульсов на катушке зажигания 300Гц. И для облегчения пересчета решил сделать перебор цвета до значений PWM-выхода (256 значений), а то, что выше этого значения запустить в моргающем режиме. Т.е. перебирать цвет будет при оборотах двигателя от 0 до 5120. Чего вполне достаточно для "осознования", что пора переключиться).
     
  6. lerik2703

    lerik2703 Гик

    нам сейчас частота не нужна пример на который я сослался считает обороты !так проще!а из ходя какого значения rpm,rpm + 128?
     
  7. Dimitry_

    Dimitry_ Нерд

    а вот в этом место я и не понимаю как реализовывать. сделал так чисто из любопытсва, посветить диодами. Там должно быть следующим образом:
    0 -> 128 ->256 rpm
    255 ->0 -> 0 Bled
    0 -> 255 -> 0 Gled
    0 -> 0 -> 255 Rled

    примерная табличка
     
  8. lerik2703

    lerik2703 Гик


    то есть по аналогии этого видео ,только синий диод горит при холостом ходе?
    а что сия входы означают?
    pinMode(color, INPUT);
    pinMode(bright, INPUT);
    pinMode(mode, INPUT);
     
  9. Dimitry_

    Dimitry_ Нерд

    Главная функция - изменяемый цвет подсветки. При этом на выбор, либо постоянно один цвет, либо цвет зависит от оборотов. И при превышении 5120 оборотов (255 импульсов с секунду) моргают только красные. Инпуты - это входа для кнопок, которыми переключаются функции: цвет вручную, яркость ( общая для обоих режимов) и собственно переключатель самих режимов.

    Синий горит на полную при заглушенном двигателе, на холостых он получится немного лазурным, ибо подсвечивается зеленый ещё.
     
  10. MrYuran

    MrYuran Нуб

    Так вроде бы все просто, чистая математика, 2 класс (или когда там пропорции изучают)

    Код (Text):
    unsigned char RedBright = 255; // яркость, чтобы можно было потом менять
    unsigned char BlueBright = 255;
    unsigned char GreenBright = 255;
    ...
    if(rpm<=128) {
        BledVal = BlueBright * rpm / 128;
        GledVal = GreenBright * rpm / 128;
        RledVal = 0;
    } else {
        RledVal = RedBright * (rpm-128) / 128;
        BledVal = 0;
        GledVal = 0;
    }
    ...
    analogWrite(Bled, BledVal );
    analogWrite(Rled, RledVal);
    analogWrite(Gled, GledVal);
     
  11. MrYuran

    MrYuran Нуб

    И ещё, вот это мне совсем не нравится
    Код (Text):
    int Gled = 9;
    int Rled = 10;
    int Bled = 11;
    int color = 4;
    int bright = 7;
    int mode =8;
    дело в том, что создаются переменные и висят в ОЗУ
    на худой конец const использовать, а лучше
    #define Rled 10
     
  12. Dimitry_

    Dimitry_ Нерд

    Хм, спасибо. Сейчас опробую.
    P.S. Програмил последний раз в учебном заведении на бейсике)
     
  13. Dimitry_

    Dimitry_ Нерд

    Вроде переписал всё. Но компилиться не желает совсем.
    Код (Text):
    #define Gled 9
    #define Rled 10
    #define Bled 11
    #define color 4
    #define bright 7
    #define mode 8
    volatile float time = 0;
    volatile float time_last = 0;
    volatile int rpm_array[5] = {0,0,0,0,0};
    void setup()
    {
    pinMode(Rled, OUTPUT);
    pinMode(Gled, OUTPUT);
    pinMode(Bled, OUTPUT);
    pinMode(color, INPUT);
    pinMode(bright, INPUT);
    pinMode(mode, INPUT);
    attachInterrupt(0, rpm_interrupt, FALLING);
    }
    void loop()
    {
    unsigned char RedBright = 255; // яркость, чтобы можно было потом менять
    unsigned char BlueBright = 255;
    unsigned char GreenBright = 255;
    int rpm = 0;
    int BledVal;
    int GledVal;
    int RledVal;
    if(rpm<=128) {
        BledVal = BlueBright * rpm / 128;
        GledVal = GreenBright * rpm / 128;
        RledVal = 0;
    } else {
        RledVal = RedBright * (rpm-128) / 128;
        BledVal = 0;
        GledVal = 0;
    analogWrite(Bled, BledVal);
    analogWrite(Rled, RledVal);
    analogWrite(Gled, GledVal);
    {
    //5 Sample Moving Average To Smooth Out The Data
    rpm_array[0] = rpm_array[1];
    rpm_array[1] = rpm_array[2];
    rpm_array[2] = rpm_array[3];
    rpm_array[3] = rpm_array[4];
    rpm_array[4] = 1000000 / time;
    //Last 5 Average RPM Counts Eqauls....
    rpm = (rpm_array[0] + rpm_array[1] + rpm_array[2] + rpm_array[3] + rpm_array[4]) / 5;

    }

    }
    }
    //Capture rpm
    void rpm_interrupt()
    {
    time = (micros() - time_last);
    time_last = micros();
    }
     
  14. MrYuran

    MrYuran Нуб

    Пришлось закачать это уг.. божество (в смысле среду разработки)

    Странно, #define не понимает.
    Ну, пусть будет const int
    Код (Text):
    const int Gled =9;
    const int Rled =10;
    const int Bled =11;
    const int color =4;
    const int bright =7;
    const int mode =8;

    volatile float time = 0;
    volatile float time_last = 0;
    volatile int rpm_array[5] = {
      0,0,0,0,0};

    unsigned char RedBright = 255; // яркость, чтобы можно было потом менять
    unsigned char BlueBright = 255;
    unsigned char GreenBright = 255;

    int rpm = 0;
    int BledVal;
    int GledVal;
    int RledVal;

    void setup()
    {
      pinMode(Rled, OUTPUT);
      pinMode(Gled, OUTPUT);
      pinMode(Bled, OUTPUT);
      pinMode(color, INPUT);
      pinMode(bright, INPUT);
      pinMode(mode, INPUT);
      attachInterrupt(0, rpm_interrupt, FALLING);
    }

    void loop()
    {
      if(rpm<=128) {
        BledVal = BlueBright * rpm / 128;
        GledVal = GreenBright * rpm / 128;
        RledVal = 0;
      }
      else {
        RledVal = RedBright * (rpm-128) / 128;
        BledVal = 0;
        GledVal = 0;
      }
      analogWrite(Bled, BledVal);
      analogWrite(Rled, RledVal);
      analogWrite(Gled, GledVal);
     
        //5 Sample Moving Average To Smooth Out The Data
        rpm_array[0] = rpm_array[1];
        rpm_array[1] = rpm_array[2];
        rpm_array[2] = rpm_array[3];
        rpm_array[3] = rpm_array[4];
        rpm_array[4] = 1000000 / time;
        //Last 5 Average RPM Counts Eqauls....
        rpm = (rpm_array[0] + rpm_array[1] + rpm_array[2] + rpm_array[3] + rpm_array[4]) / 5;
    }
    //Capture rpm
    void rpm_interrupt()
    {
      time = (micros() - time_last);
      time_last = micros();
    }
    Удачи
     
  15. Dimitry_

    Dimitry_ Нерд

    ) пашет такой вариант. потыкаюсь с таблицей RGB. а то сейчас до rpm=128 синий и зеленый, и с повышением меняется общая яркость. а при 128+ значении красный и яркость не понятно зависит от частоты ( rpm).
     
  16. Unixon

    Unixon Оракул Модератор

    Все оно нормально понимает, просто не надо переопределять под макросы часто используемые идентификаторы. В данном случае слово mode уже занято внутри Wiring под другие нужды, а этот макрос ломает код библиотеки.

    Стилизуйте код! Все макросы и глобальные константы - заглавными буквами типа PIN_MODE, имена функций - camelCase, локальные переменные - строчными с подчеркиванием типа last_time. Ну и т.д. Так не будет пересечения идентификаторов и сразу из одного вида будет понятно какого эта сущность типа.