Умный террариум

aleksjetav
Offline
Зарегистрирован: 23.11.2012

Всем добрый день 

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

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

Если у кого есть идеи прошу поделиться 

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

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

 

 

 

maksim
Offline
Зарегистрирован: 12.02.2012
скайп: maksimkstovo1985

 

aleksjetav
Offline
Зарегистрирован: 23.11.2012

я обязательно с вами свяжусь 

 

aleksjetav
Offline
Зарегистрирован: 23.11.2012

Еще есть желающие помочь готов даже оплатить работу

maksim
Offline
Зарегистрирован: 12.02.2012

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

Хотите просто помощи - выкладывайте сюда описание, фото, видео, схемы, код. Задавайте конструктивные вопросы, высказывайте свои предположения и решения. Многие откликнутся и в том числе я.

А так что бы кто-то за вас посидел 2-5 деньков за монитором и потом сказал: "вот на! готово! пользуйся!" ну подождите еще, может и такие найдутся.

vworld
vworld аватар
Offline
Зарегистрирован: 26.09.2011

предлагаю вам посмотреть наработку человека на МК AVR

aleksjetav
Offline
Зарегистрирован: 23.11.2012

maksim пишет:

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

Хотите просто помощи - выкладывайте сюда описание, фото, видео, схемы, код. Задавайте конструктивные вопросы, высказывайте свои предположения и решения. Многие откликнутся и в том числе я.

А так что бы кто-то за вас посидел 2-5 деньков за монитором и потом сказал: "вот на! готово! пользуйся!" ну подождите еще, может и такие найдутся.

Спасибо вам огромное за помошь в плавном мегании светодиодной сборкой. 

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

aleksjetav
Offline
Зарегистрирован: 23.11.2012

vworld пишет:

предлагаю вам посмотреть наработку человека на МК AVR

 

Спасибо огромное буду разбираться что к чему

aleksjetav
Offline
Зарегистрирован: 23.11.2012
#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 

}  

} 

 

aleksjetav
Offline
Зарегистрирован: 23.11.2012

Не могу понять что  к чему ? попытался оптимизировать код но на экране абракадабра изначально был написан код для экрана 20х4 а у меня 16х2 и еще вопрос как правильно дожны быть подключены кнопки для меню 

 

vworld
vworld аватар
Offline
Зарегистрирован: 26.09.2011

у вас экран 16*2

а вы устанавливаете lcd.begin(12,2); // устанавливаем размеры экрана

еще меня смущает объявление библиотеки экрана #include <LiquidCrystalExt.h> // Подключаем библиотеку управления экраном

По кнопка я бы посоветовал бы почитать форум, но на вскидку варианты:

1) кнопка на каждый пин (если окнечно есть свободные)

2) кнопки через регистр сдвига

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

aleksjetav
Offline
Зарегистрирован: 23.11.2012

#include <LiquidCrystalExt.h

эта библиотека у меня работает с дисплеем со сдвиговым регистром без нее не куда 

А про экран спасибо не заметил делал в динадцатом часу ночи )) 

а по поводу кнопок подтяжку надо делать ? или нет ? 

 

 

vworld
vworld аватар
Offline
Зарегистрирован: 26.09.2011

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

aleksjetav
Offline
Зарегистрирован: 23.11.2012

я то же долго с мучался с подключением ) 

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