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

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

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

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

вот так вот считаешь , считаешь , а потом 3-6=5 :)

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

нет, не назвал.... не надо всё переводить на деньги...

 

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

без знака и по модулю это одно и тоже получается ?

у нас в голове - ДА, у контроллера в байтах головы - по другому чуть-чуть :)

надо мине выйти, попозже буду

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

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

знаковые

0000 =

0111 = 

1001 =

беззнаковые

0000 =

0111 = 

1001 =

 

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

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

знаковые

0000 =

0111 = 

1001 =

беззнаковые

0000 =

0111 = 

1001 =

 

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

так вот пока новый скетч с датчиком DHT11 и функциями

// big respect to user SU-27-16 for help



//подключим все внешние либы----------------------------------------------------------
#include <Wire.h> // добавляем необходимые библиотеки
#include <LiquidCrystal.h> // экран
#include "DHT.h" //библиотека датчика DHT11
//-------------------------------------------------------------------------------------
 
 
 
 
 
//pins--ноги распределим(что к какамоу пину подключено)------------------------------------------------------------
//#define voltageFlipPin1   50// пин питания датчика влажности почвы
//#define voltageFlipPin2   51// пин питания датчика влажности почвы
//#define sensorPin         A7//пин считывания значения влажности почвы
#define DHTPIN           52 // ПИН подключения датчика DHT11
LiquidCrystal lcd(8, 9, 4, 5, 6, 7 );//Экран
#define POT1             A0 // пин кнопок
//-----------------------------------------------------------------------------------------------------------------






//---------------------------consts павыделяем памяти для постоянок переменок смотрим перехлесты ----------------
// Выбираем модель датчика-----------------------
#define DHTTYPE DHT11   // DHT 11 
//#define DHTTYPE DHT22   // DHT 22  (AM2302)
//#define DHTTYPE DHT21   // DHT 21 (AM2301)
DHT dht(DHTPIN, DHTTYPE);
//----------------------------------------------

int buttons=0; //переменная для отслеживания нажатия кнопок
int temperatura; //переменная для вывода температуры на экран
int Humidity;//переменная для вывода влажности на экран
float t;//переменая для считывания показания температуры с датчика
float h;//переменая для считывания показания влажности с датчика
unsigned long TempMillisTemp; //засечка времени для расчета задержек опроса датчика температуры
unsigned long TempMillisHum; //засечка времени для расчета задержек опроса датчика влажности




//-инициализация однократная ------------------------------------------------------------------
void setup(){
  lcd.begin(16,2);        //наш экран     
  lcd.print("Meteo");                      //   начальная
  lcd.setCursor(0, 1);                     //
  lcd.print("     Station");               //             заставка
  Serial.begin(9600);                     //    последовательнй порт
  Serial.println("go go go");           //  начало работы
  dht.begin();// запускаем датчик DHT11
  pinMode(POT1,INPUT);// отслеживание нажатий кнопок
  temperatura = dht.readTemperature();// первое значение температуры для экрана , чтоб не было 0 пока ждем опрос датчика в цикле
  Humidity = dht.readHumidity();// первое значение влажности для экрана , чтоб не было 0 пока ждем опрос датчика в цикле
  TempMillisTemp = millis( );//время отсчета
  TempMillisHum = millis( );//время отсчета
  }
  
  


void loop() {
  
//типа таймер для включения функции опроса датчика температуры( каждые 10 сек)-----------------------
  if ( millis( ) - TempMillisTemp > 10000 ){
  TempMillisTemp = millis( );
  temperatura=readSenseTemp();
  Serial.println(temperatura);
}
//--------------------------------------------------------------------------------------------------------------------------- 



//типа таймер для включения функции опроса датчика влажности( каждые 10 сек)-----------------------
  if ( millis( ) - TempMillisHum > 10000 ){
  TempMillisHum = millis( );
  Humidity=readSenseHum();
  Serial.println(Humidity);
}
//--------------------------------------------------------------------------------------------------------------------------- 




//------------------а тут наши три кнопки при нажатии на которые выводятся на экран показания температуры и влажности---------------------------------   
     buttons=analogRead(POT1);
  if (buttons < 100) {
    lcd.clear(); //очищаем экран
    lcd.setCursor(0, 0); 
        lcd.print("Humidity: ");
    lcd.setCursor(0, 1);
        lcd.print("         ");
        lcd.print(Humidity);
        lcd.print(" %");
  }
  else if (buttons > 100 && buttons < 200) {
    lcd.clear(); //очищаем экран
    lcd.setCursor(0, 0); 
        lcd.print("Temperature: ");
    lcd.setCursor(0, 1);
        lcd.print("        ");
        lcd.print(temperatura);
        lcd.print(" *C");
  }
  else if (buttons < 400 && buttons > 200) {
    lcd.clear(); //очищаем экран
    lcd.setCursor(0, 0);
    lcd.print("Meteo");                      //   начальная
  lcd.setCursor(0, 1);                     //
  lcd.print("     Station");               //             заставка
  }
//---------------------------------------------------------------------------------------------------------------
    
}
//-подпрограммы вызываемые многократно ----------------------------------------------

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



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

а я пока десятичные цифры напишу:)

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

знаковые

0000 = +0

0111 = +7

1001 =-1

беззнаковые

0000 =0

0111 = 7

1001 =9

 

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

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

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

вот готовый скетч с выводом на экран трех значений , отсылка их в порт и нормально работающими кнопками . большое спасибо пользователю SU-27-16 .

// big respect to user SU-27-16 for help



//подключим все внешние либы----------------------------------------------------------
#include <Wire.h> // добавляем необходимые библиотеки
#include <LiquidCrystal.h> // экран
#include "DHT.h" //библиотека датчика DHT11
//-------------------------------------------------------------------------------------
 
 
 
 
 
//pins--ноги распределим(что к какамоу пину подключено)------------------------------------------------------------
#define voltageFlipPin1   50// пин питания датчика влажности почвы
#define voltageFlipPin2   51// пин питания датчика влажности почвы
#define sensorPin         A7//пин считывания значения влажности почвы
#define DHTPIN           52 // ПИН подключения датчика DHT11
LiquidCrystal lcd(8, 9, 4, 5, 6, 7 );//Экран
#define POT1             A0 // пин кнопок
//-----------------------------------------------------------------------------------------------------------------






//---------------------------consts павыделяем памяти для постоянок переменок смотрим перехлесты ----------------
// Выбираем модель датчика-----------------------
#define DHTTYPE DHT11   // DHT 11 
//#define DHTTYPE DHT22   // DHT 22  (AM2302)
//#define DHTTYPE DHT21   // DHT 21 (AM2301)
DHT dht(DHTPIN, DHTTYPE);
//----------------------------------------------

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; //засечка времени для расчета задержек опроса датчика температуры



