Я использую функцию millis(), но после одной итерации она не проверяет условие и входит в цикл. Что делать?

Я использую датчик mq7, где мне нужно переключать vcc между 5 и 1,5 В в течение 1 мин и 1,5 мин. Для этого я использую функцию millis. Но после 1-й итерации она пропускает условие и входит в цикл.

Код выглядит следующим образом:

    //номер пина светодиода
    const int ledPin = 14;  
     float sensorPin = 34;
    // настройка свойств ШИМ
    const int freq = 5000;
    const int ledChannel = 0;
    const int resolution = 8;
    unsigned long previousMillis = 0;  
    
     
    void setup(){
      // настройка функций светодиодной ШИМ
      Serial.begin(115200);
      Serial.println("started");
      ledcAttach(ledPin, freq, resolution);
      ledcAttachChannel(ledPin, freq, resolution, 0);
    }
     
    void loop(){
      // увеличить яркость светодиода
     unsigned long  currentMillis = millis();
      Serial.println("hii");
    // изменение яркости светодиода с помощью ШИМ
        ledcWrite(ledPin, 255);
       if (currentMillis - previousMillis > 60000) 
       {
        previousMillis = currentMillis;
        // сохраните время последнего мигания светодиода
        Serial.println("switching");  
        // изменение яркости светодиода с помощью ШИМ
        ledcWrite(ledPin, 95);   
        delay(90000);
        Serial.println("switching"); 
         // нам нужно считать датчик при 5 В, но нельзя допустить его нагрева. Так что поторопитесь!
        ledcWrite(ledPin, 255);
        delay (50); //не знаю, сколько ждать, чтобы не перегреться. Получение аналогового считывания, по-видимому, занимает 100uSec
       // считываем значение с датчика:
       Serial.println("switching"); 
        int sensorValue = analogRead(sensorPin);  
        Serial.println(sensorValue);  
       }
    }

Вывод следующий:

, 👍0


1 ответ


3

Используемая вами идиома программирования на основе millis() предназначена для обрабатывать задержки, не блокируя программу при вызове delay(). Тогда вы полностью сведете на нет его предназначение, вызвав delay(90000). После этой 1,5-минутной задержки, конечно, пройдет одна минута, и тест currentMillis - previousMillis > 60000 всегда будет истинным.

Если вы хотите использовать неблокирующую парадигму, которую позволяет millis(), вы следует полностью исключить delay() из вашего словаря (а также другие блокирующие циклы).

Редактировать: Отвечая на вопрос в комментарии «Можете ли вы предложить, как мне изменить код для задержки в 1,5 минуты». Как предложил JRobert в другом комментарии, вам следует следовать «Моргнуть без задержки» Пример Arduino. Есть только одно замечание: этот пример Arduino сохраняет светодиод загорается на одну секунду и гаснет на другую секунду, пока вы хотите переключать вашу систему между двумя состояниями с разной продолжительностью.

Решение состоит в том, чтобы запомнить, в каком штате вы сейчас находитесь, и написать отдельные пути кода для обработки каждого состояния. Например, код ниже включает встроенный светодиод, оставляя его включенным в течение 100 мс и выключая на 900 мс. Это достигается за счет запоминания текущего состояния (в булеву переменную is_on ниже) и обуславливающую выполнение кода от текущего состояния (например, if (is_on && ...)).

/*
 * Включать встроенный светодиод на 100 мс каждую секунду.
 */

const unsigned long time_on  = 100;  // время включения = 100 мс
const unsigned long time_off = 900;  // время выключения = 900 мс
unsigned long previousMillis;   // предыдущее время переключения светодиода
bool is_on;                     // светодиод в данный момент горит?

void setup() {
    pinMode(LED_BUILTIN, OUTPUT);
    digitalWrite(LED_BUILTIN, LOW);
    is_on = false;
}

void loop() {
    unsigned long currentMillis = millis();

    // Если светодиод горел достаточно долго, выключите его.
    if (is_on && currentMillis - previousMillis >= time_on) {
        digitalWrite(LED_BUILTIN, LOW);
        is_on = false;
        previousMillis = currentMillis;
    }

    // Если светодиод был выключен достаточно долго, включите его.
    if (!is_on && currentMillis - previousMillis >= time_off) {
        digitalWrite(LED_BUILTIN, HIGH);
        is_on = true;
        previousMillis = currentMillis;
    }
}
,