Датчик влажности почвы ( залипание значения)

Marlen S
Offline
Зарегистрирован: 13.01.2015

Здравствуйте товарищи, прошу Вашей помощи.

Подскажите что не так? Запили код датчика влажности почвы на ардуино, через com порт показывает стабильные значения как надо было, а вот через LCD 16х2 происходит залипания последнего числа, тоесть влажность показывает как в com порту но остается еще рандомное какое то чисто и все выглядит так ( в ком порте HUN: 143 , а вот на lcd HUM:143* где * залипшее рандомное число). Как это исправить? 

http://ru.aliexpress.com/item/Soil-Hygrometer-Humidity-Detection-Module-...

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

LiquidCrystal_I2C lcd(0x27,16,2);  

int SensorHum = A0;  
int Hum = 0;

void setup()
{
  Serial.begin(9600);
  lcd.init();
  lcd.backlight();
}

void loop() 
{  
  Hum = analogRead(SensorHum);
  lcd.setCursor(0, 0);
  lcd.print("HUM:");
  lcd.setCursor(4, 0);
  lcd.print(Hum);
  Serial.print("HUM: ");
  Serial.println(Hum);
  delay(1000);
}

 

Marlen S
Offline
Зарегистрирован: 13.01.2015
#include <Wire.h> 
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27,16,2);  

int SensorHum = A0;  
int Hum = 0;

void setup()
{
  Serial.begin(9600);
  lcd.init();
  lcd.backlight();
}

void loop() 
{  
  Hum = analogRead(SensorHum);
  lcd.setCursor(0, 0);
  lcd.print("HUM:");
  lcd.setCursor(4, 0);
  lcd.print(Hum);
  Serial.print("HUM: ");
  Serial.println(Hum);
  delay(1000);
}

 

trembo
trembo аватар
Offline
Зарегистрирован: 08.04.2011

1. lcd.clear()

2. lcd.setCursor(4,0);    lcd.print( "                ");     lcd.setCursor (4,0);    lcd.print(Hum);

2009Shef
Offline
Зарегистрирован: 23.10.2014

Для начала нужно понять как работает любой текстовый экран на контроллере hd44780

а точнее особенность вывода на экран:

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

lcd.setCursor(0, 0);
lcd.print("HUM:");

дисплей будет отображать текст HUM: начиная с 0 строки и 0 символа до тех пор пока вы не выведете в место него другой текст или не выполните полную очистку дисплея.

в соответствии с выше изложенным ваш код может выглядеть так:

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

LiquidCrystal_I2C lcd(0x27,16,2);  

int SensorHum = A0;  
int Hum = 0;

void setup()
{
  Serial.begin(9600);
  lcd.init();
  lcd.backlight();
  lcd.setCursor(0, 0);
  lcd.print(F("HUM:"));
}

void loop() 
{  
  Hum = analogRead(SensorHum);
  lcd.setCursor(4, 0);
  lcd.print(Hum);
  Serial.print(F("HUM: "));
  Serial.println(Hum);
  delay(1000);
}

А для того чтобы избавиться от лишних циферек или хвостиков в общем называйте как хотите их нужно стереть сделать это можно двумя способами для моего кода приведенного выше между строкой 21 и 22 вставить строки

lcd.print(F("     ")); //Пять пробелов
lcd.setCursor(4, 0);

Для вашего кода будет достатачно такой строки:

lcd.clear();

Вставленной между строкой 21 и 22

Marlen S
Offline
Зарегистрирован: 13.01.2015

Спасибо. Буду уже дома попробую.

Marlen S
Offline
Зарегистрирован: 13.01.2015

2009Shef пишет:

Для начала нужно понять как работает любой текстовый экран на контроллере hd44780

а точнее особенность вывода на экран:

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

lcd.setCursor(0, 0);
lcd.print("HUM:");

дисплей будет отображать текст HUM: начиная с 0 строки и 0 символа до тех пор пока вы не выведете в место него другой текст или не выполните полную очистку дисплея.

в соответствии с выше изложенным ваш код может выглядеть так:

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

LiquidCrystal_I2C lcd(0x27,16,2);  

int SensorHum = A0;  
int Hum = 0;

void setup()
{
  Serial.begin(9600);
  lcd.init();
  lcd.backlight();
  lcd.setCursor(0, 0);
  lcd.print(F("HUM:"));
}