//-инициализация однократная ------------------------------------------------------------------
void setup(){
  lcd.begin(16,2);        //наш экран     
  lcd.print("Meteo");                      //   начальная
  lcd.setCursor(0, 1);                     //
  lcd.print("     Station");               //             заставка
  Serial.begin(9600);                     //    последовательнй порт
  Serial.println("go go go");           //  начало работы
  dht.begin();// запускаем датчик DHT11
  pinMode(POT1,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( );//время отсчета для влажности почвы
  
}
  
  


void loop() {
  
//типа таймер для включения функции опроса датчика температуры( каждые 10 сек)-----------------------
  if ( millis( ) - TempMillisTemp > 10000 ){
  TempMillisTemp = millis( );
  temperatura=readSenseTemp();
  Serial.println(temperatura);
}
//--------------------------------------------------------------------------------------------------------------------------- 



//типа таймер для включения функции опроса датчика влажности( каждые 10 сек)-----------------------
  if ( millis( ) - TempMillisHum > 15000 ){
  TempMillisHum = millis( );
  Humidity=readSenseHum();
  Serial.println(Humidity);
}
//--------------------------------------------------------------------------------------------------------------------------- 




//типа таймер для включения функции опроса датчика влажности почвы( каждые 10 сек)-----------------------
  if ( millis( ) - TempMillisSoil > 20000 ){
  TempMillisSoil = millis( );
  HumSoil=readSenseSoil();
  Serial.println(HumSoil);
  }
//-------------------------------------------------------------------------------------------------------




//------------------а тут наши три кнопки при нажатии на которые выводятся на экран показания температуры и влажности---------------------------------   
     buttons=analogRead(POT1);
  if (buttons < 100) {
    lcd.clear(); //очищаем экран
    lcd.setCursor(0, 0); 
        lcd.print("Humidity: ");
    lcd.setCursor(0, 1);
        lcd.print("         ");
        lcd.print(Humidity);
        lcd.print(" %");
  }
  else if (buttons > 100 && buttons < 200) {
    lcd.clear(); //очищаем экран
    lcd.setCursor(0, 0); 
        lcd.print("Temperature: ");
    lcd.setCursor(0, 1);
        lcd.print("        ");
        lcd.print(temperatura);
        lcd.print(" *C");
  }
  else if (buttons > 200 && buttons < 400) {
    lcd.clear(); //очищаем экран
    lcd.setCursor(0, 0);
    lcd.print("Meteo");                      //   начальная
  lcd.setCursor(0, 1);                     //
  lcd.print("     Station");               //             заставка
  }
  else if (buttons > 400 && buttons < 600) {
    lcd.clear(); //очищаем экран
    lcd.setCursor(0, 0);
        lcd.print("SoilHumidity");                      
  lcd.setCursor(0, 1);
        lcd.print("        ");  
        lcd.print(HumSoil);
        lcd.print(" %");  
  }
//---------------------------------------------------------------------------------------------------------------
    
}
//-подпрограммы вызываемые многократно ----------------------------------------------

//--------------функция опроса датчика температуры
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;
 }
 //--------------------------------------------------------------------

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

А пока вопрос :) чтобы упростить функцию опроса датчика влажности почвы надо под него библиотеку написать ? Ну чтоб она имела вид как в случае с датчиком DHT11 .

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

если в программе часто надо вычислить, типа, Y = X * 3,14159 / 7 * 360 - то для этого прописывают функцию с параметром входным X..... упрощение программы по чтению ( по машинным кодам - процессору пофуй ) ( не совсем ! - выгода есть в объёме исходного кода ).... тыщу раз проше прописать Y = func( X ), чем тыщу раз прописать Y = X * 3,14159 / 7 * 360....

 

про библиотеки - посложнее.... это ближе к объектам.... у которых есть много чего... функций, процедур, свойств, методов....

вам пока не нано, в смысле писать библиотеку.... пока так дорубите проект... 

 

библиотека работы с датчиком влажност вам поможет при разработке других проектов ( 10.... 50 )... в одном проекте написание библиотеки для этой задачи - трата времени :(

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

давайте без этого ! - // big respect to user SU-27-16 for help

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

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

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

 

моя баловался ДЕЛФИ, мне кажется лучше прописывать больше процедур или функций... чем в лупе прописывать всё прямо... на уход в подпрограмму тратится время :(   , зато по коду всё понятнее... может знатоки подскажут - что лучшеееееее ?

ваша readSenseSoil() - уже почти библиотека.... если её оформить библиотекой... НО - зачем ?

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

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

....зачем ждать матчасть - изучайте-думайте-пишите прям щас :)

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

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

....просьба небольшая - не повторять опыты Тесла, и чёбы в Пулково облаков никогда не было бы, ага ?

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

SU-27-16 пишет:

ваша readSenseSoil() - уже почти библиотека.... если её оформить библиотекой... НО - зачем ?

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

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

SU-27-16 пишет:

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

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

Хотя наверняка , если отслеживать какая клавиша была нажата последней , то можно эту информацию обновлять на экране. Но думаю это все не критично и не стоит код раздувать . Он и так еще раздуется управлением нагрузками и передачей информации по wifi.

Может и вправду лучше будет выводить всю инфу на экран , а кнопки использовать для ручного управления нагрузками . Правда вообще хотелось бы сделать меню . И шилд вроде как раз для этого. Кнопками вверх,вниз листаем меню. Кнопками вправо, влево меняем состояние. Кнопкой селект подтверждаем смену состояния. Кнопкой ресет , выходим в начало . 

Вообщем вариантов дофига :))))

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

создайте переменную-флаг что выводить на дисплей, 0 - заставка, 1 - ТВ, 2 - ВВ, 3 - ВП, в опросе клавиатуры присваивайте переменной соответствующее значение....     в лупе, через if и millis ( каждые 2 секунды, например ), блоком case опишите вывод на дисплей....  нажали кнопку два - две секунды видите значение ВлажВозд, потом появится заставка на 2 + 2 + 2 + ....... сек - пока снова не нажмёте кнопку.... но лучше при отсутствии нажатий сделать чтобы не обновлялся дисплей ( заставка-то не меняется )

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

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

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


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




//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 //пин управления реле вентилятора
//-----------------------------------------------------------------------------------------------------------------



//------------------------значок градусов----------------------------------------
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 flipTimer = 1000;//время задержки считывания значения с датчика влажности почвы между сменой полярности
int buttons=0; //переменная для отслеживания нажатия кнопок
int Temperatura; //переменная для вывода температуры на экран
int Humidity;//переменная для вывода влажности на экран
int HumSoil;//переменная для вывода влажности почвы на экран
float t;//переменая для считывания показания температуры с датчика
float h;//переменая для считывания показания влажности с датчика
unsigned long TempMillisTemp; //засечка времени для расчета задержек опроса датчика температуры
unsigned long TempMillisHum; //засечка времени для расчета задержек опроса датчика влажности
unsigned long TempMillisSoil; //засечка времени для расчета задержек опроса датчика температуры
int TempFanOff;// температура выключения вентилятора
int TempFanOn;// температура включения вентилятора
int CurrentStayRelayFan;// переменная для отслеживания текущего состояния реле вентилятора

