Добрый день, уважаемые друзья. Никак не получается найти логику старта действия с задержкой. Что есть: 1. Фоторезистор 2. Реле со светом Что нужно 1. Чтобы по данным от фоторезистора загорался свет. Это есть и все хорошо 2. Чтобы свет гасился с 10 секундной (10000 милисек) задержкой по данным от фоторезистора. Здесь не все хорошо. То есть, если на секунде 9999 милисекундах резистор сообщит, что пора выключаться, то мы выключимся через 1 милисекунду, а не через 10000. Помогите, пожалуйста, советом или кодом или уже ранее пройденной темой. Код (C++): int svet=11; unsigned long timing; #define PERIOD 10000 #define PIN_PHOTO_SENSOR A0 void setup() { // put your setup code here, to run once: pinMode(svet, OUTPUT); Serial.begin(9600); } void loop() { int val = analogRead(PIN_PHOTO_SENSOR); Serial.println(val); if (val > 3) { if (millis() - timing >= PERIOD) { digitalWrite(svet, LOW); timing+=PERIOD; } } else { digitalWrite(svet, HIGH); } }
в момент засвечивания фоторезистора надо только засекать время, причем только один раз (для этого ввести переменную-флаг), а отключать свет уже отдельно по истечению времени
Все верно. Почему-то не написал сам в теме, что хочу начинать отсчет времени именно от момента засвета. Вопрос стоит именно в реализации.. Я весьма и весьма посредственный человек в написании кодов, что, вероятно, очевидно. Могу или чужое перепилить или пример разобрать, а сам как минимум синтаксиса не знаю. Булин вставить - это ок. А как с ним поступить дальше и как сделать счетчик засвета и почему один раз - это уже выше моего уровня понимания.
Ну во первых ваш скетч вообще не должен компилироваться. Что это у вас за мусор Код (C++): pinMode(svet1, OUTPUT); А если у вас проблемы программированием а задача ограничивается только действиями описанными в первом посту, сделайте тупо и не по феншую. Проверяете засвет фоторезистора, если есть - включаете светодиод потом задержка в 10 сек и гасите его. Так делать не хорошо, но в вашем случае работать будет.
Это маленькая вырезка из большего скетча, чтобы другими вещами вас не грузить, я постарался вычистить всё, но эту строку упустил. Задержка в виде делея не прокатит. Если вы о нем, конечно. Есть другие части кода, которые по известным причинам будут так же отложены на 10 секунд. Я тут вот на что наткнулся. Только не понимаю на какую часть кода обратить внимание, чтобы экспроприировать. И вообще то ли это. КМК очень похоже, что да. http://forum.amperka.ru/threads/Срабатывание-таймера-только-после-выполнения-условий.11783/
Тогда да, надо делать через millis(). Но возникает дополнительный вопрос - что надо делать если фоторезистор по истечении 10 сек остаётся засвеченным? Свет нужно погасить на какой-то промежуток времени а потом опять включать, или ничего не гасить, а запустить новый отсчёт 10 секунд?
Запустить новый отсчет. Вообще, это автоматический свет для велосипеда. То есть он смотрит на мир и оценивает светло или нет. и по этим данным включает свет. Проезжая под фонарем/фонарями, свет все же выключается. я хотел поставить задержку в минуту или больше на то, что бы он оставался включенным. но в жизни на реальном тесте это быстро показало насколько я не прав в коде. Изначально думал, что сам все сделаю, но эта часть меня убивает. Там еще поворотники в коде(на сенсорных кнопках), их я и вычистил. А) чтобы не заставлять всё то читать, Б) не позориться.
поставь на велосипед такой датчик https://a.aliexpress.ru/_eLaPqY направь в низ а не в верх и отрегулируй переменным резистором ну и к нему на выход реле и все программировать не чего не надо
Sergey_K, не пойму, в чем у вас проблема. Код ведь элементарный. Не знаю, какие значения идут с фотодатчика, когда "светло", а какие "темно", поэтому напишу в общем: Код (C++): unsigned long last_dark_time; // глобальная или статическая переменная int val = analogRead(PIN_PHOTO_SENSOR); if ( "темно" ) { digitalWrite(svet, HIGH); // включаем свет last_dark_time = millis(); // засекаем время } else { // если "светло" if (millis() - last_dark_time >= PERIOD) // если время истекло { digitalWrite(svet, LOW); // выключаем свет } }
Код (C++): int svet=11; unsigned long timing; #define PERIOD 10000 #define PIN_PHOTO_SENSOR A0 char dayflag=0; //переменная-флаг void setup() { // put your setup code here, to run once: pinMode(svet, OUTPUT); Serial.begin(9600); } void loop() { int val = analogRead(PIN_PHOTO_SENSOR); Serial.println(val); if (val > 3) //если настал день { if(!dayflag)//флаг нулевой - значит до этого была ночь { //взводим флаг, теперь сюда не зайдет пока не dayflag=1;//пройдет через ночь timing=millis();//засекаем время для выключения света } } else //если настала ночь { dayflag=0; //сбрасываем флаг digitalWrite(svet, HIGH); } //если прошло время и флаг взведен - выключаем свет if (millis() - timing >= PERIOD && dayflag) { digitalWrite(svet, LOW); } } ничего не проверял, возможно будет работать неправильно, но по такой логике можно сделать чтоб работало ну или так как постом выше - без флага, а просто обнуляя счетчик каждый раз пока темно - так проще и возможно даже лучше
Товарищи, большое вам спасибо. Оба варианта работают как надо это и это как раз и есть то, что для меня было не очевидно. Код (C++): digitalWrite(svet, HIGH);// включаем свет last_dark_time = millis();// засекаем время Код (C++): if(!dayflag)//флаг нулевой - значит до этого была ночь {//взводим флаг, теперь сюда не зайдет пока не dayflag=1;//пройдет через ночь timing=millis();//засекаем время для выключения света }
Забавен тот факт, что именно от него я и хочу избавиться в схеме - он большой. мало того, с него я и выпаял фоторезистор этот датчик дает данные 1 или 0. в принципе особой разницы не вижу данные 1/0 или данные которые дает сам фоторезистор - 0-5=темно(по моим замерам) 6-1023(светло) опять же по моим замерам и у него моментальный вкл-выкл. то есть как дискотека. при любом внешнем источнике света (фары машин, фонари и т.д.), будь он хоть на микросекунду рядом.
Да. Я перенес все это добро на плату в easyEDA и если кому надо (в чем сомневаюсь), + есть визуально собранный проект с кодом и т.д. в тинкеркаде. пишите, пошарю