void loop() 
{  
  Hum = analogRead(SensorHum);
  lcd.setCursor(4, 0);
  lcd.print(Hum);
  Serial.print(F("HUM: "));
  Serial.println(Hum);
  delay(1000);
}

А для того чтобы избавиться от лишних циферек или хвостиков в общем называйте как хотите их нужно стереть сделать это можно двумя способами для моего кода приведенного выше между строкой 21 и 22 вставить строки

lcd.print(F("     ")); //Пять пробелов
lcd.setCursor(4, 0);

Для вашего кода будет достатачно такой строки:

lcd.clear();

Вставленной между строкой 21 и 22

Я понял Вашу мысль :) обнулять полностью lcd от каких либо артефактов при цикле луп, да бы не было залипаний :) Сразу не подумал (практика.....)

И простите за вопрос, а что означает значение F в данной строке  lcd.print(F("HUM:"));

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

Del

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

Если делать lcd.clear() в каждом проходе, будет неприятное мерцание. Лучше перед выводом очищать знакоместа и туда выводить.

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

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

О как, чет сайт колбасит((((

Marlen S
Offline
Зарегистрирован: 13.01.2015

2009Shef пишет:

Для начала нужно понять как работает любой текстовый экран на контроллере hd44780

а точнее особенность вывода на экран:

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

lcd.setCursor(0, 0);
lcd.print("HUM:");

дисплей будет отображать текст HUM: начиная с 0 строки и 0 символа до тех пор пока вы не выведете в место него другой текст или не выполните полную очистку дисплея.

в соответствии с выше изложенным ваш код может выглядеть так:

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

LiquidCrystal_I2C lcd(0x27,16,2);  

int SensorHum = A0;  
int Hum = 0;

void setup()
{
  Serial.begin(9600);
  lcd.init();
  lcd.backlight();
  lcd.setCursor(0, 0);
  lcd.print(F("HUM:"));
}

void loop() 
{  
  Hum = analogRead(SensorHum);
  lcd.setCursor(4, 0);
  lcd.print(Hum);
  Serial.print(F("HUM: "));
  Serial.println(Hum);
  delay(1000);
}

А для того чтобы избавиться от лишних циферек или хвостиков в общем называйте как хотите их нужно стереть сделать это можно двумя способами для моего кода приведенного выше между строкой 21 и 22 вставить строки

lcd.print(F("     ")); //Пять пробелов
lcd.setCursor(4, 0);

Для вашего кода будет достатачно такой строки:

lcd.clear();

Вставленной между строкой 21 и 22

Спасибо еще раз) то что нужно  :)

Marlen S
Offline
Зарегистрирован: 13.01.2015

Товарищи извените еще раз, возник вопрос который я сам не могу переварить :( Прощу Вашей помощи.

В данном коде хотелось реализовать что бы питания пина 11 (5v - Pvcc) подавать на датчик влажности почвы (ссылка выше) раз в 5 минут и снимать показания с него. При постоянном включенном датчике я то понял как был (считать), а вот как сделать так что бы с пинов питания не пойму :( Объясните....

 

P.S. Просто если постоянно держать датчик в земле включенным электролиз его съест :(

 

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

LiquidCrystal_I2C lcd(0x27,16,2);  

int SensorHum = A0;  
int Hum = 0;
long previousMillis2 = 0; 
long interval2 = 300000; // 5 min
int Pvcc = 11;


void setup(){

  Serial.begin(9600);
  lcd.init();
  lcd.backlight();
  lcd.print("Controller: ON  ");
  delay(1000);
  lcd.clear();  

  pinMode(Pvcc, OUTPUT);
  digitalWrite(Pvcc, LOW);
}

void loop(){

  unsigned long currentMillis2 = millis();
  if(currentMillis2 - previousMillis2 > interval2)
  {
    Hum = analogRead(SensorHum);
    lcd.setCursor(0, 0);
    lcd.print("HUM:");
    lcd.setCursor(4, 0);
    lcd.print(F("     "));
    lcd.setCursor(4, 0);
    lcd.print(Hum);
    Serial.print("HUM: ");
    Serial.println(Hum);
    delay(1000);
  }
}

 

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

Пин на питание модуля (только токи сперва замерьте), перед измерением в HIGH, выждать паузу для нормализации значения, замерить, пин в LOW. Только по картинке не понял, у вас цифровой и аналоговый выход?

Датчик кстати все равно сгниет, только медленнее.

2009Shef
Offline
Зарегистрирован: 23.10.2014

Marlen S пишет:
И простите за вопрос, а что означает значение F в данной строке  lcd.print(F("HUM:"));

F это макрос который хранит массив символов (он же char[]) в памяти программ (PROGMEM) можно использовать в функциях например:

Serial.print(F("ABCD"));

Но у макроса есть недостатки

он может быть использован только как параметр передаваемый в функцию

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

Подробней на английском http://www.baldengineer.com/arduino-f-macro.html

по поводу питания переферии с цифрового пина ардуины

Картинка

на рисунке:

Транзистор например BC327 (допустимый ток 800мА) (можно взять любой PNP Транзистор)

Резистор для данного транзистора нормальным будет номинал в 1кОм

PS картинка не моя взята с googl первая подходящая

и еще немного полезной информации (правда на английском но там все в картинках и то что написанно легко понимается при помощи https://translate.google.ruhttp://homes-smart.ru/upload/arduino/arduinoBasicConnections.pdf

Marlen S
Offline
Зарегистрирован: 13.01.2015

bwn пишет:

Пин на питание модуля (только токи сперва замерьте), перед измерением в HIGH, выждать паузу для нормализации значения, замерить, пин в LOW. Только по картинке не понял, у вас цифровой и аналоговый выход?

Датчик кстати все равно сгниет, только медленнее.

Да, он и аналог A0 и цифровой D0.  Вот кусок где я подумал так сделать как написали Вы. Если порт ардуино выдает максимальный ток в 50ma, потребуется ли этому датчику ток больше чем в 50ma?  Описание в коде правильно ли?

 

int SensorHum = A0;  
int Hvcc = 7;
int Hum = 0;
long previousMillis1 = 0; 
long interval1 = 5000; 

void setup(){

  pinMode(Hvcc, OUTPUT); 
  digitalWrite(Hvcc, LOW);
}
void loop(){

  unsigned long currentMillis1 = millis();
  if(currentMillis1 - previousMillis1 > interval1)
  { 
    previousMillis1 = currentMillis1;
    digitalWrite(Hvcc, HIGH);
    Hum = analogRead(SensorHum);  
  }
}

в куске 

unsigned long currentMillis1 = millis();
  if(currentMillis1 - previousMillis1 > interval1)
  { 
    previousMillis1 = currentMillis1;
    digitalWrite(Hvcc, HIGH);
    Hum = analogRead(SensorHum);  
  }
int SensorHum = A0;  
int Hvcc = 7;
int Hum = 0;
long previousMillis1 = 0; 
long interval1 = 5000; 

void setup(){

  pinMode(Hvcc, OUTPUT); 
  digitalWrite(Hvcc, LOW);
}
void loop(){

  unsigned long currentMillis1 = millis();
  if(currentMillis1 - previousMillis1 > interval1)
  { 
    previousMillis1 = currentMillis1;
    digitalWrite(Hvcc, HIGH);
    Hum = analogRead(SensorHum);  
  }
  if(Hum <=450)
  {
    Serial.print("Water Full = ");
    Serial.println(Hum);
  }
  else if( Hum > 450 && Hum < 700)
  {
    Serial.print("Water *** = ");
    Serial.println(Hum);
  }
  else 
  {
    Serial.print("Water Low = ");
    Serial.println(Hum);
  }
}

 

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

Del

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

Для начала, зачем int-ы, у вас больше 255 пинов? А так вроде правильно. После 18 строки надо задержку подбирать, шилд вряд ли моментально в рабочий режим войдет. А ток тестером от +5В померяйте во время замера. И вроде как 40мА рекомендуют не превышать. Если больше, то пост выше, ток транзистор  странно подключен. Такой структуры, обычно эмитер на GND, база правильно, а шилд GND к коллектору Vcc на +5В.

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

Да, обратно в LOW забыли перевести.

2009Shef
Offline
Зарегистрирован: 23.10.2014

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

 

int SensorHum = A0;  
int Hvcc = 7;
int currentHum = 0; //текущее значение Hum
int lastHum = 0; //предыдущее значение Hum

int meteringCounter = 0; //счетчик измерений
int meteringAmount = 10; //сколько раз мерять
long meteringInterval = 100; //интервал измерений
long previousMillis = 0; 

long previousMillis_2 = 0; 
long IntervalMillis = 2000;

void setup(){
  Serial.begin(9600);
  pinMode(Hvcc, OUTPUT); 
  digitalWrite(Hvcc, LOW);
}
int tempHum = 0; //временная переменная
void loop(){
  unsigned long currentMillis = millis();
  if((currentMillis - previousMillis >= meteringInterval) && meteringCounter < meteringAmount){
    meteringCounter++; //прибавляем счетчик
    previousMillis = currentMillis;
    digitalWrite(Hvcc, HIGH);
    tempHum += analogRead(SensorHum);  
  } else if(meteringCounter==meteringAmount){ //проверяем если достигли конца счетчика
    meteringCounter=0; //сбрасываем счетчик в 0
    lastHum = currentHum; //присваиваем предыдущему значению Hum текущее значение Hum
    currentHum = tempHum/meteringAmount; //обновляем текущее значение (делим временную переменную на кол-во измерений)
    tempHum=0; //сбрасываем временную переменную в 0
  }
  //Выводим значение в Serial если прошло 2 секунды и текущее значение Hum не равно предыдущему значению Hum
  if((currentMillis - previousMillis_2 >= IntervalMillis) && currentHum != lastHum){
    previousMillis_2 = currentMillis;
    Serial.print("currentHum=");
    Serial.println(currentHum);
  }
}

 

Marlen S
Offline
Зарегистрирован: 13.01.2015

bwn пишет:

Да, обратно в LOW забыли перевести.

В таком плане? 


unsigned long currentMillis1 = millis();
  if(currentMillis1 - previousMillis1 > interval1)
  { 
    previousMillis1 = currentMillis1;
    digitalWrite(Hvcc, HIGH);
    delay(1500); 
    Hum = analogRead(SensorHum); 
    digitalWrite(Hvcc, LOW);
  }

А что Вы имели ввиду int-ы ? #define что ли?  Замерив ток оказалось, что он тянет на 173-176ma. Остаеться только через транзистор или нержавеющие спицы. 

Marlen S
Offline
Зарегистрирован: 13.01.2015

2009Shef пишет:

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

 

int SensorHum = A0;  
int Hvcc = 7;
int currentHum = 0; //текущее значение Hum
int lastHum = 0; //предыдущее значение Hum

int meteringCounter = 0; //счетчик измерений
int meteringAmount = 10; //сколько раз мерять
long meteringInterval = 100; //интервал измерений
long previousMillis = 0; 

long previousMillis_2 = 0; 
long IntervalMillis = 2000;

void setup(){
  Serial.begin(9600);
  pinMode(Hvcc, OUTPUT); 
  digitalWrite(Hvcc, LOW);
}
int tempHum = 0; //временная переменная
void loop(){
  unsigned long currentMillis = millis();
  if((currentMillis - previousMillis >= meteringInterval) && meteringCounter < meteringAmount){
    meteringCounter++; //прибавляем счетчик
    previousMillis = currentMillis;
    digitalWrite(Hvcc, HIGH);
    tempHum += analogRead(SensorHum);  
  } else if(meteringCounter==meteringAmount){ //проверяем если достигли конца счетчика
    meteringCounter=0; //сбрасываем счетчик в 0
    lastHum = currentHum; //присваиваем предыдущему значению Hum текущее значение Hum
    currentHum = tempHum/meteringAmount; //обновляем текущее значение (делим временную переменную на кол-во измерений)
    tempHum=0; //сбрасываем временную переменную в 0
  }
  //Выводим значение в Serial если прошло 2 секунды и текущее значение Hum не равно предыдущему значению Hum
  if((currentMillis - previousMillis_2 >= IntervalMillis) && currentHum != lastHum){
    previousMillis_2 = currentMillis;
    Serial.print("currentHum=");
    Serial.println(currentHum);
  }
}

 

 

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

P.S. Я пытался добится именно этого) этого кода :)

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

Вместо int я имел в виду byte или const byte, последнее лучше. Нержавеющие спицы ток не снизят, так что транзисторный ключ. Не думал, что эта зараза столько жрет.

Ну а 2009Shef вместо просто задержки, сделал по методу усреднения + снял нагрузку с блока вывода(не выводит не потому что сухо, а потому что не меняется значение) . Изучайте))).

Marlen S
Offline
Зарегистрирован: 13.01.2015

bwn пишет:

Вместо int я имел в виду byte или const byte, последнее лучше. Нержавеющие спицы ток не снизят, так что транзисторный ключ. Не думал, что эта зараза столько жрет.

Ну а 2009Shef вместо просто задержки, сделал по методу усреднения + снял нагрузку с блока вывода(не выводит не потому что сухо, а потому что не меняется значение) . Изучайте))).

