Умная теплица

mitekg
Offline
Зарегистрирован: 14.05.2013

Umka пишет:

Да, простые капельницы тоже копейки стоят. Я много разных капельниц и спринклеров перепробовал, но больше всего с колышками и капеллярками понравились. Их легко перемонтировать на любую длину и количество и льет прямо под корень.

а можно ссылки в студию. очень интересно какие лучше брать и где.

Заранее спасибо

mummykbf
Offline
Зарегистрирован: 28.03.2014

mitekg пишет:

а можно ссылки в студию. очень интересно какие лучше брать и где.

Заранее спасибо

в яндексе пиши "капельный полив", очень много чего нашел и не дорого

Umka
Umka аватар
Offline
Зарегистрирован: 19.10.2012

Я на украинских остановился, завод Факел в донецке. http://fakel.dn.ua гарантия 3 года на всю продукцию, капельницы с клапаном, цена вполне по карману, разборные и легко моются... похоже на рекламу. Это только мое мнение, есть много достойных капельниц такого формата и регулируемых и с фиксированным расходом. Есть наборы готовые, есть рассыпухой. Италия, Израиль, Киталия, отечественные...

Umka
Umka аватар
Offline
Зарегистрирован: 19.10.2012

Tomasina пишет:

Насос омывателя стекла ВАЗ - давление 2,5 кг/см2 , производительность - 16 мл/сек. 

Цена за новый 80-250 руб, рассчитан на уличное применение и нетребователен к химсоставу воды.

Спалил штук 5 таких насосов в инкубаторе (система поддержания влажности). Разных заводов покупал. Они если больше минуты непрерывно работают, то плавятся и сгорают. Только импульсами короткими можно использовать. В режиме 5 секунд качаем, 10 минут отдыхаем моторчик служит третий год. Для полива совершенно не подходит.

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013

Спасибо, будем знать.

southfrost
Offline
Зарегистрирован: 20.04.2014

Привет всем!  дайте код, уважаемый dachnik!

Купил девайс вчера, вкурить побыстрее методы настройки хочется. Спасибо!

 

dachnik
Offline
Зарегистрирован: 26.07.2013
/* adress eeprom
EEPROM 0 Минимальное значение температуры актуатора
EEPROM 1 Максимальное значение темп актуатора
 1 линия полива
EEPROM 2 1/0 включение отключение полива (0=off / 1=on)
EEPROM 3 Продолжительность минут полива
EEPROM 4 минута полива
EEPROM 5 час полива
 2 линия полива
EEPROM 6 1/0 включение отключение полива (0=off / 1=on)
EEPROM 7 Продолжительность минут полива
EEPROM 8 минута полива
EEPROM 9 час полива
 3 линия полива
EEPROM 10 1/0 включение отключение полива (0=off / 1=on)
EEPROM 11 Продолжительность минут полива
EEPROM 12 минута полива
EEPROM 13 час полива
 4 линия полива
EEPROM 14 1/0 включение отключение полива (0=off / 1=on)
EEPROM 15 Продолжительность минут полива
EEPROM 16 минута полива
EEPROM 17 час полива
*/

//LCD I2C 20x4
#include <EEPROM.h>
#include <LiquidCrystal_I2C.h>
#include <Wire.h>
LiquidCrystal_I2C lcd(0x27,20,4);
//LCD

//DHT SENSOR
#include <DHT.h>
#define DHTPIN 2
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE); 
//DHT

//кнопка
// задаем константы кнопок и присваиваем им пины
const int buttonPin = 15;     // центральная кнопка
const int buttonPin_1 = 14;  //левая кнопка 
const int buttonPin_0 = 16;  //правая кнопка
const int ledPin =  13;      // номер выхода светодиода индикатора
const int irr_valve_1 = 32; //№ pin'a первая линия полива
const int irr_valve_2 = 33; //№ pin'a вторая линия полива
const int irr_valve_3 = 34; //№ pin'a третья линия полива
const int irr_valve_4 = 35; //№ pin'a четвёртая линия полива
const int rele_7 = 36; //№ pin'a четвёртая линия полива
const int rele_8 = 37; //№ pin'a четвёртая линия полива



// пины управления актуатором
const int open_actuator = 30; //открыть актуатор пином 34
const int close_actuator = 31; //закрыть актуатор пином 35

//пин управления насосом, который заполняет бочку для полива
const int nasos = 36;
const int sensor_min_level_tank = 26; //дискретный датчик нижнего уровня воды на 26 пине.
const int sensor_max_level_tank = 27;
int sensor_min_level_state= 1; //
int sensor_max_level_state= 1;



/*
int on_off_1 = EEPROM.read(2);
int dur_1 = EEPROM.read(3);
int min_dur_1 = EEPROM.read(4);
int hour_dur_1 = EEPROM.read(5);

int on_off_2 = EEPROM.read(6);
int dur_2 = EEPROM.read(7);
int min_dur_2 = EEPROM.read(8);
int hour_dur_2 = EEPROM.read(9);

int on_off_3 = EEPROM.read(10);
int dur_3 = EEPROM.read(11);
int min_dur_3 = EEPROM.read(12);
int hour_dur_3 = EEPROM.read(13);

int on_off_4 = EEPROM.read(14);
int dur_4 = EEPROM.read(15);
int min_dur_4 = EEPROM.read(16);
int hour_dur_4 = EEPROM.read(17);
*/
// глобальные переменные
int centreBtn = 0;         // переменная для хранения состояния центральной кнопки
int leftbtn = 0;     // переменная для хранения состояния левой кнопки
int rightbtn = 0;     // переменная для хранения состояния правой кнопки
/*
String irr_time =""; //переменная строки времени полива
String irr_time_2 =""; //переменная строки времени полива
String irr_time_3 =""; //переменная строки времени полива
String irr_time_4 =""; //переменная строки времени полива

String end_irr_time ="";
String end_irr_time_2 ="";
String end_irr_time_3 ="";
String end_irr_time_4 ="";
*/
int del = 500; // переменная ожидания между выборами меню(время горения ledpin в милисек)
//подсветка LCD
//int r=0;
long previousMillis = 0;        // храним время
long interval_2 = 10000; //задержка подсветки
long interval_3 = 1000; //задержка записи на SD
// интервал 
//переменные автовозврата в loop 
int interval = 50;    // интервал сколько будет длиться цикл while, после чего перейдёт к следующему меню.(кол-во итераций)
//

int valve_1[5] = {1,2,3,4,5};
int valve_2[5] = {2,6,7,8,9};
int valve_3[5] = {3,10,11,12,13};
int valve_4[5] = {4,14,15,16,17};


//ds1307 модуль часов реального времени
#include <Wire.h>
#include "RTClib.h"
RTC_DS1307 rtc;
//строка времени
String Date; //строка даты

String Time; //времени
//--ds1307

//ds1820 temp
#include <OneWire.h>
#include <DallasTemperature.h>
 // Data wire is plugged into port 2 on the Arduino
#define ONE_WIRE_BUS 3
 // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);
 // Pass our oneWire reference to Dallas Temperature. 
DallasTemperature sensors(&oneWire);
//float in_tempC;
//float out_tempC;
//--ds1820

//SD card
#include <SPI.h>
#include <SD.h>
File myFile;

//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void setup() {
//LCD
#ifdef AVR
Wire.begin();
#else
Wire1.begin(); // Shield I2C pins connect to alt I2C bus on Arduino Due
#endif
lcd.init();   // initialize the lcd 
lcd.backlight();
//--LCD

// initialize the button pin as a input:

// initialize the LED as an output:
pinMode(ledPin, OUTPUT);
pinMode(irr_valve_1, OUTPUT);
pinMode(irr_valve_2, OUTPUT);
pinMode(irr_valve_3, OUTPUT);
pinMode(irr_valve_4, OUTPUT);

pinMode(open_actuator, OUTPUT);
pinMode(close_actuator, OUTPUT);

pinMode(rele_7, OUTPUT);
pinMode(rele_8, OUTPUT);


digitalWrite(irr_valve_1, HIGH);
digitalWrite(irr_valve_2, HIGH);
digitalWrite(irr_valve_3, HIGH);
digitalWrite(irr_valve_4, HIGH);