//---------------------наше меню---------------------------------------------------
#define NUM_ITEMS 23 //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("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("DHT11",3),
  MItm("Soil Humidity",4),
  MItm(" <<BACK",0),
  MItm("DHT11",3,2), // notice that 2 in prev-index now not zero
  MItm("Temperature",5),
  MItm("Humidity",6),
  MItm("Temperature",5,3),
  MItm("Set Temp Fan On",7),
  MItm("Set Temp Fan Off",8),
  MItm("Humidity",6,3),
  MItm("Set Humidifier On",9),
  MItm("Set Humidifier Off",10),
  //MItm("Beef",8),
  //MItm("SHOW FISH",5),
  MItm(" <<BACK",2),
  MItm(" <<MAIN",0),
  MItm("Soil Humidity",4,2), 
  MItm("Set Watering On",11),
  MItm("Set Watering Off",12),
  //MItm("SHOW MEAT",4),
  MItm(" <<BACK",2),
  MItm(" <<MAIN",0)
};

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






//-инициализация однократная ------------------------------------------------------------------
void setup() {
  Serial.begin(9600);                     //    последовательнй порт
  
  //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();
  
  Serial.print(Temperatura);
  
}

void loop() {
//типа таймер для включения функции опроса датчика температуры( каждые 10 сек)-----------------------
  if ( millis( ) - TempMillisTemp > 10000 ){
  TempMillisTemp = millis( );
  Temperatura=readSenseTemp();
  Serial.println(Temperatura);
  
//-------------------------------режим работы вентилятора-------------------------------
  CurrentStayRelayFan = FanPower_PIN;// переменная для отслеживания текущего состояния реле вентилятора
  if ( Temperatura < TempFanOff ){
    digitalWrite(FanPower_PIN, LOW); //если температуры меньше заданной выключаем реле вентилятора
  }
  else if ( Temperatura > TempFanOn ){
    digitalWrite(FanPower_PIN, HIGH);// если температура поднялась выше заданной включаем реле вентилятора
  }
  else {
    digitalWrite(FanPower_PIN, CurrentStayRelay);// если температура в заданном диапазоне оставляем реле вентилятора как есть
}
//--------------------------------------------------------------------------------------------------------------------------- 



//типа таймер для включения функции опроса датчика влажности( каждые 10 сек)-----------------------
  if ( millis( ) - TempMillisHum > 15000 ){
  TempMillisHum = millis( );
  Humidity=readSenseHum();
  Serial.println(Humidity);
}
//--------------------------------------------------------------------------------------------------------------------------- 




//типа таймер для включения функции опроса датчика влажности почвы( каждые 10 сек)-----------------------
  if ( millis( ) - TempMillisSoil > 20000 ){
  TempMillisSoil = millis( );
  HumSoil=readSenseSoil();
  Serial.println(HumSoil);
  }
//-------------------------------------------------------------------------------------------------------






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






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

//------подпрограмма для изменения значений (в разработке)----------------------------------------
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);
  }
  //menu.goLast(); //return to last viewed menu
}
//-----------------------------------------------------------------------------------------------





//--------------функция опроса датчика температуры
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;
 }
 //--------------------------------------------------------------------

появились новые вопросы :)
Компилятор ругается на переменную enu_work.ino:179:32: error: 'CurrentStayRelay' was not declared in this scope

Вроде вверху написал ее . Вот вопрос какой эту переменную сделать правильно ? У нее два значения Low и High . И чего он ругается то ? Что не так я делаю ?

Здесь я все нормально расписал ? 

//типа таймер для включения функции опроса датчика температуры( каждые 10 сек)-----------------------
  if ( millis( ) - TempMillisTemp > 10000 ){
  TempMillisTemp = millis( );
  Temperatura=readSenseTemp();
  Serial.println(Temperatura);
  
//-------------------------------режим работы вентилятора-------------------------------
  CurrentStayRelayFan = FanPower_PIN;// переменная для отслеживания текущего состояния реле вентилятора
  if ( Temperatura < TempFanOff ){
    digitalWrite(FanPower_PIN, LOW); //если температуры меньше заданной выключаем реле вентилятора
  }
  else if ( Temperatura > TempFanOn ){
    digitalWrite(FanPower_PIN, HIGH);// если температура поднялась выше заданной включаем реле вентилятора
  }
  else {
    digitalWrite(FanPower_PIN, CurrentStayRelay);// если температура в заданном диапазоне оставляем реле вентилятора как есть
}
//--------------------------------------------------------------------------------------------------------------------------- 

Ну за исключением переменной .....

 

По влажности воздуха написать код вроде не сложно , интересно вообще кто то использует увлажнитель в дачных теплица и домашних оранжереях . Есть толк от него ? Или пустая трата электричества ?

 

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

 

Пояснения по коду :

                                                Меню

Показания датчиков                                                                   Настройки                      

выводят все показания на экран(работает)                            настройки датчика DHT11                             настройки датчика влажности почвы

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

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

                                             темература выкл вентилятора(в разработке)          влажность выкл увлажнителя(в разработке)

                                                                                   - влажность                               -влажность вкл увлажнителя(в разработке)

                                                                                                                                   -влажность выкл увлажнителя(в разработке)

                        

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

Ну тоесть имеем переменную

int TempFanOff;// температура выключения вентилятора

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

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

CurrentStayRelay != CurrentStayRelayFan

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

Cyoko пишет:

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

Ну тоесть имеем переменную

int TempFanOff;// температура выключения вентилятора

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

С какого устройства?

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

ну с помощью кнопочек на ардуино :)

 

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

Тут либо ин-/декрементировать значение, либо "нумпад" приделывать, либо еще какой изврат придумывать - например повесить все на одну кнопку и считать длительность нажатия

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

JollyBiber пишет:

Тут либо ин-/декрементировать значение, либо "нумпад" приделывать, либо еще какой изврат придумывать - например повесить все на одну кнопку и считать длительность нажатия

хм... я думал типа две кнопки + и - . Ну и с каждым нажатием +1 или -1 соответственно .

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

JollyBiber пишет:

CurrentStayRelay != CurrentStayRelayFan

а это где мне так написать надо ?

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

Посмотрите какую Вы переменную объявляете и какую передаете.

про +/- я так и написал. Вопрос в количестве кнопок/рычагов/педалей

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

JollyBiber пишет:

Посмотрите какую Вы переменную объявляете и какую передаете.

про +/- я так и написал. Вопрос в количестве кнопок/рычагов/педалей

 

Ой , точно , спасибо .

Так кнопки добавить не проблема , видел видео и работы с вращалкой( не знаю как правильно называется , ну типа как колесо громкости на магнитоле) . Хотя мне просто кнопки больше нравятся .

У меня шилд экран 1602 и 6 кнопок . 1 кнопка я так понял строго на ресете. Остается 5 кнопок . Меню , назад , вверх , вниз , вперед . Вот думаю может можно как то сделать так чтоб в меню установки значений кнопки вверх, вниз стали + и - . Пока не думал об этом еще .

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