На счет int я просто не на сколько познал програмирование, что бы ставить const byte (вернее еще толком не понимаю куда и когда ставить). На счет нержавеющих спиц, я просто могу давать отдельное питание на сам датчик (объединив gnd) постоянно, но думаю это будет излише? Значит буду делать через транзистор. А вот на счет тока сам был удивлен...

Изучаем :)))))  

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

Я и сам месяца четыре как вспоминаю и изучаю. Типы переменных лучше сразу привыкать ставить подходящие. Пинов у вас 20 штук и все положительные, а вы применяете от -32767 до 32767, смысл? Const - не даст вам изменить номер пина или значение переменной.

Marlen S
Offline
Зарегистрирован: 13.01.2015

bwn пишет:

Я и сам месяца четыре как вспоминаю и изучаю. Типы переменных лучше сразу привыкать ставить подходящие. Пинов у вас 20 штук и все положительные, а вы применяете от -32767 до 32767, смысл? Const - не даст вам изменить номер пина или значение переменной.

Не совсем понял про переменные, когда и в каких местах ставить сразу подходящие (нужны примеры, практика), да я использую пока что меньше 20 пинов на плате (4 реле(2,3,4,5), 1 датчик ds18b20(10) и А0 влажность почвы).

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

#define DS1307_I2C_ADDRESS 0x68
byte decToBcd(byte val)
{
  return ( (val/10*16) + (val%10) );
}
byte bcdToDec(byte val)
{
  return ( (val/16*10) + (val%16) );
}
void setDateDs1307(byte second,        // 0-59
byte minute,        // 0-59
byte hour)          // 0-99
{
  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.write(0);
  Wire.write(decToBcd(second));    
  Wire.write(decToBcd(minute));
  Wire.write(decToBcd(hour));     
  Wire.endTransmission();
}
void getDateDs1307(byte *second,
byte *minute,
byte *hour)
{
  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.write(0);
  Wire.endTransmission();
  Wire.requestFrom(DS1307_I2C_ADDRESS, 3);
  *second     = bcdToDec(Wire.read());
  *minute     = bcdToDec(Wire.read());
  *hour       = bcdToDec(Wire.read());  
}