digitalWrite(open_actuator, HIGH);
digitalWrite(close_actuator, HIGH);

digitalWrite(rele_7, HIGH);
digitalWrite(rele_8, HIGH);

digitalWrite(ledPin, HIGH); 
// initialize serial communication:
Serial.begin(9600);

    
// инициализируем пин, подключенный к кнопке, как вход
pinMode(buttonPin, INPUT);   
pinMode(buttonPin_0, INPUT);   
pinMode(buttonPin_1, INPUT);   

pinMode(nasos, OUTPUT);
pinMode(sensor_min_level_tank, INPUT);
pinMode(sensor_max_level_tank, INPUT);



//ds1307
#ifdef AVR
  Wire.begin();
#else
  Wire1.begin(); // Shield I2C pins connect to alt I2C bus on Arduino Due
#endif
  rtc.begin();

  if (! rtc.isrunning()) {
    Serial.println("RTC is NOT running!");
    // following line sets the RTC to the date & time this sketch was compiled 
    rtc.adjust(DateTime(__DATE__, __TIME__)); //строка установки системного времени во время компиляции скеча
  }
//--ds1307  

//sd
pinMode(53, OUTPUT);
if (!SD.begin(53)) {
    Serial.println("initialization SD flash card failed!");
    return;
  }
  Serial.println("initialization SD flash card done.");
//sd

//DHT
dht.begin();
//DHT

close_windows();
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//#########################################################################################################
void loop() {
//if (LCD_LED){lcd.backlight();}
time();
termostat();
//temp();  

irrigation(valve_1[0],valve_1[1],valve_1[2],valve_1[3],valve_1[4], irr_valve_1);
irrigation(valve_2[0],valve_2[1],valve_2[2],valve_2[3],valve_2[4], irr_valve_2);
irrigation(valve_3[0],valve_3[1],valve_3[2],valve_3[3],valve_3[4], irr_valve_3);
irrigation(valve_4[0],valve_4[1],valve_4[2],valve_4[3],valve_4[4], irr_valve_4);



lcd.setCursor(0,0);
  lcd.print("in= ");
  lcd.print(temp_in());
  lcd.print(" out= ");
  lcd.print(temp_out()); 
//  lcd.setCursor(0,1);
//  lcd.print(irr_time);
  lcd.print("");  
//  lcd.print(end_irr_time);
  lcd.print("");  
//  lcd.print(EEPROM.read(2));
  
  lcd.setCursor(0,2);
  lcd.print(Date);
  lcd.print("  ");
  lcd.print(Time);
  lcd.setCursor(0,3);
  lcd.print("h=");
  lcd.print(Humidity());
  lcd.setCursor(7,3);
  lcd.print("MENU");

  button_read(); //читаем кнопки // проверяем нажата ли кнопка
 
  if (centreBtn) {   // проверяем нажата ли кнопка если нажата, то 
//    LCD_LED = 1;
//    lcd.backlight();
    lcd.backlight();
    digitalWrite(ledPin, LOW);
    delay(del);// включаем светодиод   
    lcd.clear(); //очищаем экран
    digitalWrite(ledPin, HIGH);
    menu();
}

if (leftbtn) {   //включить подсветочку
   lcd.backlight(); 
  open_windows(); 
   //digitalWrite(ledPin, LOW);             
   //LCD_LED();      
   //delay(del);
   //digitalWrite(ledPin, HIGH);            
       }     
if (rightbtn) {
    lcd.backlight(); 
  close_windows(); 
} 

LCD_LED_OFF(); //таймер отключения подсветки



}
//##########################################################################################################33

void menu()
{
actuator_setup();
irrigtion_setup();
irrigation_set_time();

}

void actuator_setup()
{
int x =0;

  lcd.clear(); //очищаем экран

while(1){ // цикл 
x++;
if (x>interval){break;}

  button_read();

  lcd.setCursor(0,0);
  lcd.print(" -=ACTUATOR SETUP=- ");

  int t_mini = EEPROM.read(0);
  lcd.setCursor(0,1);
  lcd.print("min = ");
  lcd.print(t_mini);
  lcd.print((char)223);

  int t_maxi = EEPROM.read(1);
  lcd.setCursor(11,1);
  lcd.print("max = ");
  lcd.print(t_maxi);
  lcd.print((char)223);                   

  lcd.setCursor(0,2);
  lcd.print("____________________");

  lcd.setCursor(0,3);
  lcd.print("T_MIN   NEXT   T_MAX");
  digitalWrite(ledPin, HIGH);
  
   
if (centreBtn) {   
 digitalWrite(ledPin, LOW);             
 delay(del);// включаем светодиод   
 lcd.clear(); //очищаем экран
 digitalWrite(ledPin, HIGH);
 break; }
                      
 if (leftbtn) {   
 digitalWrite(ledPin, LOW);             
   lcd.clear();
        t_min();
       delay(del);
       lcd.clear(); //очищаем экран
       x =0;   
       digitalWrite(ledPin, HIGH);            
       }       
    
if (rightbtn) {   
       digitalWrite(ledPin, LOW);             
       lcd.clear();
        t_max();
       delay(del);// включаем светодиод   
       lcd.clear(); //очищаем экран
       x =0;           
       digitalWrite(ledPin, HIGH);
      }  
  
 }}


void irrigtion_setup()
{
int y =0;  
lcd.clear(); //очищаем экран
while(1){ //бесконечный цикл 
y++;
if (y>interval){break;} //выйти из цикла при y>interval
button_read();

 lcd.setCursor(0,0);
 lcd.print("-=IRRIGATION SETUP=-");
// int on_off = EEPROM.read(2);
//String x;
// if (on_off == 1) {x="ON";}
// if (on_off == 0) {x="OFF";}



 lcd.setCursor(0,1);
 lcd.print("1 ch=");
 lcd.print(on_or_off(valve_1[1])); //вызываем функцию on_or_off передаём ей параметр 2 символ массива, возвращаем string ON или OFF

 lcd.setCursor(10,1);
 lcd.print("3 ch=");
 lcd.print(on_or_off(valve_3[1]));
 
  lcd.setCursor(0,2);
 lcd.print("2 ch=");
 lcd.print(on_or_off(valve_2[1]));
 
  lcd.setCursor(10,2);
lcd.print("4 ch=");
 lcd.print(on_or_off(valve_4[1]));

/*
 int duration = EEPROM.read(3);
 lcd.setCursor(10,1);
 lcd.print("dur=");
 lcd.print(duration);
 lcd.print("min");                   
 lcd.setCursor(0,2);
 lcd.print("____________________"); 
 */
 lcd.setCursor(0,3);

 lcd.print("ON/OFF NEXT DURATION");
//                   digitalWrite(ledPin, HIGH);
    if (centreBtn) {   
           digitalWrite(ledPin, LOW);             
           delay(del);// включаем светодиод   
           lcd.clear(); //очищаем экран
            break;
           }
    
    if (rightbtn) {   
           digitalWrite(ledPin, LOW);             
           lcd.clear();
            durration_irrigation(valve_1[0],valve_1[1],valve_1[2],valve_1[3],valve_1[4]);
            durration_irrigation(valve_2[0],valve_2[1],valve_2[2],valve_2[3],valve_2[4]);
            durration_irrigation(valve_3[0],valve_3[1],valve_3[2],valve_3[3],valve_3[4]);
            durration_irrigation(valve_4[0],valve_4[1],valve_4[2],valve_4[3],valve_4[4]);
            
           delay(del);// включаем светодиод   
               lcd.clear(); //очищаем экран
           y =0;   
           digitalWrite(ledPin, HIGH);            
           }       
        
    if (leftbtn) {   
           digitalWrite(ledPin, LOW);             
           lcd.clear();
            on_off_irrigation(valve_1[0],valve_1[1]);
            on_off_irrigation(valve_2[0],valve_2[1]);
            on_off_irrigation(valve_3[0],valve_3[1]);
            on_off_irrigation(valve_4[0],valve_4[1]);
            
            
            //on_off_irrigation();  
           delay(del);// включаем светодиод   
           lcd.clear(); //очищаем экран
           y =0;            
           digitalWrite(ledPin, HIGH);
          }  
 

 }}

