nodeMCU — Millis() — Простой счетчик — Как долго горит светодиод?

ПРОГРЕСС, теперь у меня есть это (С БОЛЬШОЙ ПОМОЩЬЮ):

void setup() {
   Serial.begin(9600);
// инициализируем цифровой вывод 13 как выход.
}
uint32_t timer_start = 0;
int timer_running = false;



void loop()
 {
// Получаем информацию о LDR
  int sensorValue = analogRead(A0);         // читаем вход на аналоговом выводе 0
  float voltage = sensorValue * (5.0 / 1023.0);     // Преобразуем аналоговое показание (от 0 до 1023) в напряжение (0–5 В)
  float lux = voltage * 100;

 if (lux>150) {
    if (!timer_running) {
      // Таймер еще не запущен, поэтому зафиксируйте время начала
      timer_start = millis();
      timer_running = true;
    }
  } else {
    if (timer_running) {
      // Таймер в данный момент работает; остановить его, рассчитать/распечатать время выполнения
      timer_running = false;
      Serial.println((millis()-timer_start) / 1000.0, 3); // форматируйте здесь так, как вам нравится

    }
  }

 }

Теперь это говорит мне, сколько миллис находится в воздухе гимнаст, разделенное на 1000,0 с тремя десятичными знаками. Если я запущу последовательный монитор, когда гимнаст находится на батуте, я смогу получить секунды air_time, которые есть у гимнаста. Есть ли способ заставить этот скрипт работать ТОЛЬКО в течение 10 циклов?

, 👍2

Обсуждение

Вы проверяете, превышает ли люкс 150, и всегда выполняете этот код, пока люкс превышает 150. Вам нужно знать момент, когда люкс впервые превысит 150. Взгляните на этот пример: https://www.arduino.cc/en/Tutorial/StateChangeDetection Преобразование миллис в минуты и секунды можно выполнить с помощью /60 и %60 после того, как прошедшее миллис будет разделено на 1000., @Jot

Я думаю, вам нужно поддерживать переменную состояния static unsigned long last_off = 0; в loop{}, сбрасывая ее в конце предложения else: last_off = millis();, а также сообщать в начале else, если какое-то on_time=millis()-last_off больше некоторого порогового значения. У вас проблемы с форматированием? Или с расчетом по времени?, @Dave X

В обновленном коде вы не сохранили ту же структуру кода, что и в данном примере. В вашем обновленном коде блок if (lux>150) {...} имеет код запуска ** и остановки таймера, вместо этого блок if (lux>150) {...} должен иметь код запуска таймера, а блок else {...} (то есть, где lux<=150`) должен иметь код остановки таймера., @jose can u c


1 ответ


Лучший ответ:

3

Объявите глобальную (или статическую) логическую переменную, чтобы отслеживать, работает таймер или нет, а также переменную для хранения начального значения millis(). Когда люкс упадет ниже вашего порога, вычтите текущее значение millis() из начального значения, и вы получите продолжительность в миллисекундах, которую легко преобразовать в формат мм:сс.сссс.

Пример кода (не полный скетч)

uint32_t timer_start = 0;
uint8_t timer_running = false;

void loop() {
  if (lux>150) {
    if (!timer_running) {
      // Таймер еще не запущен, поэтому зафиксируйте время начала
      timer_start = millis();
      timer_running = true;
    }
  } else {
    if (timer_running) {
      // Таймер в данный момент работает; остановить его, рассчитать/распечатать время выполнения
      timer_running = false;
      Serial.print(millis()-timer_start); // форматируйте здесь так, как вам нравится
    }
  }
}

Теперь это говорит мне, сколько миллис находится в воздухе гимнаст, разделенное на 1000,0 с тремя десятичными знаками. Если я запущу Serial Monitor, когда гимнастка на батуте, тогда я смогу получить секунды air_time, которое есть у гимнастки. Есть ли способ запустить этот скрипт? ТОЛЬКО на 10 петель?

Конечно. Если предполагается, что вам нужно совокупное общее эфирное время, вам необходимо объявить другую глобальную или статическую переменную для хранения совокупного эфирного времени, а также вам нужна еще одна переменная для отслеживания количества прошедших циклов.< /п>

void setup() {
   Serial.begin(9600);
// инициализируем цифровой вывод 13 как выход.
}
uint32_t timer_start = 0;
int timer_running = false;
uint32_t total_time = 0;
uint8_t jump_count = 0;

void loop()
{
// Получаем информацию о LDR
  int sensorValue = analogRead(A0);         // читаем вход на аналоговом выводе 0
  float voltage = sensorValue * (5.0 / 1023.0);     // Преобразуем аналоговое показание (от 0 до 1023) в напряжение (0–5 В)
  float lux = voltage * 100;

  if (jump_count<10) {
    if (lux>150) {
      if (!timer_running) {
        // Таймер еще не запущен, поэтому зафиксируйте время начала
        timer_start = millis();
        timer_running = true;
      }
    } else {
      if (timer_running) {
        // Таймер в данный момент работает; остановить его, рассчитать/распечатать время выполнения
        timer_running = false;
        // Добавляем эфирное время этого прыжка к совокупному итогу:
        total_time += millis()-timer_start;
        // Увеличение jump_count
        jump_count++;

        Serial.println((millis()-timer_start) / 1000.0, 3); // форматируйте здесь так, как вам нравится
      }
    }
  } else {
    // Выводим общее время полета за 10 прыжков;
    Serial.println((total_time)) / 1000.0, 3);
  }
}
,

Почему uint16_t и uint8_t? Почему не просто int?, @AgoraLive

Эти типы не являются критическими. В Arduino памяти мало, поэтому лучше использовать наименьший необходимый тип переменной. timer_running может соответствовать наименьшему типу uint8_t, в то время как любой результат millis() представляет собой unsigned long, эквивалентный uint32_t (исправлено в примере кода; не должно быть uint16_t), @jose can u c

Хорошо, спасибо. Теперь что касается timer_running, в чем причина "!" восклицательный знак? И таймер включается в настройке void, в цикле void или между ними?, @AgoraLive

! — оператор отрицания. Итак, вы проверяете, НЕТ (timer_running), а затем делайте что угодно. Поэтому, если таймер уже запущен, вы не сохраняете текущий millis(), потому что вы уже отсчитываете время., @jose can u c

Что он считает? Все, что я вижу, это 1 и 0?, @AgoraLive

Он считает миллисекунды. Вот почему, когда свет гаснет, вы берете текущее значение millis() и вычитаете значение millis(), которое было сохранено при первом включении света, и вы получаете продолжительность в миллисекундах. Как уже отмечалось, преобразовать это в часы/минуты/секунды/миллисекунды тривиально. Вы понимаете код, который написали?, @jose can u c

Привет, Хосе, последний предоставленный тобой эскиз работает. Однако Serial.println the Total раз повторяется снова и снова. Есть ли способ напечатать это только один раз? Позже я планирую добавить ЖК-дисплей или экран другим способом, но сейчас Serial.print лучше, чем ничего. Что касается моего понимания кода, который я написал. Ответ будет таков: я никогда и нигде этому не учился, но испытываю и учусь, делая/наблюдая/спрашивая. Чего я не понимаю в этом коде: зачем нам jump_count++, а не только jump_count+. Я понимаю правила if, else, while и т. д., но всему этому можно научиться на практике., @AgoraLive

Давайте [продолжим обсуждение в чате](https://chat.stackexchange.com/rooms/84305/discussion-between-jose-can-uc-and-user2975926)., @jose can u c