LiquidCrystal_I2C lcd(0x27,16,2);
char incomingByte; 

OneWire oneWire(10); 
DallasTemperature sensors(&oneWire); 
DeviceAddress tempDeviceAddress;  
float temp1=0; 
int setTmp=24; 
long previousMillis1 = 0; 
long interval1 = 1000; 
//*******************************
int SensorHum = A0;  
int currentHum = 0; //текущее значение Hum
int lastHum = 0; //предыдущее значение Hum
int meteringCounter = 0; //счетчик измерений
int meteringAmount = 10; //сколько раз мерять
long meteringInterval = 100; //интервал измерений
long previousMillis = 0;
long previousMillis_2 = 0; 
long IntervalMillis = 10000;
//*******************************
int On_Time=0;
int Off_Time=0;
int Curent_Time=0;

int Relay_1 = 2; // R1 - Свет
int Relay_2 = 3; // R2 - Вентиляция
int Relay_3 = 4; // R3 - 
int Relay_4 = 5; // R4 - 

void setup(){

  Wire.begin();
  Serial.begin(9600);
  lcd.init();
  lcd.backlight();
  Serial.println("Controller: ON \n");
  delay(1000);
  lcd.clear();
  lcd.setCursor(8, 0);
  lcd.print("|");
  lcd.setCursor(8, 1);
  lcd.print("|");

  sensors.begin();
  sensors.getAddress(tempDeviceAddress, 0);
  sensors.setResolution(12);

  pinMode(Relay_1, OUTPUT); 
  pinMode(Relay_2, OUTPUT);  
  pinMode(Relay_3, OUTPUT); 
  pinMode(Relay_4, OUTPUT); 

  digitalWrite(Relay_1, LOW);
  digitalWrite(Relay_2, LOW);
  digitalWrite(Relay_3, HIGH);
  digitalWrite(Relay_4, HIGH);
}

