Умная теплица на базе Arduino Mega

witamin
Offline
Зарегистрирован: 05.04.2013

Круто - еще кусок допилен!

Cyoko
Offline
Зарегистрирован: 22.08.2014

Ну да. Правда теперь я понял что хочу экран 20 на 4 или нокиевский какойто :)

И можно уже начинать думать о связи с внешним миром . Вообщем это к растратам ))))

JollyBiber
JollyBiber аватар
Offline
Зарегистрирован: 08.05.2012

Берите сразу нормальный цветной экран. Разница по цене не большая.

Cyoko
Offline
Зарегистрирован: 22.08.2014

На счет экрана пока не решился . Вот какой прикольный походу : http://ru.aliexpress.com/item/Free-shipping-LCD-module-TFT-3-5-inch-TFT-LCD-screen-for-Arduino-MEGA2560-Board/1683788780.html

Вопросы по экрану :

Как узнать поддерживает он русские буквы ии нет ?

Походу надо будет библиотеку меню править ?

Вообщем и хочется и вроде как смысла нет .

Лучше вот думаю такую штуку закажу : http://www.aliexpress.com/store/product/2-4G-Wireless-Module-Embedded-Uart-Wifi-Module-UART-WiFi-Network-Server-Client-IEEE802-11b-with/110055_1886232538.html

И буду подключать устройство к серверу .

JollyBiber
JollyBiber аватар
Offline
Зарегистрирован: 08.05.2012

я решил для себя проблему с шрифтами очень просто - накидал 2 програмки. Одна делает картинки из шрифта, а вторая пишет код по пикселям :) Знаю что ржачно, но надо было срочно :) Клиент шибко хотел фендибоберный шрифт на экране видеть.

Puhlyaviy
Puhlyaviy аватар
Offline
Зарегистрирован: 22.05.2013

JollyBiber пишет:
Клиент шибко хотел фендибоберный шрифт на экране видеть.


ой, прям вижу как ты смотрел на себя серьзно из зеркала и требовал фельдибоберный шрифт и неприменно с завитушками. Ыыы

JollyBiber
JollyBiber аватар
Offline
Зарегистрирован: 08.05.2012

Зато стребовал!

Puhlyaviy
Puhlyaviy аватар
Offline
Зарегистрирован: 22.05.2013

JollyBiber пишет:

Зато стребовал!


Ну я ж не спорю. Красиво получилось.

witamin
Offline
Зарегистрирован: 05.04.2013

большеватый дисплей это в домашнюю теплицу с выносом в дом

в дачной теплице будет жалко - влажность и плохие жадные люди

ну и вдруг автономку городить расход питания большой подсветка

oled рулит маленький, но чёткий :) и еще есть такой, но там проводов больше и чего то скорость обновления не очень и по SPI библиотека которая заработала очень много памяти на УНО жрет, но для теплицы пойдет

несколько экранов можно сделать и листать по времени поочереди и главный экран с мелкоподробной инфой

JollyBiber
JollyBiber аватар
Offline
Зарегистрирован: 08.05.2012

witamin пишет:

ну и вдруг автономку городить расход питания большой подсветка

тумблер на разрыв питания к экрану, не?

witamin
Offline
Зарегистрирован: 05.04.2013

JollyBiber пишет:

тумблер на разрыв питания к экрану, не?

как вариант катет (по гипотенузе :) ) ну это не суть как важно

Puhlyaviy
Puhlyaviy аватар
Offline
Зарегистрирован: 22.05.2013

JollyBiber пишет:

witamin пишет:

ну и вдруг автономку городить расход питания большой подсветка

тумблер на разрыв питания к экрану, не?


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

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

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

Ещё можно контрастность шимом рулить и гасить экран полностью, если нет нажатий клавы более минуты. Было бы желание. :)

Cyoko
Offline
Зарегистрирован: 22.08.2014

JollyBiber пишет:

я решил для себя проблему с шрифтами очень просто - накидал 2 програмки. Одна делает картинки из шрифта, а вторая пишет код по пикселям :) Знаю что ржачно, но надо было срочно :) Клиент шибко хотел фендибоберный шрифт на экране видеть.

То есть можно в начале программы типа такого сделать для каждой буквы , а потом выводить их ?

//------------------------значок градусов----------------------------------------
uint8_t temp_cel[8] =
{
B00111,
B00101,
B00111,
B00000,
B00000,
B00000,
B00000
}; //закодировано в двоичной системе значек градуса
//----------------------------------------------------

Более рациональное решение есть ? :)

witamin
Offline
Зарегистрирован: 05.04.2013

Cyoko пишет:

Более рациональное решение есть ? :)

варианты : 

1. делают только отсутствующие русские буквы

2. обходятся символами как вы написали выше

3. думать SD карточку на нее картинки со всеми вытекающими 

или взять маленький дисплей :) и сразу отпадет проблема длинных текстов

краткость сестра... как вариант посмотреть интерфейсы аналогичных устройств

Cyoko
Offline
Зарегистрирован: 22.08.2014

Вообщем проще выучить английский :)

Так как сделал настройки , то понял что было бы неплохо настройки запоминать в памяти :)

На правильно ли я пути ?

#include <EEPROM.h>





void setup() {
  
//здесь считываем из памяти наши значения
HumPompOf = EEPROM.read(0);

}

void loop() {
  // здесь записываем когда изменяется
if (buttons > 100 && buttons < 200) {//кнопка + 
    ++HumPompOff;
    EEPROM.write(0, HumPompOff);//как тут записать то? так ?

    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("ChangeHumPompOff");
    lcd.setCursor(0, 1);
    lcd.print("Current: ");
    lcd.print(HumPompOff);
    delay(200);
    TempMillisCicle1 = millis( );//время отсчета для выхода из цикла
  }
}

Как правильно записать это ? Под адресс надо переменную задавать ?

witamin
Offline
Зарегистрирован: 05.04.2013

Cyoko пишет:

Как правильно записать это ? Под адресс надо переменную задавать ?

Вот делал тестовый термометр с записью в епром макс и мин и считыванием и знаком

сложность разбить на целое и дробное (есть разные способы)

в епром запись байтами приходится всё самому продумывать и интерфейс обмена и хранения

вот код местами надрал из библиотек, местами сам

/*
 * Thermometer - read temperature using an LM35 sensor and display it on a PCD8544 LCD.
 *
 * Copyright (c) 2010 Carlos Rodrigues <cefrodrigues@gmail.com>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */


#include <PCD8544.h>
#include <DS1307.h>
#include <OneWire.h>
#include <EEPROM.h>

// Init the DS1307

  long previousMillis = 0;        // will store last time LED was updated

// the follow variables is a long because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
 long interval = 1000;           // interval at which to blink (milliseconds)
 
 
//DS1307 rtc(4, 5);
//int pik = 0;
//const int buttonPin = 8;     // the number of the pushbutton pin
//const int ledPin =  11;      // the number of the LED pin
//const int ledPinG =  9;      // the number of the LED pin
//int horr;
//int minuta;
//int seki;
//Time  t;

// OneWire DS18S20, DS18B20, DS1822 Temperature Example
OneWire  ds(10);  // on pin 10
float tmax=-100, tmin=100, temp, celsius;
int address = 0;
int tmaxZN_int, tmax_int, tmaxDR_int, tminZN_int, tmin_int, tminDR_int;
int i;

// variables will change:
int buttonState = 0;         // variable for reading the pushbutton status
const int buttonPin = 9;


static const byte sensorPin = 0;
static const byte ledPin = 13;

// The dimensions of the LCD (in pixels)...
static const byte LCD_WIDTH = 84;
static const byte LCD_HEIGHT = 48;

// The number of lines for the temperature chart...
static const byte CHART_HEIGHT = 5;

// A custom "degrees" symbol...
static const byte DEGREES_CHAR = 1;
static const byte degrees_glyph[] = { 0x00, 0x07, 0x05, 0x07, 0x00 };

// A bitmap graphic (10x2) of a thermometer...
static const byte THERMO_WIDTH = 10;
static const byte THERMO_HEIGHT = 2;
static const byte thermometer[] = { 0x00, 0x00, 0x48, 0xfe, 0x01, 0xfe, 0x00, 0x02, 0x05, 0x02,
                                    0x00, 0x00, 0x62, 0xff, 0xfe, 0xff, 0x60, 0x00, 0x00, 0x00};
static PCD8544 lcd;


void setup() {



    pinMode(buttonPin, INPUT);
    pinMode(ledPin, OUTPUT);
   lcd.begin(LCD_WIDTH, LCD_HEIGHT);
   // Register the custom symbol...
  lcd.createChar(DEGREES_CHAR, degrees_glyph);
  // Setup Serial connection
    Serial.begin(9600);
      //read tmin from eeprom
  tminZN_int = EEPROM.read(3); // priznak minusa -C
  tmin_int   = EEPROM.read(4);
  tminDR_int = EEPROM.read(5); 
  
    //read tmax from eeprom
    tmaxZN_int = EEPROM.read(0);// priznak minusa -C
    tmax_int   = EEPROM.read(1);
    tmaxDR_int = EEPROM.read(2); 
 
  tmax =  tmax_int + (tmaxDR_int*0.01); 
  if (tmaxZN_int == 1) tmax=tmax * -1; // priznak minusa -C
  tmin =  tmin_int + (tminDR_int*0.01); 
  if (tminZN_int == 1) tmin=tmin * -1;  // priznak minusa -C
  //delay(100);
}


