Pametni BoX

Gimnazija Požega

Ideja projekta je automatizirati box psa (također se može koristiti i za bilo koju drugu životinju). Kontroliranje je moguće putem Blynk aplikacije te putem Web stranice. Box sadrži sisteme za: hranu, vodu, svjetlo, hlađenje te kameru za sigurnost da je vaša životinja nahranjena. Prednost projekta je i brzina jer je za davanje 100g hrane potrebno samo 950ms, a za pola litre vode samo 5 sekundi.

Video snimka

Izrada projekta

Dio za hranu je najvažnija stvar projekta uz dio za vodu. Prednost ovakvog izbacivanja hrane je brzina i pouzdanost. (100g –> 950ms).
Opis:
Hrana kroz cijev pada do spirale (puža) i tu se zadržava. Ako pritisnete tipku za davanje hrane na Webu odnosno u Blynk aplikaciji pokreće se motor koji okreće spiralu. Hrana putuje spiralom te ispada. Spirala je 3D printana.

Prednost ovakvog davanja vode životinji je također brzina. Da bi se natočilo pola litre vode potrebno je svega 5 sekundi.
Opis:
Spremnik vode smješten je u pozadini. Za točenje vode zadužena je pumpa. Ako pritisnemo tipku za točenje vode pokreće se pumpa te toči 0.5L odnosno 1L vode. Jedna od prednosti je to što je nemoguće pretočiti posudu za vodu, odnosno nemoguće je da dođe do prelijevanja.

Kamera trenutno služi samo za sigurnost da je vaša životinja dobila hranu/vodu. Ako pritisnete tipku "Uslikaj!" kamera slika te se slika pohranjuje na SD karticu.

Svjetlo se pali putem Blynk aplikaciji ili Weba. Služi vam da biste i po mraku mogli vidjeti životinju ali isto tako kako bi i ona bolje vidjela.
Svjetlo je napravljeno tako da ne smeta radu kamere.

Ventilatori su napravljeni da se pale automatski, a služe za hlađenje.
Po ljetu za velikih vrućina vašoj životinji bude vruće jednako kao i vama te joj hlađenje ne bi bilo loše. Trenutno je isprogramirano da se ventilatori pale ako je temperatura veća od 35°C a gase tek kad temperatura padne ispod 35°C.

Mobilna aplikacija

Putem Blynk aplikacije moguće je nahraniti životinju, natočiti joj vode, upaliti svjetlo te vidjeti trenutnu temperaturu unutar kućice. Uz to može se vidjeti je li hlađenje trenutno upaljeno ili ugašeno. Blynk aplikacija također omogućuje obavještavanje putem mail-a ako je niska razina vode.

Kontroliranje putem weba omogućuje isto što i Blynk, napravljeno je isključivo radi mogućnosti izbora. Nekome će se više svidjeti Web dok će se nekome više svidjeti Blynk. Vi birate!

Ako je niska razina vode dolazi obavijest na mail kako biste znali da morate natočiti još vode.

Shema projekta

2 Arduino MKR1000 su spojena tako da serijski komuniciraju. Ako se spojite na Web i pritisnete tipku Arduino2 komunicira s Arduino1 koji onda pali/gasi pojedini dio. Ako pak pošaljete naredbu putem Blynk aplikacije odmah ju preuzima Arduino1 koji je zadužen za paljenje/gašenje svakog dijela. Izuzetak je Arduino UNO koji serijski ne komunicira s prethodna dva Arduina nego samo prima naredbu kada da napravi fotografiju i pohrani ju.

Shemu ovoga projekta možete preuzeti ovdje.

Arduino program

#define BLYNK_PRINT /*

//Ovaj program je prenesen na Arduino1 (FRITZING)

#define BLYNK_PRINT SerialUSB

#include 
#include 
#include 
#include 
#include 

int D0=0;
int D1=1;
int D2=2;
int D3=3;
int D4=4;
int D5=5;
int D6=6;
int D11=11;
int Motor=7;
int Pumpa=8;
int Svjetlo=9;
int Ventilatori=10;
int Kamera=12;
int DHT11=A0;
int WaterSensor=A1;
int oD0, oD1, oD2, oD3, oD4, oD5, oD6, oD11, oWS;
char data;
dht DHT;
WidgetLCD lcd(V0);

// Token BLYNK aplikacije
char auth[] = "dd77696f68284d23b3d9a5d2306cd16a";

