Interaktivni miš za kućne ljubimce
Tehnička škola DaruvarIdeja nam je bila napraviti igračku miša koji bi bježao od mačke. Da bismo to ostvarili koristili smo 4 ultrazvučna senzora blizine i 2 kontinuirana servo motora. Senzori bi izračunali udaljenost od predmeta refleksije i zatim uz pomoć logike u kodu „miš“ odlučuje gdje će se kretati. Također se preko mobilnog uređaja može upravljati sa „mišem“ uz aplikaciju Blynk uz uvjet da je Arduino spojen na Internet tj. WiFi. Ispod presvlake „miša“ su postavljene mikro-sklopke koje se aktiviraju pritiskom na određene dijelove „miša“.
Video snimka
Izrada projekta
Arduino je usađen u pločicu preko socketa i na pločicu su nalemljeni ostali komponenti poput regulatora napona (7805) koji nam je potreban kako bi Arduino doveli konstantnih 5V. Ostali komponenti su punovalni ispravljač, koji nam jednostavno dopušta da bateriju spojimo obrnutog polaritet. Ostali komponenti su nalemljeni na žičice koje smo izvukli iz UTP kabela.
Mobilna aplikacija
Na “screenshot”-u su prikazane sve komande koje sadrži početni ekran u našoj aplikaciji. To uključuje joystick za upravljanje Arduina i 2 tipke za zujalicu i automatsku navigaciju.
Joystick widget nam daje 2 varijable. Svaka varijabla pripada X i Y osi pojedinačno. Zajedno daju nam točku u koordinatnom sustavu koja odgovara trenutnoj lokaciji joystick-a u aplikaciji. Zatim uz pomoć tih varijabli u kodu određujemo u kojem smjeru se korisnik želi kretati.
Tipka radi na toggle principu što znači da se tipka ne treba držati kako bi ostala u jednom stanju. Može se reći da je tipka bistabilna. Uz pomoć te tipke omogućujemo ili onemogućujemo automatsku navigaciju “miša”.
Shema projekta
Za napajanje Arduina koristimo 2 baterije 18650 koje idu na punovalni ispravljač koji služi samo da možemo spojiti baterije u bilo kojem polaritetu. Zatim se taj napon ispravlja na 5V. Za dvije svjetleće diode koristimo napajanje iz baterije pa koristimo tranzistor za napajanje. Ultrazvučni senzori su spojeni tako da im je trigger zajednički, a echo izlazi su svaki spojen na svoj ulaz u Arduino. Zujalica je također spojena preko napajanja baterije pa koristimo tranzistor za napajanje. Servo motori su spojeni također na bateriju a signal ulazi su spojeni na izlaze Arduina. Mikrosklopke su paralelno spojene tako da iako se jedna aktivira će se aktivirati.
Arduino program
#define #include #include // Autorizacijski kod za aplikaciju Blynk char auth[] = "76c58709e359487890ee11bee42e04b1"; // Podatci za WiFi char ssid[] = "Hotspotzabudale"; char pass[] = "lozinka1234"; //Blynk kontrolne varijable int stanjeGumba; int joystickX; int joystickY; int tipkaBuzzer; // Ultrazvucni senzor int trig = 10; //Ulazi za echo od senzora int echoFL = 6; int echoFR = 7; int echoBL = 8; int echoBR = 9; //Varijable za spremanje trajanja long trajanjeFL; long trajanjeFR; long trajanjeBL; long trajanjeBR; //Varijable za spremanje udaljenosti int udaljenostFL; int udaljenostFR; int udaljenostBL; int udaljenostBR; // Rep #include int randPos; int randDelay; //Deklariranje servo-a Servo rep; Servo servoL; Servo servoD; // Buzzer int buzzer = 5; int n; //Deklariranje izlaza za oci int oci = A3; // Microswitch int microswitch = 11; void setup() { //Pokretanje Serial Monitor-a Serial.begin(9600); //Deklariranje izlaza pinMode(oci,OUTPUT); pinMode(trig,OUTPUT); //Deklariranje ulaza pinMode(echoFL,INPUT); pinMode(echoFR,INPUT); pinMode(echoBL,INPUT); pinMode(echoBL,INPUT); //Spajanje servo-a na izlaze rep.attach(4); rep.write(90); servoL.attach(2); servoD.attach(3); //Postavljanje servo-a u stanje mirovanja servoL.write(90); servoD.write(90); // Buzzer pinMode(buzzer,OUTPUT); // Microswitch pinMode(microswitch,INPUT_PULLUP); //Oci analogWrite(oci, 255); //Povezivanje na WiFi Serial.println("Inicializacija uspjesna, povezivanje..."); Blynk.begin(auth, ssid, pass); Serial.println("Blynk spojen!"); Serial.println("Pocetak rada!"); } void loop() { Blynk.run(); //Govori Blynk library-u da provjeri dali korisnik nesto unosi preko aplikacije Buzzer(); //Poziva funckciju Buzzer repic(); //Poziva funkciju repic if (stanjeGumba == 1) //Ako je automatska navigacija ukljucena izvrsi sljedece { dohvatiSenzore(); //Pozivanje funkcije dohvatiSenzore //----- LOGIKA ZA AUTOMATSKO UPRAVLJANJE -----\\ while (udaljenostFL <= 30) //Dok je predmet refleksije udaljen za 20 od senzora cini slijedece... { Serial.println("Kontakt iza!"); //Ispis na Serial monitor servoD.write(20); //Pisemo na izlaze servo motora servoL.write(160); Buzzer(); //pozivamo funkciju Buzzer dohvatiSenzore(); //Pozivamo funkciju dohvatiSenzore Serial.print("udaljenostFL = "); Serial.println(udaljenostFL); } while (udaljenostBR <= 30) //Dok je predmet refleksije udaljen za 20 od senzora cini slijedece... { Serial.println("Kontakt naprijed!"); //Ispis na Serial monitor servoD.write(160); //Pisemo na izlaze servo motora servoL.write(20); Buzzer(); //Pozivamo funkciju Buzzer dohvatiSenzore(); //Pozivamo funkciju dohvatiSenzore Serial.print("udaljenostBR = "); Serial.println(udaljenostBR); } while (udaljenostBL <= 30) //Dok je predmet refleksije udaljen za 20 od senzora cini slijedece... { Serial.println("Kontakt desno!"); //Ispis na Serial monitor servoD.write(20); //Pisemo na izlaze servo motora servoL.write(20); Buzzer(); //pozivamo funkciju Buzzer dohvatiSenzore(); //Pozivamo funkciju dohvatiSenzore Serial.print("udaljenostBL = "); Serial.println(udaljenostBL); } while (udaljenostFR <= 30) //Dok je predmet refleksije udaljen za 20 od senzora cini slijedece... { Serial.println("Kontakt lijevo!"); //Ispis na Serial monitor servoD.write(160); servoL.write(160); Buzzer(); dohvatiSenzore(); Serial.print("udaljenostFR = "); Serial.println(udaljenostFR); } servoD.write(90); servoL.write(90); } //Ako automatska navigacija je ugasena onda kod ceka unos od korisnika } void repic() { //Generiramo nasumicni broj od 55 do 125 randPos = random(55, 125); //Na servo pisemo nasumicni broj i na toliko stupnjeva ce se servo okrenuti rep.write(randPos); //Nasumicni broj koji se koristi za kasnjenje kako bi pokreti izgledali nasumicni vise randDelay = random(250, 500); delay(randDelay); } void dohvatiSenzore() { //Odasiljemo signal preko Trigger izlaza na senzoru digitalWrite(trig, LOW); delayMicroseconds(2); digitalWrite(trig, HIGH); delayMicroseconds(10); digitalWrite(trig, LOW); //Izracunavamo trajanje povratka sa funkcijom pulseIn trajanjeFL = pulseIn(echoFL, HIGH); //Izracunavamo udaljenost senzora od predmeta refleksije udaljenostFL = trajanjeFL*0.034/2; //Malo kasnjenje kako bi se smirilo sve i kako nebi na nekom drugom senzoru dobili odaziv senzora prije delay(10); ////Odasiljemo signal preko Trigger izlaza na senzoru digitalWrite(trig, LOW); delayMicroseconds(2); digitalWrite(trig, HIGH); delayMicroseconds(10); digitalWrite(trig, LOW); //Izracunavamo trajanje povratka sa funkcijom pulseIn trajanjeFR = pulseIn(echoFR, HIGH); //Izracunavamo udaljenost senzora od predmeta refleksije udaljenostFR = trajanjeFR*0.034/2; //Malo kasnjenje kako bi se smirilo sve i kako nebi na nekom drugom senzoru dobili odaziv senzora prije delay(10); //Odasiljemo signal preko Trigger izlaza na senzoru digitalWrite(trig, LOW); delayMicroseconds(2); digitalWrite(trig, HIGH); delayMicroseconds(10); digitalWrite(trig, LOW); //Izracunavamo trajanje povratka sa funkcijom pulseIn trajanjeBL = pulseIn(echoBL, HIGH); //Izracunavamo udaljenost senzora od predmeta refleksije udaljenostBL = trajanjeBL*0.034/2; //Malo kasnjenje kako bi se smirilo sve i kako nebi na nekom drugom senzoru dobili odaziv senzora prije delay(10); //Odasiljemo signal preko Trigger izlaza na senzoru digitalWrite(trig, LOW); delayMicroseconds(2); digitalWrite(trig, HIGH); delayMicroseconds(10); digitalWrite(trig, LOW); //Izracunavamo trajanje povratka sa funkcijom pulseIn trajanjeBR = pulseIn(echoBR, HIGH); //Izracunavamo udaljenost senzora od predmeta refleksije udaljenostBR = trajanjeBR*0.034/2; //Malo kasnjenje kako bi se smirilo sve i kako nebi na nekom drugom senzoru dobili odaziv senzora prije delay(10); //---- ISPISUJEMO UDALJENOST SVIJU SENZORA NA SERIAL MONITOR ---- // Serial.print("FL : "); Serial.print(udaljenostFL); Serial.print(" FR : "); Serial.print(udaljenostFR); Serial.print(" BL : "); Serial.print(udaljenostBL); Serial.print(" BR : "); Serial.print(udaljenostBR); // -------------------------------------------------------------- // Serial.println(""); Buzzer(); //Pozivamo funkciju Buzzer } void Buzzer() { while (digitalRead(microswitch)==LOW || tipkaBuzzer == 1) //Ako je pritisnuta sklopka na misu ili tipka na aplikaciji { //Smanjujemo svjetlinu oci na 128 analogWrite(oci, 128); //Pisemo ton za Buzzer analogWrite(buzzer,200); delay(100); //Uz pomoc petlje postepeno smanjuje ton i mijenjamo osvjetljenje ledica for( n=250; n>=50; n=n-3){ analogWrite(buzzer,n); delay(3); analogWrite(oci,n*3); } //Pisemo ton na buzzer analogWrite(buzzer,100); delay(100); analogWrite(buzzer,0); //Vracamo ledice na puni intenzitet analogWrite(oci, 255); //Dohvacamo vrijednosti sa aplikacije u slucaju da smo ugasili buzzer Blynk.run(); } } BLYNK_WRITE(V3) { tipkaBuzzer = param.asInt(); //Dohvacamo vrijednost tipke na vritualnom izlazu 3 if (tipkaBuzzer == 1) { //Pozivamo funkciju buzzer i repic Buzzer(); repic(); } if (tipkaBuzzer == 0) { //U slucaju da tipka buzzer nije aktivna ne radimo nista } } BLYNK_READ(V4) { float bat = analogRead(A5); float struja = bat * (8.2 / 1023.0); Blynk.virtualWrite(V4, bat); } BLYNK_WRITE(V1) { stanjeGumba = param.asInt(); //Dohvacamo vrijednost gumba za automatsku navigaciju if (stanjeGumba == 1) { //Ako je navigacija ukljucena pokrecemo loop petlju i ispisujemo na serial monitor loop(); Serial.println("Automatska navigacija ukljucena!"); } if (stanjeGumba == 0) { //Ako je navigacija iskljucena onda pisemo na serial monitor Serial.println("Automatska navigacija iskljucena!"); } Buzzer(); //Pozivamo funkciju buzzer } BLYNK_WRITE(V0) { if (stanjeGumba == 0) { //Ako je navigacija iskljucena... //Dohvacamo osi na Joystick-u na aplikaciji joystickX = param[0].asInt(); //Vrijednost X osi joystickY = param[1].asInt(); //Vrijednost Y osi if (joystickX != 128 || joystickY != 128) { //Ako joystick je pomaknut od sredista //Ispisujemo ocitane vrijednosti na Serial Monitor Serial.print("X os: "); Serial.println(joystickX); Serial.print("Y os: "); Serial.println(joystickY); if (joystickX == 255) { //Ako je joystick pomaknut potpuno u lijevo Serial.println("Desno"); //Ispisujemo na serial monitor servoD.write(160); //Pisemo na serveo da se vrti najjace u smijeru suprotno od kazaljke na satu servoL.write(160); //Pisemo na servo da se vrti najjace u smijeru suprotno od kazaljke na satu Buzzer(); //Pozivamo funkciju buzzer } else if (joystickX == 0) { Serial.println("Ljevo"); //Ispisujemo na serial monitor servoD.write(20); //pisemo na servo da vrti najjace u smjeru kazaljke na satu servoL.write(20); //pisemo na servo da vrti najjace u smjeru kazaljke na satu Buzzer(); //Pozivamo funkciju Buzzer } else if (joystickY == 255) { Serial.println("Naprijed"); //Ispisujemo na serial monitor servoD.write(20); //pisemo na servo da vrti najjace u smjeru kazaljke na satu servoL.write(160); //pisemo na servo da vrti najjace u smjeru suprotnom od kazaljke na satu Buzzer(); //Pozivamo funkciju buzzer } else if (joystickY == 0) { Serial.println("Nazad"); //Ispisujemo na serial monitor servoD.write(160); //pisemo na servo da vrti najjace u smjeru suprotnom od kazaljke na satu servoL.write(20); //pisemo na servo da vrti najjace u smjeru kazaljke na satu Buzzer(); //Pozivamo funkciju buzzer } else { Serial.println("Error!!!"); Serial.print("JoystickX = "); Serial.println(joystickX); Serial.print("JoystickY = "); Serial.println(joystickY); } } if (joystickX == 128 && joystickY == 128) { //Ako je joystick na sredini tj ne korisnik nekoristi ga... Serial.println("Joystick nista ili fail!"); //Ispisujemo Debug poruku na serial monitor servoD.write(90); //Na servo pisemo da miruje servoL.write(90); //Na servo pisemo da miruje Buzzer(); //pozivamo funkciju buzzer } else { Serial.println("Error!!!"); Serial.print("JoystickX = "); Serial.println(joystickX); Serial.print("JoystickY = "); Serial.println(joystickY); } } }
Arduino program ovoga projekta možete preuzeti ovdje.
Autori
Projekt su izradili Teo Opić i Bruno Řehak uz mentorstvo Tomislava Krala iz Tehničke škole Daruvar.
Projekt je prijavljen na temu: Internet of Things: Kućni ljubimci i domaće životinje.