void loop() {
    buttonState = digitalRead(buttonPin);
    
      if (buttonState == HIGH) { 

       // clearmax ();
        
      Serial.println(" ");
      Serial.print("HIGH -  ");
      Serial.println(buttonState); 
  } 
  else {
    // turn LED off:
      Serial.println(" ");
      Serial.print("LOW -  ");
      Serial.println(buttonState);
  }
  // Start beyond the edge of the screen...
  static byte xChart = LCD_WIDTH;
  
  digitalWrite(ledPin, HIGH);
    // Draw the thermometer bitmap at the bottom left corner...
      Serial.println(" ");
      Serial.println("LCD_HEIGHT/8 - THERMO_HEIGHT");
      Serial.println(LCD_HEIGHT/8 - THERMO_HEIGHT);
  lcd.setCursor(0, LCD_HEIGHT/8 - THERMO_HEIGHT);
  lcd.drawBitmap(thermometer, THERMO_WIDTH, THERMO_HEIGHT);

  // Wrap the chart's current position...
  if (xChart >= LCD_WIDTH) {
    xChart = THERMO_WIDTH + 2;
  }

  // Update the temperature chart...  
  lcd.setCursor(xChart, 1);
  lcd.drawColumn(CHART_HEIGHT, map(temp, 20, 35, 0, CHART_HEIGHT*6));  // ...clipped to the 0-45C range.
  lcd.drawColumn(CHART_HEIGHT, 0);         // ...with a clear marker to see the current chart position.
  
  xChart++;

//  Read the temperature (in celsius)...
//  float temp = (1.1 * analogRead(sensorPin)  * 100.0) / 1024.0;
//  float temp = (1.1 * analogRead(sensorPin)/1.38 * 100.0) / 1024.0;
 temperature ();
  Serial.print(" ---- ++++  t C = ");
  Serial.print(celsius);
  temp=celsius;
//   Print the temperature (using the custom "degrees" symbol)...
  lcd.setCursor(26, 1);
  lcd.print(temp, 2);
  lcd.print("\001C ");
  
      lcd.setCursor(0, 0);
  if (tminZN_int == 0) lcd.print("+"); // priznak minusa -C
  if (tminZN_int == 1) lcd.print("-"); // priznak minusa -C
      lcd.print(tmin,1);
 
      lcd.setCursor(LCD_WIDTH*0.5, 0);
  if (tmaxZN_int == 0) lcd.print("+"); // priznak minusa -C
  if (tmaxZN_int == 1) lcd.print("-"); // priznak minusa -C
      lcd.print(tmax,1);

  lcd.setCursor(72, 0);
  lcd.print("\001C ");
    
  digitalWrite(ledPin, LOW);  
  delay(800);
}

void clearmax () {
      lcd.setCursor(0, 0);
      lcd.print("--- clear ----");    
  
     EEPROM.write(0, 0); 
     EEPROM.write(1, 0);  
     EEPROM.write(2, 0);
     EEPROM.write(3, 0);
     EEPROM.write(4, 30);
     EEPROM.write(5, 0);
      
      Serial.println(" ");
      Serial.print("HIGH -  ");
      Serial.println(buttonState); 
  }

float temperature ()
{
  byte i;
  byte present = 0;
  byte type_s;
  byte data[12];
  byte addr[8];
 // float fahrenheit;
  
  if ( !ds.search(addr)) {
   // Serial.println("No more addresses.");
   //  Serial.println();
    ds.reset_search();
    //delay(250);
   // return;
  }
  
  // Serial.print("ROM =");
  for( i = 0; i < 8; i++) {
    // Serial.write(' ');
    // Serial.print(addr[i], HEX);
  }

//  if (OneWire::crc8(addr, 7) != addr[7]) {
//       Serial.println("CRC is not valid!");
//      return;
//  }
//   Serial.println();
  ds.reset();
  ds.select(addr);
  ds.write(0x44,1);         // start conversion, with parasite power on at the end
  
  //delay(500);     // maybe 750ms is enough, maybe not
  // we might do a ds.depower() here, but the reset will take care of it.
  
  present = ds.reset();
  ds.select(addr);    
  ds.write(0xBE);         // Read Scratchpad
  for ( i = 0; i < 9; i++) {           // we need 9 bytes
    data[i] = ds.read();
  }
 unsigned int raw = (data[1] << 8) | data[0];
  if (type_s) {
    raw = raw << 3; // 9 bit resolution default
    if (data[7] == 0x10) {
      // count remain gives full 12 bit resolution
      raw = (raw & 0xFFF0) + 12 - data[6];
    }
  } else {
    byte cfg = (data[4] & 0x60);
    if (cfg == 0x00) raw = raw << 3;  // 9 bit resolution, 93.75 ms
    else if (cfg == 0x20) raw = raw << 2; // 10 bit res, 187.5 ms
    else if (cfg == 0x40) raw = raw << 1; // 11 bit res, 375 ms
    // default is 12 bit resolution, 750 ms conversion time
  }
  celsius = (float)raw / 16.0;
//    fahrenheit = celsius * 1.8 + 32.0;
        if (celsius < tmin) { 
           tmin = celsius;
     if (tmin >= 0) {
           tminZN_int = 0;
         }
     else
     {
       tminZN_int = 1; // priznak minusa -C
     }
     tmin_int = (int)tmin;
     tminDR_int =  (tmin - (int)tmin) * 100;
     EEPROM.write(3, tminZN_int); // priznak minusa -C
     EEPROM.write(4, tmin_int);
     EEPROM.write(5, tminDR_int);

  Serial.println("-- write tmin eerrom ----------------");
  if (tminZN_int == 0) Serial.print("+"); 
  if (tminZN_int == 1) Serial.print("-");
  Serial.print(tmin_int);
  Serial.print(".");
  Serial.println(tminDR_int); 
  Serial.println("-- celsius ----------------");
  Serial.print(celsius);
  Serial.println("------------------");
  }
 
    if (celsius > tmax | tmax == 85 | tmax > 120 ) 
   {
     tmax = celsius;
     if (tmax >= 0) {
       tmaxZN_int = 0;
     }
     else
     {
       tmaxZN_int = 1;
     }
     
     tmax_int = (int)tmax;
     tmaxDR_int =  (tmax - (int)tmax) * 100;
     
     EEPROM.write(0, tmaxZN_int); // priznak minusa -C
     EEPROM.write(1, tmax_int);  
     EEPROM.write(2, tmaxDR_int);
     
//     lcd.setCursor(LCD_WIDTH*0.5, 0);
//     if (tmaxZN_int == 0) lcd.print("+");
//     if (tmaxZN_int == 1) lcd.print("-");
//     lcd.print(tmax);
//  lcd.print(tmaxDR_int);
//  lcd.print("\001C");
     
  Serial.println("-- write tmax eerrom ----------------");
  if (tmaxZN_int == 0) Serial.print("+"); 
  if (tmaxZN_int == 1) Serial.print("-");
  Serial.print(tmax_int);
  Serial.print(".");
  Serial.println(tmaxDR_int); 
    Serial.println("-- celsius ----------------");
  Serial.print(celsius);
  Serial.println("------------------");
  }
  

  Serial.print(" t C = ");
  Serial.print(celsius);
  Serial.print(",  t max = ");
  Serial.print(tmax);
  Serial.print(",  t min = ");
  Serial.println(tmin);
  Serial.println("------------------");
}

/* EOF - Thermometer.ino  */

Считывание из епром

    
 //read tmin from eeprom
  tminZN_int = EEPROM.read(3); // priznak minusa -C
  tmin_int   = EEPROM.read(4);
  tminDR_int = EEPROM.read(5); 
  
    //read tmax from eeprom
    tmaxZN_int = EEPROM.read(0);// priznak minusa -C
    tmax_int   = EEPROM.read(1);
    tmaxDR_int = EEPROM.read(2); 
 
  tmax =  tmax_int + (tmaxDR_int*0.01); 
  if (tmaxZN_int == 1) tmax=tmax * -1; // priznak minusa -C
  tmin =  tmin_int + (tminDR_int*0.01); 
  if (tminZN_int == 1) tmin=tmin * -1;  // priznak minusa -C

Запись данных

     EEPROM.write(3, tminZN_int); // priznak minusa -C
     EEPROM.write(4, tmin_int);
     EEPROM.write(5, tminDR_int);

Стирание еепром забиваем нули

     EEPROM.write(0, 0); 
     EEPROM.write(1, 0);  
     EEPROM.write(2, 0);
     EEPROM.write(3, 0);
     EEPROM.write(4, 30);
     EEPROM.write(5, 0);