// Postavke WiFi-a
char ssid[] = "BLYNK";    //Ime WiFi mreze
char pass[] = "PametniBoX";     //Sifra mreze

void setup()
{
  pinMode(D0, INPUT);
  pinMode(D1, INPUT);
  pinMode(D2, INPUT);
  pinMode(D3, INPUT);
  pinMode(D4, INPUT);
  pinMode(D5, INPUT);
  pinMode(D6, INPUT);
  pinMode(Motor, OUTPUT);
  pinMode(Pumpa, OUTPUT);
  pinMode(Svjetlo, OUTPUT);
  pinMode(Ventilatori, OUTPUT);
  pinMode(Kamera, OUTPUT);
  SerialUSB.begin(9600);
  Blynk.begin(auth, ssid, pass);
  Serial.begin(9600);
  Serial1.begin(9600);
}

void loop()
{
 Blynk.run();
 DHT.read11(DHT11); 
 oD0=digitalRead(D0); //Ocitanje tipke Hrana(125g)
 oD1=digitalRead(D1); //Ocitanje tipke Hrana(200g)
 oD2=digitalRead(D2); //Ocitanje tipke Hrana(300g)
 oD3=digitalRead(D3); //Ocitanje tipke Hrana(450g)
 oD4=digitalRead(D4); //Ocitanje tipke Voda(0.5L)
 oD5=digitalRead(D5); //Ocitanje tipke Voda(1L)
 oD6=digitalRead(D6); //Ocitanje tipke Svjetlo
 oD11=digitalRead(D11); //Ocitanje tipke Uslikaj!
 oWS=analogRead(WaterSensor);  //Ocitanje senzora vode

 lcd.print(0, 0, "Temperatura:");    
 lcd.print(13, 0, round(DHT.temperature));  //Ispisivanje temperature zraka na LCD-u BLYNK aplikacije
 lcd.print(15, 0, "C");

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Kontroliranje putem BLYNK aplikacije
 
 if((oD6)==0) {
  digitalWrite(Svjetlo, LOW);   //Svjetlo ugaseno ukoliko je tipka "SVJETLO" u BLYNK aplikaci OFF
 }
 if((oD6)==1) {
  digitalWrite(Svjetlo,HIGH);   //Svjetlo upaljeno ukoliko je tipka "SVJETLO" u BLYNK aplikaci ON
 }
 if((oD0)==1) {
  digitalWrite(Motor, HIGH);
  delay(1188);                  //Ukoliko je pritisnut gumb "Hrana" -> 125g pokreni motor te izbaci 125g hrane
  digitalWrite(Motor, LOW);
 }
 if((oD1)==1) {
  digitalWrite(Motor, HIGH);
  delay(1900);                  //Ukoliko je pritisnut gumb "Hrana" -> 200g pokreni motor te izbaci 200g hrane
  digitalWrite(Motor, LOW);
 }
 if((oD2)==1) {
  digitalWrite(Motor, HIGH);
  delay(2850);                  //Ukoliko je pritisnut gumb "Hrana" -> 300g pokreni motor te izbaci 300g hrane
  digitalWrite(Motor, LOW);
 }
 if((oD3)==1) {
  digitalWrite(Motor, HIGH);
  delay(4275);                  //Ukoliko je pritisnut gumb "Hrana" -> 450g pokreni motor te izbaci 450g hrane
  digitalWrite(Motor, LOW);
 }
 if((oD4)==1 && (oWS)<450) { digitalWrite(Pumpa, HIGH); delay(5000); //Ukoliko je pritisnut gumb "VODA" -> 0.5L pokreni pumpu te natoci 0.5L vode, pumpu je u tom trenutku moguce pokrenuti samo ako pokretanje nebi uzrokovalo prelijevanje vode
  digitalWrite(Pumpa, LOW);
 }
 if((oD5)==1 && (oWS)<200) { digitalWrite(Pumpa, HIGH); delay(10000); //Ukoliko je pritisnut gumb "VODA" -> 1L pokreni pumpu te natoci 1L vode, pumpu je u tom trenutku moguce pokrenuti samo ako pokretanje nebi uzrokovalo prelijevanje vode
  digitalWrite(Pumpa, LOW);
 }
 if((oD11)==1) {
  digitalWrite(Kamera, HIGH);
  delay(250);                  //Ukoliko je pritisnut gumb "USLIKAJ" -> slikanje te pohranjivanje na SD karticu (gumb USLIKAJ nije dodan u aplikaciji za sada, vrlo lako se moze dodati!)
  digitalWrite(Kamera, LOW);
 }
 if((oWS)<50) {
  Blynk.email ("PametniBoX@gmail.com", "Voda", "!!! Vrlo niska razina vode !!!");     //Ukoliko je razina vode vrlo niska obavijesti me na mailu
 }
 if((DHT.temperature)<35) { digitalWrite(Ventilatori, LOW); //Ukoliko je temperatura manja od 35 stupnjeva, hladjenje je ugaseno. lcd.print(0, 1, "Hladjenje: OFF"); } if((DHT.temperature)>35) {
  digitalWrite(Ventilatori, HIGH);    //Ukoliko je temperatura veca od 35 stupnjeva, pali se hladjenje!
  lcd.print(0, 1, "Hladjenje: ON.");
 }


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Kontroliranje s WEBa

if (Serial1.available()>0) {
  data = Serial1.read();        //Ocitanje ispisa drugog Arduina
  
 if(data == 'H') {
  digitalWrite(Svjetlo, LOW);   //Svjetlo ugaseno ukoliko je tipka SVJETLO na webu "OFF"
 }
 if(data == 'G') {
  digitalWrite(Svjetlo, HIGH);   //Svjetlo upaljeno ukoliko je tipka SVJETLO na webu "ON"
 }
 if(data == 'A') {
  digitalWrite(Motor, HIGH);
  delay(1188);                  //Ukoliko je pritisnut gumb "Hrana" -> 125g pokreni motor te izbaci 50g hrane
  digitalWrite(Motor, LOW);
 }
 if(data == 'B') {
  digitalWrite(Motor, HIGH);
  delay(1900);                  //Ukoliko je pritisnut gumb "Hrana" -> 200g pokreni motor te izbaci 200g hrane
  digitalWrite(Motor, LOW);
 }
 if(data == 'C') {
  digitalWrite(Motor, HIGH);
  delay(2850);                  //Ukoliko je pritisnut gumb "Hrana" -> 300g pokreni motor te izbaci 300g hrane
  digitalWrite(Motor, LOW);
 }
 if(data == 'D') {
  digitalWrite(Motor, HIGH);
  delay(4275);                  //Ukoliko je pritisnut gumb "Hrana" -> 450g pokreni motor te izbaci 450g hrane
  digitalWrite(Motor, LOW);
 }
 if(data == 'E' && (oWS)<450) { digitalWrite(Pumpa, HIGH); delay(5000); //Ukoliko je pritisnut gumb "VODA" -> 0.5L pokreni pumpu te natoci 0.5L vode, pumpu je u tom trenutku moguce pokrenuti samo ako pokretanje nebi uzrokovalo prelijevanje vode
  digitalWrite(Pumpa, LOW);
 }
 if(data == 'F' && (oWS)<200) { digitalWrite(Pumpa, HIGH); delay(10000); //Ukoliko je pritisnut gumb "VODA" -> 1L pokreni pumpu te natoci 1L vode, pumpu je u tom trenutku moguce pokrenuti samo ako pokretanje nebi uzrokovalo prelijevanje vode
  digitalWrite(Pumpa, LOW);
 }
 if(data == 'I') {
  digitalWrite(Kamera, HIGH);
  delay(250);                  //Slikanje te pohranjivanje na SD karticu
  digitalWrite(Kamera, LOW);
 }
}
}

