Как считать время в секундах?
У меня есть заявление:
if(control > 100 && control < 130)
{
// отсчитываем время 30 секунд и открываем контакт 1 на 3 секунды.
}
Как я могу отсчитать 30 секунд и открыть пин на 3 секунды?
@user3748265, 👍3
Обсуждение4 ответа
Измените порядок примера Blink:
if(control>100 && control<130)
{
//**отсчитываем время 30 секунд и открываем контакт 1 на 3 секунды.**
delay(30000); // ждем 30 секунд
digitalWrite(1, HIGH); // включаем светодиод (HIGH - уровень напряжения)
delay(3000); // ждем 3 секунды
digitalWrite(1, LOW); // выключаем светодиод, понижая напряжение
}
Вы также можете использовать неблокирующий код, где delay()
будет блокироваться на 30 секунд. В моем предложении используется millis()
, можно сказать, аналогичный примеру мигания без задержки.
Вот пример того, что можно поместить в цикл:
//здесь объявляются переменные
if(control > 100 && control < 130 && !toggled_bit){
toggled_bit = true; //для управления секцией синхронизации
start_time = millis();
}
else if (!(control > 100 && control < 130)){
toggled_bit = false;
}
if (toggled_bit){
test1 = millis()
if(test1 - start_time > 30000){
digitalWrite(1, HIGH);
short_wait = millis();
// ждем 3 секунды после первого раза
if(short_wait - start_time > 33000)
digitalWrite(1, LOW);
toggled_bit = false;
}
}
}
// другой код здесь
Код устанавливает «флаг», toggled_bit
, который проверяется с помощью if()
позже в цикле, а также устанавливает start_time
. Затем он проверяет, прошло ли 30 секунд, а затем ждет дополнительные 3 секунды, чтобы отключить выход после включения. Затем он сбрасывает toggled_bit
.
Это также позволит вам проверять или делать другие вещи во время ожидания.
Часто требуется неблокирующая версия, так как во время ожидания часто приходится выполнять другие задачи. Шаблон "мигание без задержки" является решением, но, к сожалению, его использование с несколькими периодами времени и логикой становится утомительным.
Библиотека Timemark помогает абстрагироваться от шаблона и скрыть множество деталей. В приведенном ниже скетче используются две временные метки и простой конечный автомат, чтобы уменьшить сложность.
#include <Timemark.h>
Timemark turnOnWait(30000L);
Timemark turnOffWait(3000L);
enum {
IDLE,
TURN_ON_WAIT,
TURN_OFF_WAIT
};
int state = IDLE;
const int pin = 4;
int control = 0;
void setup()
{
...
pinMode(pin, OUTPUT);
digitalWrite(pin, LOW);
}
void loop()
{
...
switch (state) {
case IDLE:
if ((control > 100) && (control < 130)) {
turnOnWait.start();
state = TURN_ON_WAIT;
}
break;
case TURN_ON_WAIT:
if (turnOnWait.expired()) {
digitalWrite(pin, HIGH);
turnOffWait.start();
state = TURN_OFF_WAIT;
}
break;
case TURN_OFF_WAIT:
if (turnOffWait.expired()) {
digitalWrite(pin, LOW);
state = IDLE;
}
break;
default:
;
}
...
}
Для ясности используются две временные метки. Можно использовать одну метку времени и повторно инициировать ее с новым ограничением времени.
#include <Timemark.h>
const uint32_t TURN_ON_TIMEOUT = 30000L;
const uint32_t TURN_OFF_TIMEOUT = 3000L;
Timemark timemark;
enum {
IDLE,
TURN_ON_WAIT,
TURN_OFF_WAIT
};
int state = IDLE;
const int pin = 4;
int control = 0;
void setup()
{
...
pinMode(pin, OUTPUT);
digitalWrite(pin, LOW);
}
void loop()
{
...
switch (state) {
case IDLE:
if ((control > 100) && (control < 130)) {
timemark.limitMillis(TURN_ON_TIMEOUT);
timemark.start();
state = TURN_ON_WAIT;
}
break;
case TURN_ON_WAIT:
if (timemark.expired()) {
digitalWrite(pin, HIGH);
timemark.limitMillis(TURN_OFF_TIMEOUT);
timemark.start();
state = TURN_OFF_WAIT;
}
break;
case TURN_OFF_WAIT:
if (timemark.expired()) {
digitalWrite(pin, LOW);
state = IDLE;
}
break;
default:
;
}
...
}
Библиотека Scheduler позволяет использовать блокирующую версию (задержку). Неблокировка достигается переключением контекста на yield() или delay(). Ниже приведена переработка с использованием этого стиля:
#include <Scheduler.h>
const int pin = 4;
int control = 0;
void setup()
{
...
Scheduler.start(setupController, loopController);
}
void loop()
{
...
delay(1000);
}
void setupController()
{
...
pinMode(pin, OUTPUT);
digitalWrite(pin, LOW);
}
void loopController()
{
...
if ((control > 100) && (control < 130)) {
delay(30000L);
digitalWrite(pin, HIGH);
delay(3000L);
digitalWrite(pin, LOW);
}
else {
delay(100);
}
}
Ура!
Ну, 30 с равняется 30 000 мс, а в Arduino есть встроенная функция, которая считает миллисекунды, поэтому следующий код должен работать:
Time = millis(); //прошло время до входа в цикл…
If((control > 100) && (control < 130))
{
While (millis() < Time + 30000) //считает до тридцати секунд
{
While (millis() < Time + 3000) // считает до трех секунд
{
DigitalWrite(1,HIGH);
};};};
Таким образом, вы можете добавить код в циклы while, если хотите работать в многозадачном режиме.
- 4-битный счетчик вверх и вниз
- Может ли кто-нибудь объяснить этот странный код, используемый для настройки таймеров?
- Программирование Arduino Uno R3 для срабатывания реле каждые 24 часа
- Получение кода FFT arduino для работы более 9 часов с использованием micros()
- Объяснить функцию pulseIn с помощью arduino и ультразвукового датчика
- Считать данные датчика повторно через указанное время?
- Проблема с использованием Arduino Mega Timer2 с прерыванием PinChange
- Есть ли способ получить разрешение таймера 10 нс от процессора AVR?
Arduino измеряет время в миллисекундах () и задержке () и в миллисекундах, поэтому преобразование времени в секундах в миллисекунды будет 1000x., @Dave X