еепром конечно изнашивается, но народ тесты делал на убой - хватает надолго

лучше на SD карту писать заодно и логи будут

в еепроме обычно только настройки хранят

еще в часовом модуле бывает память встраивают там ее побольше и она выносливее

DS1307 - модуль часов реального времени (RTC) arduino - готовый модуль часов реального времени со слотом под батарейку.

Характеристики:

  • Подключается по I2C
  • Может объединяться в цепь с другими устройствами I2C
  • В основе лежит микросхема часов реального времени DS1307
  • Встроен чип AT24C32 IIC памяти EEPROM Объем : 32K 
Cyoko
Offline
Зарегистрирован: 22.08.2014

Вроде понял ) Щас буду пробовать

А зачем стирать ? Разве нельзя просто перезаписывать ?

Cyoko
Offline
Зарегистрирован: 22.08.2014

Спасибо большое за пример , все получилось .

witamin
Offline
Зарегистрирован: 05.04.2013

Cyoko пишет:

А зачем стирать ? Разве нельзя просто перезаписывать ?

можно перезаписать просто при первом чтении после других экспериментов чистил

и дробные числа есть способ проще записывать

как помню операции смещения регистров (>> такие) не стал вникать, а типа библиотеки не нашел

допилим общими усилиями автономное плавание теплиц :)

Наш девиз - Весна близко... :)

А вспомнил еще у меня сервы есть, но кинематику думать тяжело, надо прогу типа када что ли,

усилия рычаги посмотреть - а так идея сдвигать в пазах заслонку аля форточка или поднимать её 

в сотовом поликарбонате прорезать - будет не тяжелая (вентиляцию нужно в самом верхнем месте делать приточное внизу - можно типа завесы. Разряжением будет открываться под собственным весом закрываться)

Cyoko
Offline
Зарегистрирован: 22.08.2014

))))) а зачем дробные ? я только целую часть использую .

Паяльник уже в Москве , через дня три четыре подпояю RTC и буду мучить время :) Имхо полив по таймеру надо предусмотреть , ввиду наличия жалоб на датчик влажности почвы .

witamin
Offline
Зарегистрирован: 05.04.2013

Cyoko пишет:

))))) а зачем дробные ? я только целую часть использую .

те же  максимумы записать, да мало ли, ну это на бубущее

Cyoko пишет:

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

в таймерах ds3231 не смог год в виде 2014 назначить в одном варианте примеров только 1914 получался ну это не суть как важно можно програмно 20хх подставлять

были варианты отсчитывать время от восхода (датчик освещения ставил)

жалобы на датчик упростить можно заменив штатную щупалку на два электрода нержавейки (в инете видел, народ одобряет и использует)

Cyoko
Offline
Зарегистрирован: 22.08.2014

А таймеры ты реализовывал ? Таймеры полезно иметь :) Полив по утрам например. Я еще пока о них не думал , но думаю надо сдеать суточный и недельный .

Puhlyaviy
Puhlyaviy аватар
Offline
Зарегистрирован: 22.05.2013

witamin пишет:

допилим общими усилиями автономное плавание теплиц :)

Наш девиз - Весна близко... :)


Да, прям вижу весна и теплицы поплыли... под парусами. А еще можно консерваторий настроить везде, консервы они страсть какие вкусные. :)
Так я не пойму по таймерам. Что вам мешает в епром даты и время записывать? Можно еще флажок ставить для автоматического расчета и повторения по дням или неделям.

Cyoko
Offline
Зарегистрирован: 22.08.2014

Я пока RTC даже не смотрел . Но любой идеи реализации таймеров буду рад .

Puhlyaviy
Puhlyaviy аватар
Offline
Зарегистрирован: 22.05.2013

Есть библиотека она автоматом время считает в часах.минутах. днях недели.годах от milis. Проблема только что бы свет не моргал.

Cyoko
Offline
Зарегистрирован: 22.08.2014

Я думал установить часы реального времени . И с помощью их сделать таймеры . Так разве не надежнее ? В них и батарейка есть , и память вроде как ) Надо будет примеры поискать.....

witamin
Offline
Зарегистрирован: 05.04.2013

Cyoko пишет:

Я думал установить часы реального времени . И с помощью их сделать таймеры . Так разве не надежнее ? В них и батарейка есть , и память вроде как ) Надо будет примеры поискать.....

rts надежнее

конкуренты делают отсчет от восхода солнца типа естественный ход времени и автокоррекция

таймеры в других системах (конкурентов :) )  обычно раз в день два и три дня полив примерно 40 минут

у них через капельницу вытекает примерно 2 литра. Я покупал расходометр проточный хотел по литрам наливать бочку

есть примеры для rts ds3231 в библиотеке  я покупал такой он с памятью и батарейка перезаряжаемая LIR2032

с прерываниями пример в библиотеке

можно усыплять дуню и по прерыванию она проснется от будильника RTS

а будильник следующий ставить програмно и по кнопке вывод прерыванием принудительно из сна и вход в меню

 

Cyoko
Offline
Зарегистрирован: 22.08.2014

Усыплять дуню пока не буду :) пусть поживет еще.....

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

#include "Arduino.h"
#include <Wire.h>
#include <DS1307.h> 
#define timePIN 13

void setup()
{
  Serial.begin(9600);
  pinMode(timePIN, OUTPUT); 
}

void loop()
{
  if(Serial.available()) SetTime();

  int Hour = RTC.get(DS1307_HR, true); 
  int Minute = RTC.get(DS1307_MIN, false); 
  int Second = RTC.get(DS1307_SEC, false); 
  int FullMinutes = Hour * 60 + Minute;
  int FullMinutesTimerOn = 8 * 60 + 30;
  int FullMinutesTimerOff = 16 * 60 + 40;

  if(FullMinutes >= FullMinutesTimerOn && FullMinutes <= FullMinutesTimerOff) digitalWrite(timePIN, HIGH); 
  else digitalWrite(timePIN, LOW);
  
  Print(); // ПОСЛЕ ОТЛАДКИ НУЖНО УДАЛИТЬ !!!
  Serial.print(addZero(Hour));
  Serial.print(":");
  Serial.print(addZero(Minute));
  Serial.print(":");
  Serial.println(addZero(Second));
  delay(1000);
}

void SetTime()  
{ 
  delay(10);
  if (Serial.read() == 't') 
  { 
    int h = (Serial.read() - '0') * 10 + (Serial.read() - '0'); 
    Serial.read(); 
    int m = (Serial.read() - '0') * 10 + (Serial.read() - '0'); 
    RTC.stop(); 
    RTC.set(DS1307_SEC,0); 
    RTC.set(DS1307_MIN,m); 
    RTC.set(DS1307_HR,h); 
    RTC.start(); 
  } 
  while(Serial.available()) 
  {
    delay(2);
    Serial.read(); 
  }
}

String addZero(int val) // Добавим 0 перед значением часа/минуты/секунды, если оно меньше 10 
{ 
  if (val<10) return "0" + String(val);
  else return String(val); 
}

void Print() // ЭТУ ФУНКЦИЮ ПОСЛЕ ОТЛАДКИ НУЖНО УДАЛИТЬ !!!
{
  Serial.print(FullMinutesTimerOn);
  Serial.print(" >> ");
  Serial.print(FullMinutes);
  Serial.print(" << ");
  Serial.print(FullMinutesTimerOff);
  Serial.print("       ");
}

вот тоже вроде интересный пример

// during an alarm the INT pin of the RTC is pulled low
//
// this is handy for minimizing power consumption for sensor-like devices, 
// since they can be started up by this pin on given time intervals.

#include <Wire.h>
#include "ds3231.h"

#define BUFF_MAX 256

// time when to wake up
uint8_t wake_HOUR = 15;
uint8_t wake_MINUTE = 49;
uint8_t wake_SECOND = 9;

// how often to refresh the info on stdout (ms)
unsigned long prev = 5000, interval = 5000;

void set_alarm(void)
{

    // flags define what calendar component to be checked against the current time in order
    // to trigger the alarm - see datasheet
    // A1M1 (seconds) (0 to enable, 1 to disable)
    // A1M2 (minutes) (0 to enable, 1 to disable)
    // A1M3 (hour)    (0 to enable, 1 to disable) 
    // A1M4 (day)     (0 to enable, 1 to disable)
    // DY/DT          (dayofweek == 1/dayofmonth == 0)
    boolean flags[5] = { 0, 0, 0, 1, 1 };

    // set Alarm1
    DS3231_set_a1(wake_SECOND, wake_MINUTE, wake_HOUR, 0, flags);

    // activate Alarm1
    DS3231_set_creg(DS3231_INTCN | DS3231_A1IE);
}

void setup()
{
    Serial.begin(9600);
    Wire.begin();
    DS3231_init(DS3231_INTCN);
    DS3231_clear_a1f();
    set_alarm();
}

