Таймер полива с детектированием дня и ночи.
- Войдите на сайт для отправки комментариев
Задача: сделать таймер полива без привязки к реальному времени определяющий время суток.
Подошла бы полная копия такого устройства. Интервалы времени нужны меньше от 10сек. до часа примерно.
В зависимости от времени день или ночь – его определяет фото датчик, время работы насоса и время паузы между работой насоса регулируется отдельно 4-мя разными ручками, 2-мя справа (дневной режим) и 2-мя слева (ночной режим).
Казалось бы простейший проект ,но не пойму с чего начать. Конечно же не прошу написать скетч за меня)
Просто хотелось бы понять как строить структуру скетча и каким образом считать время.Как понимаю обычный delay не подойдет..
Очень желательно чтобы в фоне могли выполняться другие действия.
Всем заранее спасибо)
Как понимаю обычный delay не подойдет..
Очень желательно чтобы в фоне могли выполняться другие действия.
Всем заранее спасибо)
http://arduino.ru/Reference/Millis
Шаг первый. Повторяем схему из http://arduino.ru/tutorials/BlinkWithoutDelay целиком с нуля.
Шаг второй. Модифицируем предыдущую схему так, чтобы светодиод горел одно фиксированое время, а не горел другое, но тоже фиксированное время.
Шаг третий. Вставляем в эту схему поненциометр, который определяет продолжительность мигания. Продолжительность паузы оставляем фиксированной.
Шаг четвертый. Вставляем еще один потенциометр. Первый определяет продолжительность горения светодиода, второй - продолжительность паузы между вспышками.
Шаг пятый. Добавляем датчик освещения. В зависимости от датчика пусть светодиожд мигает "днем" = "согласно установкам потенциометра", а "ночью" - с фиксированными интервалами.
Шаг шестой. Еще два потенциометра, определяющих интервали мигания "ночью".
Шаг седьмой. Заменяем светодиод на насос.
Profit.
Кстати, это прекрасный пример для иллюстрации того, как сложную задачу можно и нужно решать "по частям", разбив на элементарные.
Добавьте модуль часов на батарейке RTC, у китайцев 3 бакса вместе с литиевой батарейкой и пересылкой...
фотодатчик тож не очень обязателен... восход и заход солнца можно посчитать... хотя если вы будете считать количества солнца, типа сколько воды вылить....
Большое спасибо, за ответы.
Tsostik , cпасибо за чёткий план действий) millis() это то что нужно.
Не могли бы по 2 пункту подсказать , создал две переменные - previousMillis2 и interval2 смотрю на них и не понимаю что с ними делать :)
не ожидал что так сложно будет честно говоря, думаю со следующими пунктами сам справлюсь)
/* Blink without Delay 2005 by David A. Mellis modified 8 Feb 2010 by Paul Stoffregen */ const int ledPin = 13; // номер выхода, подключенного к светодиоду // Variables will change: int ledState = LOW; // этой переменной устанавливаем состояние светодиода long previousMillis = 0; // храним время последнего переключения светодиода long intervalOn = 1000; // время включения светодиода (1 секунда) long intervalOff = 500; // время выключения светодиода (0.5 секунды) void setup() { // задаем режим выхода для порта, подключенного к светодиоду pinMode(ledPin, OUTPUT); } void loop() { // здесь будет код, который будет работать постоянно // и который не должен останавливаться на время между переключениями свето unsigned long currentMillis = millis(); //проверяем не прошел ли нужный интервал, если прошел то if (ledState == LOW) { if(currentMillis - previousMillis > intervalOff) { // сохраняем время последнего включения previousMillis = currentMillis; //включаем светодиод ledState = HIGH; digitalWrite(ledPin, ledState); } if (ledState == HIGH) { if(currentMillis - previousMillis > intervalOn) { // сохраняем время последнего выключения previousMillis = currentMillis; //выключаем светодиод ledState = LOW; digitalWrite(ledPin, ledState); } }Всё заработало! Спасибо за помощь. хотелось бы только усовершенствовать строчки:
и
чтобы if срабатывало через циклов 100 например , чтобы исключить ложные переключения.
то есть, если fotorezval будет сто раз подряд меньше 500 тогда перейти к ночной части кода.
#define FOTO_REZ A0// фото резистор #define VAR_REZ1 A1 // регулятор паузы ночью #define VAR_REZ2 A2 // регулятор полива ноью #define VAR_REZ3 A3 // регулятор паузы днем #define VAR_REZ4 A4 // регулятор полива днем const int ledPin = 13; // номер выхода, подключенного к светодиоду // Variables will change: int ledState = LOW; // этой переменной устанавливаем состояние светодиода long previousMillis = 0; // храним время последнего переключения светодиода long interval = 1000; // интервал между включение/выключением светодиода (1 секунда) void setup() { // задаем режим выхода для порта, подключенного к светодиоду pinMode(ledPin, OUTPUT); Serial.begin(9600); } void loop() { delay(1000); int fotorezval = analogRead(FOTO_REZ); Serial.print("fotorezval..."); Serial.println(fotorezval); if (fotorezval<500) //ночь { int pause = analogRead(VAR_REZ1); int watering = analogRead(VAR_REZ2); long pauseTime = pause; // Время паузы в секундах long lightTime = watering; // Время свечения в секундах Serial.print("PAUSE NIGHT---"); Serial.println(pause); Serial.print("WATERING NIGHT---"); Serial.println(watering); // здесь будет код, который будет работать постоянно // и который не должен останавливаться на время между переключениями свето unsigned long currentMillis = millis(); //проверяем не прошел ли нужный интервал, если прошел то if(currentMillis - previousMillis > pauseTime * 1000 && ledState == LOW) { // сохраняем время последнего переключения previousMillis = currentMillis; ledState = HIGH; // устанавливаем состояния выхода, чтобы включить или выключить светодиод digitalWrite(ledPin, ledState); } //проверяем не прошел ли нужный интервал, если прошел то if(currentMillis - previousMillis > lightTime * 1000 && ledState == HIGH) { // сохраняем время последнего переключения previousMillis = currentMillis; ledState = LOW; // устанавливаем состояния выхода, чтобы включить или выключить светодиод digitalWrite(ledPin, ledState); } } if (fotorezval>500) //день { int pause1 = analogRead(VAR_REZ3); int watering1 = analogRead(VAR_REZ4); long pauseTime1 = pause1; // Время паузы в секундах long lightTime1 = watering1; // Время свечения в секундах Serial.print("PAUSE DAY---"); Serial.println(pause1); Serial.print("WATERING DAY---"); Serial.println(watering1); // здесь будет код, который будет работать постоянно // и который не должен останавливаться на время между переключениями свето unsigned long currentMillis = millis(); //проверяем не прошел ли нужный интервал, если прошел то if(currentMillis - previousMillis > pauseTime1 * 1000 && ledState == LOW) { // сохраняем время последнего переключения previousMillis = currentMillis; ledState = HIGH; // устанавливаем состояния выхода, чтобы включить или выключить светодиод digitalWrite(ledPin, ledState); } //проверяем не прошел ли нужный интервал, если прошел то if(currentMillis - previousMillis > lightTime1 * 1000 && ledState == HIGH) { // сохраняем время последнего переключения previousMillis = currentMillis; ledState = LOW; // устанавливаем состояния выхода, чтобы включить или выключить светодиод digitalWrite(ledPin, ledState); } } }Обычно для этого не считают количество "срабатываний", а вводят гистерезис.
Цифры 450 и 550 взяты "от балды", правильные зависят от чувствительности и размаха Вашего датчика.
Большое спасибо.