void irrigation_set_time()
{
int x =0;
lcd.clear(); //очищаем экран
while(1){ //бесконечный цикл 
x++;
if (x>interval){break;}
button_read();
//string_irrigation_time(); //выполняем функцию строки времени полива для отображения переменной irr_time
 lcd.setCursor(0,0);
 lcd.print("IRRIGATION SET TIME");
 lcd.setCursor(0,1);
 lcd.print("1: ");
 lcd.print(string_irrigation_time(valve_1[0],valve_1[1],valve_1[2],valve_1[3],valve_1[4]));
 lcd.print(" ");
 lcd.print(string_irrigation_time(valve_3[0],valve_3[1],valve_3[2],valve_3[3],valve_3[4]));
 lcd.setCursor(0,2);
 lcd.print("2: ");
 lcd.print(string_irrigation_time(valve_2[0],valve_2[1],valve_2[2],valve_2[3],valve_2[4]));
 lcd.print(" ");
 lcd.print(string_irrigation_time(valve_4[0],valve_4[1],valve_4[2],valve_4[3],valve_4[4]));
// lcd.print(irr_time); //выводим переменную строки времени полива 



 lcd.setCursor(0,3);
 lcd.print("hours   NEXT  minuts");
 digitalWrite(ledPin, HIGH);
if (centreBtn) {   
       digitalWrite(ledPin, LOW);             
       delay(del);// включаем светодиод   
       lcd.clear(); //очищаем экран
       digitalWrite(ledPin, HIGH);
       break;
       }

if (leftbtn) {   
       digitalWrite(ledPin, LOW);             
       lcd.clear();
       irrigation_set_hours(valve_1[0],valve_1[1],valve_1[2],valve_1[3],valve_1[4]);
       irrigation_set_hours(valve_2[0],valve_2[1],valve_2[2],valve_2[3],valve_2[4]);
       irrigation_set_hours(valve_3[0],valve_3[1],valve_3[2],valve_3[3],valve_3[4]);
       irrigation_set_hours(valve_4[0],valve_4[1],valve_4[2],valve_4[3],valve_4[4]);
       delay(del);
       lcd.clear(); //очищаем экран
       x =0;   
       digitalWrite(ledPin, HIGH);            
       }       
    
if (rightbtn) {   
       digitalWrite(ledPin, LOW);             
       lcd.clear();
        irrigation_set_minuts(valve_1[0],valve_1[1],valve_1[2],valve_1[3],valve_1[4]);
        irrigation_set_minuts(valve_2[0],valve_2[1],valve_2[2],valve_2[3],valve_2[4]);
        irrigation_set_minuts(valve_3[0],valve_3[1],valve_3[2],valve_3[3],valve_3[4]);
        irrigation_set_minuts(valve_4[0],valve_4[1],valve_4[2],valve_4[3],valve_4[4]);

       delay(del);// включаем светодиод   
       lcd.clear(); //очищаем экран
       x =0;            
       digitalWrite(ledPin, HIGH);
      }  

 }}



//////--------------------------------------------------------------------------
//SUB MENU

void t_min()
{

lcd.clear(); //очищаем экран
delay(del);
while(1){ //бесконечный цикл 
button_read();

 lcd.setCursor(0,0);
 lcd.print(" TEMP MINIMUM SETUP");
 int t_min = EEPROM.read(0);
 lcd.setCursor(0,1);
 lcd.print("t = ");
 lcd.print(t_min);
 lcd.print((char)223);
 lcd.print("C");                   
 lcd.setCursor(0,3);
 lcd.print("t_min-1 NEXT t_min+1");
 lcd.setCursor(0,2);
 lcd.print("____________________");

 digitalWrite(ledPin, HIGH);
    if (centreBtn) {   
           digitalWrite(ledPin, LOW);             
           delay(del);// включаем светодиод   
           lcd.clear(); //очищаем экран
           digitalWrite(ledPin, HIGH);
           break;

           }
    
    if (rightbtn) {   
            delay(del);     
            digitalWrite(ledPin, LOW);             
            lcd.clear();
            EEPROM.write(0, t_min + 1);
            digitalWrite(ledPin, HIGH);            
           }       
        
    if (leftbtn) {   
          delay(del); 
          digitalWrite(ledPin, LOW);             
          lcd.clear();
          EEPROM.write(0, t_min - 1);
          digitalWrite(ledPin, HIGH);
          }  
 
 }
}

void t_max()
{

lcd.clear(); //очищаем экран
delay(del);
while(1){ //бесконечный цикл 
button_read();

 lcd.setCursor(0,0);
 lcd.print(" TEMP MAXIMUM SETUP");
 int t_max = EEPROM.read(1);
 lcd.setCursor(0,1);
 lcd.print("t = ");
 lcd.print(t_max);
 lcd.print((char)223);
 lcd.print("C");                   
 lcd.setCursor(0,3);
 lcd.print("t_max-1 NEXT t_max+1");
 lcd.setCursor(0,2);
 lcd.print("____________________");

 digitalWrite(ledPin, HIGH);
    if (centreBtn) {   
           digitalWrite(ledPin, LOW);             
           delay(del);// включаем светодиод   
           lcd.clear(); //очищаем экран
           digitalWrite(ledPin, HIGH);
           break;

           }
    
    if (rightbtn) {   
            delay(del);     
            digitalWrite(ledPin, LOW);             
            lcd.clear();
            EEPROM.write(1, t_max + 1);
            digitalWrite(ledPin, HIGH);            
           }       
        
    if (leftbtn) {   
          delay(del); 
          digitalWrite(ledPin, LOW);             
          lcd.clear();
          EEPROM.write(1, t_max - 1);
          digitalWrite(ledPin, HIGH);
          }  
 
 }
}

void on_off_irrigation(int ch,int on_off_x)
{

lcd.clear(); //очищаем экран
delay(del);
while(1){ //бесконечный цикл 
button_read();

 lcd.setCursor(0,0);
 lcd.print("ON/OFF IRRIGATION");
 //int on_off = EEPROM.read(on_off_x);
 //String x;
 //if (on_off == 1) {x="ON";}
 //if (on_off == 0) {x="OFF";}


 lcd.setCursor(0,2);
 lcd.print("irrigation = ");
 lcd.print(on_or_off(on_off_x));
 //lcd.print(on_off);
 lcd.setCursor(0,1);
 lcd.print("chanel N=");
 lcd.print(ch);
 lcd.setCursor(0,3);
 lcd.print("ON      NEXT     OFF");


 digitalWrite(ledPin, HIGH);
    if (centreBtn) {   
           digitalWrite(ledPin, LOW);             
           delay(del);// включаем светодиод   
           lcd.clear(); //очищаем экран
           digitalWrite(ledPin, HIGH);
           break;

           }
    
    if (rightbtn) {   
            delay(del);     
            digitalWrite(ledPin, LOW);             
            lcd.clear();
            EEPROM.write(on_off_x, 0);
            digitalWrite(ledPin, HIGH);            
           }       
        
    if (leftbtn) {   
          delay(del); 
          digitalWrite(ledPin, LOW);             
          lcd.clear();
          EEPROM.write(on_off_x, 1);
          digitalWrite(ledPin, HIGH);
          }  
 
 }
}
void durration_irrigation(int ch,int on_off_x, int dur, int min_dur, int hour_dur)
{

lcd.clear(); //очищаем экран
delay(del);
while(1){ //бесконечный цикл 
button_read();
string_end_irrigation_time(ch, on_off_x, dur, min_dur, hour_dur);
 lcd.setCursor(0,0);
 lcd.print("DURRATION IRRIGATIN");
 int duration = EEPROM.read(dur);
 lcd.setCursor(0,1);
 lcd.print("ch N=");
 lcd.print(ch);
 lcd.print(" dur=");
 lcd.print(duration);
 lcd.print(" min");                   
 lcd.setCursor(0,3);
 lcd.print("-1min   NEXT   +1min");
 lcd.setCursor(0,2);
 lcd.print(string_irrigation_time(ch, on_off_x, dur, min_dur, hour_dur)); 
 lcd.print("    ");
 lcd.print(string_end_irrigation_time(ch, on_off_x, dur, min_dur, hour_dur));

 digitalWrite(ledPin, HIGH);
    if (centreBtn) {   
           digitalWrite(ledPin, LOW);             
           delay(del);// включаем светодиод   
           lcd.clear(); //очищаем экран
           digitalWrite(ledPin, HIGH);
           break;

           }
    
    if (rightbtn) {   
            delay(del);     
            digitalWrite(ledPin, LOW);             
            lcd.clear();
            EEPROM.write(dur, duration + 1);
            digitalWrite(ledPin, HIGH);            
           }       
        
    if (leftbtn) {   
          delay(del); 
          digitalWrite(ledPin, LOW);             
          lcd.clear();
          EEPROM.write(dur, duration - 1);
          digitalWrite(ledPin, HIGH);
          }  
 
 }
}

