Нужна помощь с millis()
- Войдите на сайт для отправки комментариев
Ср, 14/10/2015 - 20:34
Доброго времени суток, осваиваю ардуино. Суть вопроса такова, вот код
#define sensor 8
#define siren 13
int val;
void setup()
{
pinMode(siren, OUTPUT);
pinMode(sensor,INPUT);
digitalWrite(siren,LOW);
}
void loop()
{
val = digitalRead(sensor);
if(val >=1)
{
digitalWrite(siren,HIGH);
delay(10000);
digitalWrite(siren,LOW);
}
}
Это система аварийного выключения водоснабжения. Мне нужно, избавится от delay(). Избавится таким оброзом, чтобы сирена включалась на 5 минут и в это время МК совершал прочие действия и т.д. То есть, мне нужно использовать millis(), но как это сделать, чтобы МК выполнял действия до тревоги и после нее я не пойму пока. Да, я вникал в туториал по миганию диодом с millis() но ни чего так и не понял, прошу помощи. Спасибо всем, кто пишет чтобы помоч.
Доброго времени суток, осваиваю ардуино. Суть вопроса такова, вот код
#define sensor 8 #define siren 13 int val; void setup() { pinMode(siren, OUTPUT); pinMode(sensor,INPUT); digitalWrite(siren,LOW); } void loop() { val = digitalRead(sensor); if(val >=1) { digitalWrite(siren,HIGH); delay(10000); digitalWrite(siren,LOW); } }Это система аварийного выключения водоснабжения. Мне нужно, избавится от delay(). Избавится таким оброзом, чтобы сирена включалась на 5 минут и в это время МК совершал прочие действия и т.д. То есть, мне нужно использовать millis(), но как это сделать, чтобы МК выполнял действия до тревоги и после нее я не пойму пока. Да, я вникал в туториал по миганию диодом с millis() но ни чего так и не понял, прошу помощи. Спасибо всем, кто пишет чтобы помоч.
#define sensor 8 #define siren 13 int val; unsigned long lastMillis = millis(); boolean flag = 0; void setup() { pinMode(siren, OUTPUT); pinMode(sensor, INPUT); digitalWrite(siren, LOW); } void loop() { val = digitalRead(sensor); if (val >= 1 && flag == 0) { digitalWrite(siren, HIGH); lastMillis = millis(); flag = 1; } if (millis() - lastMillis >= 10000) { digitalWrite(siren, LOW); flag = 0; } }Я бы строку 23 кода keefa записал бы так
if(flag == 1 && millis() - lastMillis >= 10000) {Я бы строку 23 кода keefa записал бы так
if(flag == 1 && millis() - lastMillis >= 10000) {А я бы отдал должное Лешаку.
А я и отдал .. в смысле заценил и вставил в свою либу готовый макрос .. даже 2шт: на базе millis() для работы с миллисекундами и на базе ovf_count для снижения затрат на него. В ряде применений ещё и параметры "времени в миллисекундах" укоротил до 2-х байт (uint16_t вместо unsigned long), что позволяет сократить каждое обращение к функциям времени на 6 байт кода. :)
Обсуждение либы, свистки про ошибки принимаются тут: http://arduino.ru/forum/programmirovanie/arduino-kak-konechnyi-avtomat-zaodno-umenshaem-sketchi
#define SENSOR_PIN 8 #define SIREN_PIN 13 #define SIREN_TIMEOUT (10000 <= millis() - sirenStartTime) #define ALARM (digitalRead(SENSOR_PIN)) #define ON HIGH #define OFF LOW unsigned long sirenStartTime; void setup() { pinMode(SIREN_PIN, OUTPUT); pinMode(SENSOR_PIN, INPUT); digitalWrite(SIREN_PIN, LOW); } void loop() { if (ALARM) siren(ON); if (SIREN_TIMEOUT) siren(OFF); } void siren(boolean state) { if (state == ON) sirenStartTime = millis(); digitalWrite(SIREN_PIN, state); }Так же нагляднее, особенно когда код сильно разрастется ;)
Спасибо за ответ и помощь, но я яхочу понять, как все это работает, а не просто получить готовый код как халявщик какой-то) Я написал комментарии к коду и если не сложно прошу объяснить, что происходит в непонятных мне строках и исправить если нужно. Спасибо.#define sensor 8 //Пин сенсора 8 #define siren 13 // Пин сирены 13 int val; unsigned long lastMillis = millis(); // ВОТ ЭТО НУЖНО ОБЪЯСНИТЬ boolean flag = 0; void setup() { pinMode(siren, OUTPUT); pinMode(sensor, INPUT); digitalWrite(siren, LOW); } void loop() { val = digitalRead(sensor); // Считываем значение и записываем в переменную val if (val >= 1 && flag == 0) // если val больше или равно И flag равно нулю { digitalWrite(siren, HIGH); // Включаем сирену lastMillis = millis(); // НУЖНО ОБЪЯСНИТЬ, ЧТО ЗДЕСЬ ПРОИСХОДИТ flag = 1; // Записываем в flag еденицу } if (flag == 1 && millis() - lastMillis >= 10000)// НУЖНО ОБЪЯСНИТЬ, ЧТО ЗДЕСЬ ПРОИСХОДИТ { digitalWrite(siren, LOW); // Выключаем сирену flag = 0; // Записываем ноль в flag } }ответ в теле кода
Очень блогадарен за помощь)
Очень блогадарен за помощь)
Всегда рад помочь. Надеюсь что понятно объяснил.
#define SENSOR_PIN 8 #define SIREN_PIN 13 #define SIREN_TIMEOUT (10000 <= millis() - sirenStartTime) #define ALARM (digitalRead(SENSOR_PIN)) #define ON HIGH #define OFF LOW unsigned long sirenStartTime; void setup() { pinMode(SIREN_PIN, OUTPUT); pinMode(SENSOR_PIN, INPUT); digitalWrite(SIREN_PIN, LOW); } void loop() { if (ALARM) siren(ON); if (SIREN_TIMEOUT) siren(OFF); } void siren(boolean state) { if (state == ON) sirenStartTime = millis(); digitalWrite(SIREN_PIN, state); }Так же нагляднее, особенно когда код сильно разрастется ;)
круто , не знал что в defaine можно подставлять уравнения
не могли бы вы пояснить как работает 20 строчка кода. не должно ли быть после (ALARM) например == HIGH или == LOW (в зависимости от сенсора)
и как у нас идет обращение к void siren
не нужно ли в loop добавить siren();
#define имя заменить_так_то
работает до компилятора. Это препроцессор. Он тупо делает подстановки текстов лексем и может проверять то что получилось на наличие подстановок ещё, спускаясь вглубь сколь угодно глубоко, но без рекурсий. Обеспечивается это тем, что каждый #define умеет находить только те подстановки, которые были текстуально определены до него конкретно.
В данном случае, происходит преобразование текста до компиляции в такой:
unsigned long sirenStartTime; void setup() { pinMode(13, 1); pinMode(8, 0); digitalWrite(13, 0); } void loop() { if ( (digitalRead(8)) ) siren(1); // помним что 0 это false остальное true if ( (10000 <= millis() - sirenStartTime) ) siren(0); } void siren(boolean state) { if (state == 1) sirenStartTime = millis(); digitalWrite(13, state); }Это, что увидит комплятор. avg-gcc запущенный с ключом -E выдаст примерно такое.
Arhat109-2
спасибо что ответили,
то что дефайн подставляет до компиляции это я понимал. не знал только что можно такие уровнения подставлять
мне все равно непонятно , теперь уже 13 строка ((
в " if" ведь должно быть условие.
например 14 строку я понимаю так
if( (10000 <= millis() - sirenStartTime) ) siren(0);если отработали 10 сек. то сирену выключить (поставить в ноль, LOW, false)
то есть тут у нас явное условие "прошло ли 10 сек.?"
а вот строку 13 вашего последнего поста понимаю так.
if( (digitalRead(8)) ) siren(1);если МОЖЕМ ПРОЧИТАТЬ pin8, то siren будет true.
получается что тут "условие" это сама возможность прочитать пин8, но ведь мы всегда его можем прочитать.
не должно ли быть что -то типо этого
{ siren=1; }if( digitalRead(8) == HIGH)если мы прочитали pin8 и ОН РАВЕН high то siren будет равен одному (включится)
тут "условие" pin8 ==HIGH?
тоесть я виду к тому, что в вашем варианте нет явного условия при котором siren станет true
простите что задаю глупые вопросы.
про #define уже написали, все верно, просто тупая замена синонима на его содержимое. Именно что тупая, без проверки на корректность, поэтому длинные выражения всегда должны быть в скобках, чтобы сохранить задуманный порядок действий.
Для компилятора выражение if(...) всегда возвращает только два состояния: true если содержимое скобок истинно и false если ложно. Поэтому if (ALARM) развернется до if (digitalRead(8)), и выражение читается ЕСЛИ СОСТОЯНИЕ ПИНА 8 , далее по-любому будет либо true, либо false, поэтому если ожидается TRUE, собственно само равенство ==TRUE можно не писать. Если ожидается FALSE, то можно просто написать через инверсию: if (!ALARM) ...
Короче, выражения if (digitalRead(8) == HIGH) и if (digitalRead(8)) полностью равноценны, писать можно и так и так, для наглядности в строках 20 и 27 они написаны по-разному.
>и как у нас идет обращение к void siren. не нужно ли в loop добавить siren();
не нужно. Обращение идёт после проверки if, допустим, если true, то обращаемся к функции siren и передаем ей параметр ON, который является синонимом TRUE, который равен 1. Эта единичка присваивается локальной (внутренней) переменной state и дальше новое сравнение if.
Строка (millis() - sirenStartTime >= 10000) у меня просто зеркально перевернута: (10000 <= millis() - sirenStartTime) для удобства, чтобы в блоке define все цифры были слева, так их визуально быстрее найти.
Таким образом, если я через год захочу поменять какой-то параметр, мне не придется тратить десятки минут и шарить по всему коду, чтобы вспомнить как оно работает и какой пин или цифру надо поменять, а просто исправить заданные уставки, что займёт секунды, потому что все это вынесено в самое начало. И за счет использраания синонимов #define сама логика основного цикла через год так же легко прочитается, без вникания в детали:
{
ЕСЛИ ТРЕВОГА, ТО СИРЕНУ ВКЛЮЧИТЬ
ЕСЛИ СИРЕНА ОРЕТ ДОЛГО, ТО СИРЕНУ ВЫКЛЮЧИТЬ
}
...то найти другого хозяина.
сгоревший автомобиль ищет умного хозяина
Tomasina спасибо за то что все объяснили .
в " if" ведь должно быть условие.
Увы, это от недостатка образования.
У нас посему-то научить программировать пытаются прежде, чем прочитан курс булевой алгебры. А булева алгебра, пожалуй, для программирования поважнее, чем арифметика.
Собственно, в "if" должно быть не условие, а логическое (булево) выражение.
А в языках C/C++ традиционно считается, что "0" - это "false", а все, что не равно нулю - "true".
... Короче, выражения if (digitalRead(8) == HIGH) и if (digitalRead(8)) полностью равноценны
Отнюдь.
В используемых терминах полностью равноценны if (digitalRead(8) != LOW) и if (digitalRead(8)).
Истинно так. Опередили. :)
Что страшного в том что я назвал " логическое (булево) выражение" - " условием"?
я не программист и не знаю тонкостей и правильных названий, люди меня поняли а я понял их думаю этого достаточно,
То что я не достаточно хорошо разбираюсь в программировании не говорит о том что у меня недостаток образования,
я специалист в другой сфере, а arduino это хобби.
не думаю что вы такой на все руки мастер,
Уверен что если вас попросить приготовить какое-то блюдо скажем из французской или скажем из сербской кухни , вы его правильно приготовите .
я думаю форумы существуют как раз для того чтоб более опытные люди делились опытом и давали наставления,
а не для того чтоб выслушивать критику по поводу своего образования.
P.S . получаеться что здесь http://arduino.ru/Reference/If нас всех обманывают . написанно именно условие а не "логическое (булево) выражение"
Что страшного в том что я назвал " логическое (булево) выражение" - " условием"?
ничего страшного - тебя просто съест рептилоид.
Уверен что если вас попросить приготовить какое-то блюдо скажем из французской или скажем из сербской кухни , вы его правильно приготовите .
я больше тебе скажу, что никто правильно не приготовит. Всегда найдется кто нить и скажет что ты не праввильно все сделал. Так вот и здесь... что бы ты не сделал, все не правильно. Сделай так что бы работало, а как там, правильно написал или нет, главное что бы было вкусно.
Что страшного в том что я назвал " логическое (булево) выражение" - " условием"?
я не программист и не знаю тонкостей и правильных названий, люди меня поняли а я понял их думаю этого достаточно,
То что я не достаточно хорошо разбираюсь в программировании не говорит о том что у меня недостаток образования,
я специалист в другой сфере, а arduino это хобби.
А что страшного в том, если кто-то плохо разбирающийся в кулинарии приготовит что-то несъедобное?
Если бы Вы внимательно прочитали мое сообщение, поняли бы, что недостаток образования ни у одного Вас. Это вообще характерно для начинающих программистов.
Как бы Вы посмотрели на человека, который пытается программировать, ни при этом не имеет поняия об арифметических операциях?
А с булевой алгеброй именно так и происходит.
И, собственно, я писл не для того, чтобы Вас обидеть, а для того, чтобы подсказать Вам, чего Вам не хватает, на что следовало бы обратить внимание, если Вы хотите программировать.
P.S . получаеться что здесь http://arduino.ru/Reference/If нас всех обманывают . написанно именно условие а не "логическое (булево) выражение"
Именно так.
У того, кто это писал, тоже наблюдается недостаток образования.
Что как раз подтверждает мои слова.