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 циклов?
@AgoraLive, 👍2
Обсуждение1 ответ
Лучший ответ:
Объявите глобальную (или статическую) логическую переменную, чтобы отслеживать, работает таймер или нет, а также переменную для хранения начального значения 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
- Как использовать миллис вместо задержки?
- NodeMCU - Vin контакт как выход 5V?
- Как справиться с rollover millis()?
- Как заставить 5-вольтовое реле работать с NodeMCU
- ESP8266 не подключается к Wi-Fi
- Разве в узле MCU v3 (LoLin) нет встроенного светодиода?
- Использование millis() и micros() внутри процедуры прерывания
- Разница между этими двумя платами NodeMCU?
Вы проверяете, превышает ли люкс 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