Led Ring

Тема в разделе "Схемотехника, компоненты, модули", создана пользователем Salk, 20 ноя 2014.

  1. Unixon

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

    Да с ней просто всё понятно, даже не знаю что еще можно было бы обсудить...
     
  2. Unixon

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

    Светодиодную шкалу не хотите сделать цветной (белый-синий-зеленый-желтый-оранжевый-красный)?
     
  3. Salk

    Salk Гик

    Саму шкалу одного переменного? А не получится какой-то винегрет ? :)
    Я хотел сделать, регулировку громкости по центру, а НЧ и ВЧ по бокам, а шкалы одноцветными.
    Хотяяя.. Я только что, по-моему, понял Вашу мысль. Вы имеете ввиду сделать разноцветную шкалу, которая бы визуально отображала текущую громкость, т.е. 0% - белый, 10% - синий, 50% - зеленый, 80% - оранжевый и 100% - красный ?
    Хм, заманчиво, скорее всего я возьму эту идею на вооружение. Но тут надо ещё посмотреть какие SMD светодиоды мне удастся приобрести. Был в двух магазинах, то нужного размера нет (я же не буду совсем мелочь ставить, нужны более менее крупные светодиоды, примерно, как на видео), то цвет только один... Но спасибо за идею :)
     
  4. Unixon

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

    Да, верно, идея такая. У вас тоже свой стиль - монотонные каналы одного или разных цветов, может быть это и лучше. Локально с наличием всегда какие-нибудь проблемы, заказывайте с доставкой оттуда, где есть. Типоразмер 1206 скорее всего, дальше идут сверх-яркие и осветительные в нестандартных корпусах.
     
  5. RxdTxd

    RxdTxd Нуб

    Добрый день! Очень интересует финальная версия. Хотелось бы посмотреть на скетч где есть 1 переменный резистор, 1шт. 74HC595 и 10 светодиодов. Буду очень признателен!
     
  6. rkit

    rkit Гуру

    И никаких скетчей. И дешевле регистров.
     

    Вложения:

  7. RxdTxd

    RxdTxd Нуб

    rkit, благодарю за идею! Но нужен скетч с участием ардуино , уже имеющегося 74HC595 и 8 (10) светодиодов.
     
  8. Salk

    Salk Гик

    Добрый день, RxdTxd. Выкладываю фото и скетч, уже устаревшего проекта. Надеюсь, Вы, сможете повторить и сделать куда лучше, чем я.
    Код (C++):
    #include <IRremote.h>            // IR
    #define DATA_PIN    5 // пин данных (англ. data); DS; SDI - пин данных
    #define LATCH_PIN   7 // пин строба (англ. latch); STcp; SS - защелка (CS)
    #define CLOCK_PIN   6 // пин такта (англ. clock); SHcp; CLK - тактовый вывод (синхронизация)
    #define IR_PIN 5
    // пины регулировок (потенциометров)
    #define POT_LOW A1   // Громкость
    #define POT_VOL A2   // НЧ
    #define POT_HIGH A3  // ВЧ
    IRrecv irrecv(IR_PIN);
    decode_results results;
    int potV; // здесь хранится показания потенциометра (0-15)
    int potL;
    int potH;
    unsigned int ledV; // полученная комбинация битов, для отправки на регистры
    unsigned int ledL;
    unsigned int ledH;
    int n = 17; // Кол-во светодиодов
    int h; // переключение на режим "точка" и назад
    int zeros;

    void setup()
    {
      pinMode(VSS, OUTPUT);
      pinMode(POT_VOL, INPUT);
      pinMode(POT_LOW, INPUT);
      pinMode(POT_HIGH, INPUT);
      pinMode(DATA_PIN, OUTPUT);
      pinMode(CLOCK_PIN, OUTPUT);
      pinMode(LATCH_PIN, OUTPUT);
      digitalWrite(VSS, HIGH);
      irrecv.enableIRIn(); // Включаем ресивер
    }

    void loop()
    {
      potV = map(analogRead(POT_VOL), -143, 1167, 0, n);
      potL = map(analogRead(POT_LOW), -143, 1167, 0, n);
      potH = map(analogRead(POT_HIGH), -143, 1167, 0, n);
      if (irrecv.decode(&results))
      {
        if (results.value == 66561) // Нажали кнопку пульта "1", включили режим "точка" для всех потенциометров
        {
          h = 1;
        }
        if (results.value == 1025) // Нажали повторно "1", выключили режим "точка" для всех потенциометров
        {
          h = 0;
        }
        if (results.value == 1026)
        {
          h = 2;
        }
        if (results.value == 66562)
        {
          h = 3;
        }
        irrecv.resume(); // Получаем следующее значение
      }
      if (h == 2) // Режим "Подкова"
      {
        ledV = 0;
        ledL = 0;
        ledH = 0;
        potV = map(analogRead(POT_VOL), 0, 1023, 0, n / 2 + 1);
        potL = map(analogRead(POT_LOW), 0, 1023, 0, n / 2 + 1);
        potH = map(analogRead(POT_HIGH), 0, 1023, 0, n / 2 + 1);
        unsigned long pre_ledV = 0x0000FFFF >> (16 - potV);
        ledV = pre_ledV << (n - potV);
        ledV |= pre_ledV;
        LEDRing();
        unsigned long pre_ledL = 0x0000FFFF >> (16 - potL);
        ledL = pre_ledL << (n - potL);
        ledL |= pre_ledL;
        LEDRing();
        unsigned long pre_ledH = 0x0000FFFF >> (16 - potH);
        ledH = pre_ledH << (n - potH);
        ledH |= pre_ledH;
        LEDRing();
      }
      if (h == 3) // Режим "Обратная подкова"
      {
        potV = map(analogRead(POT_VOL), -160, 1247, 0, n);
        potL = map(analogRead(POT_LOW), -160, 1247, 0, n);
        potH = map(analogRead(POT_HIGH), -160, 1247, 0, n);

        potV = (potV % 2) ? potV : potV + 1;
        potL = (potL % 2) ? potL : potL + 1;
        potH = (potH % 2) ? potH : potH + 1;

        ledV = 0x0000FFFF >> (16 - potV);
        ledL = 0x0000FFFF >> (16 - potL);
        ledH = 0x0000FFFF >> (16 - potH);

        ledV = ledV << ((n - potV) / 2);
        ledL = ledL << ((n - potL) / 2);
        ledH = ledH << ((n - potH) / 2);
        LEDRing();
      }

      if (h == 1) // Режим "точка"
      {
        ledV = (1L << (n)) >> (n - potV); // режим "точка" (n - 1)
        ledL = (1L << (n)) >> (n - potL);
        ledH = (1L << (n)) >> (n - potH);
        LEDRing();
      }
      if (h == 0) // "обычный" режим + режим "влево-вправо"
      {
        // формула: биты сдвигаются вправо относительно показаний с потенциометра
        // Обычный режим (последоватльный)
        // ledV = 0;
        for (int i = 0; i < 15; i++) ledV = (ledV << 1) + 1; // загоняем n единиц "n"
        ledV = ledV >> (15 - potV);

        // Режим "влево-вправо" от центрального светодиода для ВЧ
        if (n % 2)
        {
          int shift = potH - (n / 2); // для n=15 значения  0 - 6 превратит в -7 - -1, 7 - в 0, 8 - 14 в 1-7
          if (shift == 0)
          {
            ledH = 1 << (n / 2); //включить только центральную позицию (7)
          }
          else if (shift < 0)
          {
            shift = -shift; // делаем положительным
            ledH = 0;
            for (int i = 0; i < n / 2 + 1; i++) ledH = (ledH << 1) + 1; // загоняем n/2 +1 единиц
            ledH = ledH >> (n / 2 - shift ); // получаем массив из нужного количества  единиц (shift)
            //сдвигаем эти единицы в нужное место
            ledH = ledH << (n / 2 - shift);
          }
          else
          {
            //shift=shift+1; // из 0-7 делаем 1-8
            ledH = 0;
            for (int i = 0; i < n / 2 + 1; i++) ledH = (ledH << 1) + 1; // загоняем n/2 единиц
            ledH = ledH >> (n / 2 - shift ); // получаем массив из нужного количества  единиц (shift)
            //сдвигаем эти единицы в нужное место
            ledH = ledH << n / 2; // справа, в младшие позиции, должны вдвинуться нули, теоретически должны получить shift заполненных позиций справа от средней точки
          }
        }
        else
        {
          // Сначала определяем, отклонение от центральной позиции влево
          // (в сторону уменьшения значения) или вправо (увеличение).
          int shift = potH - (n / 2); // для n=16 значения  0 - 7 превратит в -8 - -1, 8 - 15 в 0-7
          if (shift < 0)
          {
            shift = -shift; // делаем положительным
            ledH = 0;
            for (int i = 0; i < n / 2; i++) ledH = (ledH << 1) + 1; // загоняем n/2 единиц
            ledH = ledH >> (n / 2 - shift ); // получаем массив из нужного количества  единиц (shift)
            //сдвигаем эти единицы в нужное место
            ledH = ledH << (n / 2 - shift); // справа, в младшие позиции, должны вдвинуться нули, теоретически должны получить n/2 заполненных позиций влево (в младшие позиции) от средней точки
          }
          else
          {
            shift = shift + 1; // из 0-7 делаем 1-8
            ledH = 0;
            for (int i = 0; i < n / 2; i++) ledH = (ledH << 1) + 1; // загоняем n/2 единиц
            ledH = ledH >> (n / 2 - shift ); // получаем массив из нужного количества  единиц (shift)
            //сдвигаем эти единицы в нужное место
            ledH = ledH << shift + (n / 2 - shift); // справа, в младшие позиции, должны вдвинуться нули, теоретически должны получить shift заполненных позиций справа от средней точки
          }
        }
        // Режим "влево-вправо" от центрального светодиода для НЧ
        if (n % 2)
        {
          int shift = potL - (n / 2); // для n=15 значения  0 - 6 превратит в -7 - -1, 7 - в 0, 8 - 14 в 1-7
          if (shift == 0)
          {
            ledL = 1 << (n / 2); //включить только центральную позицию (7)
          }
          else if (shift < 0)
          {
            shift = -shift; // делаем положительным
            ledL = 0;
            for (int i = 0; i < n / 2 + 1; i++) ledL = (ledL << 1) + 1; // загоняем n/2 +1 единиц
            ledL = ledL >> (n / 2 - shift ); // получаем массив из нужного количества  единиц (shift)
            //сдвигаем эти единицы в нужное место
            ledL = ledL << (n / 2 - shift);
          }
          else
          {
            //shift=shift+1; // из 0-7 делаем 1-8
            ledL = 0;
            for (int i = 0; i < n / 2 + 1; i++) ledL = (ledL << 1) + 1; // загоняем n/2 единиц
            ledL = ledL >> (n / 2 - shift ); // получаем массив из нужного количества  единиц (shift)
            //сдвигаем эти единицы в нужное место
            ledL = ledL << n / 2; // справа, в младшие позиции, должны вдвинуться нули, теоретически должны получить shift заполненных позиций справа от средней точки
          }
        }
        else
        {
          // Сначала определяем, отклонение от центральной позиции влево
          // (в сторону уменьшения значения) или вправо (увеличение).
          int shift = potL - (n / 2); // для n=16 значения  0 - 7 превратит в -8 - -1, 8 - 15 в 0-7
          if (shift < 0)
          {
            shift = -shift; // делаем положительным
            ledL = 0;
            for (int i = 0; i < n / 2; i++) ledL = (ledL << 1) + 1; // загоняем n/2 единиц
            ledL = ledL >> (n / 2 - shift ); // получаем массив из нужного количества  единиц (shift)
            //сдвигаем эти единицы в нужное место
            ledL = ledL << (n / 2 - shift); // справа, в младшие позиции, должны вдвинуться нули, теоретически должны получить n/2 заполненных позиций влево (в младшие позиции) от средней точки
          }
          else
          {
            shift = shift + 1; // из 0-7 делаем 1-8
            ledL = 0;
            for (int i = 0; i < n / 2; i++) ledL = (ledL << 1) + 1; // загоняем n/2 единиц
            ledL = ledL >> (n / 2 - shift ); // получаем массив из нужного количества  единиц (shift)
            //сдвигаем эти единицы в нужное место
            ledL = ledL << shift + (n / 2 - shift); // справа, в младшие позиции, должны вдвинуться нули, теоретически должны получить shift заполненных позиций справа от средней точки
          }
        }
        LEDRing();
      }
    }

    void LEDRing() // Отправляем биты на сдвиговые регистры
    {
      digitalWrite(LATCH_PIN, LOW);
      // задвигаем (англ. shift out) байт-маску бит за битом,
      // начиная с младшего (англ. Least Significant Bit first)
      shiftOut(DATA_PIN, CLOCK_PIN, LSBFIRST, ledL & 0xFF);
      shiftOut(DATA_PIN, CLOCK_PIN, LSBFIRST, (ledL & 0xFF00) >> 8);

      shiftOut(DATA_PIN, CLOCK_PIN, LSBFIRST, ledV & 0xFF);
      shiftOut(DATA_PIN, CLOCK_PIN, LSBFIRST, (ledV & 0xFF00) >> 8);

      shiftOut(DATA_PIN, CLOCK_PIN, LSBFIRST, ledH & 0xFF);
      shiftOut(DATA_PIN, CLOCK_PIN, LSBFIRST, (ledH & 0xFF00) >> 8);
      // чтобы переданный байт отразился на выходах Qx, нужно
      // подать на пин строба высокий сигнал
      digitalWrite(LATCH_PIN, HIGH);
    }
    P.S. В код включена еще работа с ИК пультом, а также и с обычным потенциометром. ИК можно выкинуть, если не требуется. Так же, как и различные режимы.
    И еще совет, токоограничивающий резистор можно использовать один по питанию 74HC595, вместо для каждого светодиода отдельный.
     

    Вложения:

    • 22.jpg
      22.jpg
      Размер файла:
      1,5 МБ
      Просмотров:
      679
    • 28.jpg
      28.jpg
      Размер файла:
      1,4 МБ
      Просмотров:
      659
    • 23.jpg
      23.jpg
      Размер файла:
      1,5 МБ
      Просмотров:
      709
    • CAM00428.jpg
      CAM00428.jpg
      Размер файла:
      1,4 МБ
      Просмотров:
      710
    Последнее редактирование: 27 ноя 2016
    RxdTxd нравится это.
  9. RxdTxd

    RxdTxd Нуб

    Уважаемый Salk,спасибо Вам большое за скетч и фотографии, буду смотреть, разбираться!
     
  10. rkit

    rkit Гуру

    Нельзя.
     
    RxdTxd нравится это.
  11. Salk

    Salk Гик

    И это почему же, поясните? Питание на светодиоды поступает от тех же 5V, питающих сами 74HC595. Единственный минус, что может быть чуть заметна разница в яркости свечении. Т.е. 1 светодиод будет гореть ярче, а все 8 уже чуть тусклее, но это не так заметно и экономия, как времени на пайку, так и в стоимости.
     
  12. rkit

    rkit Гуру

    Светодиоды начнут сгорать один за другим через пол-года использования. И питаются они от тока, а не от напряжения. И светодиодов с напряжением в пять вольт я ни разу не встречал.
     
  13. alp69

    alp69 Форумчанин

    Разница будет ощутимой. rkit Вам дело говорит. Цитата из wiki:
     
  14. Salk

    Salk Гик

    Да, да, если все делать по правилам, скучно :)
    Иногда этими правилами можно пренебречь. Поставить, заведомо большего сопротивления, резистор, пусть яркость будет меньше для всех. Иногда на плате нет просто места или лень паять для каждого диода свой резистор, для мини-проекта :)
     
  15. alp69

    alp69 Форумчанин

    Дело Ваше...;) Но есть резисторные сборки. Неплохая вещь для таких целей.