//Hrana - 100g >> 950ms


Arduino program ovoga projekta možete preuzeti ovdje.

#define BLYNK_PRINT /*

//Ovaj program je prenesen na Arduino2 (FRITZING)
//Kontroliranje putem WEB aplikacije

#include 
#include 
#include 
#include 

char ssid[] = "WEB";               // Internet SSID (ime)
char pass[] = "PametniBoX";              // Internet sifra
int keyIndex = 0;              

int status = WL_IDLE_STATUS;
WiFiServer server(80);
///////////////////////////////////////////////////////////////////////////

int DHT11=A1;
dht DHT;

///////////////////////////////////////////////////////////////////////////

void setup() {
  Serial.begin(9600);
  Serial1.begin(9600);

  while (!Serial) {
    ; 
  }
  
  if (WiFi.status() == WL_NO_SHIELD) {
    Serial.println("WiFi stit nije prikazan");
    while (true);
  }

  Serial.print("Pristupna tocka: ");
  Serial.println(ssid);

  status = WiFi.beginAP(ssid);
  if (status != WL_AP_LISTENING) {
    Serial.println("Neuspjesno kreiranje pristupne tocke");
    while (true);
  }

  // Pricekaj 10 sekundi za povezivanje
  delay(10000);

  // Kreiraj web server na portu: 80
  server.begin();
  printWiFiStatus();
}