void loop()
{
    char buff[BUFF_MAX];
    unsigned long now = millis();
    struct ts t;

    // once a while show what is going on
    if ((now - prev > interval) && (Serial.available() <= 0)) {
        DS3231_get(&t);

        // display current time
        snprintf(buff, BUFF_MAX, "%d.%02d.%02d %02d:%02d:%02d", t.year,
             t.mon, t.mday, t.hour, t.min, t.sec);
        Serial.println(buff);

        // display a1 debug info
        DS3231_get_a1(&buff[0], 59);
        Serial.println(buff);

        if (DS3231_triggered_a1()) {
            // INT has been pulled low
            Serial.println(" -> alarm1 has been triggered");
            // clear a1 alarm flag and let INT go into hi-z
            DS3231_clear_a1f();
        }
        prev = now;
    }
}

Но хочется чтоб и время устанавливать самому из меню , и таймер недельный :)))))

Весна близко !!! ))

Cyoko
Offline
Зарегистрирован: 22.08.2014

У меня кстати РТС ds1307 но вроде они почти одинаковые .

witamin
Offline
Зарегистрирован: 05.04.2013

Cyoko пишет:

У меня кстати РТС ds1307 но вроде они почти одинаковые .

отличия не смертельные, в ds1307 точность сильно зависит от кварца мне (да и на форумах часто жаловались) попадался с неправильным кварцем не 32768. Уходит на минуту в сутки и больше (сейчас заказал с правильным кварцем проверю)

itjunky
Offline
Зарегистрирован: 15.09.2014

А зачем в часы ставить "не правильный" кварц? Что бы сбить с толку врага?

Cyoko
Offline
Зарегистрирован: 22.08.2014

Видимо китайцы впаивают что под рукой есть :)

Мне кстати пришел наконец то паяльник :) Осталось научится паять и приступим к интеграции чаосв в устройство .

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

itjunky пишет:

А зачем в часы ставить "не правильный" кварц? Что бы сбить с толку врага?

зачем ВРАГА ? сразу уж Вас ! у врага - другие ЧИПЫ !

Cyoko
Offline
Зарегистрирован: 22.08.2014

Всем привет , появились вопросы с часами:)

Паяльщик из меня конечно еще тот, но вроде ножки держатся.

Вообщем вот что пока получил:

библиотеки 

#include <EEPROM.h>
#include <DS1307.h>
 
//Массив, содержащий время компиляции
char compileTime[] = __TIME__;
DS1307 clock;
 
в сетапе:
void setup() {
  
  //Запускаем часы реального времени
  clock.begin();

тупо вбиваем любую дату

clock.fillByYMD(2013,1,19);//Jan 19,2013
clock.fillByHMS(15,28,30);//15:28 30"
clock.fillDayOfWeek(SAT);//Saturday
clock.setTime();//write time to the RTC chip
 
в лупе:
clock.getTime();
lcd.clear();
   lcd.setCursor(0, 0);
   lcd.print(clock.hour);
   lcd.setCursor(0, 1);
   lcd.print(clock.minute);

 

 

ошибки не выдает , но и время тоже :)

пишет 45 и 165 в строках и они не меняются. Значит чтото я делаю не так .

 

Первый вопрос : у меня scl и sda это пины 20 и 21. Что то я не вижу где их менять. Может из-за этого все ? Еще где то про пин 4 слышал чтото нехорошее.....

 

witamin
Offline
Зарегистрирован: 05.04.2013

должен автоматом определить что мега и взять эти sda scl

можно глянуть в самой библиотеке может там есть где поменять пины

еще есть вариант (непомню какой-то сработал на меге) пройтись сканером  устройств i2c  или другим 

и взять библиотеку с принудительной установкой пинов

 

Cyoko
Offline
Зарегистрирован: 22.08.2014

А ларчик просто открывался :) У меня модуль с алиэкспресса , квадратный такой, без ножек. Так вот там с двух сторон дырки под ножки. Я с другой стороны подпаял и все заработало.

Теперь я так понимаю время у меня есть :)

Думки вот о чем:

Как совместить меню и часы.

Настройка времени кнопками с шилда.

Хранение в памяти....NV Ram это для этого ? Видел гдето в скетчах.....

Ну и сообственно недельный и суточный таймер.

Так что есть чем занятся пока идет етернет шилд :)

itjunky
Offline
Зарегистрирован: 15.09.2014

А я тут заметил, что датчики влажности почвы, полное УГ =(

Там на обычную печатную плату нанесён тонкий слой меди. Разумеется, через пару месяцев у поверхности почвы целиком разъело окисью этот тонкий слой меди =(

 

Видимо придётя учиться самому делать и калибровать подобные датчики из обычных металических гвоздей или чего-нить подобного.

Cyoko
Offline
Зарегистрирован: 22.08.2014

Так и есть , об этом много чего написано.... Хотя покупать на сезон этот датчик за 50р думаю тоже норм.

Но я и хочу добить таймеры, чтоб всегда была возможность сделать полив по таймеру.

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

не протянет он сезона. лучше сразу электроды поменять на нержавейку.

witamin
Offline
Зарегистрирован: 05.04.2013

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

Тима пишет:

не протянет он сезона. лучше сразу электроды поменять на нержавейку.

еще были идеи подключать этот датчик только для измерения (раз в час например)

окисляется сильнее при постоянном пропускании тока

Cyoko
Offline
Зарегистрирован: 22.08.2014

это реализовано

Cyoko
Offline
Зарегистрирован: 22.08.2014

Что то с часами пока подвижек мало , так что пофантазирую....

Итак что хотелось бы видеть:

1) При включении ардуинки выводим заставку, опрашиваем датчики, выводим на экран время. Ну и собственно реализации установки времени с помощью кнопок.

2) следит за датчиками, управляет релюхами.

3)В меню добавить пункт настройки времени

Ну и само собой по времени выходить из меню , вроде реализовал, не помню :)

4) В меню добавить пару пунктов настройки таймеров, суточный и недельный например.

5) запись времени в нврам.

 

Вот такое нафантазировалось )))

Упращенный вариант :

Установка времени в сетапе, таймер

Давно не выкладывал скетч 

/* big respect to users SU-27-16 for help
                       DenisNP
                       witamin
                       leshak 
*/


//подключим все внешние либы----------------------------------------------------------
#include <Wire.h> // добавляем необходимые библиотеки
#include <MyMenu.h>// библиотека меню созданная пользователем DenisNP
#include <LiquidCrystal.h>// стандартная библиотека LCD экрана
#include "DHT.h" //библиотека датчика DHT11
#include <EEPROM.h>
#include <DS1307new.h>
#include <TimeHelpers.h>
//-------------------------------------------------------------------------------------




//pins--ноги распределим(что к какамоу пину подключено)------------------------------------------------------------
#define voltageFlipPin1   50// пин питания датчика влажности почвы
#define voltageFlipPin2   51// пин питания датчика влажности почвы
#define sensorPin         A7//пин считывания значения влажности почвы
#define DHTPIN           52 // ПИН подключения датчика DHT11
LiquidCrystal lcd(8, 9, 4, 5, 6, 7 );//Экран
#define ButtonPin             A0 // пин кнопок на шилде экрана
#define FanPower_PIN 49 //пин управления реле вентилятора
#define PompPower_PIN 48 //пин управления реле насоса
//-----------------------------------------------------------------------------------------------------------------



//------------------------значок градусов----------------------------------------
uint8_t temp_cel[8] =
{
B00111,
B00101,
B00111,
B00000,
B00000,
B00000,
B00000
}; //закодировано в двоичной системе значек градуса
//----------------------------------------------------


//---------------------------consts павыделяем памяти для постоянок переменок смотрим перехлесты ----------------
// Выбираем модель датчика-----------------------
#define DHTTYPE DHT11   // DHT 11 
//#define DHTTYPE DHT22   // DHT 22  (AM2302)
//#define DHTTYPE DHT21   // DHT 21 (AM2301)
DHT dht(DHTPIN, DHTTYPE);
//----------------------------------------------
int qq;
int VixodIzCicla;// переменная для выхода из цикла
int flipTimer = 1000;//время задержки считывания значения с датчика влажности почвы между сменой полярности
int buttons=0; //переменная для отслеживания нажатия кнопок
int Temperatura; //переменная для вывода температуры на экран
int Humidity;//переменная для вывода влажности на экран
int HumSoil;//переменная для вывода влажности почвы на экран
float t;//переменая для считывания показания температуры с датчика
float h;//переменая для считывания показания влажности с датчика
unsigned long TempMillisTemp; //засечка времени для расчета задержек опроса датчика температуры
unsigned long TempMillisHum; //засечка времени для расчета задержек опроса датчика влажности
unsigned long TempMillisSoil; //засечка времени для расчета задержек опроса датчика температуры
unsigned long TempMillisCicle1;//засечка времени для расчета времени выхода из меню настроек включения вентилятора
unsigned long qqQQ;
int TempFanOff;// температура выключения вентилятора
int TempFanOffZN_int; //знак температуры выключения вентилятора
int TempFanOff_int;//модуль для хранения в еепром
int TempFanOn;// температура включения вентилятора
int TempFanOnZN_int; //знак температуры включения вентилятора
int TempFanOn_int;//модуль для хранения в еепром
int HumPompOn;// влажность почвы для включения полива
int HumPompOff;//влажность почвы для выключения полива
int CurrentStayRelayFan;// переменная для отслеживания текущего состояния реле вентилятора
int CurrentStayRelayPomp;//переменная для отслеживания текущего состояния реле насоса
char buf[80];