void irrigation_set_minuts(int ch,int on_off_x, int dur, int min_dur, int hour_dur)
{

lcd.clear(); //очищаем экран
delay(del);
while(1){ //бесконечный цикл 
button_read();
//string_irrigation_time();
 lcd.setCursor(0,0);
 lcd.print("SET IRR-TION MINUTES");
 int minuts = EEPROM.read(min_dur);
 lcd.setCursor(0,1);
 lcd.print("ch N_");
 lcd.print(ch);
 lcd.print("= ");
 
 lcd.print(string_irrigation_time(ch, on_off_x, dur, min_dur, hour_dur));
// lcd.print("min");                   
 lcd.setCursor(0,2);
 lcd.print("____________________");
 lcd.setCursor(0,3);
 lcd.print("-1min   NEXT   +1min");
 digitalWrite(ledPin, HIGH);
  
    if (centreBtn) {   
           digitalWrite(ledPin, LOW);             
           delay(del);// включаем светодиод   
           lcd.clear(); //очищаем экран
           digitalWrite(ledPin, HIGH);
           break;
           }
    
    if (rightbtn) {   
            delay(del);     
            digitalWrite(ledPin, LOW);             
            lcd.clear();
            minuts = minuts + 1;
            if (minuts >59){minuts=0;}
            EEPROM.write(min_dur, minuts);
            digitalWrite(ledPin, HIGH);            
           }       
        
    if (leftbtn) {   
          delay(del); 
          digitalWrite(ledPin, LOW);             
          lcd.clear();
          minuts = minuts - 1;
          if (minuts < 0) {minuts=59;}
          EEPROM.write(min_dur, minuts);
          digitalWrite(ledPin, HIGH);
          }  
 
 }

}
void irrigation_set_hours(int ch,int on_off_x, int dur, int min_dur, int hour_dur)
{

lcd.clear(); //очищаем экран
delay(del);
while(1){ //бесконечный цикл
button_read();
//string_irrigation_time();
 lcd.setCursor(0,0);
 lcd.print(" SET IRR-TION HOURS");
 int hours = EEPROM.read(hour_dur);
 lcd.setCursor(0,1);
  lcd.print("ch N_");
 lcd.print(ch);
 lcd.print("= ");
 lcd.print(string_irrigation_time(ch, on_off_x, dur, min_dur, hour_dur));
// lcd.print("min");                   
 lcd.setCursor(0,2);
 lcd.print("____________________");
 lcd.setCursor(0,3);
 lcd.print("-1hour  NEXT  +1hour");

 digitalWrite(ledPin, HIGH);
    if (centreBtn) {   
           digitalWrite(ledPin, LOW);             
           delay(del);// включаем светодиод   
               lcd.clear(); //очищаем экран
               digitalWrite(ledPin, HIGH);
               break;
           
           }
    
    if (rightbtn) {   
            delay(del);     
            digitalWrite(ledPin, LOW);             
            lcd.clear();
            hours = hours + 1;
            if (hours >23){hours=0;}
            EEPROM.write(hour_dur, hours);
            digitalWrite(ledPin, HIGH);            
           }       
        
    if (leftbtn) {   
          delay(del); 
          digitalWrite(ledPin, LOW);             
          lcd.clear();
          hours = hours - 1;
          if (hours < 0) {hours=23;}
          EEPROM.write(hour_dur, hours);
          digitalWrite(ledPin, HIGH);
          }  
 }
}
String string_irrigation_time(int ch, int on_off_x, int dur, int min_dur, int hour_dur) // функция формирования строки времни полива
{
String irr_time = ""; //очистим глобальную переменную навсякий случай. 


 int minuts = EEPROM.read(min_dur); //читаем память
 int hours = EEPROM.read(hour_dur);
 if (hours >= 0 && hours <=9) {irr_time += 0; irr_time += hours;} else{irr_time += hours;} //дописываем нолик для hours
 
 irr_time += ":";
 if (minuts >= 0 && minuts <=9){irr_time += 0; irr_time += minuts;} else{irr_time += minuts;} //дописываем нолик для minuts
 
 
 irr_time += ":";
 irr_time += "00"; //собрали строку времени полива
// lcd.setCursor(0,1);
// lcd.print("irr_time=");
// lcd.print(irr_time);
return irr_time;
}

String string_end_irrigation_time(int ch, int on_off_x, int dur, int min_dur, int hour_dur) // функция формирования строки времни полива
{
String end_irr_time = ""; //очистим глобальную переменную навсякий случай. 

 int minuts = EEPROM.read(min_dur) + EEPROM.read(dur); //читаем память
 int hours = EEPROM.read(hour_dur);
 if (minuts > 59) {int x = minuts / 60; hours += x; int y = x * 60; minuts -= y;}
 if (hours >= 0 && hours <=9) {end_irr_time += 0; end_irr_time += hours;} else{end_irr_time += hours;} //дописываем нолик для hours
 
 end_irr_time += ":";
 if (minuts >= 0 && minuts <=9){end_irr_time += 0; end_irr_time += minuts;} else{end_irr_time += minuts;} //дописываем нолик для minuts
  
 end_irr_time += ":";
 end_irr_time += "00"; //собрали строку времени полива
// lcd.setCursor(0,1);
// lcd.print("irr_time=");
// lcd.print(irr_time);
return end_irr_time;
}

void button_read() //функция проверки нажатия кнопки
{
centreBtn = digitalRead(buttonPin); //запоминаем значение кнопки
rightbtn = digitalRead(buttonPin_0); //запоминаем значение кнопки
leftbtn = digitalRead(buttonPin_1); //запоминаем значение кнопки
}
void LCD_LED_OFF()//таймер отключения подсветки
{
  unsigned long currentMillis = millis();
  //проверяем не прошел ли нужный интервал, если прошел то
  if(currentMillis - previousMillis > interval_2) {
   // сохраняем время последнего переключения
   previousMillis = currentMillis; 
 lcd.noBacklight();        
//  lcd.setCursor(0,3);
 // lcd.print("led");
 // if(r==0)
//      {lcd.print("led off"); r=1;  lcd.noBacklight();    } 
 // else if(r==1)//если кнопка НЕ нажата 
  //    {lcd.print("led on"); r=0;   lcd.backlight();     } 
}
}

void time() //функция строки времени
{    
//  int x;
  DateTime now = rtc.now();
    Date = "";
    Date += now.year();
    Date += "/";
     if (now.month() >=0 && now.month() <=9)
     {
      Date += "0";
      Date += now.month();
     } else {Date += now.month();}
  Date += "/";
     if (now.day() >= 0 && now.day() <=9)
     {
       Date += "0";
       Date += now.day();
     } else {Date += now.day();}
   //dataString += " ";
     Time ="";
     if (now.hour() >= 0 && now.hour() <=9 )
     { 
       
       Time += "0";
       Time += now.hour();
     } else {Time += now.hour();}
   Time += ":";
     if (now.minute() >= 0 && now.minute() <=9 )
     {
       Time += "0";
       Time += now.minute();
     } else {Time += now.minute();}
    Time += ":";
      if (now.second() >= 0 && now.second() <= 9)
      {
      Time += "0";
      Time += now.second();
      }
     else {Time += now.second();}
 //   Time += " ";
}
float temp_in()
 {
   sensors.requestTemperatures(); // Send the command to get temperatures
  float in_tempC = sensors.getTempCByIndex(0);
return in_tempC;
}