Ну или тупо еще две кнопки добавить .

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

В прошлом году подобным делом автоматизации занялся

К весне было на руках:

насос 12V (у меня бак большой, а в трубах воду дают 2 раза в неделю по 1 часу :( вот и задумал для подогрева воду в мини бочку качать) накачивает в бочку воду за 25 минут,

реле 12В (на моем давлении так нормально и не открылось хотя дорабатывал, но не помогло и жрало много тока), убрал из программы прогрев воды :( - просто налив и в это время слив, налив до полного  - стоп насос.

капельная система, бочка 35 литров, 

дисплей nokia 3310, фоторезистор, щупы с операционным усилителем для измерения влажности почвы как у топик стартера, датчик DHT22 (чуть точнее), датчик давления BMP085, датчик температуры 18B20, часы ds1307 позднее ds3231 (точнее), блок из 2х реле ардуино, датчик верхнего уровня воды от ВАЗ 2110 в бочке и конечно ардуино уно, а потом и нано в принципе входов хватает с моим дисплеем.

Отстроил полив цветов в офисе  более менее. 

В теплицу перенес в начале сезона. Программу так сырую набросал тупо полив по времени 2 раза в день с проверкой влажности почвы и тестовый прогон по кнопке.

Алгоритм такой: утром насос из бака накачивает воду в бочку до сработки датчика уровня, через 3-4 часа открытие клапана на час (за это время через капельный полив бочка точно сливалась), потом через 15 минут новый второй цикл, налив - подогрев воды солнцем - полив.

Все кончилось на пропаже электричества на даче. Набора батареек 4xAA не хватало надолго. Начала греться кренка на ардуине пробовал дать отдельное питание на модули тут светоапокалипсис случился.

Меню думал, но не сделал, тормознулся на создании набора из 3х кнопок с резисторами по принципу как ваш шилд "set" и "+" и "-" думаю хватит на всё готовые чужие наработки есть.

Код сырой, местами без коментов, как есть

может вместе добъем автоматизацию только БЕЗ артилериста art100

/*
 * PCD8544 - Interface with Philips PCD8544 (or compatible) LCDs.
 *
 * 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.
 */
// Mods by Jim Park
// jim(^dOt^)buzz(^aT^)gmail(^dOt^)com
// hope it works for you
//#define PIN_SCE   7  // LCD CS  .... Pin 3
//#define PIN_RESET 6  // LCD RST .... Pin 1
//#define PIN_DC    5  // LCD Dat/Com. Pin 5
//#define PIN_SDIN  4  // LCD SPIDat . Pin 6
//#define PIN_SCLK  3  // LCD SPIClk . Pin 4
// LCD Gnd .... Pin 2
// LCD Vcc .... Pin 8
// LCD Vlcd ... Pin 7

//#define PIN_light 8
/*
 * To use this sketch, connect the eight pins from your LCD like thus:
 *
 * Pin 1 -> +3.3V (rightmost, when facing the display head-on)
 * Pin 2 -> Arduino digital pin 3
 * Pin 3 -> Arduino digital pin 4
 * Pin 4 -> Arduino digital pin 5
 * Pin 5 -> Arduino digital pin 7
 * Pin 6 -> Ground
 * Pin 7 -> 10uF capacitor -> Ground
 * Pin 8 -> Arduino digital pin 6
 *
 * Since these LCDs are +3.3V devices, you have to add extra components to
 * connect it to the digital pins of the Arduino (not necessary if you are
 * using a 3.3V variant of the Arduino, such as Sparkfun's Arduino Pro).
 */

#include <OneWire.h>
#include <PCD8544.h>
#include <Adafruit_BMP085.h>
#include <Wire.h>
#define DS3231_I2C_ADDRESS 0x68 // SDA A4, SCL A5
#define BUFF_MAX 28
byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;  // данные с DS3231
//byte dayOfMonth_1;  // данные с DS3231
//unsigned long prev, interval = 1000;
//String sday;
//String sday, ss, ddate;
//int dayw = 0;
char bufft[BUFF_MAX];
//char buffd[BUFF_MAX];
//int dateprint = 0;

long Press;
Adafruit_BMP085 bmp;

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

byte i;
byte present = 0;
byte type_s;
byte data[12];
byte addr[8];
float celsius;
byte  address_1[8] = { 0x28, 0x18, 0xEC, 0x55, 0x04, 0x00, 0x00, 0xD8}; //outside
//  28 7C A9 C1 04 00 00 13
byte  address_2[8] = { 0x28, 0xB2, 0xD5, 0x55, 0x04, 0x00, 0x00, 0x3C}; //inside
//0x28, 0x18, 0xEC, 0x55, 0x04, 0x00, 0x00, 0xD8
//0x28, 0xB2, 0xD5, 0x55, 0x04, 0x00, 0x00, 0x3C
OneWire ds (2); // все OneWire устройства на pin 10


#include "DHT.h"
#define DHTPIN 9     // what pin we're connected to
#define DHTTYPE DHT22   // DHT 22  (AM2302)
DHT dht(DHTPIN, DHTTYPE);

float h, t;
int flag_Naliv = 0, flag_Sliv = 0, flag_Poln = 0;
int VL; // влажность почвы
int time_old;
int hourStart;
int minuteStart ;
//-----------------------------------------------------------
int timeH_startBak_1; // 1 набор воды в бак
int timeM_startBak_1; // минуты 1 набор воды в бак

int timeH_startBak_2; // 2 набор воды в бак
int timeM_startBak_2; // минуты 2 набор воды в бак
//-----------------------------------------------------------
int timeH_startPoliv_1; // час полива 1
int timeM_startPoliv_1; // минуты полива 1

int timeH_startPoliv_2; // час полива 2
int timeM_startPoliv_2; // минуты полива 2
//-----------------------------------------------------------

int time_nasos = 25 ; // time_nasos = 25 время набора воды в бочку минут
int PolivH = 2; // часов поливать
int temp_watter, temp_inside, temp_outside; //температуры
int VLmax = 70; // максимальная влажность запрет полива
int VLmin = 50;// минимальная влажность полив разрешен

int pin_rele_Nas = 10; //пин реле Насос
int pin_rele_Klap = 11; //пин реле клапана
int led_pin = 13; // определили pin 13 для светодиода
// пины сенсоров
const int button_1Pin = 13;     // the number of the pushbutton_ pin
const int button_2Pin = 12;     // the number of the pushbutton_ pin

// пины кнопок
const int button_BPin = 8;     // the number of the pushbutton_ pin
//const int button_2Pin = 10;     // the number of the pushbutton_ pin
int countbuttonTest= 0;

// variables will change:
int button_1State = 0;         // variable for reading the pushbutton_ status
int button_2State = 0;         // variable for reading the pushbutton_ status
int button_BState = 0;         // variable for reading the pushbutton_ status

void setup() {
  //  Serial.begin  (9600);
  //  Serial.println("Setup on");
  // put your setup code here, to run once:  Serial.begin  (9600);
  pinMode(led_pin, OUTPUT);
  pinMode(pin_rele_Nas, OUTPUT);
  pinMode(pin_rele_Klap, OUTPUT);
  digitalWrite(pin_rele_Nas, HIGH); // закрыт
  digitalWrite(pin_rele_Klap, HIGH); // закрыт

  // initialize the pushbutton_ pin as an input:
  pinMode(button_1Pin, INPUT);
  pinMode(button_2Pin, INPUT);
  pinMode(button_BPin, INPUT);

  lcd.begin(LCD_WIDTH, LCD_HEIGHT);
  dht.begin();
  // Start up the library
  // sensors.begin();
  if (!bmp.begin()) {
    //   Serial.println("Could not find a valid BMP085 sensor, check wiring!");
    while (1) {}
  }
  klapan (0);
  nasos (0);
  draw_disp();
  //-----------------------------------------------------------
  snprintf(bufft, BUFF_MAX, "%02d:%02d", hour, minute);
  //Serial.println();
  //  Serial.print(bufft);
  //  Serial.println(" tek");
  //-----------------------------------------------------------
  timeH_startBak_1 = 10; // 1 набор воды в бак
  timeM_startBak_1 = 00; // минуты 1 набор воды в бак

  timeH_startBak_2 = 12; // 2 набор воды в бак
  timeM_startBak_2 = 00; // минуты 2 набор воды в бак
  //-----------------------------------------------------------
  timeH_startPoliv_1 = timeH_startBak_1; // час полива 1
  timeM_startPoliv_1 = timeM_startBak_1 + time_nasos + 5; // минуты полива 1

  timeH_startPoliv_2 = timeH_startBak_2; // час полива 2
  timeM_startPoliv_2 = timeM_startBak_2 + time_nasos + 5; // минуты полива 2
  //-----------------------------------------------------------

  //  Serial.println("Setup off");
}

void loop()
{
  button_1State = digitalRead(button_1Pin);
  button_2State = digitalRead(button_2Pin);
  button_BState = digitalRead(button_BPin);

  if (button_1State == LOW)  {
    lcd.setCursor(45, 5);
    lcd.print("T");
    flag_Poln = 1;
//    nasos (0);
  } else {
    lcd.setCursor(45, 5);
    lcd.print(" ");
    flag_Poln = 0;
  }
  if (button_2State == HIGH)  {
    lcd.setCursor(51, 5);
    lcd.print("B");
  } else {
    lcd.setCursor(51, 5);
    lcd.print(" ");
  }
  // проверка нажатия на кнопку и выполнение действий
  if (button_BState == HIGH)  {
    lcd.setCursor(58, 5);
    lcd.print("P");
    lcd.print(countbuttonTest);
    countbuttonTest++;
  } else {
    lcd.setCursor(58, 5);
    lcd.print("  ");
  }
  if (countbuttonTest == 1) test_Quik();
  if (countbuttonTest == 2) test_Smal();
  if (countbuttonTest >= 3) countbuttonTest = 0 ;

  draw_disp();
  //  Serial.print(VL);
  //  Serial.println(" -- VL fakt ---");

  if (VL >= VLmax) { // большая влажность >70% почвы ничего не делаем ждем
    if (flag_Naliv == 0 & flag_Sliv == 0 ) {
      klapan (0);
      nasos (0);
    }
    if (flag_Sliv == 0 ) {
      klapan (0);
      nasos (0); // пока нет клапана
      }
    } else { 
      cikl_Naliv_Poliv(10 , 01 , 25);
  }
}

void cikl_Naliv_Poliv (int startH, int startM, int NasosTime) {
  // второй цикл полива
  if  (hour == (startH) & minute == startM)
  {
    klapan (1);
    flag_Sliv = 1;
    Serial.println("++++ Poliv2_ON ++++");
  }
  if  (hour == startH & minute == startM + time_nasos)
  {
    klapan (0);
    flag_Sliv = 0;
    Serial.println("---- Poliv2_OFF ----");
  }
  
  
  
  
  
    //Serial.print(VL);
    //    Serial.println(" -- VL <= VLmax --- ");

    // первый налив в бак
    if  (hour == timeH_startBak_1)
    { 
      if  (minute >= timeM_startBak_1 & minute <= timeM_startBak_1 + time_nasos) 
      {
      nasos (1); // включаем насос с проверкой условий в подпрограмме
      klapan (0);
      flag_Naliv = 1;
     //     Serial.println("++++ Bak1_ON ++++");
    }
    }
    if  (hour == timeH_startBak_1 & minute == (timeM_startBak_1 + time_nasos))
    {
      nasos (0); // после 25 мин / наполнения бака насос отключаем
      klapan (0);
      flag_Naliv = 0;
      //     Serial.println("---- Bak1_OFF ----");
    }

    // первый цикл полива
    if  (hour == timeH_startPoliv_1 & minute == timeM_startPoliv_1)
    {
      klapan (1);
      flag_Sliv = 1;
      //      Serial.println("++++ Poliv1_ON ++++");
    } 
    if  (hour == (timeM_startPoliv_1 ) & minute == timeM_startPoliv_1 + time_nasos)
    {
      klapan (0);
      flag_Sliv = 0;
      //      Serial.println("---- Poliv1_OFF ----");
    }
    
    
    
}

// включаем или выключаем насос с проверкой условий
void nasos (int statN) {
  //  digitalWrite (pin_rele_Nas, LOW);
  //  digitalWrite(led_pin, LOW);
  if (statN == 1 & flag_Poln == 0)
  {
    digitalWrite (pin_rele_Nas, LOW);
    digitalWrite(led_pin, HIGH);
    lcd.setCursor(38, 5);
    lcd.print("N");
    //    Serial.print(statN);
    //    Serial.println(" stat Nasos");
    //    Serial.println("__________Nasos OPEN______________");
  }
  if (statN == 0 || flag_Poln == 1) {
    digitalWrite (pin_rele_Nas, HIGH);
    digitalWrite(led_pin, LOW);
    lcd.setCursor(38, 5);
    lcd.print(" ");
    //    Serial.print(statN);
    //    Serial.println(" stat Nasos");
    //    Serial.println("__________Nasos  CLOSE______________");
    //  Serial.println( timeM_startPoliv_ + time_nasos);
    // Serial.println("__________Poliv______________");
  }
}



void klapan(int statK) { //boolean
  //  digitalWrite (pin_rele_Klap, LOW);
  //  digitalWrite(led_pin, LOW);
  if (statK == 1)
  {
    digitalWrite (pin_rele_Klap, LOW);
    digitalWrite(led_pin, HIGH);
    lcd.setCursor(30, 5);
    lcd.print("K");
    //    Serial.print(statK);
    //    Serial.println(" stat pin_rele_Klap");
    //    Serial.println("__________Klap OPEN______________");
  }
  if (statK == 0) {
    digitalWrite (pin_rele_Klap, HIGH);
    digitalWrite(led_pin, LOW);
    lcd.setCursor(30, 5);
    lcd.print(" ");
    //    Serial.print(statK);
    //    Serial.println(" stat pin_rele_Klap");
    //    Serial.println("__________Klap CLOSE______________");
  }
}


void menu () {

  // if  (h == time_start) digitalWrite (pin_rele_Nas, HIGH);

  // put your main code here, to run repeatedly:

}

void draw_t(void) {
  //  snprintf(bufft, BUFF_MAX, "%02d:%02d:%02d", hour, minute, second);
  snprintf(bufft, BUFF_MAX, "%02d:%02d", hour, minute);
  lcd.setCursor(54, 0);
  lcd.print(bufft);
}

void reeds18b20() //ds18b20
{
  if (ds.search(addr) != 1)
  {
    ds.reset_search();
    delay(250);
    return;
  }
  ds.reset();
  ds.select(addr);
  ds.write(0x44, 1); // start conversion, with parasite power on at the end

  delay(1000); // 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++) data[i] = ds.read ();
  // convert the data to actual temperature
  unsigned int raw =  (data[1] << 8) | data[0];
  if (type_s)
  {
    raw = raw << 3; // 9 bit resolution default
    if (data[7] == 0x10) 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
  }

  celsius = (float)raw / 16.0;
}


// *******************************************************************
// Подпрограммы для DS3231
// *******************************************************************
byte decToBcd(byte val)
{
  return ( (val / 10 * 16) + (val % 10) );
}
// ---------------------------
byte bcdToDec(byte val)
{
  return ( (val / 16 * 10) + (val % 16) );
}
// ---------------------------
void setDateDs3231(byte second,        // 0-59
                   byte minute,        // 0-59
                   byte hour,          // 1-23
                   byte dayOfWeek,     // 1-7
                   byte dayOfMonth,    // 1-28/29/30/31
                   byte month,         // 1-12
                   byte year)          // 0-99
{
  Wire.beginTransmission(DS3231_I2C_ADDRESS);
  Wire.write(0);
  Wire.write(decToBcd(second));
  Wire.write(decToBcd(minute));
  Wire.write(decToBcd(hour));
  Wire.write(decToBcd(dayOfWeek));
  Wire.write(decToBcd(dayOfMonth));
  Wire.write(decToBcd(month));
  //Wire.write(decToBcd(year));
  Wire.endTransmission();
}
// ---------------------------
void getDateDs3231(byte *second,
                   byte *minute,
                   byte *hour,
                   byte *dayOfWeek,
                   byte *dayOfMonth,
                   byte *month,
                   byte *year)
{

  Wire.beginTransmission(DS3231_I2C_ADDRESS);
  Wire.write(0);
  Wire.endTransmission();

  Wire.requestFrom(DS3231_I2C_ADDRESS, 7);

  *second     = bcdToDec(Wire.read() & 0x7f);
  *minute     = bcdToDec(Wire.read());
  *hour       = bcdToDec(Wire.read() & 0x3f);
  *dayOfWeek  = bcdToDec(Wire.read());
  *dayOfMonth = bcdToDec(Wire.read());
  *month      = bcdToDec(Wire.read());
  *year       = bcdToDec(Wire.read());
  //Wire.requestFrom(DS3231_TEMPERATURE_ADDR, 7);
}

void draw_disp(void) {
  getDateDs3231(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year); // Читаем время
  draw_t();

  //  if  (h == time_start) digitalWrite (pin_rele_Nas, HIGH);
  reeds18b20();
  if (!memcmp(address_1, addr, 8))
  { // (address == '28190C040074')
    //    Serial.print  ("Temperature 1 = ");
    //    Serial.println  (celsius);
    lcd.setCursor(0, 1);
    lcd.print("OU");
    lcd.print(celsius, 1);
  }

  if (!memcmp(address_2, addr, 8))
  { //(address == '0208564C04003A')
    //    Serial.print  ("Temperature 2 = ");
    //    Serial.println  (celsius);
    lcd.setCursor(0, 2);
    lcd.print("IN");
    lcd.print(celsius, 1);
  }

  // Reading temperature or humidity takes about 250 milliseconds!
  // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
  float h = dht.readHumidity();
  float t = dht.readTemperature();

  // check if returns are valid, if they are NaN (not a number) then something went wrong!
  if (isnan(t) || isnan(h)) {
    //   Serial.println("Failed to read from DHT");
  }
  else {

    lcd.setCursor(0, 0);
    lcd.print("H");
    //lcd.setCursor(60, 0);
    lcd.print(h, 0);
    //    Serial.print("Hum ");
    //    Serial.print(h, 0);
    //    Serial.print(" %\t");
    // lcd.setCursor(60, 0);
    //lcd.print(h);
    //    Serial.print("T dht= ");
    //    Serial.print(t, 2);
    //    Serial.print(" *C\t");
    //lcd.setCursor(60, 1);
    //lcd.print(t, 1);
    int sensorValue = analogRead(A0);
    int Lux = map(sensorValue, 0, 1020, 0, 100);
    //    Serial.print("Lux ");
    //    Serial.print( Lux);
    //    Serial.println("%");
    lcd.setCursor(0, 5);
    lcd.print("    ");
    lcd.setCursor(0, 5);
    lcd.print("L");
    lcd.print(Lux);
    //lcd.print("");

    int sensorValueVL = analogRead(A1);
    VL = map(sensorValueVL, 0, 1020, 100, 0);
    //    Serial.print("V ");
    //    Serial.print( VL);
    //    Serial.println("%");
    //lcd.setCursor(20, 5);
    //lcd.print("            ");
    lcd.setCursor(27, 0);
    lcd.print("    ");
    lcd.setCursor(27, 0);
    lcd.print("V");
    lcd.print(VL);
    //lcd.print("");
  }
  //  Serial.print("Temperature bmp= ");
  float bmpTemp = bmp.readTemperature();
  //  Serial.print(bmp.readTemperature());
  //  Serial.println(" *C");
  //lcd.setCursor(0,4);
  //lcd.print("AD ");
  //lcd.print(bmpTemp);
  //lcd.print("mRs")
  Press = bmp.readPressure();
  //  Serial.print("Pressure = ");
  //  Serial.print(Press);
  //  Serial.println(" Pa");
  //  Serial.print("Pressure = ");
  Press = Press / 133.322368;
  //  Serial.print(Press);
  //  Serial.println(" mmRtSt");
  lcd.setCursor(0, 3);
  lcd.print("AD");
  lcd.print(Press);
  //lcd.print("");
  //Serial.println(" mmRtSt");


  // Calculate altitude assuming 'standard' barometric
  // pressure of 1013.25 millibar = 101325 Pascal
  // you can get a more precise measurement of altitude
  // if you know the current sea level pressure which will
  // vary with weather and such. If it is 1015 millibars
  // that is 5 .
  //  Serial.print("Altitude = ");
  //  Serial.print(bmp.readAltitude());
  //  Serial.println(" meters");
  //  Serial.print("Real altitude = ");
  //  Serial.print(bmp.readAltitude(101500));
  //  Serial.println(" meters");

  //  Serial.println();
  //
  //
  //  //Serial.print(" ");
  //  Serial.print(timeH_startBak_1);
  //  Serial.print(":");
  //  Serial.print(timeM_startBak_1);
  //  Serial.print(" ");
  //  Serial.print(timeH_startBak_2);
  //  Serial.print(":");
  //  Serial.print(timeM_startBak_2);
  //
  //  Serial.println();
  //  Serial.print(timeH_startPoliv_1);
  //  Serial.print(":");
  //  Serial.print(timeM_startPoliv_1);
  //  Serial.print(" ");
  //  Serial.print(timeH_startPoliv_2);
  //  Serial.print(":");
  //  Serial.print(timeM_startPoliv_2);
  //  Serial.println(" -- Serial.print(timeH_startPoliv_2) ---");


  snprintf(bufft, BUFF_MAX, "%02d:%02d", timeH_startBak_1, timeM_startBak_1);
  lcd.setCursor(54, 1);
  lcd.print(bufft);
  snprintf(bufft, BUFF_MAX, "%02d:%02d", timeH_startPoliv_1, timeM_startPoliv_1);
  lcd.setCursor(54, 2);
  lcd.print(bufft);
  snprintf(bufft, BUFF_MAX, "%02d:%02d", timeH_startBak_2, timeM_startBak_2);
  lcd.setCursor(54, 3);
  lcd.print(bufft);
  snprintf(bufft, BUFF_MAX, "%02d:%02d", timeH_startPoliv_2, timeM_startPoliv_2);
  lcd.setCursor(54, 4);
  lcd.print(bufft);
}

void test_Quik () {
  time_nasos = 2 ; // time_nasos = 25 время набора воды в бочку минут
  // PolivH = 2; // часов поливать
  lcd.setCursor(0, 4);
  lcd.print("tQuik");
  hourStart = hour;
  minuteStart = minute + 1;

  if (minute > 48) {
    hourStart = hour + 1;
    minuteStart = 1;
  }
  timeH_startBak_1 = hourStart; // 1 набор воды в бак
  timeM_startBak_1 = minuteStart; // минуты 1 набор воды в бак

  timeH_startBak_2 = timeH_startBak_1; // 2 набор воды в бак
  timeM_startBak_2 = timeM_startBak_1 + 6; // минуты 2 набор воды в бак
  //-----------------------------------------------------------
  timeH_startPoliv_1 = timeH_startBak_1; // час полива 1
  timeM_startPoliv_1 = timeM_startBak_1 + 3; // минуты полива 1

  timeH_startPoliv_2 = timeH_startBak_1; // час полива 2
  timeM_startPoliv_2 = timeM_startBak_1 + 9; // минуты полива 2

}

void test_Smal () {
  time_nasos = 25 ; // time_nasos = 25 время набора воды в бочку минут
  // PolivH = 2; // часов поливать
  lcd.setCursor(0, 4);
  lcd.print("tSmal");
  hourStart = hour;
  minuteStart = minute + 1;

  if (minute > 48) {
    hourStart = hour + 1;
    minuteStart = 1;
  }
  timeH_startBak_1 = hourStart; // 1 набор воды в бак
  timeM_startBak_1 = minuteStart; // минуты 1 набор воды в бак

  timeH_startBak_2 = timeH_startBak_1+1; // 2 набор воды в бак +1 час от текущего
  timeM_startBak_2 = 01 ; // минуты 2 набор воды в бак
  //-----------------------------------------------------------
  timeH_startPoliv_1 = timeH_startBak_1; // час полива 1
  timeM_startPoliv_1 = timeM_startBak_1 + time_nasos + 5; // минуты полива 1

  timeH_startPoliv_2 = timeH_startBak_1+2; // час полива 2 +2 часа от текущего
  timeM_startPoliv_2 = timeM_startBak_1 + time_nasos + 5; // минуты полива 2

}

 

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

Да не :) он нормальный , хоть веселит . Код посмотрю.... У меня как раз пока о поливе мыслей нет ,буду перенимать опыт :) Опять же таймер реального времени лежит у мну , но я какойто дешевый взял , без пинов . Походу надо припаять , а у меня паяльника нет :) такой прикол .

