Некоторые блоки кода зацикливаются, не знаю почему

Приведенный ниже код застревает в функции "Светодиод выключен?" &ампер; «Кнопка проверки». Я использую редактор Blockyduino. Код кнопки проверки был задуман как тумблер для освещения. Когда я удалил "Led Off?" и "Выключить все светодиоды", код не застрял.

int Button_Status;

// Код переключения для кнопки.
void Check_Button() {
  Serial.println("Check button Activated");
  if (Button_Status == 1) {
    if (digitalRead(13)) {
      Button_Status = 0;
    }
  }
  if (Button_Status == 0) {
    if (digitalRead(13)) {
      Button_Status = 1;
    }
  }
  LED_OFF_();
}

void Left_Animation() {
  Check_Button();
  digitalWrite(2, HIGH);
  digitalWrite(3, HIGH);
  Check_Button();
  delay(1000);
  digitalWrite(4, HIGH);
  digitalWrite(5, HIGH);
  Check_Button();
  delay(500);
  digitalWrite(2, LOW);
  digitalWrite(3, LOW);
  Check_Button();
  delay(300);
  digitalWrite(4, LOW);
  digitalWrite(5, LOW);
  Serial.println("Finshed Left cycle");
}

void Right_Animation() {
  Check_Button();
  digitalWrite(8, HIGH);
  digitalWrite(9, HIGH);
  Check_Button();
  delay(1000);
  digitalWrite(10, HIGH);
  digitalWrite(11, HIGH);
  Check_Button();
  delay(500);
  digitalWrite(8, LOW);
  digitalWrite(9, LOW);
  Check_Button();
  delay(300);
  digitalWrite(10, LOW);
  digitalWrite(11, LOW);
  Serial.println("Finished Right cycle");
}

// Ядро основного цикла
void Main_Loop() {
  while (Button_Status == 1) {
    Left_Animation();
    Right_Animation();
    Serial.println("Finshed Main Loop 1111");
  }
  while (Button_Status == 0) {
    Check_Button();
    Serial.println("Finished Main Loop 2222");
  }
}

// Проверяет, отключена ли переменная кнопки-переключателя.
void LED_OFF_() {
  Serial.println("LED off? Activated");
  if (Button_Status == 0) {
    Turn_Off_All_LED();
  }
  Main_Loop();
}

// Выключает все светодиоды
void Turn_Off_All_LED() {
  Serial.println("LED Turn off Activated");
  digitalWrite(2, LOW);
  digitalWrite(3, LOW);
  digitalWrite(4, LOW);
  digitalWrite(5, LOW);
  digitalWrite(6, LOW);
  digitalWrite(7, LOW);
  digitalWrite(8, LOW);
  digitalWrite(9, LOW);
  digitalWrite(10, LOW);
  digitalWrite(11, LOW);
  Main_Loop();
}

void setup()
{
  Serial.begin(9600);
  pinMode(13, INPUT);
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);
  pinMode(11, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
}

void loop()
{
  // Начинать
  Button_Status = 1;
  Main_Loop();
}

, 👍1


1 ответ


1

В этой программе возникла проблема с бесконечной рекурсией: loop() вызывает Main_Loop(), который вызывает Left_Animation(), который вызывает Check_Button(), который вызывает LED_OFF_(), который вызывает Main_Loop(), который вызывает Left_Animation(), который вызывает Check_Button(), который вызывает LED_OFF_(), который вызывает Main_Loop(), который вызывает... Это будет довольно быстро исчерпывает память вашего Arduino.

Если вы разбираетесь только в графическом программировании, это может не иметь большого значения. смысла для вас. Поэтому я прошу вас представить, что в вашем определении Main_Loop() (большая структура с названием «to Main Loop») вы заменяете маленькое поле с надписью «Левая анимация» по собственному определению (большой структура с надписью «to Left Animation»). В рамках этого определения вы замените «Кнопку проверки» ее собственным определением и так далее. Ты будешь скоро достигните точки, когда вам нужно внедрить определение Main_Loop() внутри себя. Это должно выглядеть примерно так:

Основной цикл
│ повторять, пока Состояние кнопки = 1
│ сделать левую анимацию
│ │ │ Кнопка проверки
│ │ │ │ Серийный номер Печать «Кнопка проверки активирована»
│ │ │ │ ...
│ │ │ │ Светодиод ВЫКЛ?
│ │ │ │ │ Серийный номер Печать «Светодиод выключен? активирован»
│ │ │ │ │ если Состояние кнопки = 0
│ │ │ │ │ do Выключить все светодиоды
│ │ │ │ │ Основной цикл
│ │ │ │ │ │ повторять, пока Состояние кнопки = 1
│ │ │ │ │ │ do Левая анимация
│ │ │ │ │ │ │ │ Кнопка проверки
│ │ │ │ │ │ │ │ │ Серийный номер Печать «Кнопка проверки активирована»
│ │ │ │ │ │ │ │ │ ...
│ │ │ │ │ │ │ │ │ Светодиод ВЫКЛ?
│ │ │ │ │ │ │ │ │ │ Серийный номер Печать «Светодиод выключен? активирован»
│ │ │ │ │ │ │ │ │ │ если Состояние кнопки = 0
│ │ │ │ │ │ │ │ │ │ do Выключить все светодиоды
│ │ │ │ │ │ │ │ │ │ Основной цикл
│ │ │ │ │ │ │ │ │ │ │ повторять, пока Состояние кнопки = 1
│ │ │ │ │ │ │ │ │ │ │ do Левая анимация
│ │ │ │ │ │ │ │ │ │ │ │ │ Кнопка проверки
│ │ │ │ │ │ │ │ │ │ │ │ │ │ Серийный номер Печать «Кнопка проверки активирована»
│ │ │ │ │ │ │ │ │ │ │ │ │ │ ...
│ │ │ │ │ │ │ │ │ │ │ │ │ │ Светодиод ВЫКЛ?
│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ Серийный номер Печать «Светодиод выключен? активирован»
│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ если Состояние кнопки = 0
│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ do Выключить все светодиоды
│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ Основной цикл
...и так до бесконечности...

Обратите внимание, что можно писать программы, используя рекурсию, но:

  1. Это своего рода «продвинутая тема», не подходящая для кого-то еще программирование на графическом уровне.
  2. Вы должны принять меры предосторожности, чтобы избежать бесконечно рекурсивно.
  3. На микроконтроллере с небольшим объемом памяти необходимо убедиться, что рекурсия всегда очень поверхностна. Это сложно, поэтому люди пишут встроенный код вообще избегает рекурсии.
,