Почему это не срабатывает как задержка?

Я начну с того, что скажу, что я очень-очень новичок в кодировании, поэтому, пожалуйста, откровенничайте со мной.

Я выполняю задание, в котором задача состоит в создании системы светофоров, но задержки блокировки не допускаются. Я изучил "мигать без задержки", но, похоже, этот вариант потребует от меня создания слишком запутанного и длинного кода, чем это необходимо. Поэтому вместо этого я использовал функции для, else и goto вместе, так как это было намного проще и чище,но я слышал, что goto не является предпочтительным вариантом,

for(int i = 0; i < 20; i = i + 1)
{
    break0:
    digitalWrite(Traffic_R, HIGH);
    long int CurrentMillis1 = millis();
    
    break1:
    if (millis() - CurrentMillis1 <= 250){
        digitalWrite(Pedestrian_R, HIGH);
        goto break1;
    }else{
        long int CurrentMillis2 = millis();
        
        break2:
        if (millis() - CurrentMillis2 <= 250){
            digitalWrite(Pedestrian_R, LOW);
            goto break2;
        }
    }
}

Затем я сделал другой путь без функции goto,

for(int Test1 = millis(); Test1 < 7500; Test1 + millis())
{
  digitalWrite(LED, HIGH);
}

TLDR Поэтому мой вопрос в том, является ли любой из этих методов "методом блокировки", как и задержка? Также каковы плюсы и минусы каждого метода? Также я могу загрузить код для первого метода, если это необходимо. Заранее огромное спасибо!

, 👍-1

Обсуждение

Я действительно не согласен с тем, что этот код “проще и чище”. 1 - е решение-это то, что вы назвали бы “кодом спагетти”, и оно не делает ничего, кроме “занятого ожидания”, т. Е. Оно не позволит вам делать что-либо еще, пока происходит задержка (как и обычная “задержка ()”). 2 - е решение также “занято ожиданием”, но немного более чистый код. Причина, по которой существуют такие решения, как “мигание без задержки”, заключается в том, что они позволяют вашему коду задерживать некоторые вещи (например, включение светодиода в определенном ритме), продолжая при этом другие (например. Проверка наличия кнопки или обработка ввода-вывода). Ваш код не может этого сделать., @StarCat

TBH, ваше первое решение выглядит уродливо, как с точки зрения логики потока управления, так и отступов. И, как говорит StarCat, нет никакой разницы между циклом ожидания с занятостью и использованием " delay ()". Ваше второе решение не работает, главным образом потому, что "Test1" не изменяется в цикле. -- В любом случае, нет необходимости повторно вызывать "digitalWrite ()" с одними и теми же аргументами., @the busybee

**[Старайтесь избегать использования гото, говорят, что это плохая практика](https://stackoverflow.com/questions/3517726/what-is-wrong-with-using-goto)**, @Giorgos Xou

**Забавный факт:** *(Здесь, в Греции [я не знаю, есть ли где-нибудь еще])* **мы называем гото "белой вороной" программирования**, @Giorgos Xou


2 ответа


2

Здесь у меня есть простой пример переключения на 3 светодиода с одинаковой "задержкой" для каждого светодиода.

void loop() {

  static unsigned long previousMillis;
  static uint8_t cycleCounter;

  if (millis() - previousMillis > 100) {
    previousMillis = millis();
    digitalWrite(LEDS_CENTRAL_PIN, cycleCounter == 0);
    digitalWrite(LEDS_LEFT_PIN, cycleCounter == 1);
    digitalWrite(LEDS_RIGHT_PIN, cycleCounter == 2);
    cycleCounter++;
    if (cycleCounter == 3) {
      cycleCounter = 0;
    }
  }
}
,

2
break1: 
if (something) 
  goto break1; 

это в основном цикл while - просто более запутанный для чтения.


Также я могу загрузить код для первого метода, если это необходимо.

Вы, конечно, можете загрузить его. Лично я бы отметил вас за использование goto.


является ли любой из этих методов "методом блокировки", как и задержка?

Ни один из методов буквально не блокирует. Функция задержки блокируется, потому что она не возвращается до истечения времени. Ваши циклы не блокируются, потому что вы, возможно, могли бы сделать что-то еще в цикле.


Я слышал, что гото не является предпочтительным вариантом

По уважительной причине. Как вы думаете, если бы вы снова посмотрели на свой код через год, вы бы легко его поняли? Я кодирую уже много лет и должен был бы тщательно следить за всеми способами, которыми goto может перемещаться неожиданными способами.

По крайней мере, с циклом while у вас есть четко определенные начало и конец цикла.

,