я правда пока щас думаю как настройку на ардуино сделать . Походу придется код дачника начинать читать :) а у него там еепромы какието . Но кнопками прикольно было б регулировать температуру хотя б. Хотя в принципе это не так уж и актуально имхо . Но интересно. Опять же можно будет хотя б принудительно включать вентилятор или форточку открывать. И клапан или насос какой для полива .

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

артилериста art100

от чего такие выводы ? кантуженными могут быть ВСЕ.....

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

Cyoko пишет:

ну с помощью кнопочек на ардуино :)

 

 среднее решение  - энкодер с кнопкой  - и продуманное меню.....

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

Во точно . Энкодер эта ручка называется :) Но честно сказать не нравятся мне энкодеры , которые я видел на видео . Убого как то выглядят . Хотя , если найти маленбкий и аккуратный .

Сегодня надеюсь будет время покумекать над кодом . Я так понял какойто цикл надо будет сделать . И вопрос не по теме. Есть какойто аналог оператора перехода к определенной строчке ? Типа GOTO в бейсике вроде был .

Cyoko
Offline
Зарегистрирован: 22.08.2014
//------подпрограмма для изменения значений (в разработке)----------------------------------------
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==7 ){
   lcd.clear();
   lcd.setCursor(0, 0);
   lcd.print("Input Temp Max:");
   lcd.setCursor(0, 1);
   lcd.print("Current: ");
   lcd.print(TempFanOn);
   //-----------------------------------------запускаем цикл------------------------------------------------
   ab = 0;
   while(ab != 200){
 if (buttons > 100 && buttons < 200) {//кнопка + 
    //menu.goUp();
    delay(200);
    ++TempFanOn;
    lcd.clear();
   lcd.setCursor(0, 0);
   lcd.print("Input Temp Max:");
   lcd.setCursor(0, 1);
   lcd.print("Current: ");
   lcd.print(TempFanOn);
  }
  else if (buttons > 200 && buttons < 400) {//кнопка -
   // menu.goDown();
    delay(200);  
    --TempFanOn;
    lcd.setCursor(0, 1);
    lcd.print("Current: ");
    lcd.print(TempFanOn);    
  }
  else if (buttons > 400 && buttons < 600) {//кнопка назад
    menu.goBack();
    delay(200);
   ab = 200; 
  }
  else if (buttons > 600 && buttons < 800) {
    menu.goMain();
    delay(200); 
    ab = 200;
  }
}

  
  }
  //menu.goLast(); //return to last viewed menu
}
//-----------------------------------------------------------------------------------------------