int tempHum = 0; //временная переменная

void loop(){

  byte second, minute, hour;
  getDateDs1307(&second, &minute, &hour);
  lcd.setCursor(0,0);
  if (hour < 10) {
    lcd.print ("0");
    lcd.print (hour);
  } 
  else {
    lcd.print (hour);
  }
  lcd.print(":"); 
  if (minute < 10) {
    lcd.print ("0");
    lcd.print (minute);
  } 
  else {
    lcd.print (minute);
  } 
  lcd.print(":");
  if (second < 10) {
    lcd.print ("0");
    lcd.print (second);
  } 
  else {
    lcd.print (second);
  }

  //************************************************************
  On_Time=(6*60+01)-1; 
  Off_Time=(23*60+59)-1;  
  Curent_Time=hour*60+minute;
  if(On_Time < Off_Time)
  {
    if (Curent_Time >= On_Time && Curent_Time <= Off_Time)
    {
      digitalWrite(Relay_1, LOW);
      lcd.setCursor(9, 0);
      lcd.print("R1+");      
    }
    else
    {
      digitalWrite(Relay_1, HIGH);
      lcd.setCursor(9, 0);
      lcd.print("R1-");
    }
  }
  else
  {
    if ((Curent_Time >= On_Time && Curent_Time <= 2820)||(Curent_Time >= 0 && Curent_Time <= Off_Time))
    {
      digitalWrite(Relay_1, LOW);
      lcd.setCursor(9, 0);
      lcd.print("R1+");
    }
    else
    {
      digitalWrite(Relay_1, HIGH);
      lcd.setCursor(9, 0);
      lcd.print("R1-");
    }
  }
  //************************************************************
  unsigned long currentMillis = millis();
  if(currentMillis - previousMillis1 > interval1)
  { 
    previousMillis1 = currentMillis; 
    sensors.setWaitForConversion(false);
    sensors.requestTemperatures();
    sensors.setWaitForConversion(true);
    sensors.getAddress(tempDeviceAddress, 0);
    temp1=sensors.getTempC(tempDeviceAddress);
    lcd.setCursor(0, 1);
    lcd.print(temp1);
    lcd.setCursor(5, 1);
    lcd.print(" C+");
  }
  if (temp1>=setTmp)
  {
    digitalWrite(Relay_2, LOW);
    lcd.setCursor(13, 0);
    lcd.print("R2+");
  }
  if (temp1<setTmp)
  {
    digitalWrite(Relay_2, HIGH);
    lcd.setCursor(13, 0);
    lcd.print("R2-");
  }
  //************************************************************
  if((currentMillis - previousMillis >= meteringInterval) && meteringCounter < meteringAmount){
    meteringCounter++; //прибавляем счетчик
    previousMillis = currentMillis;
    tempHum += analogRead(SensorHum);  
  } 
  else if(meteringCounter==meteringAmount){ //проверяем если достигли конца счетчика
    meteringCounter=0; //сбрасываем счетчик в 0
    lastHum = currentHum; //присваиваем предыдущему значению Hum текущее значение Hum
    currentHum = tempHum/meteringAmount; //обновляем текущее значение (делим временную переменную на кол-во измерений)
    tempHum=0; //сбрасываем временную переменную в 0
  }
  //Выводим значение в Serial если прошло 2 секунды и текущее значение Hum не равно предыдущему значению Hum
  if((currentMillis - previousMillis_2 >= IntervalMillis) && currentHum != lastHum)
  {
    previousMillis_2 = currentMillis;
    Serial.print("Hum = ");
    Serial.println(currentHum);
  }
  //************************************************************
  if (Serial.available() > 0) 
  {
    incomingByte = Serial.read()-48;
    if(incomingByte == 1)
    {
      Serial.print("Temp: "); 
      Serial.print(temp1);
      Serial.println(" *C");
      Serial.print("Time: ");
      if (hour < 10) {
        Serial.print ("0");
        Serial.print (hour);
      } 
      else 
      {
        Serial.print(hour);
      }
      Serial.print(":"); 
      if (minute < 10) 
      {
        Serial.print ("0");
        Serial.print (minute);
      } 
      else 
      {
        Serial.print (minute);
      } 
      Serial.print(":");
      if (second < 10) 
      {
        Serial.print ("0");
        Serial.println (second);
      } 
      else
      {
        Serial.println (second);
      } 
      Serial.print(F("Core: "));
      Serial.print(GetTemp(),1);
      Serial.println("  *C");
    }
    if(incomingByte == 2)
    {
      if(currentHum <=450)
      {
        Serial.print("Water Full = ");
        Serial.println(currentHum);
      }
      else if( currentHum > 450 && currentHum < 700)
      {
        Serial.print("Water *** = ");
        Serial.println(currentHum);
      }
      else 
      {
        Serial.print("Water Low = ");
        Serial.println(currentHum);
      }
    }
    if(incomingByte == 3)
    {
      int Val = !digitalRead(Relay_3);
      digitalWrite(Relay_3, Val);
      lcd.setCursor(9, 1);
      lcd.print( Val ? "R3-" : "R3+" );
      Serial.println( Val ? "Relay_3 OFF" : "Relay_3 ON" );
    } 
    if(incomingByte == 4)
    {
      int Val = !digitalRead(Relay_4);
      digitalWrite(Relay_4, Val);
      lcd.setCursor(13, 1);
      lcd.print( Val ? "R4-" : "R4+" );
      Serial.println( Val ? "Relay_4 OFF" : "Relay_4 ON" );
    } 
  }
}
//************************************************************
double GetTemp(void)
{
  unsigned int wADC;
  double t;
  // Set the internal reference and mux.
  ADMUX = (_BV(REFS1) | _BV(REFS0) | _BV(MUX3));
  ADCSRA |= _BV(ADEN);  // enable the ADC
  delay(20);            // wait for voltages to become stable.
  ADCSRA |= _BV(ADSC);  // Start the ADC
  // Detect end-of-conversion
  while (bit_is_set(ADCSRA,ADSC));
  // Reading register "ADCW" takes care of how to read ADCL and ADCH.
  wADC = ADCW;
  // The offset of 324.31 could be wrong. It is just an indication.
  t = (wADC - 324.31 ) / 1.22;
  // The returned temperature is in degrees Celcius.
  return (t);
}