//---------------------наше меню---------------------------------------------------
#define NUM_ITEMS 18 //length of items array include submenu headers

MItm items[NUM_ITEMS] = {
  MItm("Menu",0,0), //main header always 0,0
  MItm("Show Readings",1), //1 пункт меню - Показания датчиков
  //MItm("1",2),
  MItm("Settings",2),
  MItm("Time",9),
  //MItm("FRUITS LIST",1,0), //this is the submenu with index 1 (0 is previous menu index)
  //MItm("Apple",50), // if there is no "50" submenu callback will run
  //MItm("Orange",60),
  //MItm("Banana",70),
  //MItm("Pear",80),
  //MItm(" <<BACK",0), //means "go to submenu with index 0"
  //MItm("VEGGIES LIST",2,0),
  //MItm("Tomato",90),
  //MItm("Potato",100),
  //MItm("Smth else",110),
  //MItm(" <<BACK",0),
  MItm("Settings",2,0),
  MItm("Fan",3),
  MItm("Pompa",4),
  MItm(" <<BACK",0),
  MItm("Fan",3,2), // notice that 2 in prev-index now not zero
  MItm("Temp FanOn",5),
  MItm("Temp FanOff",6),
  MItm(" <<BACK",2),
  MItm(" <<MAIN",0),
  MItm("Popma",4,2), 
  MItm("Set Pomp On",7),
  MItm("Set Pomp Off",8),
  MItm(" <<BACK",2),
  MItm(" <<MAIN",0)
};

Menu menu(items,NUM_ITEMS,&lcd,menuCallback);
//-----------------------------------------------------------------------------------------------------------------------------


// Функция отправки HTTP-запроса на сервер
void sendHTTPRequest() {
Serial.println(buf); 
}



//-инициализация однократная ------------------------------------------------------------------
void setup() {
  Serial.begin(115200);                     //    последовательнй порт
  
  //-------------------------------------проверка модуля часов-------------------------------
  if(RTC.isPresent()){ // обнаружен ли модуль?
    Serial.println("RTC Ready"); // все хорошо
  } else {
    Serial.println("Error RTC Module not found"); // сообщаем о проблеме
    while(1); // и останавливаем скетч
  }
  //---------------------------------------------------------------------------------------
  
  
  //set button pins
  pinMode(ButtonPin,INPUT);// отслеживание нажатий кнопок
  
  lcd.begin(16,2);        //наш экран     
  lcd.print("Meteo");                      //   начальная
  lcd.setCursor(0, 1);                     //
  lcd.print("     Station");               //             заставка
  lcd.createChar(1, temp_cel); // я так понял подгружаем наш значок в экран
  dht.begin();// запускаем датчик DHT11
  pinMode(FanPower_PIN, OUTPUT);
  pinMode(ButtonPin,INPUT);// отслеживание нажатий кнопок
  pinMode(voltageFlipPin1, OUTPUT);//пин питания датчика влажности почвы
  pinMode(voltageFlipPin2, OUTPUT);//пин питания датчика влажности почвы
  pinMode(sensorPin, INPUT);//пин считывания значений с датчика влажности почвы
  Temperatura = dht.readTemperature();// первое значение температуры для экрана , чтоб не было 0 пока ждем опрос датчика в цикле
  Humidity = dht.readHumidity();// первое значение влажности для экрана , чтоб не было 0 пока ждем опрос датчика в цикле
  
  //----------------получяем первое значение для влажности почвы----------- надо будет как то улучшать----------------------------
  
    digitalWrite(voltageFlipPin1, HIGH);
    digitalWrite(voltageFlipPin2, LOW);
    delay(flipTimer);
  int val1 = analogRead(sensorPin);
    delay(flipTimer);
    digitalWrite(voltageFlipPin1, LOW);
    digitalWrite(voltageFlipPin2, HIGH);
    delay(flipTimer);
  // invert the reading
  int val2 = 1023 - analogRead(sensorPin);
  HumSoil = (val1 + val2) / 2;
//-------------------------------------------------------------------------------------------------------------------------------

  TempMillisTemp = millis( );//время отсчета для температуры
  TempMillisHum = millis( );//время отсчета для влажности
  TempMillisSoil = millis( );//время отсчета для влажности почвы
  
  //show main menu on screen
  //menu.goMain();
  
  //-----------------------------загрузка температуры выключения вентилятора-------------------------------------
  TempFanOffZN_int = EEPROM.read(1); // priznak minusa -C
  TempFanOff_int = EEPROM.read(2);
  if (TempFanOffZN_int == 1 ) TempFanOff=TempFanOff_int*-1;
  else TempFanOff=TempFanOff_int;
  
  
  
  //-----------------------------загрузка температуры включения вентилятора-------------------------------------
  TempFanOnZN_int = EEPROM.read(3); // priznak minusa -C
  TempFanOn_int = EEPROM.read(4);
  if (TempFanOnZN_int == 1 ) TempFanOn=TempFanOn_int*-1;
  else TempFanOn=TempFanOn_int;


  qq=1;
}

void loop() {
  RTC.getTime();// получить время от модуля
  printTimeToSerial(); // выводим полученное время в лог
  if ( millis( ) - qqQQ > 10000) qq=1;
  if (qq==1) printTimeToLCD(); // выводи время на экран
  doSerialCommands(); // слушаем и выполняем команды из Serial
  
//типа таймер для включения функции опроса датчика температуры( каждые 10 сек)-----------------------
  if ( millis( ) - TempMillisTemp > 10000 ){
  TempMillisTemp = millis( );
  Temperatura=readSenseTemp();
  Serial.println(Temperatura);
  sprintf(buf, "GET http://192.168.1.111/objects/?object=TempDHT11&op=set&p=Value&v=%i HTTP/1.0", (int)Temperatura);
  sendHTTPRequest();
//-------------------------------режим работы вентилятора-------------------------------
  CurrentStayRelayFan = FanPower_PIN;// переменная для отслеживания текущего состояния реле вентилятора
  if ( Temperatura < TempFanOff ){
    digitalWrite(FanPower_PIN, LOW); //если температуры меньше заданной выключаем реле вентилятора
  }
  else if ( Temperatura > TempFanOn ){
    digitalWrite(FanPower_PIN, HIGH);// если температура поднялась выше заданной включаем реле вентилятора
  }
  else {
    digitalWrite(FanPower_PIN, CurrentStayRelayFan);// если температура в заданном диапазоне оставляем реле вентилятора как есть
  }
}
//--------------------------------------------------------------------------------------------------------------------------- 



//типа таймер для включения функции опроса датчика влажности( каждые 10 сек)-----------------------
  if ( millis( ) - TempMillisHum > 10000 ){
  TempMillisHum = millis( );
  Humidity=readSenseHum();
  Serial.println(Humidity);
  sprintf(buf, "GET http://192.168.1.111/objects/?object=HumidityDHT11&op=set&p=Value&v=%i HTTP/1.0", (int)Humidity);
  sendHTTPRequest();
}
//--------------------------------------------------------------------------------------------------------------------------- 




//типа таймер для включения функции опроса датчика влажности почвы( каждые 10 сек)-----------------------
  if ( millis( ) - TempMillisSoil > 20000 ){
  TempMillisSoil = millis( );
  HumSoil=readSenseSoil();
  Serial.println(HumSoil);
  //-------------------------------режим работы насоса-------------------------------
  CurrentStayRelayPomp = PompPower_PIN;// переменная для отслеживания текущего состояния реле вентилятора
  if ( HumSoil < HumPompOff ){
    digitalWrite(PompPower_PIN, LOW); //если температуры меньше заданной выключаем реле вентилятора
  }
  else if ( HumSoil > HumPompOn ){
    digitalWrite(PompPower_PIN, HIGH);// если температура поднялась выше заданной включаем реле вентилятора
  }
  else {
    digitalWrite(PompPower_PIN, CurrentStayRelayPomp);// если температура в заданном диапазоне оставляем реле вентилятора как есть
  }
}
//---------------------------------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------------






//------------------а тут наши три кнопки при нажатии на которые выводятся на экран показания температуры и влажности---------------------------------   
     buttons=analogRead(ButtonPin);
  if (buttons < 100) {
    menu.goNext();
    delay(200);
    qq=0;
    qqQQ = millis( );
  }
  else if (buttons > 100 && buttons < 200) {
    menu.goUp();
    delay(200);
   qq=0; 
   qqQQ = millis( );
  }
  else if (buttons > 200 && buttons < 400) {
    menu.goDown();
    delay(200);
   qq=0; 
   qqQQ = millis( );   
  }
  else if (buttons > 400 && buttons < 600) {
    menu.goBack();
    delay(200);
   qq=0; 
  }
  else if (buttons > 600 && buttons < 800) {
    menu.goMain();
    delay(200);
   qq=0; 
   qqQQ = millis( );
  }
//---------------------------------------------------------------------------------------------------------------
}






