Не понятно... как одно от другого зависит
- Войдите на сайт для отправки комментариев
Всем привет.
Не могу понять в чем проблема. Железо простое, все работает. понимаю, что-то в программе, а вот что....???
Итак имеется - UNO, LCD 16x2, шилд на 4 реле на 5 В, кнопка с фиксатором на анлоговом входе A1 (земля при нажатии, +5В через 2 кОм), 2 датчика температуры, часы, датчик влажности DHT22.
Все работает. На экран все выводится, что хотел. От одного датчика температуры, при срабатывании порога, включается реле.
Пр нажатии на кнопку - включается второе реле.
Вот сам скетч:
// Подключение необходимых библиотеки #include <Wire.h> #include "RTClib.h" #include <OneWire.h> #include <DallasTemperature.h> #include <DHT.h> // Датчик (или датчики) температуры подключается к пину "3" Ардуины #define ONE_WIRE_BUS 3 // Датчик влажности подключають к пину 2 Ардуины #define DHTPIN 2 #define DHTTYPE DHT22 DHT dht(DHTPIN, DHTTYPE); // настройка «onewire» для работы с любыми другими девайсами (не только Dallas датчиками температуры) OneWire oneWire(ONE_WIRE_BUS); // подключаем Dallas Temperature. DallasTemperature sensors(&oneWire); #include <LiquidCrystal.h> LiquidCrystal lcd(9, 8, 7, 6, 5, 4); int reading; // назначение переменной int Temp_1=LOW; int u=0; // назначение 2-й переменной для датчика уровня int v=0; // назначение 3-й переменной для охлаждения воды int Relay1 = 11; // вентилятор охлаждения назначаем 11-й выход int Relay2 = 10; // кнопка, назначаем 10-й выход RTC_DS1307 RTC; void setup () { lcd.begin(16, 2); Wire.begin(); RTC.begin(); sensors.begin(); dht.begin(); // инициализация датчика // pinMode(A0, INPUT); // настраиваем аналоговый вход A0 pinMode(A1, INPUT); // настраиваем аналоговый вход A1 // назначаем на 10-м и 11-м пинах (пины реле) низкий уровень pinMode(Relay1, OUTPUT); digitalWrite(Relay1, LOW); pinMode(Relay2, OUTPUT); digitalWrite(Relay2, LOW); if (! RTC.isrunning()) { lcd.setCursor(0, 0); lcd.print("RTC no time"); //RTC.adjust(DateTime(__DATE__, __TIME__)); } } // Вывод на экран текущего времени и температуры void LCD_Time() { DateTime now = RTC.now(); sensors.requestTemperatures(); // запрос показаний температуры float h = dht.readHumidity(); // запрос показаний влажности // float t = dht.readTemperature(); // управление исполнительным реле { u=analogRead(A1); // значение «u» равно аналоговому входу A1 if (u<5) // при срабатывании датчика уровня, на выходе 4 устанавливается высокий уровень { digitalWrite(Relay2, HIGH); } else if (u>=30) // при срабатывании датчика уровня, на выходе 4 устанавливается низкий уровень { digitalWrite(Relay2, LOW); } } // управление вентилятором охлаждения по температуре { v=sensors.getTempCByIndex(1); // переменной "v" присваивается темп. 1-го датчика (Т воды) reading = digitalRead(Relay1); Temp_1 = reading; if (v>=28) // если температура поднимается до 28 градусов, срабатывает реле на вентилятор охлаждения { digitalWrite(Relay1, HIGH); } else if ((Temp_1 == HIGH) && (v < 27)) // если температура опускается до 27 градусов, вентилятор выключается { digitalWrite(Relay1, LOW); } } { lcd.setCursor(0, 0); if(now.hour()<10){lcd.print("0");} lcd.print(now.hour(), DEC); lcd.print(":"); if(now.minute()<10){lcd.print("0");} lcd.print(now.minute(), DEC); // lcd.print(":"); // if(now.second()<10){lcd.print("0");} // lcd.print(now.second(), DEC); // lcd.print(" "); lcd.setCursor(9, 0); lcd.print("T="); lcd.print(sensors.getTempCByIndex(0),1); // получение данных температуры от 1-го датчика lcd.print("C"); //lcd.setCursor(0, 1); //lcd.print("Arina"); lcd.setCursor(0, 1); lcd.print("H="); lcd.setCursor(3, 1); lcd.print(h,1); lcd.print("%\t"); //lcd.print("%"); lcd.setCursor(8, 1); lcd.print(" "); lcd.setCursor(9, 1); lcd.print("A="); lcd.setCursor(11, 1); lcd.print(sensors.getTempCByIndex(1),1); // получение данных температуры от 2-го датчика lcd.print("C"); } } void loop () { if ( ( millis() % 2000 ) == 0 ) //вызов функции раз в 2 сек. { LCD_Time(); } }
А вот проблема в следующем:
Когда температура больше 28 град. срабатывает реле, а также температура в пределах от 27 до 28 град. - т.е. на на 11 выходе высокий уровень - на кнопку UNO не реагирует(( На кнопку начинает реагировать, т.е. на 10 вых. HIGH - только тогда, когда температура ниже 27 гр. и на 11 вых. - LOW/
Я просто не понимаю...
Мне кажется, что ищите соплю. А вот компота в коде много, начиная от переменных, таящих в себе грабли (присваивать типу int бинарное значение LOW).
Непонятны строки 88-89 и последующее использование Temp_1. Если температура ниже 27, то и так запишется LOW, если оно уже там записано при повторной записи ничего не изменится, что вы спокойно используете в строках 91-94.
И уж если взялись выносить код в отдельные функции, не лепите все в одну. Считывание и отображение времени это одно, температура и ее обработка другое. Сам бы выделил отдельно и кнопку с влажностью, с вызовом либо последовательно, либо из другой функции. Для отладки много легче.
bwn, присваивать int переменной значение LOW не наказуемо, всё нормально, а вот использовать int для такой переменной - пустой расход ресурсов. 88, 89 - тоже пустая трата ресурсов (места).
А вот сравнение в loop: ((millis() % 2000) == 0) можно легко пропустить вызов LCD_Time. Дались вам всем эти %. Считайте дельту и не парьтесь. Будет точно надежней и точно не пропустите вызовы LC_Time.
analogRead(A1), почему бы не использовать digitalRead(A1)? К тому же зачем такое значение 5 (после чтения analogRead(A1)) для сравнения, если тупо посчитать 1024 - 5В, то 5 - это примерно 24мВ (вроде правильно посчитал :), для чего так жестко 0 зажимать? Не, ну дело Ваше, конечно. Да вроде у Вас есть еще цифровые пины, если есть сомнения. Хотя бы для отладки перекиньте кнопку на цифровой пин, вместо Ваших уровней 5 и 30 (это 24мВ и 146мВ). Зачем такой узкий коридор? Дребезг не страшит?
Короче, сначала разобраться с millis, чтобы срабатывало четко, потом с кнопкой, вот тогда можно будет остальное посмотреть.
PS Форматируйте исходники в ArduinoIDE, нажмите просто Ctrl-T и всё будет намного читабельней.
bwn, присваивать int переменной значение LOW не наказуемо, всё нормально, а вот использовать int для такой переменной - пустой расход ресурсов. 88, 89 - тоже пустая трата ресурсов (места).
kisoft, я ведь и не сказал, что так нельзя. Мне кажется, что столь вольное обращение с числовыми переменными в начале пути, способствует дополнительной каше в голове. ИМХО.
bwm, ну не знаю, я проблемы в этом не вижу. Было бы правильней описать byte Temp_1 = LOW;, а не int.
Ок, какие другие варианты? byte Temp_1 = true? (ужас) byte Temp_1 = 1; (еще ужасней). Переменная Temp_1 используется для хранения значения, полученного из digitalRead, а он возвращает что? HIGH или LOW и никаких других значений. Значит переменная должна быть беззнаковым байтом, т.е. byte или uint8_t (и никаких unsigned char).
kisoft, убедили )))) То, что не пользуешь сам, не значит неправильно. Как то ни разу не требовалось таким образом присвоить значение, а в сравнении всегда применял x!=0 или x==0.
Не пинайте, сам учусь))).
bwn, а я попинаю ;) Шучу.
Давайте рассмотрим исходник digitalRead
Здесь видно, что возвращается int (приплыли, видно по каким то религиозным причинам, либо по историческим, хватило бы и uint8_t, впрочем, может быть это для камней не 8 битных тоже) и возвращаться могут всего два значения LOW или HIGH и никак иначе. Что такое LOW & HIGH, это можно найти в Arduino.h, а именно:
Да, формально можно использовать 0 и 1, однако правильней использовать именно те константы, которые возвращает функция digitalRead, т.е. LOW & HIGH. И в сравнениях использовать тоже только эти два значения LOW или HIGH.
Вообще это вопрос философии каждого программиста и каждый решает эти вопросы сам, исходя из опыта и граблей, по которым он ходил.
Разумеется я сам иногда косячу, отклоняясь от своего убеждения, так что..
PS А вообще я не идеален и проповедую здесь всего лишь свою философию, делюсь своим опытом и ни в коем случае не навязываю :)
PPS А еще, при сравнении пишите сначала константу, потом переменную, как я уже говорил, будет меньше ошибок типа if(var = 0) вместо правильного if(val == 0), а есть напишешь if(0 = val), то компилятор выругается, что позволит исправить эту ошибку, а не удивляться, почему это у меня сранение работает неправильно?!
PPPS И вообще, программирование - это тяжелый труд, куча стандартов, постоянные обновления стандартов, короче, дурдом и единого стиля или букваря, как правильно - нет, точнее таких букварей море :)
kisoft, спасибо за разъяснения, по исходникам - так глубоко еще не влез, нынче уровень офортранненного бейсика в переложении на С++, буду потихоньку разбираться. )))