float temp_out()
 {
   sensors.requestTemperatures(); // Send the command to get temperatures
float out_tempC = sensors.getTempCByIndex(1);
return out_tempC;
 }

void irrigation(int ch, int on_off_x, int dur, int min_dur, int hour_dur, int irr_valve)
{
 int x=EEPROM.read(on_off_x);
 if (x == 1){
//  string_irrigation_time(ch, on_off_x, dur, min_dur, hour_dur);
//  string_end_irrigation_time(ch, on_off_x, dur, min_dur, hour_dur);
    if(string_irrigation_time(ch, on_off_x, dur, min_dur, hour_dur) == Time)
    {
      digitalWrite(irr_valve, LOW); 
      Serial.print("ch: ");
      Serial.print(ch);
      Serial.print(" ");
      Serial.print("pin: ");
      Serial.print(irr_valve);
      Serial.print(" ");
      Serial.print("Status: ");
      Serial.println(" ON");
      
      String file_name = "irrigat.txt";
      String  value = "";
              value += ch;
             value += ";1;";
             sd_write (file_name, value);
      
    }
    if(string_end_irrigation_time(ch, on_off_x, dur, min_dur, hour_dur) == Time)
    {
      digitalWrite(irr_valve, HIGH);
      Serial.print("ch: ");
      Serial.print(ch);
      Serial.print(" ");
      Serial.print("pin: ");
      Serial.print(irr_valve);
      Serial.print(" ");
      Serial.print("Status: ");
      Serial.println(" OFF");
      
      String file_name = "irrigat.txt";
      String  value = "" ;
              value += ch;
             value += ";0;";
             sd_write (file_name, value);
}
}

}

String on_or_off (int on_off)
{
int z = EEPROM.read(on_off);
  String x;
 if (z == 1) {x="ON";}
 if (z == 0) {x="OFF";}
 return x;
}

int termostat ()
{
int temp_min = EEPROM.read(0);
int temp_max = EEPROM.read(1);
  if (temp_out() > temp_max && digitalRead(close_actuator)==LOW)
  {
    open_windows();
  }

  if (temp_out() < temp_min && digitalRead(open_actuator)==LOW)
  {
  close_windows();
  }
}
void open_windows()
{
    digitalWrite(close_actuator, HIGH);
    delay(1000);
    digitalWrite(open_actuator, LOW);

//    lcd.setCursor(0,0);
 //   lcd.print("Open window");   
    lcd.setCursor(0,1);
    lcd.print("OPEN ACTUATOR");
String file_name = "actuator.txt";
String value = "1";
sd_write (file_name, value);
}
void close_windows()
{
    digitalWrite(open_actuator, HIGH);
    delay(1000);
    digitalWrite(close_actuator, LOW);

//    lcd.setCursor(0,0);
 //   lcd.print("Open window");   
    lcd.setCursor(0,1);
    lcd.print("CLOSE ACTUATOR");
    String file_name = "actuator.txt";
    String value = "0";
    sd_write (file_name, value);
}
int _nasos()
{
sensor_min_level_state = digitalRead(sensor_min_level_tank);
sensor_max_level_state = digitalRead(sensor_max_level_tank);
if (sensor_min_level_state == LOW) 
 {
 digitalWrite(nasos, HIGH);
      String file_name = "nasos.txt";
      String value = "0";
      sd_write (file_name, value);
 }
if (sensor_max_level_state == HIGH)
 {
 digitalWrite(nasos,LOW);
      String file_name = "nasos.txt";
      String value = "1";
      sd_write (file_name, value);
 }

}

int sd_write (String file_name, String value)
{
unsigned long currentMillis = millis();
  //проверяем не прошел ли нужный интервал, если прошел то
  if(currentMillis - previousMillis > interval_3) {
   // сохраняем время последнего переключения
   previousMillis = currentMillis; 
 
char f_n[file_name.length()+1];
file_name.toCharArray(f_n, file_name.length()+1);
myFile = SD.open(f_n , FILE_WRITE);
//myFile = SD.open(file_name.c_str() , FILE_WRITE);
  
  // if the file opened okay, write to it:
  if (myFile) {
    Serial.print("Writing to ");
    Serial.print(f_n);
//    Serial.print(file_name.c_str());
    Serial.print(" ");
    myFile.print(Date);
    myFile.print(";");
    myFile.print(Time);
    myFile.print(";");
    myFile.println(value);
    	// close the file:
    myFile.close();
    Serial.print("done. Writed: ");
    Serial.print(Date);
    Serial.print(";");
    Serial.print(Time);
    Serial.print(";");
    Serial.println(value);
    return(1);
  } else {
    // if the file didn't open, print an error:
    Serial.println("error opening sd card. File: ");
    Serial.print(file_name.c_str());
    return(0);
    
  }
  }
}
int Humidity()
{
int h = dht.readHumidity();
return h;
}

 

Probelzaelo
Offline
Зарегистрирован: 15.04.2011

Тут две "соосные" темы появились  вернее по сути то это дубли одной.

Управление микроклиматом теплицы  

Контроль климата в теплице
 

 

 

 

southfrost
Offline
Зарегистрирован: 20.04.2014

Даа а чего?! Интересная такая тема... Родители старики, тяжело поливать каждый вечер. А помогать некогда. Либо работать, либо помогать...

dachnik
Offline
Зарегистрирован: 26.07.2013

а тем временем идёт сборка ящега управления.

потроха:

Когда был произведён первый запуск обнаружилось, что блок реле на красном текстолите работают наоборт в отличии от блоков реле на синем текстолите. т.е. при логическом 0 на реле - включенно. 1 - выключенно. Это специально китайцы так придумали?=) пришлось сменить на синий блок.

Тимур
Тимур аватар
Offline
Зарегистрирован: 30.04.2014

Про насосы, возьмите дополнительную помпу Бош

 

стоит около 1600, напряжение 12 В, ток замерянный на машине 1,2-1,5 А. Сколько прокачивает литров точно не скажу, но капельницам хвати за глаза это точно. По давлению: ДТ (солярку) поднимала на 2,5 метра на ура (хотя вообще качает тосол). Разъём подходит от форсунки ВАЗ стоит 30-50 руб. Парт номер для заказа в отделе иномарок 0392020034 Бош. Есть отечественные аналоги, но они стоят на 100 руб дешевле, потребляют около 3 А, гудят и текут 

вот видео работы

 

http://www.youtube.com/watch?v=RaqqusQ5EGA

 

(как тут у Вас видео вставить чтобы сразу окошко было?)

southfrost
Offline
Зарегистрирован: 20.04.2014

Несколько вопросов появилось! Будьте добры, ответьте))

 

1. Как реализованы физически датчики уровня воды в бочке?

Нужно ведь чтоб не окислялись они. Латунь?

2. Как включается полив по времени?

Плата часов нужна по ходу. Хотя можно и будильник на первых порах попробовать.

3. Что используете в качестве крана для открытия полива? Что все-таки выбрали?

 

dachnik
Offline
Зарегистрирован: 26.07.2013

southfrost пишет:

Несколько вопросов появилось! Будьте добры, ответьте))

 

1. Как реализованы физически датчики уровня воды в бочке?

Нужно ведь чтоб не окислялись они. Латунь?

Дачики пластиковые они не окисляюся такие.

southfrost пишет:

2. Как включается полив по времени?

Плата часов нужна по ходу. Хотя можно и будильник на первых порах попробовать.

Нужно ведь чтоб не окислялись они. Латунь?

Задал во сколько старт и продолжиельность. и понеслось.

southfrost пишет:

3. Что используете в качестве крана для открытия полива? Что все-таки выбрали?

если вы про клапана, то я о них писал уже. 12 вольовые, расчитанные на слабое давление.

Тима
Тима аватар
Offline
Зарегистрирован: 11.04.2013

southfrost пишет:

Несколько вопросов появилось! Будьте добры, ответьте))

 

1. Как реализованы физически датчики уровня воды в бочке?

Нужно ведь чтоб не окислялись они. Латунь?

