Умный террариум
- Войдите на сайт для отправки комментариев
Всем добрый день
У меня появилась необходимость сделать умный террариум для змеи ей как оказалось нужны очень четкие параметры температуры и влажности в течении дня и световой день должен быть с рассветом и закатом, а то из за это го она у меня ничего не ест приходится носить в магазин где ее насильно кормят
Вот думаю сделать регулятор температуры, влажности и освещения на базе ардуиноСам в этом мало пока разбираюсь (пока изучение на уровне поморгать диодом на 13 порте )
Если у кого есть идеи прошу поделиться
Из устройств есть блок реле, датчик температуры и влажности DHT 22, дисплей 16х2, и часы реального времени, ну и мелочевка всякая там типам транзисторов, резисторов, конденсаторов.
Если кто готов написать код за разумную плату готов даже заплатить (правда я не знаю сколько это будет стоить и как сложен код)
я обязательно с вами свяжусь
Еще есть желающие помочь готов даже оплатить работу
Вы как то не понятно себя ведете, я так и не понял нужно вам террариум автоматизировать или нет...
Если вам нужно готовое решение, то нужно поинтересоваться сколько это будет стоить, сроки, что да как и т.д. и т.п., тогда ваше даже готов не катит.
Хотите просто помощи - выкладывайте сюда описание, фото, видео, схемы, код. Задавайте конструктивные вопросы, высказывайте свои предположения и решения. Многие откликнутся и в том числе я.
А так что бы кто-то за вас посидел 2-5 деньков за монитором и потом сказал: "вот на! готово! пользуйся!" ну подождите еще, может и такие найдутся.
предлагаю вам посмотреть наработку человека на МК AVR
Вы как то не понятно себя ведете, я так и не понял нужно вам террариум автоматизировать или нет...
Если вам нужно готовое решение, то нужно поинтересоваться сколько это будет стоить, сроки, что да как и т.д. и т.п., тогда ваше даже готов не катит.
Хотите просто помощи - выкладывайте сюда описание, фото, видео, схемы, код. Задавайте конструктивные вопросы, высказывайте свои предположения и решения. Многие откликнутся и в том числе я.
А так что бы кто-то за вас посидел 2-5 деньков за монитором и потом сказал: "вот на! готово! пользуйся!" ну подождите еще, может и такие найдутся.
Спасибо вам огромное за помошь в плавном мегании светодиодной сборкой.
А кактит или не катит это уже не из этой оперы. я просто написал что готов оплатить разработку порраммы для террариума, так как сам посидев несколько вечеров не разобрался, видимо это не мое вот и написал.
предлагаю вам посмотреть наработку человека на МК AVR
Спасибо огромное буду разбираться что к чему
#include <DHT.h> #include <DS1307.h> // Подключаем библиотеку управления модулем реального времени #include <LiquidCrystalExt.h> // Подключаем библиотеку управления экраном #include <LineDriver.h> // Далее вспомогательные библиотеки для реализации интерфейса SPI #include <SPI.h> #include <SPI_Bus.h> #include <Wire.h> #include <EEPROM.h> // Подключаем библиотеку для работы с энергонезависимой памятью #define DHTPIN 9 // Считывающий пин с датчика #define DHTTYPE DHT22 // Модель датчика #define tPIN 7 // Пин управления температурой #define hPIN 6 // Пин управления влажностью #define lPIN 8 // Пин управления светом #define sdPIN 5 // Пин управления светодиодной лентой #define switchPIN_1 4 // Кнопка №1 "MODE" #define switchPIN_2 3 // Кнопка №2 "+" #define switchPIN_3 2 // Кнопка №2 "_" DHT dht(DHTPIN, DHTTYPE); // Создаем объект dht int tStatus = HIGH; // определяем переменную, отвечающую за состоянеие нагревателя HIGH=выкл, LOW=вкл int tempDay; // Декларируем переменную, которая будет хранить желаемую температуру int tempNight = tempDay-1; // Желаемая ночная температура в градусах Цельсия int hStatus = HIGH; // определяем переменную, отвечающую за состоянеие увлажнителя HIGH=выкл, LOW=вкл int humDay; // Декларируем переменную, которая будет хранить желаемую влажность int humNight = humDay+1; // Желаемая ночная влажность int DaySt; // Декларируем переменную, которая будет хранить желаемую времени начала дня int DayFin; // Декларируем переменную, которая будет хранить желаемую времени конца дня int LightOn; // Декларируем переменную, которая будет хранить желаемую времени начала полудня int LightOff; // Декларируем переменную, которая будет хранить желаемую времени конца полудня int edit = 0; // Переменную будем использовать для определения режима редактирования long last_micros = 0; // Вспомогательная переменная, используется для определения сколько микросекунд прошло после предыдущей операции int lastButton1 = LOW; // Предыдущее состояние кнопки №1 int currentButton1 = LOW; // Текущее состояние кнопки №1 int lastButton2 = LOW; // Предыдущее состояние кнопки №2 int currentButton2 = LOW; // Текущее состояние кнопки №2 int lastButton3 = LOW; // Предыдущее состояние кнопки №3 int currentButton3 = LOW; // Текущее состояние кнопки №3 SPI_Bus shreg(_8bit, 10); // Подключаем сдвиговый регистр LiquidCrystal lcd(1, 2, 3, 4, 5, 6, &shreg, 7); // Инициализируем дисплей void setup() // инициализация основных данных { Serial.begin(9600); // Инициализируем COM-порт dht.begin(); // Инициализируем датчик pinMode(tPIN, OUTPUT); // Определяем пин для управления температурой как Вывод pinMode(hPIN, OUTPUT); pinMode(lPIN, OUTPUT); pinMode(sdPIN, OUTPUT); tempDay = EEPROM.read(1); // Получаем параметр из первой ячейки if (tempDay == 255) tempDay = 26; // Если ячейка пуста, т.е. ее значение = 255, то устанавливаем параметр температуры в значение по умолчанию, вданном случае 26С. humDay = EEPROM.read(3); // Получаем параметр из 3 ячейки DaySt = EEPROM.read(9); // Получаем параметр из 9 ячейки if (DaySt == 255) DaySt = 8; // Если ячейка пуста, то установим параметр в 8 DayFin = EEPROM.read(10); // Получаем параметр из 10 ячейки if (DayFin == 255) DayFin = 21; // Если ячейка пуста, то установим параметр в 21 LightOn = EEPROM.read(11); // Получаем параметр из 11 ячейки if (LightOn == 255) LightOn = 11; // Если ячейка пуста, то установим параметр в 11 LightOff = EEPROM.read(12); // Получаем параметр из 12 ячейки if (LightOff == 255) LightOff = 18; // Если ячейка пуста, то установим параметр в 18 pinMode(switchPIN_1, INPUT); // Устанавливаем тип контакта Кнопки №1 как Вход pinMode(switchPIN_2, INPUT); // Устанавливаем тип контакта Кнопки №2 как Вход pinMode(switchPIN_3, INPUT); // Устанавливаем тип контакта Кнопки №3 как Вход lcd.begin(12,2); // устанавливаем размеры экрана } void loop() // зацикливание (код управляющей программы) { static unsigned long lastTime = 0; // Декларируем переменную и устанавливаем ее начальное значение в 0 if (millis() - lastTime > 3000) // Не используем в данном случае задержку Delay, т.к. это приведет к запаздыванию нажатий кнопок { lastTime = millis(); } Switch(); if (Serial.available() > 0) SetTime(); // Если на COM-порт поступила информация, то изменим системное время float h = dht.readHumidity(); // Считываем влажность float t = dht.readTemperature(); // Считываем температуру int Hour = RTC.get(DS1307_HR,true); // Получаем значение текущего часа int Minute = RTC.get(DS1307_MIN,false); int Second = RTC.get(DS1307_SEC,false); int Date = RTC.get(DS1307_DATE,false); int Mon = RTC.get(DS1307_MTH,false); int Ye = RTC.get(DS1307_YR,false); boolean Day = (Hour >= DaySt & Hour <DayFin); // Если текущий час находится в промежутке от DaySt до DayFin, то действуют дневные параметры boolean Light = (Hour >= LightOn & Hour < LightOff); // Если текущий час находится в промежутке от LightOn до LightOff, то действуют полуденные параметры tStatus = (t < ((Day) ? tempDay : tempNight)) ? LOW:HIGH; // Если температура меньше желаемой, то статус обогревателя=Вкл, в противном случае Выкл digitalWrite(tPIN, tStatus); if (h < ((Day) ? humDay : humNight)) hStatus = LOW; else hStatus = HIGH; // Если влажность меньше желаемой, то статус увлажнителя=Вкл, в противном случае Выкл digitalWrite(hPIN, hStatus); digitalWrite(lPIN, (Light) ? HIGH:LOW); // Если полуденное время, то включим подсветку if (Hour==LightOn-1) analogWrite(sdPIN, map(Minute, 0, 59, 0, 255)); else if (Hour==LightOff) analogWrite(sdPIN, map(Minute, 0, 59, 255, 0)); else analogWrite(sdPIN, (Light) ? 255:0); lcd.setCursor(0,0); // устанавливаем курсор для вывода времени lcd.print(addZero(Hour));lcd.print(":");lcd.print(addZero(Minute));lcd.print(":");lcd.print(addZero(Second)); //Выводим время lcd.setCursor(0,9);lcd.print((tStatus == LOW) ? "+":" "); // Выводим индикатор работы подогрева lcd.setCursor(1,0); // устанавливаем позицию курсора на экране (на один символ правее левого нижнего угла) lcd.print("T:");lcd.print(t, 1); lcd.print("C "); lcd.setCursor(12,0); lcd.print("H:");lcd.print(h, 1); lcd.print("%"); // Выводим информацию о климате } void SetTime() // установка времени из шаблона tчч:мм { if (Serial.read() == 't') // Если первый символ t, то установим указанное время { int h = (Serial.read() - '0') * 10 + (Serial.read() - '0'); Serial.read(); int m = (Serial.read() - '0') * 10 + (Serial.read() - '0'); Serial.read(); int D = (Serial.read() - '0') * 10 + (Serial.read() - '0'); Serial.read(); int M = (Serial.read() - '0') * 10 + (Serial.read() - '0'); Serial.read(); int Y = (Serial.read() - '0') * 10 + (Serial.read() - '0'); RTC.stop(); RTC.set(DS1307_SEC,0); //set the seconds RTC.set(DS1307_MIN,m); //set the minutes RTC.set(DS1307_HR,h); //set the hours RTC.set(DS1307_DATE,D); //set the date RTC.set(DS1307_MTH,M); //set the month RTC.set(DS1307_YR,Y); //set the year RTC.start(); } Serial.flush(); } String addZero(int val) { if (val<10) return "0" + String(val);else return String(val); } void Switch() { if (millis() - last_micros >= 300) // Производим опрос кнопок каждую треть секунды, это необходимо, чтобы избежать повторных выполнений кода в следствие дребезга контактов { last_micros = millis(); currentButton1 = digitalRead(switchPIN_1); // Считываем текущее состояние кнопки №1 currentButton2 = digitalRead(switchPIN_2); // Считываем текущее состояние кнопки №2 currentButton3 = digitalRead(switchPIN_3); // Считываем текущее состояние кнопки №3 if (lastButton1 == LOW && currentButton1 == HIGH) // Если Кнопка №1 изменила состояние на Нажатие { long t_millis = millis(); // Фиксируем начальное время нажатие кнопки, чтобы определить, не была ли она зажата while (digitalRead(switchPIN_1) == HIGH && millis() - t_millis <= 2000 && edit==0) {} // Пока кнопка зажата не даем программе двигаться дальше if (millis() - t_millis > 2000) // Если кнопка была нажата дольше 2-х секунд, то переведем состояние в режим программирования { edit = 1; lcd.clear();lcd.setCursor(1, 1); lcd.print("TempD:"); lcd.print(tempDay); lcd.print("C");lcd.print(" edit"); } // Иначе отрабатываем короткое нажатие при различных условиях else if (edit==1) { edit = 3; lcd.clear();lcd.setCursor(1, 1); lcd.print("Humid:");lcd.print(humDay); lcd.print("%");lcd.print(" edit");} // Если программа была в режиме изменения первого параметра, переведем ее на изменение 3 параметра else if (edit==8) { edit = 9; lcd.clear();lcd.setCursor(1, 1); lcd.print("DaySt:");lcd.print(DaySt); lcd.print(" edit");}//Если программа была в режиме изменения 8 параметра, переведем ее на изменение 9 параметра else if (edit==9) { edit = 10; lcd.clear();lcd.setCursor(1, 1); lcd.print("DayFin:");lcd.print(DayFin); lcd.print(" edit");}//Если программа была в режиме изменения 9 параметра, переведем ее на изменение 10 параметра else if (edit==10) { edit = 11; lcd.clear();lcd.setCursor(1, 1); lcd.print("LightOn:");lcd.print(LightOn); lcd.print("edit");}// Если программа была в режиме изменения 10 параметра, переведем ее на изменение 11 параметра else if (edit==11) { edit = 12; lcd.clear();lcd.setCursor(1, 1); lcd.print("LightOff:");lcd.print(LightOff); lcd.print("edit");}// Если программа была в режиме изменения 11 параметра, переведем ее на изменение 12 параметра else if (edit==12) // Если программа была в режиме изменения 8 параметра, переведем ее в штатный режим и сохраним параметры в энергонезависимую память { edit = 0; lcd.clear(); EEPROM.write(1, tempDay); // Запимываем параметр температуры в 1-ю ячейку памямти EEPROM.write(3, humDay); EEPROM.write(9, DaySt); EEPROM.write(10, DayFin); EEPROM.write(11, LightOn); EEPROM.write(12, LightOff); } else {}; // Если программа не была в режиме редактирования, то можно выполнить тоже какое-то действие, для этого в фигурных скобках необходимо описать его функционал } if (currentButton2 == HIGH && edit != 0) // Если нажата Кнопка №2, при состоянии редактирования параметров то... { if (edit == 1) // ...если режим изменения температуры { lcd.clear(); lcd.setCursor(1, 1); lcd.print("TempD:"); lcd.print(tempDay); lcd.print("C +"); tempDay = (tempDay == 35) ? 10:(tempDay+1); } else if (edit == 3) // ...если режим изменения влажности { lcd.clear(); lcd.setCursor(1, 1); lcd.print("Humid:"); lcd.print(humDay); lcd.print("% +"); humDay = (humDay == 95) ? 20:(humDay+1); } else if (edit == 9) // ...если режим изменения DaySt { lcd.clear(); lcd.setCursor(1, 1); lcd.print("DaySt:"); lcd.print(DaySt); lcd.print(" + "); DaySt = (DaySt == 23) ? 0:(DaySt+1); } else if (edit == 10) // ...если режим изменения DayFin { lcd.clear(); lcd.setCursor(1, 1); lcd.print("DayFin:"); lcd.print(DayFin); lcd.print(" + "); DayFin = (DayFin == 23) ? 0:(DayFin+1); } else if (edit == 11) // ...если режим изменения LightOn { lcd.clear(); lcd.setCursor(1, 1); lcd.print("LightOn:"); lcd.print(LightOn); lcd.print(" + "); LightOn = (LightOn == 23) ? 0:(LightOn+1); } else if (edit == 12) // ...если режим изменения LightOff { lcd.clear(); lcd.setCursor(1, 1); lcd.print("LightOff:"); lcd.print(LightOff); lcd.print(" + "); LightOff = (LightOff == 23) ? 0:(LightOff+1); } } else if (lastButton2 == LOW && currentButton2 == HIGH) // Если было короткое нажатие на Кнопку №2 не в режиме редактирования, то можно выполнить какое либо действие, если описать его в фигурных скобках ниже { } if (currentButton3 == HIGH && edit != 0) // Если нажата Кнопка №3, при состоянии редактирования параметров то... { if (edit == 1) // ...если режим изменения температуры { tempDay = (tempDay == 10) ? 35:(tempDay-1); lcd.clear(); lcd.setCursor(1, 1); lcd.print("TempD: "); lcd.print(tempDay); lcd.print("C -"); } else if (edit == 3) // ...если режим изменения влажности { humDay = (humDay == 20) ? 95:(humDay-1); lcd.clear(); lcd.setCursor(1, 1); lcd.print("Humid:"); lcd.print(humDay); lcd.print("% -"); } else if (edit == 9) // ...если режим изменения DaySt { lcd.clear(); lcd.setCursor(1, 1); lcd.print("DaySt:"); lcd.print(DaySt); lcd.print(" - "); DaySt = (DaySt == 0) ? 23:(DaySt-1); } else if (edit == 10) // ...если режим изменения DayFin { lcd.clear(); lcd.setCursor(1, 1); lcd.print("DayFin:"); lcd.print(DayFin); lcd.print(" - "); DayFin = (DayFin == 0) ? 23:(DayFin-1); } else if (edit == 11) // ...если режим изменения LightOn { lcd.clear(); lcd.setCursor(1, 1); lcd.print("LightOn:"); lcd.print(LightOn); lcd.print(" - "); LightOn = (LightOn == 0) ? 23:(LightOn-1); } else if (edit == 12) // ...если режим изменения LightOff { lcd.clear(); lcd.setCursor(1, 1); lcd.print("LightOff:"); lcd.print(LightOff); lcd.print(" - "); LightOff = (LightOff == 0) ? 23:(LightOff-1); } } else if (lastButton3 == LOW && currentButton3 == HIGH) // Если было короткое нажатие на Кнопку №3 не в режиме редактирования, то можно выполнить какое либо действие, если описать его в фигурных скобках ниже {} lastButton1 = currentButton1; // Запоминаем предыдущее значение Кнопки №1 lastButton2 = currentButton2; // Запоминаем предыдущее значение Кнопки №2 lastButton3 = currentButton3; // Запоминаем предыдущее значение Кнопки №23 } }Не могу понять что к чему ? попытался оптимизировать код но на экране абракадабра изначально был написан код для экрана 20х4 а у меня 16х2 и еще вопрос как правильно дожны быть подключены кнопки для меню
у вас экран 16*2
а вы устанавливаете
lcd.begin(12,2);// устанавливаем размеры экранаеще меня смущает объявление библиотеки экрана
#include <LiquidCrystalExt.h> // Подключаем библиотеку управления экраномПо кнопка я бы посоветовал бы почитать форум, но на вскидку варианты:
1) кнопка на каждый пин (если окнечно есть свободные)
2) кнопки через регистр сдвига
3) кнопки шлейфом через сопротивления и отслеживать нажатие по изменению напряжения (у меня такое работает не стабильно)
#include <LiquidCrystalExt.h
эта библиотека у меня работает с дисплеем со сдвиговым регистром без нее не куда
А про экран спасибо не заметил делал в динадцатом часу ночи ))
а по поводу кнопок подтяжку надо делать ? или нет ?
про библу не могу сказать, т.к. у самого используется сдвиговый регистр и подключение через него дисплея по 3ем проводам к ардуино...вот тут я боролся с подключением...в итоге вроде как поборол, но кириллицу использовать не получилось :(
я то же долго с мучался с подключением )
про кирилицу я пока даже и не думаю пока бы собрать все устройстро а потом причесывать )