Выход из функции for после обнаружения препятствий

loop
#include <HCSR04.h>

int red = 13;
int green = 12;
int blue = 11;
int trigger = 9;
int echo = 8;
int halt;

void setup(){
  pinMode(red, OUTPUT);
  pinMode(green, OUTPUT);
  pinMode(blue, OUTPUT);
  pinMode(trigger, OUTPUT);
  pinMode(echo, INPUT);
  Serial.begin(9600);
}

void redLed(){
  rgb(255,0,0);
  delay(200);
}

void rgb(int r, int g, int b){
  analogWrite(red, r);
  analogWrite(green, g);
  analogWrite(blue, b);
}

void fadeBlu(){
  
    for (int i=0; i<=255; i+=5){
    rgb(0,0,i);
    delay(40);

    Serial.print("halt in IF is ");
    Serial.println(halt);
    }
    
    for(int i=255; i>=0; i-=5) {
      rgb(0,0,i);
      delay(40);

      Serial.print("halt ELSE is ");
      Serial.println(halt);
    } 
}

void human() {
  
  UltraSonicDistanceSensor distanceSensor(trigger, echo);
  double distance = distanceSensor.measureDistanceCm();
  halt = 0;

  // cover sensor
  if (distance<=30) {
    halt=0;
    redLed();
  }
  // no cover
    halt=-1;
    fadeBlu();
}

void loop(){
  human();
}

Я ищу способ выйти из цикла "for" функции fadeBlue (), если рука обнаружена перед датчиком. Я бы хотел, чтобы в любом случае выцветание и если есть рука перед датчиком, светодиод стал красным. В моем коде светодиод не остается красным, если я держу руку перед датчиком, а также значение "стоп" не меняется. Я поставил несколько serial.println, чтобы сделать отладку.

, 👍-1

Обсуждение

Вы пытались [сломать](https://www.arduino.cc/reference/en/language/structure/control-structure/break/) вышел из петли?, @Edgar Bonet

Нет, я не знаю, как использовать break здесь.. - я должен вломиться?, @tommy

если( [некоторое условие] ) возвращается;, @Gerben

Кроме того, вычислите яркость синего светодиода, основываясь на времени (millis()). Например, rgb(0,0, (millis()/40)%256);, @Gerben

Я не понимаю, как там использовать миллис.., @tommy


1 ответ


0

Во-первых, постарайтесь избежать дублирования кода, поэтому создайте вспомогательную функцию (я немного изменил инструкцию печати, но предполагаю, что это только для отладки):

void fadeBlu()
{
    fadeBlueCycle(0, 255, 5);
    fadeBlueCycle(255, 0, -5);
}

void fadeBlueCycle(uint8_t start, uint8_t end, int8_t step)
{
    for (int i = start; i != end; i += step)
    {
        rgb(0, 0, i);
        delay(40);

        Serial.print("halt in step ");
        Serial.print(step);
        Serial.println(halt);
    }
}

Теперь, чтобы вырваться из за, вы можете использовать breakили просто вернуться. Не рекомендуется использовать несколько операторов возврата в одной функции, поэтому ставьте ее в конце и используйте разрыв. Кроме того, некоторые люди не любят перерывов и предпочитают использовать "пока". Это будет выглядеть так:

void fadeBlueCycle(uint8_t start, uint8_t end, int8_t step)
{
    uint8_t i = start;
    bool condition = true;

    while ((i != end) && condition) // или !условие, в зависимости от того, что вы предпочитаете
    {
        rgb(0, 0, i);
        delay(40);

        Serial.print("halt in step ");
        Serial.print(step);
        Serial.println(halt);

        condition = `некоторое условие`;
        i += step;
    }
}
,

Хороший ответ, как обычно. Обратите внимание, что цикл for в C/C++ позволяет добавлять дополнительные проверки, поэтому вы также можете записать цикл for как for (int i = start; i < завершите && условие; i += шаг) и получите тот же эффект, что и цикл while, при этом цикл for будет управлять счетчиком., @Duncan C

@DuncanC Правда ... и лично мне не нравится эта концепция, так как она похожа на цикл "на время", написанный как цикл "для". Но это личное. Я видел много профессиональных проектов, использующих его таким образом (с "для"). Лично я рассматриваю цикл " для "как безусловный цикл, где заранее известно количество итераций, а цикл "пока" как условный цикл, где количество итераций заранее неизвестно. Заявление о "разрыве" в этом смысле можно обсудить. (Но все лучше, чем "гото")., @Michel Keijzers

Состояние в то время как в моем случае должно быть, если перед датчиком есть препятствия?, @tommy

Это зависит от ваших требований. Если вы хотите разорвать цикл на основе какого-либо условия, используйте необходимое вам условие. Цикл "в то время как" остановится, когда "условие" истинно, или вы можете использовать оператор не (!) (таким образом, "условие"), чтобы остановить цикл "в то время как", когда условие ложно., @Michel Keijzers

Я заметил, что разрыв происходит ТОЛЬКО после окончания цикла while, а не в любой момент, когда перед датчиком возникает препятствие, почему это происходит?, @tommy

Назначьте реализованное условие переменной " условие` и распечатайте его... Это должно измениться в соответствии с тем, что вы реализовали., @Michel Keijzers

Нет, я не могу понять, какое состояние мне там нужно. Единственным условием остановки цикла while должно быть что-то, связанное с расстоянием от датчика, (расстояние<=30) но я использовал это для функции человека ()..., @tommy

Давайте [продолжим это обсуждение в чате](https://chat.stackexchange.com/rooms/109490/discussion-between-tommy-and-michel-keijzers)., @tommy