Помогите заменить все задержки с delay() на millis()

Тема в разделе "Arduino & Shields", создана пользователем Bornigan, 26 апр 2019.

Метки:
  1. Bornigan

    Bornigan Нерд

    Доброе время суток.
    В детсаду попросили изготовить светофор для обучения ПДД наших детишек.
    Так как в программированием я занимаюсь крайне редко и в основном на уровне копипаста и найти готовый вариант под наши запросы не смог в сети, то пришлось самостоятельно набросать алгоритм поведения светофора. Только вот мигание и переключение светодиодов, как и большинство новичков, реализовал через функцию delay()
    Хотелка у воспитателей следующая:
    Помимо автоматического режима работы должна быть возможность перевести светофор в ручной режим управления, для этого я хочу прикрутить библиотеку кнопок от уважаемого AlexGyver. Но чтобы работал опрос состояния кнопок мне нужно избавиться от delay(), ибо контроллер тупо висит на паузе и не обрабатывает нажатий кнопок.
    Не буду постить мой нерабочий код с вариантом прикрученной библиотекой. Кто сможет, гляньте ниже код и скажите как все тоже самое сделать с функцией millis()?
    Код (C++):
    /*
      Светофор для старшей группы детского садика "Северянка"
      Arduino Pro Mini + 12 LED WS2812B
      (C) Папа Селезнёва Романа
    */


    #define led_strip_1 2
    #define led_strip_2 3
    #define leds_num 3

    #include <Adafruit_NeoPixel.h>
    Adafruit_NeoPixel traffic1 = Adafruit_NeoPixel(leds_num, led_strip_1, NEO_RGB + NEO_KHZ800);
    Adafruit_NeoPixel traffic2 = Adafruit_NeoPixel(leds_num, led_strip_2, NEO_RGB + NEO_KHZ800);

    void setup() {
      traffic1.begin();
      traffic2.begin();
      traffic1.clear();
      traffic2.clear();
      traffic1.show();
      traffic2.show();
    }

    void loop() {
      // зажигаем красный на лицевой панели и зеленый сбоку
      traffic1.clear();
      traffic2.clear();
      traffic1.setPixelColor(2, traffic1.Color(0, 150, 0));
      traffic2.setPixelColor(0, traffic1.Color(150, 0, 0));
      traffic1.show();
      traffic2.show();
      delay(10000);
      // зеленый начинает мигать
      for (int i = 0; i < 2; i++) {
        traffic2.setPixelColor(0, traffic1.Color(0, 0, 0));
        traffic2.show();
        delay(400);
        traffic2.setPixelColor(0, traffic1.Color(150, 0, 0));
        traffic2.show();
        delay(400);
        traffic2.clear();
      }
      // зеленый сбоку продолжает мигать, загорается желтый на лицевой
      for (int i = 0; i < 3; i++) {
        traffic1.setPixelColor(1, traffic1.Color(150, 150, 0));
        traffic1.show();
        traffic2.setPixelColor(0, traffic1.Color(0, 0, 0));
        traffic2.show();
        delay(400);
        traffic2.setPixelColor(0, traffic1.Color(150, 0, 0));
        traffic2.show();
        delay(400);
      }
      // выключаются все, загорается зеленый на лицевой панели и красный сбоку
      traffic2.clear();
      traffic1.clear();
      traffic2.setPixelColor(2, traffic1.Color(0, 150, 0));
      traffic2.show();
      traffic1.setPixelColor(0, traffic1.Color(150, 0, 0));
      traffic1.show();
      delay(10000);
      // зеленый на лицевой начинает мигать
      for (int i = 0; i < 2; i++) {
        traffic1.setPixelColor(0, traffic1.Color(0, 0, 0));
        traffic1.show();
        delay(400);
        traffic1.setPixelColor(0, traffic1.Color(150, 0, 0));
        traffic1.show();
        delay(400);
        traffic1.clear();
      }
      //зеленый на лицевой продолжает мигать, загорается желтый сбоку
      for (int i = 0; i < 3; i++) {
        traffic2.setPixelColor(1, traffic1.Color(150, 150, 0));
        traffic2.show();
        traffic1.setPixelColor(0, traffic1.Color(0, 0, 0));
        traffic1.show();
        delay(400);
        traffic1.setPixelColor(0, traffic1.Color(150, 0, 0));
        traffic1.show();
        delay(400);
      }
    }
    P.S. Почему выбор пал на светодиоды WS2812B?... Да потому что у меня их еще вагон и маленькая тележка.
     
  2. DetSimen

    DetSimen Guest

    300р/delay()
     
  3. b707

    b707 Гуру

    Дед прав - такое беслатно не делают
     
  4. Airbus

    Airbus Радиохулиган Модератор

    Странная хотелка.Детсад это институт?А воспитатель это Препод?Другово смысла замены delay на millis именно в этом коде не вижу.Можно сделать ручное управление из прерывания-Препод оценит.И поставит 5
     
    DetSimen нравится это.
  5. DetSimen

    DetSimen Guest

    Я, главна, смысла не вижу delay() менять. Вроде ничего, кроме моргания светодиодами, эта карикатура не делает.
     
  6. Airbus

    Airbus Радиохулиган Модератор

    Классическое задание для студентов.Надо уже в отдельную тему вывести и закрепить чтоб 1001 раз не писали.
     
  7. DetSimen

    DetSimen Guest

    ну там же написано, что это папа Селезнева Романа, садик Серевянка...
    Пошто ты думаешь, что он в 45 лет еще скудентик?
     
  8. vvr

    vvr Инженерище

    деде, дык тс написал же, что хочет ручное управление прицепить и делеи мешают этому.
    а как делеи поменять на милис он не знает.
     
  9. b707

    b707 Гуру

    трешник за все - и переделаем :)
     
  10. KindMan

    KindMan Гуру

    Так на сайте Ардуино тоже написано
    ...easy-to-use hardware and software. It's intended for anyone making interactive projects.
    Но вот не фига изи и эниван не получилось.
    Я кому-то делал образец светофора, вот тут с миллис. Но там просто копипастом не обойтись
     
  11. DetSimen

    DetSimen Guest

    ТС, каков уровень твоих сакральных знаний в Си? Если Ctrl+C + Ctrl+V чужого кода, то ответ будет один, если шаришь хоть чучуть, я тебе ссылку дам, где, разобравшысь, сможешь сам смонстрячить всё что угодно.
     
  12. !@#$

    !@#$ Нерд

    Это замена последнего delay твоего скетча
    ***
    if( round(millis()/100%4 != 0)) //Эквивалент delay (400). Эту строчку писать перед выполнением задерживаемого события
    { traffic1.setPixelColor(0, traffic1.Color(150, 0, 0));
    traffic1.show()};
    // delay(400);
    else {traffic1.clear()};
    А это если нужно 10 секунд: ( round(millis()/1000%10 != 0)
     
  13. b707

    b707 Гуру

    if( round(millis()/100%4 != 0)) - крайне корявый и ненадежный метод. Не стоит советовать плохое.
     
  14. DetSimen

    DetSimen Guest

    типичный авнакод.
     
  15. !@#$

    !@#$ Нерд

    Зато не надо флагами размахивать. Работает нормально. Сбоев не видел. У себя применяю.
     
  16. parovoZZ

    parovoZZ Гуру

    а что не так с флагами?
     
  17. b707

    b707 Гуру

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

    Но это если б вы написали правильно. А у вас написан полный аллес капут. ТС нужно выдавать логический "1" ОДИН РАЗ в 400 мс. А ваш код что делает? Вы хоть его понимаете, или где-то тупо скопировали? Ваш IF будет выдвать логичический "1" при каждом обращении в течении 300мс, а потом в течении 100мс будет выдавать "0".
     
  18. Bornigan

    Bornigan Нерд

    Правильно говоришь, становлюсь кузнецом по мере свободного времени, к сожалению ВУЗов не кончал и в 45 уже не до того. Знания поверхностные, особо не засиживаюсь за программированием, но чтобы не терять из виду спины молодежи, идущих в ногу со временем сам себе придумываю задания. Так что если поделишься наработками, честно, постараюсь в них разобраться. О копипасте, разумеется иронизировал, всем же понятно, что когда нужно быстро, сначала находишь что-то чужое, потом обтесываешь под себя, это я о тех, чей уровень как раз с моим совпадает. Учиться с чето-то же нужно.
    Теперь к хейтерам обращаюсь.
    Не нужно говорить, что мне это уже не нужно. Я сам принимаю решения как дожить до моего "обнуления". Уж точно ТВ меня смотреть не заставите, машину продал, чтобы катать на веле, винду снес с пол-года назад, чтобы не прозибать с мышиной тыкалкой, а запускать проги из терминала из под рута, да еще в говняной гноме 3. И мне это все по душе, чувствуется, что старость еще где-то далеко за горами.
     
    b707 и parovoZZ нравится это.
  19. b707

    b707 Гуру

    ну, 45 это совсем не много. Совсем не старость, а скорее наоборот - пик интеллектуальной жизни. Я сам ардуину впервые увидал в 47 :)
     
  20. KindMan

    KindMan Гуру

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