Извиняюсь что нет комментариев,  но мне без куда более удобней.

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

Все объявления пинов - cost byte  они нкогда не будут отрицательными и не превысят значение 254.

Все ваши переменные типа currentMillis - unsigned long иначе при переполнении счетчика переменная уйдет в отрицательные значения и начнутся чудеса.

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

например у вас температура объявлена как float, если не планируете мерять отрицательные значения и десятые градуса, можете объявить ее byte.

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

byte занимает 1байт в памяти, int - два, long и float - четыре.

А комментами зря пренебрегаете, через два месяца сами не вспомните чего нашкодили.

 

Marlen S
Offline
Зарегистрирован: 13.01.2015

bwn пишет:

Все объявления пинов - cost byte  они нкогда не будут отрицательными и не превысят значение 254.

Все ваши переменные типа currentMillis - unsigned long иначе при переполнении счетчика переменная уйдет в отрицательные значения и начнутся чудеса.

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

например у вас температура объявлена как float, если не планируете мерять отрицательные значения и десятые градуса, можете объявить ее byte.

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

byte занимает 1байт в памяти, int - два, long и float - четыре.

А комментами зря пренебрегаете, через два месяца сами не вспомните чего нашкодили.

 

Как я Вас понял, что лучше  всегда пины контактов объявлять через cost byte вместо int. Просто я писал стандартно как указано в примерах :( 

unsigned long с этим я не понял, что Вы имели ввиду :( А вот на счет типа переменных я уже понял что играет роль тип. 

На счет измерения float я об этом думал как избавится от десятых градуса (от ненадобности) но Вы мне пролили свет :) Спасибо!

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

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

P.S Я бы и содрал у кого то код и не парился) но мной движет познание) по этому делаю сам с приведенных примеров.  

 

 

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

unsigned long с этим я не понял, что Вы имели ввиду

long это знаковая переменная, unsigned long беззнаковая - принмающая только положительные значения и при переполнении начиная снова с 0. Знаковая при положительном переполнении станет не 0, а отрицательным значением. Там цифири большие, на память не напишу. Для примера знаковый int от -32767 до 32767. Беззнаковый от 0 до 65535.