Очень нужна помощь

Тема в разделе "Arduino & Shields", создана пользователем nerealnostkvest, 28 май 2015.

  1. nerealnostkvest

    nerealnostkvest Нерд

    Всем привет. Помогите пожалуйста, в силу не опытности, не могу решить проблему. Емею выходной сдвиговый регистр, к которому подключены светодиоды. Необходимо при выполнении определенных условий, мигать одним из диодов 5 секунд. Но без delay, так как еще выводится инфа на индикаторы, а из-за delay, все работает некорректно.

    Вот кусок кода. Как сюда добавить условие, что бы диод мигал 3 секунды.
    Код (Text):
    #include <Shift595.h>
    #define  dataPin          11      // pin 14 on the 74HC595
    #define  latchPin          10      // pin 12 on the 74HC595
    #define  clockPin          12
    #define  numOfRegisters    1
    #define LED 7
    Shift595 Shifter(dataPin, latchPin, clockPin, numOfRegisters);


    int ledState = LOW;          
    unsigned long previousMillis = 0;        // will store last time LED was updated


    const long interval = 1000;          // interval at which to blink (milliseconds)

    void setup() {
      // set the digital pin as output:

    }

    void loop()
    {

      unsigned long currentMillis = millis();
      if(currentMillis - previousMillis >= interval) {
     
        previousMillis = currentMillis;

       
        if (ledState == LOW)
          ledState = HIGH;
        else
          ledState = LOW;

     
        Shifter.setRegisterPin(LED, ledState);
      }
    }
    Буду очень благодарен за подсказку. Проект очень горит.
     
  2. DrProg

    DrProg Вечный нерд

    Зачем такие сложности с отдельной библиотекой, если все решается штатными функциями. Вот для вывода переменной на регистр:
    Код (Text):
      digitalWrite(latchPin, LOW);
      shiftOut(sataPin, clockPin, LSBFIRST,    byteMask);
      digitalWrite(latchPin, HIGH);
    Нужный светодиод установить так:
    Код (Text):
    byteMask = 0;
    bitSet(byteMask,n);
    где n - номер бита где нужно включить светодиод.

    То есть вывели нуль - все темно. Поставили 1 в нужный бит, вывели - загорелся. Выждали секунду или сколько там и снова нуль вывели, опять темно. И так далее сколько нужно.
     
  3. nerealnostkvest

    nerealnostkvest Нерд

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

    Не подскажите как в моем случае можно задать мигание в течении 3 секунд?
     
  4. DrProg

    DrProg Вечный нерд

    Давайте лучше напишу как мигать без библиотек. )
    В чем суть? Какой должен мигать светодиод? Любой или разные? От чего должно зависеть?

    Вижу скетч писан не очень профессионально, вот такая конструкция например:
    Код (Text):
    if (ledState == LOW)
          ledState = HIGH;
        else
          ledState = LOW;
     
    пишется как:
    Код (Text):
    ledState = !ledState;
     
    Последнее редактирование: 28 май 2015
  5. nerealnostkvest

    nerealnostkvest Нерд

    Буду очень вам признателен за помощь) Кусок кода, который вы привели как пример, брал из образцов в Arduino IDE ))

    Вообщем какая задача:
    1. Есть потенциометр, подключенный к А0
    2. Три диода, красный, синий, зеленый, подключенные к регистру.
    3. При включении должен гореть красный диод, при достижении определенной границы, которая получается с А0, красный выключается, и начинает мигать синий с интервалом в секунду, в течении 5 секунд. После того как прошло 5 секунд, синий гаснет, и включается зеленый.

    И это все должно работать без delay. Так как он мешает работе таймера и вывода значений на дисплей.
     
  6. DrProg

    DrProg Вечный нерд

    Еще один вопрос: а обязательно через регистр? Если светодиода всего три и пинов для регистра используется три, не проще ли прицепить их напрямую?
     
  7. nerealnostkvest

    nerealnostkvest Нерд

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

    DrProg Вечный нерд

    Код на схеме не проверялся, но должен работать. Если что, достругать напильником:

    Код (Text):
    #define pinData  11
    #define pinLatch 10
    #define pinClock 12
    #define pinA0 A0

    unsigned migTime;
    byte ledM;
    int interval = 500; // интервал мигания в мс, вкл и столько же выкл, если нужна другая пропорция, то добавить еще одну переменную

    void setup() {
      pinMode(pinData, OUTPUT);
      pinMode(pinLatch, OUTPUT);
      pinMode(pinClock, OUTPUT);
    }

    void loop() {
      // зажигаем led 1 (красный)
      ledM = 0b10000000; // для пущей наглядности ряд битов в двоичном виде 0 - не горит, 1 - горит
      ledON(ledM);

      // тут нужен кусок кода ждущий пока А0 не созреет для перехода на следующий уровень, например:
     while (digitalRead(pinA0) <= 500);

      // зажигаем led 2 (синий) и мигаем им 5 сек
      for (int i = 0; i <= 4; i++) {
        ledM = 0b01000000;
        ledON(ledM); //вкл
        migTime = millis();
        while ((millis() - migTime) < interval); // ждем
        ledOFF(); // выкл
        migTime = millis();
        while ((millis() - migTime) < interval); // ждем
      }

      // зажигаем led 3 (зеленый)
      ledM = 0b00100000;
      ledON(ledM);

      // тут я вешаю контроллер т.к. не знаю что делать дальше
      while (true);
    }

    void ledON (byte ledMask) { //выбранный единицей светодиод загорается
      digitalWrite(pinLatch, LOW);
      shiftOut(pinData, pinClock, LSBFIRST, ledMask); // если загораетя не с того конца, поменять на MSBFIRST
      // если нужен второй регистр и так далее
      //    shiftOut(pinData, pinClock, LSBFIRST, ledMask);
      digitalWrite(pinLatch, HIGH);
    }

    void ledOFF () { //светодиод гаснет - вместо этого можно использовать ledON(0);
      digitalWrite(pinLatch, LOW);
      shiftOut(pinData, pinClock, LSBFIRST, 0);
      // если нужен второй регистр и так далее
      // shiftOut(pinData, pinClock, LSBFIRST, 0);
      digitalWrite(pinLatch, HIGH);
    }
    Возможно, некоторые участки получилось бы сделать изящнее, но время позднее, голова уже наполовину спит. Попробуйте пока так.
     
    Последнее редактирование: 29 май 2015
    nerealnostkvest нравится это.
  9. nerealnostkvest

    nerealnostkvest Нерд

    Спасибо большое, код работает. Есть только два вопроса:
    1. Как все таки подключить второй регистр, если второй подключен каскадом к первому? Например если надо вывести бит с пина 1 первого регистра, и пина 0 второго?

    2. При мигании синего диода, таймер остановился. После переключения на зеленый диод, снова продолжил работу. Может ли быть какой то конфликт, если функция таймера тоже использует millis() ?
     
  10. Megakoteyka

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

    Дело не в конфликте, а в том, что
    Код (Text):
    migTime = millis();
    while ((millis() - migTime) < interval); // ждем
    ничем не отличается от delay и точно также вешает программу.
    Чтобы программа не вешалась, нужно сделать автомат на switch и переключать его состояния по достижении заданных условий.
     
  11. DrProg

    DrProg Вечный нерд

    1. Ножка Q7' (со штрихом) соединяется с ножкой DS второго регистра, Q7' второго с DS третьего и так далее, ножки latch и clock соединяются у всех регистров. После подачи LOW на latch подаются данные на data, второй байт пропихивает первый байт во второй регистр, третий пропихивает первый в третий, а второй во второй и так далее, то есть последний поданный байт остается в первом, после чего регистры защелкиваются при помощи HIGH на latch и на ножках выхода появляется сигнал.

    2. Таймер не останавливается, он продолжает работу. Но, как сказали выше, что при delay, что вариант в while контроллер просто ждет пока пройдет определенное количество времени и ничего другого в этот момент не делает. А что он должен делать?
     
  12. nerealnostkvest

    nerealnostkvest Нерд

    1. Подключить то я подключил) А вот как написать код, что бы вывести например одновременно байт с первого и второго, что то не пойму.
    2. Мне самое главное, что бы в этот момент, продолжала выводиться информация на индикатор http://amperka.ru/product/troyka-quad-display. Т.е. все время работы программы, на индикатор выводится отсчет от 2 минут и до нуля.
     
  13. DrProg

    DrProg Вечный нерд

    Выводить вот так:
    Код (Text):
      digitalWrite(pinLatch, LOW);
      // второй регистр:
      shiftOut(pinData, pinClock, LSBFIRST, ledMask_2);
      // первый регистр:
      shiftOut(pinData, pinClock, LSBFIRST, ledMask_1);
      digitalWrite(pinLatch, HIGH);
    выведутся оба одновременно.

    Про индикатор пока сказать не могу. Он точно подключен к другим ногам? По идее не должен никак быть связан с событиями на регистрах, во время delay и прочих ожиданий картинка замирает и все. Работаете с ним при помощи библиотеки? Может быть там пины задействованы те, которые на регистры идут. Попробуйте пины сменить.
     
  14. nerealnostkvest

    nerealnostkvest Нерд

    1. С регистром сделал как вы сказали, задав еще одну переменную byte ledMask2, вывод прописал так, основываясь на вашем предыдущем коде
    Код (Text):
    ledMask2 = 0b10000000;
    ledON(ledMask2);
    Выдает ошибку
    collect2.exe: error: ld returned 5 exit status

    2. Индикатор не подключен к регистру. Подключен на отдельный выход ардуины. Но как только заходит в while при считывании данных с потенциометра, то тут же гаснет. Хотя таймер продолжает считать время. Если выйти из while, то инфа на него снова выводится.
     
  15. DrProg

    DrProg Вечный нерд

    Переменная ledMask2 была объявлена? Вторая строка в ledOn раскоменчена? Второй входной байт в функцию добавлен? Передача данных на два регистра должна быть между общими LOW и HIGH на latch. Попробуйте такой код для двух регистров:

    Код (Text):
    void ledON (byte ledMask_1, byte ledMask_2) { // для двух регистров
      digitalWrite(pinLatch, LOW);
      shiftOut(pinData, pinClock, LSBFIRST, ledMask_1);
      shiftOut(pinData, pinClock, LSBFIRST, ledMask_2);// ledMask_1 пропихивается во второй регистр, если нужно наоборот, поменять местами
      digitalWrite(pinLatch, HIGH);
    }
     
    Почему индикатор гаснет не понятно, по идее при таком скетче он должен всего лишь замирать пока мигает синий светодиод. Замирание можно обойти, например вызывая в промежутках между миганием функцию отсчета времени. Но почему гаснет? У мена такого индикатора нет, проверить не могу.
     
    Последнее редактирование: 29 май 2015
  16. nerealnostkvest

    nerealnostkvest Нерд

    вот весь код:
    Код (Text):
    #define pinData  11
    #define pinLatch 10
    #define pinClock 12
    #define pinA0 A0

    unsigned migTime;
    byte ledMask;
    byte ledMask2;

    //int clean=0;
    void setup() {
      pinMode(pinData, OUTPUT);
      pinMode(pinLatch, OUTPUT);
      pinMode(pinClock, OUTPUT);
      pinMode(pinA0, INPUT);
    }

    void loop() {
      // зажигаем led 1 (красный)
    //  ledMask = 0b00001000; // для пущей наглядности ряд битов в двоичном виде 0 - не горит, 1 - горит
    //  ledON(ledMask);
      ledMask2 = 0b10000000; // для пущей наглядности ряд битов в двоичном виде 0 - не горит, 1 - горит
      ledON(ledMask, ledMask2);
      // тут нужен кусок кода ждущий пока А0 не созреет для перехода на следующий уровень, например:
      while (analogRead(pinA0)>500&&analogRead(pinA0)<600){
     
      // зажигаем led 2 (синий) и мигаем им 5 сек
      for (int i = 0; i <= 3; i++) {
        ledMask = 0b00010000;
        ledON(ledMask, ledMask2);
        migTime = millis();
        while ((millis() - migTime) < 1000);
        ledOFF();
        migTime = millis();
        while ((millis() - migTime) < 1000);
      }
     
      ledMask = 0b00000100;
      ledON(ledMask, ledMask2);
    //  clean=1;
      }
      // зажигаем led 3 (зеленый)
     

      // тут я вешаю контроллер т.к. не знаю что делать дальше
    //  while (true);
    }

    void ledON (byte ledMask, byte ledMask2) { //выбранный единицей светодиод загорается
      digitalWrite(pinLatch, LOW);
     
      shiftOut(pinData, pinClock, LSBFIRST, ledMask); // если загораетя не с того конца, поменять на MSBFIRST
      // если нужен второй регистр и так далее
      shiftOut(pinData, pinClock, LSBFIRST, ledMask2);
      digitalWrite(pinLatch, HIGH);
    }

    void ledOFF () { //светодиод гаснет - вместо этого можно использовать ledON(0);
      digitalWrite(pinLatch, LOW);
      shiftOut(pinData, pinClock, LSBFIRST, 0);
      // если нужен второй регистр и так далее
      //shiftOut(pinData, pinClock, LSBFIRST, 0);
      digitalWrite(pinLatch, HIGH);
    }
    все равно ошибка:
    collect2.exe: error: ld returned 5 exit status
     
  17. DrProg

    DrProg Вечный нерд

    Скопипастил, у меня компильнулось нормально. Попробуйте, сохранив скеч, перезапустить IDE. Иногда бывают такие глюки.
     
  18. nerealnostkvest

    nerealnostkvest Нерд

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

    DrProg Вечный нерд

    Какой IDE стоит? Если на моем компилируется, то и на вашем должен. А где именно показывает ошибку?
     
  20. nerealnostkvest

    nerealnostkvest Нерд

    Смогло скомпилиться, только после того как перенес
    Код (Text):
    byte ledMask;
    byte ledMask2;
    в начало loop.
    В итоге первый регистр исправно выводит, второй нет. IDE 1.6.3. Показывает в черном окне под кодом.