Я использовал нержавеющие электроды для дуговой сварки.

southfrost пишет:

2. Как включается полив по времени?

Плата часов нужна по ходу. Хотя можно и будильник на первых порах попробовать.

Часы реального времени для дуины или http://www.ebay.com/itm/THC-15A-Digital-LCD-Weekly-Programmable-Timer-AC-220V-Time-Relay-Switch-04-/271031555181?pt=LH_DefaultDomain_0&hash=item3f1abd546d

southfrost пишет:

3. Что используете в качестве крана для открытия полива? Что все-таки выбрали?

У меня включался насос, без крана. А алгоритм такой: включение насоса по времени, отключение по уровню! Пришло время, полил сколько надо, отключил насос и заполнил емкость.

Тима
Тима аватар
Offline
Зарегистрирован: 11.04.2013

Да, и еще, кран не ставил. Вместо него поставил обычный обратный клапан. Самотеком воде вытечь не хватает давления, а насос его открывает на ура.

southfrost
Offline
Зарегистрирован: 20.04.2014

обратный клапан на то и обратный, чтоб воде не вытечь.... Не понятно! Где насос стоит?       резервуар -> клапан -> насос???

ИЛИ все-таки   резервуар -> насос -> клапан???

Тима
Тима аватар
Offline
Зарегистрирован: 11.04.2013

резервуар--> насос -> клапан.

Обратный клапан - он для того, чтоб поток обратно не пропускать. Тут клапан используется не по прямому назначению. Используется в качестве перепускного клапана. Если емкость будет высокая, то давление высоты водяного столба может продавить и через обратный клапан. Тогда нужно подбирать перепускной клапан, они бывают регулируемые.

southfrost
Offline
Зарегистрирован: 20.04.2014

а есть фоточка?

Тима
Тима аватар
Offline
Зарегистрирован: 11.04.2013

к сожалению нет. Эта теплица у меня была лет 6-7 назад. теплицу уже снесли...

southfrost
Offline
Зарегистрирован: 20.04.2014

Часы для дуины интереснее. Можно зависимости полива от датчиков более гибкими способами прописать. Эта штука с Е-бея на зависимости от времени года и температуры не настроить. Таким же макаром можно пищалку с будильника снять и на цифровой вход на INPUT провод цепануть или старую мобилу. Решение неполноценно.

 

 

Тима
Тима аватар
Offline
Зарегистрирован: 11.04.2013

Ну, если теплицей будет управлять дуина, то да. Но 7 лет назад я о дуине еще не знал и делал тем, что было в продаже. Тогда у меня в теплице балом правил "ОВЕН".

Shir
Offline
Зарегистрирован: 21.02.2014

southfrost пишет:

Несколько вопросов появилось! Будьте добры, ответьте))

 

1. Как реализованы физически датчики уровня воды в бочке?

У меня за уровнем воды следит система из двух герконов ( Мин и Мах ), шланг и поплавок с магнитом.

Магнит проходит Мин включает насос, доходит до Мах выключает. 

 

 
southfrost
Offline
Зарегистрирован: 20.04.2014

Интересная задумка. Заводского изготовления или колхоз?

Shir
Offline
Зарегистрирован: 21.02.2014

Идея не нова. Схему подглядели где то. Основную работу проделал Тесть. Использовали корпус ббп-20, оттуда же брали питание 12V для реле.

 
ZagZag
Offline
Зарегистрирован: 08.05.2014

Всем привет. Здорово, что такая тема жива. Делюсь своими наработками.

// Термодатчик DS18B20
#include <OneWire.h>
#include <DallasTemperature.h>
// Спящий режим
#include <avr/sleep.h>
#include <avr/power.h>
#include <avr/wdt.h>
// Остальное
#include <EEPROM.h>
#include <Streaming.h>

// Часы реального времени
byte day = 0;
byte hours = 0;
byte minutes = 0;
byte seconds = 0;

// Время в гексаминутах ;)
// Так в 1 байт помещается.
// 1440 минут в сутках (24 часа), делим на 6 = 240. 
// Можно хранить максимум 24 часа в байте с точностью до 1/6 минуты
byte time;       // Время суток
byte water_time = 120; // Время последнего полива. 120 для проверки

// Флаги состояния
byte t1_online, t2_online; // Наличие термодатчиков
byte t1_val, t2_val;       // Значение термодатчиков
byte online = 1;           // если 0 - система на паузе

// Сдвиговый регистр
int switches = 0; // Состояние выводов сдвигового регистра
byte LIGHT   = 0;
byte WATER   = 1;
byte T1_UP   = 2;
byte T1_DOWN = 3;
byte T2_UP   = 4;
byte T2_DOWN = 5;

// Выводы Arduino
byte PIN_LATCH   = 8;  // Затвор сдвигового регистра (ST_CP)
byte PIN_ONEWIRE = 10; // Шина для датчиков температуры (OneWire)
byte PIN_DATA    = 11; // Данные для сдвигового регистра (DS)
byte PIN_CLOCK   = 12; // Тактирование сдвигового регистра (SH_CP)
byte PIN_LED     = 13; // Индикаторный светодиод

// Настройки (EEPROM)
byte CONF_ADDR = 32; // Смещение структуры в EEPROM
byte CONF_VER = 2;   // Версия настроек. Если версия не совпадает, то загрузятся настройки по-умолчанию

struct ConfigStruct {
  byte version;
  byte t1_id[8], t2_id[8]; // Идентификаторы датчиков демпературы
  float t1_min, t1_max; // Настройки термостата 1
  float t2_min, t2_max; // Настройки термостата 2
  float delta_temp;  // Разница температур, как условие для полива. Если разница небольшая, то датчик в земле сухой.
  byte water_period; // Время проверки необходимости полива в гексаминутах.
  byte light[200]; // Световая схема на каждый из 200 дней. В гексаминутах.
} config = {
  CONF_VER, 
  {}, {}, 
  22.00, 26.00, 
  21.00, 25.00, 
  1.50, 10, 
  {120,120,120,120}
};

OneWire oneWire(PIN_ONEWIRE);
DallasTemperature sensors(&oneWire);

// Прерывания
ISR(WDT_vect)
{
  digitalWrite(PIN_LED, !digitalRead(PIN_LED));
}
void serialEvent() {
  while (Serial.available()) {
    cmd_receive();
//    char inChar = (char)Serial.read();
//    inputString += inChar;
//    if (inChar == '\n') {
//      stringComplete = true;
//    }
  }
}

// Main code
void setup() {
  pinMode(PIN_LED,   OUTPUT);
  pinMode(PIN_LATCH, OUTPUT);
  pinMode(PIN_CLOCK, OUTPUT);
  pinMode(PIN_DATA,  OUTPUT);
  
  Serial.begin(9600);
  config_load();
  sensors.begin();

  // Watchdog timer
  MCUSR &= ~(1<<WDRF); /* Clear the reset flag. */
  WDTCSR |= (1<<WDCE) | (1<<WDE);
  WDTCSR = 1<<WDP0 | 1<<WDP3; /* 8.0 seconds */ /* set new watchdog timeout prescaler value */
  WDTCSR |= _BV(WDIE); /* Enable the WD interrupt (note no reset). */

  // Инициализация прошла
  for(byte i = 0; i < 10; i++) {
    digitalWrite(PIN_LED, !digitalRead(PIN_LED));
    delay(200);
  }
}


