Как выполнить цикл for один раз в loop

Тема в разделе "Технологии радиолюбителя", создана пользователем Mr_dsa1, 20 июн 2018.

  1. Mr_dsa1

    Mr_dsa1 Нуб

    Дело в том, что я делаю умную подсветку, которая включается на движение, когда темно. На днях решил улучшить программную сторону, мне надо чтоб лента плавно включается и дальше горела (а не постоянно плавно включалась) и тоже само чтоб плавно выключалась и всё. Посоветуйте как такое можно сделать.

    Схема - https://www.screencast.com/t/ry8m3aZez

    Код:
    Код (C++):
    #define move_sensor 8   // датчик движения
    #define mosfet 3   // мосфет модуль
    void setup() {
    pinMode(mosfet, OUTPUT); // Объявляем пин мосфета как выход
    digitalWrite(mosfet, HIGH); // Выключаем мосфет - посылаем высокий сигнал
      delay(1000);
    digitalWrite(mosfet, LOW);   //Выключаем мосфет - посылаем низкий сигнал (это для тестирования что всё хорошо)
    }

    void loop() {
    int light = analogRead(A0);
    Serial.println(light);

    if ((light < 75 ) && (digitalRead(move_sensor) == HIGH ) )
      {
       for(int i=0;i<=255;i++)    // собственно вот это и надо один раз выполнить
    {
      analogWrite(3, i);
      delay(5); // ставим задержку для эффекта
    }
       delay(15);
       digitalWrite(mosfet, HIGH);
       }
    else if (digitalRead(move_sensor)==LOW)
        {
         digitalWrite(mosfet, LOW);
        }
         }
     
  2. добавить событие по которому отрабатывает цикл
     
  3. Mr_dsa1

    Mr_dsa1 Нуб

    Можешь пожалуйста пример навести, а то я не совсем понял что именно нужно.
     
  4. SergeiL

    SergeiL Гуру

  5. Mr_dsa1

    Mr_dsa1 Нуб

    Ага, окей спасибою.
     
  6. Mr_dsa1

    Mr_dsa1 Нуб

    Я уже сделал плавное включение, конечно знаю что код возможно не совсем грамотный (со стороны программирования). Но я так подумал лучше сделать код работу которого ты полностью понимаешь, чем слепо копировать чужой, который будет работать, но в котором ты почти ничего не понял. Тем более я предусмотрел в корпусе отверстие для мини-usb, так что когда придет время, я спокойно смогу перепрошить. А пока пускай так будет. Если будут поправки к коду, буду рад выслушать.
    Код (C++):
    int i = 0;
    #define move_sensor 8   // датчик движения
    #define mosfet 3   // мосфет модуль
    void setup() {
      pinMode(mosfet, OUTPUT); // Объявляем пин реле как выход
      digitalWrite(mosfet, HIGH); // Выключаем мосфет - посылаем высокий сигнал
      delay(1000);
      digitalWrite(mosfet, LOW);   //Выключаем мосфет - посылаем низкий сигнал (это для тестирования что всё хорошо)
      Serial.begin(9600);
    }

    void loop() {
      int light = analogRead(A0);
      Serial.println(light);

      if ((light < 75 ) && (digitalRead(move_sensor) == HIGH ))
      {
        if ((i < 255) && (i != 255))
        {
          for (int i = 0; i <= 255; i++)
          {
            analogWrite(3, i);
            delay(5); // ставим задержку для эффекта
          }
        }
        else
        {
          digitalWrite(mosfet, HIGH);
        }
      }
      else if (digitalRead(move_sensor) == LOW)
      {
        digitalWrite(mosfet, LOW);
        int i = 0;
      }
    }

     
     
  7. parovoZZ

    parovoZZ Гуру

    А что, других циклов в Си нету???
     
  8. Mr_dsa1

    Mr_dsa1 Нуб

    Конечно есть, но я не знаю какой именно мне нужен ? Если подскажите название, буду очень благодарен.
     
  9. parovoZZ

    parovoZZ Гуру

    Ну так выучи синтаксис!

    do while. Выполняется один раз как минимум.
     
    Mr_dsa1 нравится это.
  10. Mr_dsa1

    Mr_dsa1 Нуб

    Спасибо за подсказку. Но теперь новая проблема сделал через do...while лента включается плавно и дальше горит (с включением проблем нет), но от при выключении начинает постоянно плавно выключатся, и очень странно то делает это 5 минут, то почти сразу перестает. У меня вариант что датчик движения постоянно шлет LOW сигнал, и так как цикл do...while выполняется один раз, а потом проверяет условие то лента постоянно плавно выключается, так как если я проведу рукой над датчиком движения, то он посылает HIGH сигнал, и лента перестает мигать, но не включается так светло для выполнения условия включения ленты. Может попробовать через другой цикл ? Сейчас буду пробовать, может параллельно кто-то что-то подскажет.
    Код (C++):
    int dim1 = 0;  // это для выполнения пустого условия (тоесть чтоб оно 1 раз выполнялось)
    int dim2 = 0; //
    #define move_sensor 8   // датчик движения
    #define mosfet 3   // мосфет модуль
    void setup() {
      pinMode(mosfet, OUTPUT); // Объявляем пин реле как выход
      digitalWrite(mosfet, HIGH); // Выключаем мосфет - посылаем высокий сигнал
      delay(1000);
      digitalWrite(mosfet, LOW);   //Выключаем мосфет - посылаем низкий сигнал (это для тестирования что всё хорошо)
      Serial.begin(9600);
    }

    void loop() {
      int light = analogRead(A0);
      Serial.println(light);

      if ((light < 75 ) && (digitalRead(move_sensor) == HIGH ))
      {
        do
        {
          for (int i = 0; i <= 255; i++)
          {
            analogWrite(3, i);
            delay(5); // ставим задержку для эффекта
          }
        } while (dim1 != 0);
       digitalWrite(mosfet, HIGH);
      }
      else if (digitalRead(move_sensor) == LOW)
      {
      do
        {
        for(int i=255;i>=0;i--)  // вот с этим проблема !!!!
        {
          analogWrite(3, i);
          delay(5); // ставим задержку для эффекта
        }
        } while (dim2 != 0);
        digitalWrite(mosfet, LOW);
      }
    }

     
     
  11. Mitrandir

    Mitrandir Гуру

    Сделайте конечный автомат. Типа такого.
    Код (C++):
    #define LED_STATE_OFF 1

    #define LED_STATE_ON 2


    byte state;

    void setup(){

    //…

    state = LED_STATE_OFF;

    //…


    }


    void loop(){

       int mvSens = digitalRead(move_sensor);


       if (mvSens == HIGH && state == LED_STATE_OFF){

           playOnAmination();

           state = LED_STATE_ON;

       } else if (mvSens == LOW && state ==LED_STATE_ON){

           playOffAmination();

           state = LED_STATE_OFF;

       }

    }


    void playOnAnimation(){

    for(int i =0; i <=255; i++)
         {
            analogWrite(3, i);
            delay(5);// ставим задержку для эффекта
         }
      digitalWrite(mosfet, HIGH)
    }


    void playOffAnimation(){

    //….

    }
     
    Последнее редактирование: 22 июн 2018
  12. parovoZZ

    parovoZZ Гуру

    Такие вещи делаются через case и флаги.
     
  13. Mr_dsa1

    Mr_dsa1 Нуб

    Окей спасибо, щас буду разбираться и попробую сделать.
     
  14. Mr_dsa1

    Mr_dsa1 Нуб

    С флагами первый раз сталкиваюсь, щас буду изучать, но тоже спасибо за ответ.
     
  15. parovoZZ

    parovoZZ Гуру

    Флаг - это булева переменная.
     
  16. Mr_dsa1

    Mr_dsa1 Нуб

    А можно очень простой пример применения флага ?
     
  17. DetSimen

    DetSimen Гуру

    Код (C++):
    bool IsRelayOn = false;    // флаг. включено ли реле
    .
    .
    .
    if (!IsRelayOn) Relay.On();  // проверяем флаг.  Если реле не включено - включаем.
     
    Daniil, Mr_dsa1 и Mitrandir нравится это.
  18. Вопрос не по теме - Подскажите, чем делаются рисунки как на ссылке в первом сообщении - ну на котором макетная плата и ардуина ?
     
  19. Mitrandir

    Mitrandir Гуру

    Fritzing
     
  20. Mr_dsa1

    Mr_dsa1 Нуб

    Fritzing