Последовательное включение диодов друг за другом, помощь в скетче

Тема в разделе "Arduino & Shields", создана пользователем Samum, 30 ноя 2015.

  1. Samum

    Samum Нуб

    Здравствуйте, уважаемые участники форума. У нас с собой было
    В наличии arduino uno, 20 диодов, 3 сдвиговых регистра и огромное желание сделать так, чтобы эти 20 диодов включились друг за другом в столбик с 1 по 20, простояли включёнными некоторое время, далее всё погасло и столбик начинал расти заново. Как некая шкала или индикатор.
    За некоторое время изучения интернетов на предмет подобных решений родился скетч. Его итерации умеют:
    -зажигать диоды по отдельности, (т.е. первый горит,следующий гаснет)сверху вниз
    -и снизу вверх,
    - от любого диода в столбике до следующего любого диода,
    - все 20 диодов включаются одновременно
    - одновременно включается рандомное число диодов в столбике
    ..но научить его работать так, как мне надо не получилось. :(
    На всякий случай, выкладываю скетч, который зажигает и гасит диоды по отдельности друг за другом
    Код (C++):
    //ST_CP вход
    const int latchPin = 8;
    //SH_CP вход
    const int clockPin = 12;
    //DS вход
    const int dataPin = 11;

    void setup() {
      //режим OUTPUT
      pinMode(latchPin, OUTPUT);
      pinMode(dataPin, OUTPUT);
      pinMode(clockPin, OUTPUT);
    }

    void loop() {
      // проходим по всем выходам трёх регистров, 25 потому, что если 24
    // то последний диод не горит
      for (int thisLed = 0; thisLed < 25; thisLed++) {
      // записываем сигнал в регистр для очередного светодиода
      registerWrite(thisLed, LOW);
      // если это не первый светодиод, то отключаем предыдущий
      if (thisLed > 0) {
      registerWrite(thisLed - 1, HIGH);
      }
      // если это первый светодиод, то отключаем последний
      else {
      registerWrite(15, LOW);
      }
      // делаем паузу
      delay(250);
      }
    }
    // этим куском кода подключаем регистры в нужном кол-ве
    void registerWrite(int whichPin, int whichState) {
    // инициализируем и обнуляем байт
      byte bitsToSend[3] = {0, 0, 0};
      digitalWrite(latchPin, LOW);
      // устанавливаем HIGH в соответствующем бите
      bitWrite(bitsToSend[whichPin/8], whichPin%8, whichState);
      // проталкиваем байт в регистр
      for(int i = 0; i < 3; i++) shiftOut(dataPin, clockPin, LSBFIRST, bitsToSend[i]);
      // "защелкиваем" регистр, чтобы байт появился на его выходах
      digitalWrite(latchPin, HIGH);
    }
    Помогите, пожалуйста, в решении
    p.s. По аналогии с Экспериментом пульсар сделать тоже не получилось
     
  2. 9xA59kK

    9xA59kK Гик

    У тебя же все подписано, просто не отключай предыдущий светодиод. Тогда будет загораться по очереди все светодиоды. Если надо чтобы они после этого гасли в обратном порядке, тогда надо доработать код чтобы при достижении счета 16 напрмер менялся знак на "-" той переменной
    Код (C++):
    // если это не первый светодиод, то отключаем предыдущий
      if (thisLed > 0) {
       registerWrite(thisLed - 1, HIGH);
       }
    Удали эти строки и все.
    А если надо сначала чтобы столб из светодиодов рос, а потом уменьшался. То придется изменить код. И например использовать два условия IF. Первое отвечает за возрастание столба, а второе за уменьшение. Или тот же цикл For, но тогда придется менять знак переменной thisLed при достижении максимума на противоположный.

    Потренеруйся сначала без регистра сдвига. Логика работы одна. ЗАжги(напиши код) с помощью ардуины три светодиода последовательно один за другим с интервалом в пол секунды. Потом погаси все светодиоды. Вставь задержку в пол секунды в конце кода. И все это будет повторяться непрерывно - как раз как ты хотел.
     
    Последнее редактирование: 30 ноя 2015
  3. Samum

    Samum Нуб

    Большое спасибо за совет:)
    с помощью Ардуино уже получалось зажигать-гасить маленькую светодиодную шкалу(10 диодов) и привязывать к этой конструкции потенциометр и фоторезистор. Дело, видимо не в логике, а в каскаде из регистров.
     
  4. DrProg

    DrProg Вечный нерд

    3 последовательно соединенных регистра, к их выходным ножкам по светодиоду. Далее в программе заготавливаются и передаются на регистры три байта у которых постепенно добавляется по одному биту со сдвигом в следующий байт.
    Если я правильно понял, надо вот примерно так, только вместо вывода в ком-порт выводить в регистры:
    Код (C++):
    byte t1 = 0;
    byte t2 = 0;
    byte t3 = 0;

    void setup() {
      Serial.begin(9600);
    }

    void loop() {
      Serial.print(t3, BIN);
      Serial.print(t2, BIN);
      Serial.println(t1, BIN);
      t1 = t1 << 1;
      t2 = t2 << 1;
      t3 = t3 << 1;
      t1 |= 1;
      t2 |= (t1 == 0b11111111);
      t3 |= (t2 == 0b11111111);
      delay(200);
      if (t3 == 0b11111111) {
        t1=0;
        t2=0;
        t3=0;
      }
    }
     
    Последнее редактирование: 1 дек 2015
    ИгорьК, Samum и Tomasina нравится это.
  5. Tomasina

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

    а как вот это работает?
    Код (C++):
    t2 |= (t1 == 0b11111111);
     
  6. DrProg

    DrProg Вечный нерд

    Это условие. Когда первая переменная переполняется, результатом сравнения становится 1, она и двигается далее во второй и так же с третей переменной. Кстати, в данном случае есть недоработка, единичка должна перепрыгивать не сразу, а через раз, но пусть это будет "заданием на дом". )
     
    ИгорьК нравится это.
  7. Samum

    Samum Нуб

    Спасибо, буду пробовать. )