void loop() {
  ////// Каждые 8 секунд
  // Часы тикают
  seconds += 8;
  if (seconds >= 60) {
    minutes++; seconds -= 60;
    if (minutes == 60) {
      hours++; minutes=0;
      if (hours == 24) {
        day++; hours = 0;
      }
    }

    ////// Каждую минуту
    // Текущее время в гексаминутах, округляем, да.
    time = hours * 10 + minutes / 6; // В одном часе 10 гексаминут

    // Свет
    switch_set(LIGHT, ((time >= config.light[day]) ? HIGH : LOW));

    // Опрос термометров
    sensors.setResolution(config.t1_id, 10);
    sensors.setResolution(config.t2_id, 10);
    sensors.requestTemperatures();
    t1_val = sensors.getTempC(config.t1_id);
    if (t1_val == -127.00) { t1_online = 0; } else { t1_online = 1; }
    t2_val = sensors.getTempC(config.t2_id);
    if (t2_val == -127.00) { t2_online = 0; } else { t2_online = 1; }

    // Полив
    if (t1_online && t2_online) {
      if ((t1_val - t2_val) < config.delta_temp) {
        if (max(time, water_time) - min(time, water_time) >= config.water_period) {
          water_time = time;
          switch_set(WATER, HIGH);
          delay(1000);
          switch_set(WATER, LOW);
        }
      }
    }

    // Термостат
    if (t1_online) {
      switch_set(T1_DOWN, ((t1_val > config.t1_max) ? HIGH : LOW));
      switch_set(T1_UP, ((t1_val < config.t1_min) ? HIGH : LOW));
    }

    if (t2_online) {
      switch_set(T2_DOWN, ((t2_val > config.t2_max) ? HIGH : LOW));
      switch_set(T2_UP, ((t2_val < config.t2_min) ? HIGH : LOW));
    }
  }
  do_sleep(); // В спящий режим
}


// Функции
void cmd_receive() {
// формат: команда[ параметр[ значение]]
// пример: set t1_max 26.80
// исключение light второй параметр 200 байт
  char param[6] = {0,0,0,0,0,0};

  // Принять команду, до пробела
  serial_read_param(param);
  switch (param[0]) {
  case '0': // Вывести всю информацию
    status_show();
    break;
  case '1':
    Serial << "(under construction)" << endl;
    break;
  case '2':
    config_save();
    break;
  case '3':
    Serial << "(under construction)" << endl;
    break;
  default:
    Serial << "Commands:" << endl << "0 - view status" << endl << "1 - set parameter" << endl << "2 - save settings to EEPROM" << endl << "3 - list online termometers" << endl;
  }
  Serial.flush();
}

// это скорее всего не работает, но смысл ясен
void serial_read_param(char* param) {
  byte rx = 0, i = 0;
  do {
    rx = (byte)Serial.read();
    switch (rx) {
    case 0:
    case 10:
    case 13:
    case 32:
      return;
    }
    *(param + i) = (char)rx;
    i++;
  } while (i < 5);
}

void status_show() {
  Serial << "Status: " << ((online == 1) ? "Online" : "Offline") << endl;
  Serial << "Time: "; // DDD:HH:MM:SS
  Serial << ((day < 100) ? "0" : "") << ((day < 10) ? "0" : "") << day << ":";
  Serial << ((hours < 10) ? "0" : "") << hours << ":";
  Serial << ((minutes < 10) ? "0" : "") << minutes << ":";
  Serial << ((seconds < 10) ? "0" : "") << seconds << endl;

  Serial << "Last watering: ";
  byte water_time_h = water_time / 10;
  Serial << ((water_time_h < 10) ? "0" : "") << water_time_h << ":";
  byte water_time_m = (water_time % 10) * 6;
  Serial << ((water_time_m < 10) ? "0" : "") << water_time_m << endl;
  
  Serial << "Termostat 1: " << ((t1_online == 1) ? "Online" : "Offline") << endl;
//  if (t1_online) {
    Serial << _FLOAT(t1_val, 2) << " (" << _FLOAT(config.t1_min, 2) << ".." << _FLOAT(config.t1_max, 2) << ")" << endl;
//  }
  
  Serial << "Termostat 2: " << ((t2_online == 1) ? "Online" : "Offline") << endl;
//  if (t2_online) {
    Serial << _FLOAT(t2_val, 2) << " (" << _FLOAT(config.t2_min, 2) << ".." << _FLOAT(config.t2_max, 2) << ")" << endl;
//  }

  Serial << "Watering: 1 second every " << (config.water_period * 6) << " minutes, if (temp 1 - temp 2) < " << _FLOAT(config.delta_temp, 2) << endl;
}

void config_load() {
  Serial << "Loading config... ";
  if (EEPROM.read(CONF_ADDR) != CONF_VER) {
    Serial << "DEFAULT" << endl;
    return;
  }
  for (unsigned int t = 0; t < sizeof(config); t++)
    *((char *)&config + t) = EEPROM.read(CONF_ADDR + t);
  Serial << "EEPROM" << endl;
}

void config_save() {
  Serial << "Saving config to EEPROM... ";
  for (unsigned int t = 0; t < sizeof(config); t++) {
    EEPROM.write(CONF_ADDR + t, *((char *)&config + t));
  }
  Serial << "OK" << endl;
}

void switch_set(byte pos, byte state) {
  bitWrite(switches, pos, state);
  if (online == 1) switches_update();
}

void switches_update() {
  digitalWrite(PIN_LATCH, LOW);
  // Вывод будет MSBFIRST с первого (левого) бита
  shiftOut(PIN_DATA, PIN_CLOCK, MSBFIRST, (switches >> 8)); 
  shiftOut(PIN_DATA, PIN_CLOCK, MSBFIRST, switches);
  digitalWrite(PIN_LATCH, HIGH);
}

void do_sleep(void) {
  Serial << "(sleep)" << endl;
  delay(1000); // Ждем периферию, на всякий
  set_sleep_mode(SLEEP_MODE_IDLE);
  sleep_enable();
  // Отрубаем лишнюю периферию
  power_adc_disable();
  power_spi_disable();
  power_timer0_disable();
  power_timer1_disable();
  power_timer2_disable();
  power_twi_disable();
  sleep_mode();
  sleep_disable();
  power_all_enable();
}

Фишки:

1. Часы реального времени на сторожевом таймере. Тикают раз в 8 секунд. Основной цикл спит.

2. Управление настройками и просмотр состояния по терминалу. Возможно потом экранчик 16х2 прикручу.

3. Два термостата с управлением охлаждением/нагревом

4. Полив включается, если разница температур между датчиков меньше заданной. Смысл что один датчик в земле, пока она мокрая, полив не включится.

5. Возможность указать световую схему на 200 дней. Для каждого дня можно указать время включения освещения с точностью до 1/6 минуты. Например, сначала месяц 18 часовой "день", потом плавно уменьшается до 12 часов.

6. Управление нагрузками через сдвиговый регистр (свет, полив, нагреватель1, нагреватель2, охладитель1, охладитель2)

Есть пара вопросов:

1. Почему происходит сброс при каждом подключении COM?

2. Как лучше организовать работу с настройками по терминалу? Помогите написать обработчик команд.

3. Нужно ли отдельную тему на форуме под этот проект создавать?

Проект еще сырой, просто на вопросах застрял.

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013

Лучше отдельную тему, потом искать будет проще

Probelzaelo
Offline
Зарегистрирован: 15.04.2011

Уже параллельно существуют 3 одинаковые темы. Куда уже еще одну?

ZagZag
Offline
Зарегистрирован: 08.05.2014

Почему сброс происходит? Может ресет надо подтянуть или пины поменять? Хотя RX/TX - это же пины 0 и 1, они свободны у меня.

Да вообще сейчас ничего не подключено, кроме встроенного светодиода. Я в Ардуине новичок.

Вечером попробую пустой проект, только прерывания и Serial. Нужно локализовать проблему.

Probelzaelo
Offline
Зарегистрирован: 15.04.2011

ZagZag пишет:
Почему сброс происходит?

Тебя интересует сброс при подключении USB ? Так задумано. Смотрим схему, при подключении инициализируется USB-Serial - FT232R, а он уже и выдает сигнал DTR(Data Terminal Ready) на 2 пин - готовность подключенного устройства, который через конденсатор C13 "проскакивает" коротким импульсом на RESET и таким образом сбрасывает CPU. Это нужно, тк иначе можно потерять возможность выполнить загрузчик и перепрошить чип через USB, то есть без программатора. Потому что если он занимается чем то, выполняет программу пользователя, то ему совсем не интересен прошивальщик.

Если эта функция очень мешает, а перепрошивка не планируется то можно попытать нештатное но решение и "нейтрализовать", совсем выпаивать его не комильфо, но можно например повесить дополнитльно сопротивлюшку в 200-500(можно подобрать) Ом в параллель имеющемуся R3, между контактами X1(+5В) и X1(Reset) подбирать нужно от макс к мин, пока не перестанет реагировать на сброс от USB