//----------------------------------------------------подпрограммы вызываемые многократно ----------------------------------------------

//------подпрограмма для изменения значений (в разработке)----------------------------------------
void menuCallback(int idx){
  //do something according to index of item selected
  if(idx == 1){
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Hum: ");
    lcd.print(Humidity);
    lcd.print("%");
    lcd.print(" ");
    lcd.print("T: ");
    lcd.print(Temperatura);
    char temp2[]={'\1', 67, '\0'}; //Отрисовка градусов Цельсия
    lcd.print(temp2);
    
  }
  
  //-----------------------------входим в экран установки температуры вкл фентилятора-----------------------------------------------
  else if( idx==5 ){
   lcd.clear();
   lcd.setCursor(0, 0);
   lcd.print("Change Fan On");
   lcd.setCursor(0, 1);
   lcd.print("Current: ");
   lcd.print(TempFanOn);
   char temp2[]={'\1', 67, '\0'}; //Отрисовка градусов Цельсия
    lcd.print(temp2);
   //-----------------------------------------запускаем цикл------------------------------------------------
   VixodIzCicla = 200;// переменная для выхода из цикла
   TempMillisCicle1 = millis( );//время отсчета для выхода из цикла
 while(VixodIzCicla == 200){
     buttons=analogRead(ButtonPin);
 if (buttons > 100 && buttons < 200) {//кнопка + 
    ++TempFanOn;
    if (TempFanOn >= 0) {
           TempFanOnZN_int = 0;
           TempFanOn_int = TempFanOn;
    }
    else
   {
    TempFanOnZN_int = 1; // priznak minusa -C
    TempFanOn_int = TempFanOn*-1;
   }
   EEPROM.write(3, TempFanOnZN_int); // priznak minusa -C
   EEPROM.write(4, TempFanOn_int);
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Change Fan On");
    lcd.setCursor(0, 1);
    lcd.print("Current: ");
    lcd.print(TempFanOn);
    char temp2[]={'\1', 67, '\0'}; //Отрисовка градусов Цельсия
    lcd.print(temp2);
    delay(200);
    TempMillisCicle1 = millis( );//время отсчета для выхода из цикла
  }
  else if (buttons > 200 && buttons < 400) {//кнопка -
    --TempFanOn;
    if (TempFanOn >= 0) {
           TempFanOnZN_int = 0;
           TempFanOn_int = TempFanOn;
    }
    else
   {
    TempFanOnZN_int = 1; // priznak minusa -C
    TempFanOn_int = TempFanOn*-1;
   }
   EEPROM.write(3, TempFanOnZN_int); // priznak minusa -C
   EEPROM.write(4, TempFanOn_int);
    lcd.setCursor(0, 1);
    lcd.print("Current: ");
    lcd.print(TempFanOn);
    char temp2[]={'\1', 67, '\0'}; //Отрисовка градусов Цельсия
    lcd.print(temp2);
    lcd.print("  ");
    delay(200);
    TempMillisCicle1 = millis( );//время отсчета для выхода из цикла    
  }
  else if (buttons > 400 && buttons < 600) {//кнопка назад
    VixodIzCicla = 2;
    menu.goBack();
    delay(200);
    
  }
  else if (buttons > 600 && buttons < 800) {
    menu.goMain();
    delay(200); 
    VixodIzCicla = 2;
  }
  if ( millis( ) - TempMillisCicle1 > 10000 ){
  menu.goLast(); //return to last viewed menu
  VixodIzCicla = 2;
  delay(200);
  }
}

  
  }
  
 //-----------------------------входим в экран установки температуры вкыл вентилятора-----------------------------------------------
  else if( idx==6 ){
   lcd.clear();
   lcd.setCursor(0, 0);
   lcd.print("Change Fan Off");
   lcd.setCursor(0, 1);
   lcd.print("Current: ");
   lcd.print(TempFanOff);
   char temp2[]={'\1', 67, '\0'}; //Отрисовка градусов Цельсия
    lcd.print(temp2);
   //-----------------------------------------запускаем цикл------------------------------------------------
   VixodIzCicla = 200;// переменная для выхода из цикла
   TempMillisCicle1 = millis( );//время отсчета для выхода из цикла
 while(VixodIzCicla == 200){
     buttons=analogRead(ButtonPin);
 if (buttons > 100 && buttons < 200) {//кнопка + 
    ++TempFanOff;
    if (TempFanOff >= 0) {
           TempFanOffZN_int = 0;
           TempFanOff_int = TempFanOff;
    }
    else
   {
    TempFanOffZN_int = 1; // priznak minusa -C
    TempFanOff_int = TempFanOff*-1;
   }
   EEPROM.write(1, TempFanOffZN_int); // priznak minusa -C
   EEPROM.write(2, TempFanOff_int);
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Change Fan Off");
    lcd.setCursor(0, 1);
    lcd.print("Current: ");
    lcd.print(TempFanOff);
    char temp2[]={'\1', 67, '\0'}; //Отрисовка градусов Цельсия
    lcd.print(temp2);
    delay(200);
    TempMillisCicle1 = millis( );//время отсчета для выхода из цикла
  }
  else if (buttons > 200 && buttons < 400) {//кнопка -
    --TempFanOff;
    if (TempFanOff >= 0) {
           TempFanOffZN_int = 0;
           TempFanOff_int = TempFanOff;
    }
    else
   {
    TempFanOffZN_int = 1; // priznak minusa -C
    TempFanOff_int = TempFanOff*-1;
   }
   EEPROM.write(1, TempFanOffZN_int); // priznak minusa -C
   EEPROM.write(2, TempFanOff_int);
   
    lcd.setCursor(0, 1);
    lcd.print("Current: ");
    
    lcd.print(TempFanOff);
    char temp2[]={'\1', 67, '\0'}; //Отрисовка градусов Цельсия
    lcd.print(temp2);
    lcd.print("  ");
    delay(200);
    TempMillisCicle1 = millis( );//время отсчета для выхода из цикла    
  }
  else if (buttons > 400 && buttons < 600) {//кнопка назад
    VixodIzCicla = 2;
    menu.goBack();
    delay(200);
    
  }
  else if (buttons > 600 && buttons < 800) {
    menu.goMain();
    delay(200); 
    VixodIzCicla = 2;
  }
  if ( millis( ) - TempMillisCicle1 > 10000 ){
  menu.goLast(); //return to last viewed menu
  VixodIzCicla = 2;
  delay(200);
  }
}

  
  }//---------------------конец пункта выбора значения------------------------------------------------
 
 
 
 //-----------------------------входим в экран установки влажности почвы вкл полива-----------------------------------------------
  else if( idx==7 ){
   lcd.clear();
   lcd.setCursor(0, 0);
   lcd.print("ChangeHumPompOn");
   lcd.setCursor(0, 1);
   lcd.print("Current: ");
   lcd.print(HumPompOn);
   //-----------------------------------------запускаем цикл------------------------------------------------
   VixodIzCicla = 200;// переменная для выхода из цикла
   TempMillisCicle1 = millis( );//время отсчета для выхода из цикла
 while(VixodIzCicla == 200){
     buttons=analogRead(ButtonPin);
 if (buttons > 100 && buttons < 200) {//кнопка + 
    ++HumPompOn;
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("ChangeHumPompOn");
    lcd.setCursor(0, 1);
    lcd.print("Current: ");
    lcd.print(HumPompOn);
    delay(200);
    TempMillisCicle1 = millis( );//время отсчета для выхода из цикла
  }
  else if (buttons > 200 && buttons < 400) {//кнопка -
    --HumPompOn;
    lcd.setCursor(0, 1);
    lcd.print("Current: ");
    lcd.print(HumPompOn);
    lcd.print("  ");
    delay(200);
    TempMillisCicle1 = millis( );//время отсчета для выхода из цикла    
  }
  else if (buttons > 400 && buttons < 600) {//кнопка назад
    VixodIzCicla = 2;
    menu.goBack();
    delay(200);
    
  }
  else if (buttons > 600 && buttons < 800) {
    menu.goMain();
    delay(200); 
    VixodIzCicla = 2;
  }
  if ( millis( ) - TempMillisCicle1 > 10000 ){
  menu.goLast(); //return to last viewed menu
  VixodIzCicla = 2;
  delay(200);
  }
}

  
  }//---------------------конец пункта выбора значения------------------------------------------------
  
  
  //-----------------------------входим в экран установки влажности почвы выкл полива-----------------------------------------------
  else if( idx==8 ){
   lcd.clear();
   lcd.setCursor(0, 0);
   lcd.print("ChangeHumPompOff");
   lcd.setCursor(0, 1);
   lcd.print("Current: ");
   lcd.print(HumPompOff);
   //-----------------------------------------запускаем цикл------------------------------------------------
   VixodIzCicla = 200;// переменная для выхода из цикла
   TempMillisCicle1 = millis( );//время отсчета для выхода из цикла
 while(VixodIzCicla == 200){
     buttons=analogRead(ButtonPin);
 if (buttons > 100 && buttons < 200) {//кнопка + 
    ++HumPompOff;
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("ChangeHumPompOff");
    lcd.setCursor(0, 1);
    lcd.print("Current: ");
    lcd.print(HumPompOff);
    delay(200);
    TempMillisCicle1 = millis( );//время отсчета для выхода из цикла
  }
  else if (buttons > 200 && buttons < 400) {//кнопка -
    --HumPompOff;
    lcd.setCursor(0, 1);
    lcd.print("Current: ");
    lcd.print(HumPompOff);
    lcd.print("  ");
    delay(200);
    TempMillisCicle1 = millis( );//время отсчета для выхода из цикла    
  }
  else if (buttons > 400 && buttons < 600) {//кнопка назад
    VixodIzCicla = 2;
    menu.goBack();
    delay(200);
    
  }
  else if (buttons > 600 && buttons < 800) {
    menu.goMain();
    delay(200); 
    VixodIzCicla = 2;
  }
  if ( millis( ) - TempMillisCicle1 > 10000 ){
  menu.goLast(); //return to last viewed menu
  VixodIzCicla = 2;
  delay(200);
  }
}

  
  }//---------------------конец пункта выбора значения------------------------------------------------
}
//-----------------------------------------------------------------------------------------------





