Как считать время в секундах?

У меня есть заявление:

if(control > 100 && control < 130)
{

  // отсчитываем время 30 секунд и открываем контакт 1 на 3 секунды.

}

Как я могу отсчитать 30 секунд и открыть пин на 3 секунды?

, 👍3

Обсуждение

Arduino измеряет время в миллисекундах () и задержке () и в миллисекундах, поэтому преобразование времени в секундах в миллисекунды будет 1000x., @Dave X


4 ответа


1

Измените порядок примера Blink:

if(control>100 && control<130)
{
  //**отсчитываем время 30 секунд и открываем контакт 1 на 3 секунды.**
  delay(30000);             // ждем 30 секунд
  digitalWrite(1, HIGH);    // включаем светодиод (HIGH - уровень напряжения)
  delay(3000);              // ждем 3 секунды
  digitalWrite(1, LOW);     // выключаем светодиод, понижая напряжение
}
,

2

Вы также можете использовать неблокирующий код, где 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.

Это также позволит вам проверять или делать другие вещи во время ожидания.

,

5

Часто требуется неблокирующая версия, так как во время ожидания часто приходится выполнять другие задачи. Шаблон "мигание без задержки" является решением, но, к сожалению, его использование с несколькими периодами времени и логикой становится утомительным.

Библиотека 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);
  }
}

Ура!

,

1

Ну, 30 с равняется 30 000 мс, а в Arduino есть встроенная функция, которая считает миллисекунды, поэтому следующий код должен работать:

Time = millis();  //прошло время до входа в цикл…
If((control > 100) && (control < 130))
{ 
While (millis() < Time + 30000) //считает до тридцати секунд
{
While (millis() < Time + 3000) // считает до трех секунд
{
DigitalWrite(1,HIGH);
};};};

Таким образом, вы можете добавить код в циклы while, если хотите работать в многозадачном режиме.

,