ZagZag пишет:
Может ресет надо подтянуть или пины поменять? Хотя RX/TX - это же пины 0 и 1, они свободны у меня.

По сути так и есть, reset там подтянут, но можно его притянуть еще сильнее, только не спалить бы ногу FT232...

Кстати если подключаься к сериалу не через разьем USB а напрямую к ногам RX/TX, (пины D0 и D1) то сериал будет вполне адекватно работать и меняться данными без  инициализации сброса

ZagZag
Offline
Зарегистрирован: 08.05.2014

Спасибо. Приделаю внешний USB-RS232.

Probelzaelo
Offline
Зарегистрирован: 15.04.2011

а смысл? или ты просто хочешь сделать обмен с компом через ЮСБ? ни чего не изменяя? попробуй с доп сопротивлюшкой, сложности ни какой а разьемчик снять-поставить на X1 дело одной секунды. для работы нацепить, для прошивки снять... красота.

ZagZag
Offline
Зарегистрирован: 08.05.2014

Нашел как отключить перезагрузку http://atroshin.ru/ru/content/avtomaticheskaya-perezagruzka-arduino-pri-podklyuchenii-terminala

Вечером попробую убрать перемычку. У меня Uno, я ее там видел.

Вообще, хотелось бы обойтись минимумом компонентов. Например, есть модуль RTC 1307, но встроенного таймера вполне хватает. Даже если точность будет не идеальная, можно будет внести корректирующую секунду/минуту в сутки.

Офф. Для себя заметочку оставлю http://atroshin.ru/ru/content/avtomatizaciya-grouboksa

Probelzaelo
Offline
Зарегистрирован: 15.04.2011

ZagZag пишет:
Нашел как отключить перезагрузку http://atroshin.ru/ru/content/avtomaticheskaya-perezagruzka-arduino-pri-podklyuchenii-terminala

Вечером попробую убрать перемычку. У меня Uno, я ее там видел.

Тогда считай совсем повезло, просто перемычечка это не на всех платах есть.

ZagZag пишет:
Например, есть модуль RTC 1307, но встроенного таймера вполне хватает. Даже если точность будет не идеальная, можно будет внести корректирующую секунду/минуту в сутки.

"А потом мне дали овса. Песок не важная замена овсу"(с) О`Генри "Вождь краснокожих"

Все же 1307 это не просто таймер, а часы плюс энергонезависимая память.  Незаменимые вещи на случай непоняток с питанием и все такое.

ZagZag
Offline
Зарегистрирован: 08.05.2014

Как отключить сброс при подключении Serial
Рабочий способ. Перед прошивкой приходится зажимать кнопку Reset

dachnik
Offline
Зарегистрирован: 26.07.2013

Модуль управления теплицей v2 установлен и запущен =)

Umka
Umka аватар
Offline
Зарегистрирован: 19.10.2012

Что нового во второй версии?

dachnik
Offline
Зарегистрирован: 26.07.2013

Umka пишет:

Что нового во второй версии?

Ящик прежде всего =),

Удобная разводка проводов по перфорированному коробу(избавился от макетки),arduino mega вместо uno, 4х строчный lcd дисплей вместо 2х строчного, запись логов на sdшку,  часы реального времени, хранение и изменение параметров работы ящика в энергонезависимой памяти контролера, 4х зонный капельный полив.

ZagZag
Offline
Зарегистрирован: 08.05.2014

А скетч можно увидеть?

dachnik
Offline
Зарегистрирован: 26.07.2013

пост #207

Serega
Offline
Зарегистрирован: 14.05.2014

Добрый день. Решил автоматизировать две теплички и полив огорода. Приобрел всякие железяки ардуино. И тут началось, мозги закипели, комп практически тоже. Самому с кодом сложновато поэтому решил воспользоваться Вашим кодом для уно и попытаться адаптировать его под свои условия. При компиляции Вашего кода выдало кучу ошибок. Несколько победил установкой библиотек ))). А с очередной, засада, пишет "OneWire does not name a type" не пойму в чем дело. Если Вам не трудно помогите победить ее.

dachnik
Offline
Зарегистрирован: 26.07.2013

Вы в какой IDE компилируете? я просто компилировал в 1.5.3, а попробовал в 1.0 - не получилось....Если надо могу скинуть вам свои библиотеки, может траблы в них...

Serega
Offline
Зарегистрирован: 14.05.2014

В Ide 1.5.6 компилировал. Буду признателен за библиотеки, может в них засада т.к. устанавливал какие нашел. 

dachnik
Offline
Зарегистрирован: 26.07.2013
Serega
Offline
Зарегистрирован: 14.05.2014

Переустановил библиотеки, все равно таже ошибка.

Все библиотеки в скетче рыжего цвета, а библиотека DHT.h осталась черным. Может в этом проблема? 

dachnik
Offline
Зарегистрирован: 26.07.2013

по 1wire работают датчики темп ds1820 смотри в коде может что-то стёр лишнее?при компиляции должно выдавать номер строки с ошибкой.

Serega
Offline
Зарегистрирован: 14.05.2014

Типо этого? teplicaUNO:34: error: 'OneWire' does not name a type

dachnik
Offline
Зарегистрирован: 26.07.2013

ага, ссылается на 34 строку.

попробуй залить этот код, простой термостат

#include <OneWire.h>
#include <DallasTemperature.h>
#include <Wire.h> 
#include <LiquidCrystal_I2C.h>

int outPin = 8;//

LiquidCrystal_I2C lcd(0x27,16,2); 
// Data wire is plugged into pin 2 on the Arduino
#define ONE_WIRE_BUS 2
 
// Setup a oneWire instance to communicate with any OneWire devices 
// (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);
 
// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);
 
void setup(void)
{
  // start serial port
//  Serial.begin(9600);
//  Serial.println("Dallas Temperature IC Control Library Demo");
pinMode(outPin, OUTPUT);

lcd.init();                      // initialize the lcd 
 
  // Print a message to the LCD.
  lcd.backlight();
  // Start up the library
  sensors.begin();
int t_out = sensors.getTempCByIndex(0);
}
 
 
void loop(void)
{
  // call sensors.requestTemperatures() to issue a global temperature
  // request to all devices on the bus
//  Serial.print(" Requesting temperatures...");
  sensors.requestTemperatures(); // Send the command to get temperatures
//  Serial.println("DONE");

//  Serial.print("Temperature for Device 1 is: ");
//  Serial.print(sensors.getTempCByIndex(0)); // Why "byIndex"? 

lcd.setCursor(0,0);
lcd.print("t_out=");
lcd.setCursor(6,0);
lcd.print(sensors.getTempCByIndex(0));

if (sensors.getTempCByIndex(0) > 30 && digitalRead(outPin) == LOW) 
  {
  digitalWrite(outPin, HIGH);
  lcd.setCursor(13,0);
  lcd.print("ON ");
}


if (sensors.getTempCByIndex(0) < 29 && digitalRead(outPin) == HIGH) 
  {
    digitalWrite(outPin, LOW);
   lcd.setCursor(13,0);
  lcd.print("OFF");
}
//
lcd.setCursor(0,1);
lcd.print("t_in =");
lcd.setCursor(6,1);
lcd.print(sensors.getTempCByIndex(1));
//delay(1000);

    // You can have more than one IC on the same bus. 
    // 0 refers to the first IC on the wire
 
}

 

Serega
Offline
Зарегистрирован: 14.05.2014

Пишет туже ошибку и выделяет вот эту строку в коде: OneWire oneWire(ONE_WIRE_BUS);

Обнаружил, что если из списка вызвать библиотеку ONEWIRE, то в коде появляется пустая строка. Хотя эта же библиотека уже прописана в коде и окрашена в рыжий цвет.

dachnik
Offline
Зарегистрирован: 26.07.2013

попробуй в другой IDE

Serega
Offline
Зарегистрирован: 14.05.2014

Пробовал, не помогает. А каких нибудь особенностей при загрузке библиотеки OneWire нет? В папку examples нужно чего нибудь вставлять?