///////////////////////////////////////////////////////////////////////////

void loop() {
   DHT.read11(DHT11);

  // Usporedi prijasnji status sa sadasnjim statusom
  if (status != WiFi.status()) {
    status = WiFi.status();

    if (status == WL_AP_CONNECTED) {
      byte remoteMac[6];

      Serial.print("Uredaj spojen, MAC adresa: ");
      WiFi.APClientMacAddress(remoteMac);
      Serial.print(remoteMac[5], HEX);
      Serial.print(":");
      Serial.print(remoteMac[4], HEX);
      Serial.print(":");
      Serial.print(remoteMac[3], HEX);
      Serial.print(":");
      Serial.print(remoteMac[2], HEX);
      Serial.print(":");
      Serial.print(remoteMac[1], HEX);
      Serial.print(":");
      Serial.println(remoteMac[0], HEX);
    } else {

      Serial.println("Uredaj odspojen");
    }
  }
  
  WiFiClient client = server.available();  

  if (client) {                         
    Serial.println("Novi korisnik");     
    String currentLine = "";           
    while (client.connected()) {         
      if (client.available()) {          
        char c = client.read();             
        Serial.write(c);                   
        if (c == '\n') {                    

          if (currentLine.length() == 0) {
            client.println("HTTP/1.1 200 OK");
            client.println("Content-type:text/html");
            client.println();

            client.print("Pametni BoX 
");
            client.print(" 
");
            client.print("HRANA 125g 
");
            client.print("HRANA 200g 
");
            client.print("HRANA 300g 
");
            client.print("HRANA 450g 
");                               //Kreiranje web stranice te pravljenje tipki
            client.print(" 
");
            client.print("VODA 0.5L 
");
            client.print("VODA 1L 
");
            client.print(" 
");
            client.print("SVJETLO ON   OFF 
");
            client.print(" 
");
            client.print("Temperatura: ");
            client.print(round(DHT.temperature));
            client.print(" 
 ");
            client.print(" 
 ");
            client.print("Uslikaj!");
            

            client.println();
            break;
          }
          else {   
            currentLine = "";
          }
        }
        else if (c != '\r') {
          currentLine += c;      
        }

///////////////////////////////////////////////////////////////////////////

 // Provjeri status tipke te izvrsi radnje       
 if(currentLine.endsWith("GET /H")) {
  Serial1.write('H');                           //GET /H gasi svjetlo (PametniBoX1 program)
 }
 if(currentLine.endsWith("GET /G")) {
  Serial1.write('G');                          //GET /G pali svjetlo (PametniBoX1 program)   
 }
 if(currentLine.endsWith("GET /A")) {
  Serial1.write('A');
  delay(250);                           //GET /A daje 125g hrane (PametniBoX1 program)
  Serial1.write('N');
 }
 if(currentLine.endsWith("GET /B")) {
  Serial1.write('B');
  delay(250);                           //GET /B daje 200g hrane (PametniBoX1 program)                         
  Serial1.write('N');
 }
 if(currentLine.endsWith("GET /C")) {
  Serial1.write('C');
  delay(250);                           //GET /C daje 300g hrane (PametniBoX1 program)
  Serial1.write('N');
 }
 if(currentLine.endsWith("GET /D")) {
  Serial1.write('D');
  delay(250);                           //GET /D daje 450g hrane (PametniBoX1 program)
  Serial1.write('N');
 }
 if(currentLine.endsWith("GET /E")) {
  Serial1.write('E');
  delay(250);                           //GET /E daje 0.5L vode (PametniBoX1 program)
  Serial1.write('N');
 }
 if(currentLine.endsWith("GET /F")) {
  Serial1.write('F');
  delay(250);                           //GET /F daje 1L vode (PametniBoX1 program)
  Serial1.write('N');
 }
 if(currentLine.endsWith("GET /I")) {
  Serial1.write('I');
  delay(250);                           //Slikanje te pohranjivanje na SD karticu
  Serial1.write('N');
 }
    }
  }
    
    client.stop();
    Serial.println("Korisnik odspojen");
  }
}

///////////////////////////////////////////////////////////////////////////

void printWiFiStatus() {
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  IPAddress ip = WiFi.localIP();
  Serial.print("IP adresa: ");
  Serial.println(ip);
  
  long rssi = WiFi.RSSI();
  Serial.print("Jakost signala (RSSI):");
  Serial.print(rssi);
  Serial.println(" dBm");

  Serial.print("Link: http://");
  Serial.println(ip);

}

Arduino program ovoga projekta možete preuzeti ovdje.

#define BLYNK_PRINT /*

//Ovaj program je prenesen na Arduino3 (FRITZING)

#include 
#include 
#include 
#include   

#define chipSelect 4

#if ARDUINO >= 100
SoftwareSerial cameraconnection = SoftwareSerial(2, 3);
#else
NewSoftSerial cameraconnection = NewSoftSerial(2, 3);
#endif

Adafruit_VC0706 cam = Adafruit_VC0706(&cameraconnection);

int D1=1;
int oD1;    //Ocitanje pina 8 

void setup() {
#if !defined(SOFTWARE_SPI)
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
  if(chipSelect != 53) pinMode(53, OUTPUT); 
#else
  if(chipSelect != 10) pinMode(10, OUTPUT); 
#endif
#endif

  pinMode(D1, INPUT);
  Serial.begin(9600);
}


void loop() {
 oD1=digitalRead(D1); 

if ((oD1) == 1) {

  if (!SD.begin(chipSelect)) {
    Serial.println("Neuspjelo ocitavanje SD kartice");
    return;
  }  
  
  if (cam.begin()) {
    Serial.println("Kamera pronadena:");
  } else {
    Serial.println("Kamera nije pronadena");
    return;
  }
  char *reply = cam.getVersion();
  if (reply == 0) {
    Serial.print("Neuspjelo trazenje verzije");
  } else {
    Serial.println("-----------------");
    Serial.print(reply);
    Serial.println("-----------------");
  }

  // Velicina slika
  
  cam.setImageSize(VC0706_640x480);        // najveca
  //cam.setImageSize(VC0706_320x240);        // srednja
  //cam.setImageSize(VC0706_160x120);          // mala

  uint8_t imgsize = cam.getImageSize();
  Serial.print("Velicina slike: ");
  if (imgsize == VC0706_640x480) Serial.println("640x480");
  if (imgsize == VC0706_320x240) Serial.println("320x240");
  if (imgsize == VC0706_160x120) Serial.println("160x120");

  Serial.println("Slikam u 5 sekundi...");
  delay(5000);

  if (! cam.takePicture()) 
    Serial.println("Greska u slikanju");
  else 
    Serial.println("Uslikano!");
  
  char filename[13];
  strcpy(filename, "IMAGE00.JPG");
  for (int i = 0; i < 100; i++) { filename[5] = '0' + i/10; filename[6] = '0' + i%10; if (! SD.exists(filename)) { break; } } // Otvaranje datoteke File imgFile = SD.open(filename, FILE_WRITE); uint16_t jpglen = cam.frameLength(); Serial.print("Pohranjivanje "); Serial.print(jpglen, DEC); Serial.print(" bajtova slike."); int32_t time = millis(); pinMode(8, OUTPUT); byte wCount = 0; while (jpglen > 0) {
    uint8_t *buffer;
    uint8_t bytesToRead = min(32, jpglen); 
    buffer = cam.readPicture(bytesToRead);
    imgFile.write(buffer, bytesToRead);
    if(++wCount >= 64) { 
      Serial.print('.');
      wCount = 0;
    }
    jpglen -= bytesToRead;
  }
  imgFile.close();

  time = millis() - time;
  Serial.println("Uspjesno!");
  Serial.print(time); Serial.println(" ms potrosene na spremanje");
}
}

Arduino program ovoga projekta možete preuzeti ovdje.

Autori

Projekt su izradili Ivor Kakuk i Marin Francuz uz mentorstvo Sanje Grabusin iz Gimnazije Požega.

Projekt je prijavljen na temu: Internet of Things: Kućni ljubimci i domaće životinje.

Drugi projekti