//--------------функция опроса датчика температуры
int readSenseTemp() {
   float t = dht.readTemperature();//значение температуры с датчика DHT11
   return t;
}
//--------------------------------------------------------------------



//--------------функция опроса датчика влажности
int readSenseHum() {
   float h = dht.readHumidity();//значение влажности с датчика DHT11
   return h;
}
//--------------------------------------------------------------------



//--------------функция опроса датчика влажности почвы---------------------
int readSenseSoil(){
 
    digitalWrite(voltageFlipPin1, HIGH);
    digitalWrite(voltageFlipPin2, LOW);
    delay(flipTimer);
  int val1 = analogRead(sensorPin);
    delay(flipTimer);
    digitalWrite(voltageFlipPin1, LOW);
    digitalWrite(voltageFlipPin2, HIGH);
    delay(flipTimer);
  // invert the reading
  int val2 = 1023 - analogRead(sensorPin);
  int avg = (val1 + val2) / 2;
  return avg;
 }
 //--------------------------------------------------------------------
 
 
 
 // Выводит текущие время в Serial
void printTimeToSerial(){
 
  byte static prevSecond=0; // тут будем хранить, сколько секунд было при прошлом отчете
   
  if(RTC.second!=prevSecond){ // что-то делаем только если секунды поменялись
    Serial.print(RTC.hour); // часы
   
    Serial.print(":"); // разделитель
    Serial.print(RTC.minute);
   
    Serial.print(":"); 
    Serial.println(RTC.second);
     
    prevSecond=RTC.second; // запомнили когда мы "отчитались"
  }
}
 
// Выводит текущие время на LCD
 
void printTimeToLCD(){
    byte static prevSecond=0; // тут будем хранить, сколько секунд было при выводе
     
    if(RTC.second!=prevSecond){ // что-то делаем только если секунды поменялись
       lcd.clear();
       lcd.setCursor(5,1); // устанавливаем позицию курсора
        
      if(RTC.hour<10)lcd.print(" ");
      lcd.print(RTC.hour); // часы
     
      lcd.print( (RTC.second % 2)?" ":":"); // разделитель моргает
       
      if(RTC.minute<10)lcd.print(0); // лидирующий ноль, если нужен
      lcd.print(RTC.minute);
     
    prevSecond=RTC.second; // запомнили когда мы "отчитались"
  }
}
 
// устанавливает часы модуля на какое-то заранее определенное время
void setSomeTime(){
  RTC.stopClock();// останавливаем часы
  RTC.fillByHMS(19,15,0); // "подкручиваем стрелки на 19:15:00
  RTC.setTime();// отправляем "подкрученное время" самому модулю
  RTC.startClock(); // и опять запускаем часы
}
 
// слушает из Serial команды и выполняет их. Каждая команда - один символ.
// доступны команды:
//  s - установить время указанное в функции setSomeTime()
void doSerialCommands(){
  if(Serial.available()){ // что-нибудь пришло?
    char ch=Serial.read(); // читаем что пришло
     
    switch(ch){
      case 's': // команда установки времени
           setSomeTime(); // устанавливаем
           break;
            
       // тут, в будущем, мы можем добавлять дополнительные команды
      default:;
           // на неизвестную команду - ничего не делаем
    };
  }
}

Код чтото разрастается, надо срочно разобраться с временем и таймерами :)

Cyoko
Offline
Зарегистрирован: 22.08.2014

Ребят вот нашел хороший пример

// #############################################################################
// #
// # Scriptname : DS1307_Test.pde
// # Author     : Peter Schmelzer, Oliver Kraus
// # Date       : 2011-04-08
// # Version    : 1.21
// # License    : cc-by-sa-3.0
// #
// # Description:
// # Test file for the DS1307new library. Assumes that you have a DS1307 
// # connected to the I2C-Bus of your Arduino and that it has a battery backup.
// # 
// #############################################################################
// *********************************************
// INCLUDE
// *********************************************
#include <Wire.h>                       // For some strange reasons, Wire.h must be included here
#include <DS1307new.h>

// *********************************************
// DEFINE
// *********************************************

// *********************************************
// VARIABLES
// *********************************************
uint16_t startAddr = 0x0000;            // Start address to store in the NV-RAM
uint16_t lastAddr;                      // new address for storing in NV-RAM
uint16_t TimeIsSet = 0xaa55;            // Helper that time must not set again

// *********************************************
// SETUP
// *********************************************
void setup()
{
  pinMode(2, INPUT);                    // Test of the SQW pin, D2 = INPUT
  digitalWrite(2, HIGH);                // Test of the SQW pin, D2 = Pullup on

  Serial.begin(9600);

/*
   PLEASE NOTICE: WE HAVE MADE AN ADDRESS SHIFT FOR THE NV-RAM!!!
                  NV-RAM ADDRESS 0x08 HAS TO ADDRESSED WITH ADDRESS 0x00=0
                  TO AVOID OVERWRITING THE CLOCK REGISTERS IN CASE OF
                  ERRORS IN YOUR CODE. SO THE LAST ADDRESS IS 0x38=56!
*/
  RTC.setRAM(0, (uint8_t *)&startAddr, sizeof(uint16_t));// Store startAddr in NV-RAM address 0x08 

/*
   Uncomment the next 2 lines if you want to SET the clock
   Comment them out if the clock is set.
   DON'T ASK ME WHY: YOU MUST UPLOAD THE CODE TWICE TO LET HIM WORK
   AFTER SETTING THE CLOCK ONCE.
*/
//  TimeIsSet = 0xffff;
//  RTC.setRAM(54, (uint8_t *)&TimeIsSet, sizeof(uint16_t));  

/*
  Control the clock.
  Clock will only be set if NV-RAM Address does not contain 0xaa.
  DS1307 should have a battery backup.
*/
  RTC.getRAM(54, (uint8_t *)&TimeIsSet, sizeof(uint16_t));
  if (TimeIsSet != 0xaa55)
  {
    RTC.stopClock();
        
    RTC.fillByYMD(2011,4,8);
    RTC.fillByHMS(22,7,0);
    
    RTC.setTime();
    TimeIsSet = 0xaa55;
    RTC.setRAM(54, (uint8_t *)&TimeIsSet, sizeof(uint16_t));
    RTC.startClock();
  }
  else
  {
    RTC.getTime();
  }

/*
   Control Register for SQW pin which can be used as an interrupt.
*/
  RTC.ctrl = 0x00;                      // 0x00=disable SQW pin, 0x10=1Hz,
                                        // 0x11=4096Hz, 0x12=8192Hz, 0x13=32768Hz
  RTC.setCTRL();

  Serial.println("DS1307 Testsketch");
  Serial.println("Format is \"hh:mm:ss dd-mm-yyyy DDD\"");

  uint8_t MESZ;

  MESZ = RTC.isMEZSummerTime();
  Serial.print("MEZ=0, MESZ=1 : ");
  Serial.println(MESZ, DEC);    
  Serial.println();
}

