Я использую функцию 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);
}
}
Вывод следующий:
@Yukta Sanghvi, 👍0
1 ответ
Используемая вами идиома программирования на основе 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;
}
}
- ESP32 millis не работает должным образом
- Как сбросить ESP32 через определенное время?
- Как справиться с rollover millis()?
- Использование millis() и micros() внутри процедуры прерывания
- esp32, platformio A fatal error occurred: Packet content transfer stopped (received 8 bytes) *** [upload] Error 2
- Как выбрать альтернативные контакты I2C на ESP32?
- Драйверы для чипа последовательного порта CH9102X
- Как преобразовать форматированный оператор print в строковую переменную?
Можете ли вы подсказать, как мне изменить код для задержки в 1,5 минуты, если я напишу цикл millis?, @Yukta Sanghvi
См. примеры в Arduino IDE. Во второй группе, «Цифровые», скетч «Мигание без задержки» показывает хороший пример того, как это сделать., @JRobert
@YuktaSanghvi ваш код уже содержит задержку в 1 минуту с использованием millis()... что мешает вам изменить ее на 1,5 минуты?, @jsotola