Это кусок кода для меню установки температуры включения . Вроде норм написал :) Но чет не хотит . Опишу идею для понимания . 
Попал в нужный пункт меню , нарисовалась инфа с просьбой ввести значение и выводом текущего значения . С этим проблем нет , работает :) А вот с циклом для отслеживания нажатия кнопок трабл . Что то не так делаю . По моей задумке мы попадаем в цикл и отслеживаем клавиши : кнопка вверх +1 нрадус к температуре , кнопка вниз -1 , ну и назад и меню для выхода из настройки .
Но чтото выводит он сообщение и начальную температуру равной 0 и все . Кнопки не работают . Типа зависло :) Куда копать то ?)

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

Cyoko пишет:

Сегодня надеюсь будет время покумекать над кодом . Я так понял какойто цикл надо будет сделать . И вопрос не по теме. Есть какойто аналог оператора перехода к определенной строчке ? Типа GOTO в бейсике вроде был .

Судя по этому сообщению Вы от понятия принципа работы Ардуины и программирования далеки :) Без курения мануалов Вам не обойтись, ну или терпеть насмешки и издевательства от таких как я и ждать спасения от leshak'a :D

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

Последний раз писал чтото в институте. Да и программами это назвать было нельзя. и было это лет 10 назад . Так что конечно все забыл . Но вот вроде покурил и надумал . Но чтото не работает . Подскажите почему цикл ведет себя не адекватно ? Значение переменной TempFanOn не меняется , на кнопки назад и меню тоже не реагирует . Я так понимаю либо в цикл вообще не заходит , либо заходит , но внутри него кнопки не отслеживает.