// *********************************************
// MAIN (LOOP)
// *********************************************
void loop()
{
  RTC.getTime();
  if (RTC.hour < 10)                    // correct hour if necessary
  {
    Serial.print("0");
    Serial.print(RTC.hour, DEC);
  } 
  else
  {
    Serial.print(RTC.hour, DEC);
  }
  Serial.print(":");
  if (RTC.minute < 10)                  // correct minute if necessary
  {
    Serial.print("0");
    Serial.print(RTC.minute, DEC);
  }
  else
  {
    Serial.print(RTC.minute, DEC);
  }
  Serial.print(":");
  if (RTC.second < 10)                  // correct second if necessary
  {
    Serial.print("0");
    Serial.print(RTC.second, DEC);
  }
  else
  {
    Serial.print(RTC.second, DEC);
  }
  Serial.print(" ");
  if (RTC.day < 10)                    // correct date if necessary
  {
    Serial.print("0");
    Serial.print(RTC.day, DEC);
  }
  else
  {
    Serial.print(RTC.day, DEC);
  }
  Serial.print("-");
  if (RTC.month < 10)                   // correct month if necessary
  {
    Serial.print("0");
    Serial.print(RTC.month, DEC);
  }
  else
  {
    Serial.print(RTC.month, DEC);
  }
  Serial.print("-");
  Serial.print(RTC.year, DEC);          // Year need not to be changed
  Serial.print(" ");
  switch (RTC.dow)                      // Friendly printout the weekday
  {
    case 1:
      Serial.print("MON");
      break;
    case 2:
      Serial.print("TUE");
      break;
    case 3:
      Serial.print("WED");
      break;
    case 4:
      Serial.print("THU");
      break;
    case 5:
      Serial.print("FRI");
      break;
    case 6:
      Serial.print("SAT");
      break;
    case 7:
      Serial.print("SUN");
      break;
  }
  Serial.print(" seconds since 1.1.2000:");
  Serial.print(RTC.time2000, DEC);
  uint8_t MESZ = RTC.isMEZSummerTime();
  Serial.print(" MEZ=0, MESZ=1 : ");
  Serial.print(MESZ, DEC);  
  
  Serial.print(" - Address in NV-RAM is: ");
  RTC.getRAM(0, (uint8_t *)&lastAddr, sizeof(uint16_t));
  Serial.print(lastAddr, HEX);
  lastAddr = lastAddr + 1;              // we want to use it as addresscounter for example
  RTC.setRAM(0, (uint8_t *)&lastAddr, sizeof(uint16_t));
  RTC.getRAM(54, (uint8_t *)&TimeIsSet, sizeof(uint16_t));
  if (TimeIsSet == 0xaa55)              // check if the clock was set or not
  {
    Serial.println(" - Clock was set!");
  }
  else
  {
    Serial.println(" - Clock was NOT set!");
  }    
  delay(1000);                          // wait a second
}

Не совсем понятно по коду.....

вот это 

RTC.getRAM(0, (uint8_t *)&lastAddr, sizeof(uint16_t));
  Serial.print(lastAddr, HEX);
  lastAddr = lastAddr + 1;              // we want to use it as addresscounter for example
  RTC.setRAM(0, (uint8_t *)&lastAddr, sizeof(uint16_t));
  RTC.getRAM(54, (uint8_t *)&TimeIsSet, sizeof(uint16_t));

зачем ?

кто может рассказать человеческим языком что тут с записью чтением и для чего это надо ?

Сделал вот так :

#include <DS1307new.h>

unsigned long TempMillisTime; //засечка времени для отображения часов

RTC.setRAM(0, (uint8_t *)&startAddr, sizeof(uint16_t));// Store startAddr in NV-RAM address 0x08 
  /*
   Uncomment the next 2 lines if you want to SET the clock
   Comment them out if the clock is set.
   DON'T ASK ME WHY: YOU MUST UPLOAD THE CODE TWICE TO LET HIM WORK
   AFTER SETTING THE CLOCK ONCE.
*/
  //TimeIsSet = 0xffff;
  //RTC.setRAM(54, (uint8_t *)&TimeIsSet, sizeof(uint16_t));  
 
/*
  Control the clock.
  Clock will only be set if NV-RAM Address does not contain 0xaa.
  DS1307 should have a battery backup.
*/
  RTC.getRAM(54, (uint8_t *)&TimeIsSet, sizeof(uint16_t));
  if (TimeIsSet != 0xaa55)
  {
    RTC.stopClock();
        
    RTC.fillByYMD(2014,10,15);
    RTC.fillByHMS(11,37,10);
    
    RTC.setTime();
    TimeIsSet = 0xaa55;
    RTC.setRAM(54, (uint8_t *)&TimeIsSet, sizeof(uint16_t));
    RTC.startClock();
  }
  else
  {
    RTC.getTime();
  }
 
/*
   Control Register for SQW pin which can be used as an interrupt.
*/
  RTC.ctrl = 0x00;                      // 0x00=disable SQW pin, 0x10=1Hz,
                                        // 0x11=4096Hz, 0x12=8192Hz, 0x13=32768Hz
  RTC.setCTRL();
 
  
  uint8_t MESZ;
 
  MESZ = RTC.isMEZSummerTime();
  Serial.print("MEZ=0, MESZ=1 : ");
  Serial.println(MESZ, DEC);    
  Serial.println();
 
 
  //----------------------------------------------------------------------------
TempMillisTime = millis( );//время отсчета для часов
 
void loop() {
  RTC.getTime();
//----------таймер для часов----------------------------------------------------------------  
  if ( millis( ) - TempMillisTime > 30000 ){
  TempMillisTime = millis( );
  int time;
  time = takeTime();
  }
//-------------------------------------------------------------------------------------------
 
int takeTime(){
  lcd.clear();
   lcd.setCursor(0, 0);
   if (RTC.hour < 10)                    // correct hour if necessary
  {
    lcd.print("0");
    lcd.print(RTC.hour, DEC);
  } 
  else
  {
    lcd.print(RTC.hour, DEC);
  }
   lcd.print(":");
  if (RTC.minute < 10)                  // correct minute if necessary
  {
    lcd.print("0");
    lcd.print(RTC.minute, DEC);
  }
  else
  {
    lcd.print(RTC.minute, DEC);
  }
  
}
 
Время на экране показывает. Вроде отключил от питания , подождал пару минут , время тоже. Или мало ждал ?
Cyoko
Offline
Зарегистрирован: 22.08.2014

и еще вот это что за пин такой ? 

pinMode(2, INPUT);                    // Test of the SQW pin, D2 = INPUT
  digitalWrite(2, HIGH);                // Test of the SQW pin, D2 = Pullup on
Cyoko
Offline
Зарегистрирован: 22.08.2014

чтото не хотит никто помогать :) Ну ладно будем думать вслух.
Пока основная проблема с пониманием логики работы библиотек...

Вот какая идея у меня:

1. При вкючении питания выводим время с РТС на экран

2. Если время не правильное, то дуем в меню настройки времени

3. там нас ждут подпункты год месяц все дела.

4. Вот тут вопрос можно ли обновлять только часы например или надо выключать таймер , полностью перезаписывать и включать ?Тогда заходим в них , присваем переменной значение и изменяем ее на нужное нам. Такс....Ну и при выходе надо обновить значения всех переменных времени и выкл-записываем-вкл таймер с новыми значениями.

5. а после выхода попадаем в функцию вывода времени на экран уже с новыми значениями.

Как вам мой вариант :)))) Чет мудрено помойму .

Какие есть идеи по данной реализации ? Можно ли в функции обновлять значения времени таймера ?

Cyoko
Offline
Зарегистрирован: 22.08.2014

помогите понять что это значит ?

RTC.setRAM(0, (uint8_t *)&startAddr, sizeof(uint16_t));

или это

RTC.getRAM(54, (uint8_t *)&TimeIsSet, sizeof(uint16_t));

не могу понять что куда записывается.....

Cyoko
Offline
Зарегистрирован: 22.08.2014

Так время вроде удалось сделать.... Но вот вопрос , почему не перезаписывает значения ?

RTC.getRAM(54, (uint8_t *)&yy, sizeof(uint16_t));
  RTC.getRAM(49, (uint8_t *)&mm, sizeof(uint16_t));
  RTC.getRAM(45, (uint8_t *)&dd, sizeof(uint16_t));
  RTC.getRAM(40, (uint8_t *)&hh, sizeof(uint16_t));
  RTC.getRAM(35, (uint8_t *)&mn, sizeof(uint16_t));
  
  RTC.getTime();
  if (RTC.year != yy) RTC.setRAM(54, (uint8_t *)&yy, sizeof(uint16_t));
  if (RTC.month != mm) RTC.setRAM(49, (uint8_t *)&mm, sizeof(uint16_t));
  if (RTC.day != dd) RTC.setRAM(45, (uint8_t *)&dd, sizeof(uint16_t));
  if (RTC.hour != hh) RTC.setRAM(40, (uint8_t *)&hh, sizeof(uint16_t));                  
  if (RTC.minute != mn) RTC.setRAM(35, (uint8_t *)&mn, sizeof(uint16_t));

 

bwn
Offline
Зарегистрирован: 25.08.2014

Возьми просто "DS1307.h". Там все проще и явное обращение к переменным времени.

Cyoko
Offline
Зарегистрирован: 22.08.2014

Не могу чтото примера найти. Вот с какой библиотекой нашел , так и сделал:) Вообщем то не проблема залить сначала нормальную дату и запомнить ее навсегда.
Сейчас таймеры думаю , вот это вроде норм такая задачка оказалась :)