11 svi Oaza
Tehnička škola Ruđera Boškovića Vinkovci
Oaza je projekt za sve ljubitelje životinja koje zahtijevaju posebne uvjete staništa. Namijenjeno je najviše teraristima i onima koji imaju egzotične životinje koje teško preživljavaju naše uobičajene uvjete. U terariju očitavamo temperaturu, vlagu u zraku, temperaturu grijane točke, vlažnost podloge, količinu vode u posudi i najvažnije da li su nam vrata terarija otvorena, da ne bi životinja slučajno pobjegla (jako važno ako imate krhke ili potencijalno opasne životinje).
Na temelju očitanja radimo korekcije mikroklime kako bi se što bolje približili idealnim vrijednostima za životinju koju imamo. Parametre klime možemo sami ubaciti u kod ili postaviti negdje na webu odakle bi se učitali prilikom spajanja na internet.
Na prvoj fotografiji vidimo grijač podloge koji grije samo jednu stranu terarija. Na podlozi je temperaturna sonda otporna na tekućinu i vanjske uvjete, tako da ne može smetati životinji. S desne strane imamo senzor vlage u zemlji, važno kasnije za usporedbu relativne vlage zraka, jer natapanjem zemlje možemo povećati kod grijača relativnu vlagu zraka. Sve će to biti pokriveno supstratom, odnosno podlogom tako da neće biti ni vidljivo.
Pumpu smo izradili na 3D printeru u školi. Radi se o peristaltičkoj pumpi koja koristi koračni (step) motor za pumpanje vode kroz cjevčicu. Pumpa je s lijeve strane, bijelo kućište. Kablovi su malo neuredni, no sve je vidljivo kako je spojeno. Ekran nam očitava cijelo vrijeme vrijednosti senzora, tako da znamo što se događa unutar terarija cijelo vrijeme.
Aplikacija služi za nadzor i davanje nekoliko osnovnih naredbi. Imamo veliki ekran koji pokazuje očitane vrijednosti kao i ekran na terariju. Gumb “Sljedeca vrijednost” za listanje. Zatim gumbovi “Vrata” za otvaranje i zatvaranje, gumb “dosipaj vodu” koji aktivira pumpu da doda vodu u posudu, gumb “Svjetlo” koji pali/gasi svjetlo i gumb “Grijac” koji pali/gasi grijač.
Odakle početi sa spajanjem… Idemo metodom kazaljke na satu: Temperaturna sonda je spojena na napajanje i digitalni pin, no morali smo koristiti otpornik za premostiti visoki napon i digitalni ulaz. Gumb je normalno spojen na pin koji omogućava prekidni način rada, tako da neovisno o radu ostalih komponenti, on može odraditi zadanu naredbu. Hallov senzor služi da detektira magnet na vratima da znamo kad su otvorena ili zatvorena. Nismo našli komponentu u programu, pa je korištena dioda za simbol, no naznačeno u komentaru o čemu se radi. Pošto je već bila na maloj pločici s otpornicima, nije bilo potrebe dodavati dodatno otpornike koje bi trebali kao i s temperaturnom sondom. Relej smo jednostavno spojili s jedne strane na pločicu za kontrolu, s druge strane prema grijaču i utičnici s 220V da se pali/gasi. DHT senzor je isto na svojoj pločici s otpornicima, pa preko digitalnog pina možemo očitati sve vrijednosti. LCD smo spojili preko I2C sklopa, ne bi nikako imali dovoljno digitalnih pinova da to nismo napravili. Koračni, odnosno step motor na slici je reprezentativan. Koristili smo ta 4 pina za spajanje na steper kontroler. To nam je motor koji koristimo za vodenu pumpu. Senzor razine vode nam je u posudi s vodom. Spojen je na Vcc napon i analogni pin, jer mjerimo vrijednost obzirom na očitanje analognog pina. Ventilator je prikazan DC motorom (opet nedostatak simbola u Fritzing-u). Tu je bilo problema, morali smo koristiti tranzistorsku sklopku jer je ventilator 5V, a MKR je 3.3V. Gate je spojen na PWM pin, pa time iako nije PWM ventilator, možemo zbog brzine rada tranzistorske sklopke regulirati brzinu vrtnje DC motora. LED rasvjeta je spojena sljedeća. Svjetleće diode su spojene paralelno, no i taj spoj je spojen serijski na otpornik da ne bi slučajno pregorjele zbog većeg napona. Sljedeći je senzor vlage, koji je isto analogni senzor. Spajamo ga tako da mu dovodimo referentni napon, te pin za očitavanje stanja stavljamo na analogni ulaz. Zadnji je beskonačni servo koji služimo za otvaranje i zatvaranje vrata s njegovim okretajima. Spaja se direktno kontrolni kontakt s mikroupravljačem i naravno moramo mu dovesti referentno napajanje.
#define BLYNK_PRINT /*
#pragma region Biblioteke
//Biblioteke za korištenje ekrana
#include
#include
#include
//Biblioteke za DHT senzor
#include
#include
//Potrebno za DS18B20 senzor temperature:
#include
#include
//biblioteka za servo motor korišten za otvaranje/zatvaranje vrata
#include
//blynk biblioteke
#define BLYNK_PRINT SerialUSB
#include
#include
#include
#include
#include
#pragma endregion
#pragma region Inicijalizacije_elemenata
//blynk auth token
char auth[] = “f818571615004b44bbebe6fac664f5ef”;
// WiFi postavke
char ssid[] = “Stojka”;
char pass[] = “Nemasifre123”;
//za pristup posebnom web serveru
int status = WL_IDLE_STATUS;
//za pristup lokalnom server na laptopu, lagano se kasnije zamjeni za neku domensku adresu
//Važno da kad radimo upite, da se cijelo vrijeme odnosi na Terarij 1. S strane servera moguće ih je imati koliko god želimo
const char* host = “http://192.168.1.23/Terarij/1”;
WiFiClient wificlient;
HttpClient httpclient;
// Inicijalizacijski dio ekrana
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
// Inicijalizacijski dio za senzor temperature i vlage
DHT tempvlaga(14, DHT11);
//Inicijalizacija temepraturne sonde DS18B20
OneWire oneWire(0);
DallasTemperature sensors(&oneWire);
//Osvjetljenje na pin 13, trenutno spojene LED diode, no moguće je spojiti relej za upravljanje IC i UVB lampama
#define OSVJETLJENJE 13
#define GUMB_OSVJETLJENJA 5 //mora biti interuptibilni pin
bool upaljeno_svjetlo = false;
//Pin releya za grijač podloge
#define GRIJAC 1
//Ventilator za vađenje zraka (PWM pin za regulaciju pošto je istosmjerni DC ventilator. Korištena tranzistorska sklopka jer je 5V ventilator
#define VENTILATOR 2
//Provjera da li su vrata otvorena pomoću Hallovog senzora
#define SENZOR_VRATA 3
//Pin za servo motor otvaranja-zatvaranja vrata
#define MOTOR_VRATA 4
Servo servoVrata;
//Senzor vode Analogni pin 6
#define VODOMJER A6
//Senzor vlage podloge na analognom pinu 6
#define VLAGA_PODLOGE A5
//declaracija varijabli za servo pumpe
int motorPin1 = 6; // 28BYJ48 pin 1
int motorPin2 = 7; // 28BYJ48 pin 2
int motorPin3 = 8; // 28BYJ48 pin 3
int motorPin4 = 9; // 28BYJ48 pin 4
int motorSpeed = 800; // brzina stepera
int count = 0; // brojač koraka stepera
int countsperrev = 512; // broj koraka za puni okret od 360 stupnjeva
int lookup[8] = { B01000, B01100, B00100, B00110, B00010, B00011, B00001, B01001 };
// Pozicije u poljima za očitane vrijednosti
#define TEMPERATURA 0
#define RELATIVNA_VLAGA 1
#define TEMPERATURA_TLA 2
#define RAZINA_VODE 3
#define VLAZNOST_TLA 4
#define VRATA 5
// Polja za pomoć prilikom ispisa
String mjerenaVelicina[] = { “Temperatura”,”Relativna vlaga”,”Temperatura tla”,”Razina vode”,”Vlaznost tla”,”Vrata” };
String mjerenaJedinica[] = { “C”,”%”,”C”,”mm”,”%”,””, };
// Polje za ciljane vrijednosti koje moramo dobiti i vrijednosti koje smo pročitali
float ciljaneVrijednosti[] = { 24,60,29,40,1 };
float ocitaneVrijednosti[] = { 0, 0, 0, 0, 0 };
#pragma endregion
#pragma region Arduino_funkcije
void setup()
{
Serial.begin(9600);
// spajanje na wifi mrežu… zaglavi u beskonačnu petlju dok se ne spoji
while (status != WL_CONNECTED) {
status = WiFi.begin(ssid, pass);
//sačekaj 10 sekundi da se spoji
delay(10000);
}
//Očitavanje svih potrebnih ciljanih vrijednosti s lokalnog servera
for (int i=0;i<6;i++){
if (wificlient.connect(host, 80)) {
String poziv = “GET “;
wificlient.println(“GET /” +mjerenaVelicina[i] + “HTTP/1.1”);
ciljaneVrijednosti[i]= wificlient.readString().toFloat();
wificlient.stop();
}
}
delay(2000);
// inicijalizacija lcd ekrana
lcd.begin(16, 2);
lcd.backlight();
// inicijalizacija dht senzota
tempvlaga.begin();
//Osvjetljenje
pinMode(OSVJETLJENJE, OUTPUT);
pinMode(GUMB_OSVJETLJENJA, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(GUMB_OSVJETLJENJA), paligasi, FALLING);
//Grijač
pinMode(GRIJAC, OUTPUT);
//ventilator
pinMode(VENTILATOR, OUTPUT);
//vrata
pinMode(SENZOR_VRATA, INPUT);
servoVrata.attach(MOTOR_VRATA);
// deklaracija pinova motora koje koristimo za izlaz
pinMode(motorPin1, OUTPUT);
pinMode(motorPin2, OUTPUT);
pinMode(motorPin3, OUTPUT);
pinMode(motorPin4, OUTPUT);
//početak blynk aplikacije
Blynk.begin(auth, ssid, pass);
}
void loop()
{
Serial.println(“Čitanje vrijednosti senzora”);
temp_i_vlaga();
vlaga_podloge();
temp_grijane_tocke();
razina_vode();
vrata();
//akcije potrebene za dolazak do ciljanih vrijednosti (na koje možemo utjecati)
//temperatura zraka, možemo samo s ventilatorom vući topal zrak ako treba smanjiti temperaturu. Da ne bi ozljedili životinju, važnije nam je regulirati temperaturu tla da ne opečemo životinju
if (ocitaneVrijednosti[TEMPERATURA] <= ciljaneVrijednosti[TEMPERATURA]) hladjenje(0);
else hladjenje((ocitaneVrijednosti[TEMPERATURA] – ciljaneVrijednosti[TEMPERATURA]) / 5);
//Temperaturu tla održavamo stalnom, no pošto je velika masa i veliki grijač, kontroliramo putem releja
if (ocitaneVrijednosti[TEMPERATURA_TLA] < ciljaneVrijednosti[TEMPERATURA_TLA]) grijac(true);
else grijac(false);
//Razina vode iz pojilišta, ako je preniska, onda aktiviramo pumpu da doda vodu. pratimo da ne padne ispod minimuma
if (ocitaneVrijednosti[RAZINA_VODE] < ciljaneVrijednosti[RAZINA_VODE]) pumpaj();
svjetlo(true);
//cikliranje vrijednosti na ekranu da se može na licu mjesta vidjeti stanje
ekran();
//blynk nakon svega, prednost ima fizički hardware i automatske postavke 🙂
Blynk.run();
}
#pragma endregion
#pragma region Osvjetljenje
//Paljenje i gašenje osvjetljenja
void svjetlo(bool pali) {
if (pali) digitalWrite(OSVJETLJENJE, HIGH);
else digitalWrite(OSVJETLJENJE, LOW);
}
//finkcija za paljenje i gašenje led dioda, poziva se kao interupt na gumbu
void paligasi() {
upaljeno_svjetlo = !upaljeno_svjetlo;
svjetlo(upaljeno_svjetlo);
}
#pragma endregion
//ispis vrijednosti na ekran i njegovo listanje
void ekran() {
// Ispis podatka
for (int i=0; i<6; i++) { // Reset ekrana lcd.clear(); lcd.home(); lcd.setCursor(0, 0); lcd.print(mjerenaVelicina[i]); lcd.setCursor(0, 1); if (i == 5) { //prikaz otvorenosti vrata if (ocitaneVrijednosti[i] == 0) lcd.print(“Otvorena”); else lcd.print(“Zatvorena”); } else lcd.print(String(ocitaneVrijednosti[i]) + ” ” + mjerenaJedinica[i]); //pauza prebacivanja vrijednosti delay(2000); } } #pragma region Temperatura i vlaga //Paljenje i gašenje grijača void grijac(bool pali) { if (pali) digitalWrite(GRIJAC, HIGH); else digitalWrite(GRIJAC, LOW); } //Paljenje i gašenje grijača void grijac(bool pali) { if (pali) digitalWrite(GRIJAC, HIGH); else digitalWrite(GRIJAC, LOW); } //funkcija za ventilator void hladjenje(float razina) { if (razina >= 1) digitalWrite(VENTILATOR, HIGH);
else if (razina <= 0) digitalWrite(VENTILATOR, LOW);
else analogWrite(VENTILATOR, (int)(razina * 255));
}
// Funkcija očitavanja temperature i vlage zraka
void temp_i_vlaga() {
float h = tempvlaga.readHumidity();
ocitaneVrijednosti[RELATIVNA_VLAGA] = h;
float t = tempvlaga.readTemperature();
ocitaneVrijednosti[TEMPERATURA] = t;
}
void temp_grijane_tocke() {
//Sonda mjeri vrijednost od -55 do 125
sensors.requestTemperatures();
float val = sensors.getTempCByIndex(0);
Serial.print(“Temperaturna sonda: “);
Serial.println();
ocitaneVrijednosti[TEMPERATURA_TLA] = val;
}
//očitavanje vlažnosti tla
void vlaga_podloge() {
int senzorvlage = analogRead(VLAGA_PODLOGE);
ocitaneVrijednosti[VLAZNOST_TLA] = (float)senzorvlage / 1024.0 * 100;
}
#pragma endregion
#pragma region Voda i pumpa
//očitavanje razine vode
void razina_vode() {
int val = analogRead(VODOMJER);
ocitaneVrijednosti[RAZINA_VODE] = (float)val / 1024.0*5.0;
}
//pumpanje vode u posudu s tekućinom
void pumpaj() {
//okreni pumpu 10 okretaja
for (int i = 0; i<countsperrev*10; i++) for (int i = 7; i >= 0; i–)
{
setOutput(i);
delayMicroseconds(motorSpeed);
}
}
void setOutput(int out)
{
digitalWrite(motorPin1, bitRead(lookup[out], 0));
digitalWrite(motorPin2, bitRead(lookup[out], 1));
digitalWrite(motorPin3, bitRead(lookup[out], 2));
digitalWrite(motorPin4, bitRead(lookup[out], 3));
}
#pragma endregion
#pragma region Vrata
//Provjera senzora vrata
void vrata() {
ocitaneVrijednosti[VRATA] = (float)(digitalRead(SENZOR_VRATA));
}
//otvaranje vrata
void otvori_vrata() {
vrata();
if (ocitaneVrijednosti[VRATA] > 0) {
//pokreni servo
servoVrata.write(60);
delay(5000);
//servo radi 5 sekundi i onda se zaustavlja
servoVrata.write(90);
}
else {
//vrata su već otvorena!
return;
}
}
//zatvaranje vrata
void zatvori_vrata() {
vrata();
if (ocitaneVrijednosti[VRATA] < 1) {
//pokreni servo
servoVrata.write(120);
//servo mora raditi dokle god ne očitamo da je zatvoreno
while (true) {
vrata();
if (!ocitaneVrijednosti[VRATA] < 1) break;
}
//zaustavi servo
servoVrata.write(90);
}
else {
//vrata su već zatvorena!
return;
}
}
#pragma endregion
Arduino program ovoga projekta možete preuzeti ovdje.
Projekt su izradili Sara Stojanović i Karla Blažević uz mentorstvo Danijela Pobija iz Tehničke škole Ruđer Bošković Vinkovci.
Projekt je prijavljen na temu: Internet of Things: Kućni ljubimci i domaće životinje.