вот в этом куске кода 

//------подпрограмма для изменения значений (в разработке)----------------------------------------
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==7 ){
   lcd.clear();
   lcd.setCursor(0, 0);
   lcd.print("Input Temp Max:");
   lcd.setCursor(0, 1);
   lcd.print("Current: ");
   lcd.print(TempFanOn);
   //-----------------------------------------запускаем цикл------------------------------------------------
   ab = 0;
   while(ab != 200){
 if (buttons > 100 && buttons < 200) {//кнопка + 
    //menu.goUp();
    delay(200);
    ++TempFanOn;
    lcd.clear();
   lcd.setCursor(0, 0);
   lcd.print("Input Temp Max:");
   lcd.setCursor(0, 1);
   lcd.print("Current: ");
   lcd.print(TempFanOn);
  }
  else if (buttons > 200 && buttons < 400) {//кнопка -
   // menu.goDown();
    delay(200);  
    --TempFanOn;
    lcd.setCursor(0, 1);
    lcd.print("Current: ");
    lcd.print(TempFanOn);    
  }
  else if (buttons > 400 && buttons < 600) {//кнопка назад
    menu.goBack();
    delay(200);
   ab = 200; 
  }
  else if (buttons > 600 && buttons < 800) {
    menu.goMain();
    delay(200); 
    ab = 200;
  }
}

  
  }
  //menu.goLast(); //return to last viewed menu
}
//-----------------------------------------------------------------------------------------------

 

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

однозначно в serial слать в каждом куске и смотреть что происходит - отладка однако :(

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

Кхм... Когда-то очень давно смотрел кино про Султана. К его женам пришел дохтур (не я!), так вот султан сказал что его жен может видеть только он или евнух. Дохтур от кастрации отказался и поэтому должен был ставить диагнозы по показанной руке из-за занавески.

Я тоже отказываюсь от кастрации! Но и "по руке" ставить диагноз не буду. Может у Вас эта функция нигде и никогда не вызывается?

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

:)

Вызывается , на экране же пишет это 

lcd.clear();
19
   lcd.setCursor(0, 0);
20
   lcd.print("Input Temp Max:");
21
   lcd.setCursor(0, 1);
22
   lcd.print("Current: ");
23
   lcd.print(TempFanOn);

а вот что с циклом хз , кнопки не работают. Надо правда посмотреть что в порт кидать будет .....

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

главное проверить присвоение ab = 200;

ведь по нему выход из цикла и может еще дать по времени выход

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

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

Ну так как раз где кнопка меню и назад там последней строчкой идет присвоение переменной ab значения 200 . Вот и не пойму что не так :( 

Вообщем поставил вывод значений в порт.....

//-----------------------------входим в экран установки температуры вкл фентилятора-----------------------------------------------
  else if( idx==7 ){
   lcd.clear();
   lcd.setCursor(0, 0);
   lcd.print("Input Temp Max:");
   lcd.setCursor(0, 1);
   lcd.print("Current: ");
   lcd.print(TempFanOn);
   Serial.print("1");
   //-----------------------------------------запускаем цикл------------------------------------------------
   ab = 200;
   buttons=analogRead(ButtonPin);
   while(ab == 200){
 if (buttons > 100 && buttons < 200) {//кнопка + 
    Serial.print("2");
    delay(200);
    ++TempFanOn;
    lcd.clear();
   lcd.setCursor(0, 0);
   lcd.print("Input Temp Max:");
   lcd.setCursor(0, 1);
   lcd.print("Current: ");
   lcd.print(TempFanOn);
  }
  else if (buttons > 200 && buttons < 400) {//кнопка -
   Serial.print("3");
    delay(200);  
    --TempFanOn;
    lcd.setCursor(0, 1);
    lcd.print("Current: ");
    lcd.print(TempFanOn);    
  }
  else if (buttons > 400 && buttons < 600) {//кнопка назад
  Serial.print("4");
    ab = 2;
    menu.goBack();
    delay(200);
    
  }
  else if (buttons > 600 && buttons < 800) {
    menu.goMain();
    delay(200); 
    ab = 2;
  }
  Serial.print("5");
}

  
  }

При входе в этот пункт меню в порт выскакивает 1 , тоесть вход в меню сработал . А потом пишет постоянно 5 , тоесть цикл работает. Но кнопки внутри цикла не отслеживает . Почему ?!!!???

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

О все заработало :) надо было в цикл считывание пина запустить :) ну деревня блин)))))

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

А в каком месте Вы их пытаетесь отследить В ЦИКЛЕ? Допусти зашли с buttons == 100

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

захожу я с переменной ab=200 , а вот уже внутри buttons отслеживает какую кнопку я нажимаю . и если это + или - то соответственно увеличиваю или уменьшаю переменную TempFanOn ну и вывожу ее на экран.

А если это кнопки назад или меню то закрываю цикл и в меню выхожу .

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

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

Опять чтоль mills пытать придется :(

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

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

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

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

может с ними подумать 

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

нажал кноку проснулась дуня меню для изменения настроек показала или время пришло проснулась проверила данные и спатеньки - еще рано поливатеньки

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

Cyoko пишет:

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

перед циклом запомнить миллис и в цикле его проверять на превышение

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

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

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

Cyoko пишет:

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

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

а то само выскочит из меню у горячих эстонских парней

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

да да )))это тоже доделал )))) так и было ))))

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

я доволен как слон )))) все работает .