Nos, összeszerelni sikerült azok alapján, ahogy a tesztelésnél csináltam, igaz, egyszer összehoztam egy helyes kis zárlatot, mert a breadboard jobb oldalán két földet sikerült az 5V sorra dugni hála a kábeldzsungelnek, meg már megint elfelejtettem, hogy a ledeknek nem ártana egy 220-as ellenállás (habár azok megsütését egyelőre sikerült elkerülni). Az sem egy utolsó dolog, hogy a szenzort hogyan köti be az ember lánya, mert a megszokás nagy úr, jelen esetben azonban nem szerencsés követni, mivel itt az egyik lábra közvetlenül megy az 5V, a másikra viszont a data, és erről a lábról megy a 10K ohm ellenállással a föld (lol hát nyilván a földet kötöttem a másik lábra, és az ellenállással a data-t, ahogy a ledeknél, ezért hozott olyan lehetetlenül alacsony értékeket...).
Az LCD-t külön most nem adtam hozzá a rajzhoz, mert azt már itt megcsináltam, viszont ezen a képen már szépen látszik, hogyan kell jól bekötni ahhoz, hogy ne makkanjon meg minden. 5V-os verziót nem találtunk a tápból (ez azért kellett, mert a szervo elszívta az áramot a többi alkatrész elől, amikor dolgozott), úgyhogy az a 3.3V az igazából 5V.
Miután ezeket az "apró" dolgokat kijavítottam, az LCD végre jól mutatta a szöveget a korábbi hieroglifák helyett, a szervomotor sem zizegett egyfolytában, viszont a felszínre jött néhány újdonság, amit eddig nem fedeztünk fel.
Az első az, hogy a szervomotor nem tud körbeforogni, csak 180-at hajlandó, így nem is nagyon érti, hogy mit akarok a 270 fokkal a kódolásban, a másik pedig az, hogy az északhoz bekötött fényérzékelő egyszerűen nem hajlandó együttműködni. Valami nem stimmel a shielddel, de mivel a szervo egyébként sem tud 360-at, inkább átvariálom három ledesre a tervemet, nézzük, hogy ha kivonom a forgalomból ezt a kis hisztérikát, javul-e valamennyit a szitu.
Amúgy tök cuki volt, ahogy délután az asztalra sütött a nap, a délnek megfelelő érzékelő szólt is miatta :D
Na de most akkor átvarázsolom a rendszert, és megnézem, úgy mihez kezd a helyzettel.
Igazából annyi történt, hogy amikor beállítom az alapállást 0-ra, valamiért ott zizeg a szervomotor, amúgy végre normálisan reagál arra, honnan kapja a fényt, bár nyugaton a helyzet kissé necces, mert spéttel veszi észre, hogy mégis melyik az irány, ahonnan a fény jön, így először keletként azonosítja be magát, és csak pár másodperc után áll át nyugatra.
Ettől függetlenül pöpecül működik, bár azt hiszem, visszatérek a kevésbé összetett feladatokhoz, mert fejben picit egyszerűbbnek tűnt, mint amilyen a végére lett a kód...akkor talán nem kell napokig ülnöm felette, mire kitalálom, hogyan rakjam úgy össze, hogy minden működjön és látszódjon a végén :D
A programozás mondjuk elég brutálra sikerült, létrehoztam egy halom változót, csak, hogy legyen mire hivatkozni később. Az "elfordulas" és az "utolso_elfordulas" kellett ahhoz, hogy csak akkor adjon jelet a servomotornak, ha új állásba kell fordulnia, ne vezérelje feleslegesen, ha már eleve jó állásban van, az alapértelmezett helyzete indulásnál a 0, amit majd a loop-ban felülír(hatja) a függvény a fénytől függően, a maximum szintén később a loop-ban kell majd, amikor azt kell összehasonlítani, hogy melyik érzékelő kapja a legtöbb fényt.
Ezért sirdogálok mindig a programozásnál, mert vagy előre kell tudnom, hogy milyen változókra lesz majd szükségem, vagy pedig ide-oda kell ugrálni, ahogy épp szükség van új változókra. Meh.
1 2 3 4 5 6 7 |
int analogValueDel; int analogValueKelet; int analogValueNyugat; int elfordulas; int maximum; int utolso_elfordulas = 0; |
Még itt az elején meghatároztam a ledek állásait is. Amennyiben nincs fény (itt jött először képbe a maximum 0 értékkel), egyik sem világít, ha pedig valamelyik szenzort fényt éri, attól függően, hogy merre kell a motornak elfordulnia, az ahhoz tartozó led fog felvillanni.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
void setleds (){ if (maximum == 0){ digitalWrite (piros, LOW); digitalWrite (sarga, LOW); digitalWrite (zold, LOW); } else { if (elfordulas == 0){ digitalWrite (piros, LOW); digitalWrite (sarga, HIGH); digitalWrite (zold, LOW); } if (elfordulas == 90){ digitalWrite (piros, HIGH); digitalWrite (sarga, LOW); digitalWrite (zold, LOW); } if (elfordulas == 180){ digitalWrite (piros, LOW); digitalWrite (sarga, LOW); digitalWrite (zold, HIGH); } } } |
Mielőtt azonban rátérünk a változók kifejtésére, a setup részben még egy-két dolgot létre kellett hozni. A serial monitor használatához (ami ahhoz kellett, hogy megnézzük, milyen értékeket produkáltak a szenzorok, ha fény érte őket) kellett a Serial.begin, utána jött a pinek olvasásának beállítása, a servomotor pin és kezdőállásának meghatározása, majd a ledek írásának beállítása, végül az LCD-nek először a pin és annak írása, aztán a kontraszt és az, hogy 16 karaktert tartalmazhat két sorban.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
void setup() { Serial.begin(9600); pinMode(del, INPUT); pinMode(kelet, INPUT); pinMode(nyugat, INPUT); servo.attach(servoPin); servo.write (0); pinMode(piros, OUTPUT); pinMode(zold, OUTPUT); pinMode(sarga, OUTPUT); pinMode(9, OUTPUT); analogWrite(9, 50); //change 50 to adjust contrast lcd.begin(16, 2); } |
Ezután jött a loop, ahol elkezdtük használni a létrehozott változókat.
Ez még itt a lájtosabb rész, össze kellett hozni az analogValue-kat a hozzájuk tartozó pinekkel, aztán - hogy ki tudjuk olvasni serialmonitoron keresztül az értékeket - a Serial.prinln-hez illesztés jött az eredmény tizes számrendszerben megjelenítésével. A sok kis kötőjelet azért írtuk bele a kódba, hogy szépen látszódjon, hol ér véget az előző adatcsomag, és mikor kezdődik a következő.
1 2 3 4 5 6 7 8 9 |
void loop() { analogValueDel = analogRead(del); analogValueKelet = analogRead(kelet); analogValueNyugat = analogRead(nyugat); Serial.println(analogValueDel, DEC); Serial.println(analogValueKelet, DEC); Serial.println(analogValueNyugat, DEC); Serial.println("---------"); |
Aztán jött az a rész, amiért létre kellett hozni a maximumot, az elfodulást és az utolsó elfordulást. Kiindulópontnak a "kelet"-nek beállított szenzort jelöltem meg, ahhoz rendeltük a szervo 0 alapállását, az "if" függvényekkel pedig összehasonlítottuk az egyes pinekre érkező értékeket, valamint a szervo elfordulásának mértékét.
Az "utolso_elfordulas" pedig mindig megkapja azt az elfordulásértéket, amelyik a legutolsó, fényt érzékelő szenzorhoz tartozik, amit az utolsó "if" függvény küld át a servo motornak, azaz ha az utolsó elfordulás értéke nem egyezik meg az elfordulás alapértékével, akkor azt az elfordulást fogja a servo-nak megadni, amelyik az előző "if"-ekből igaz lesz.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
maximum = analogValueKelet; elfordulas = 0; if (analogValueDel > maximum){ maximum = analogValueDel; elfordulas = 90; } if (analogValueNyugat > maximum){ maximum = analogValueNyugat; elfordulas = 180; } if (utolso_elfordulas != elfordulas){ servo.write(elfordulas); } utolso_elfordulas = elfordulas; setleds(); |
A végére már csak egy kis könnyed ujjgyakorlat maradt, amivel az LCD-t kérjük meg arra, hogy legyen szíves valamilyen információval szolgálni arról, hogy miért forog a szervomotor:
Ha a maximum érték 0, akkor egyik szenzor sem kap fényt, tehát sötét van. Az előző részben megadtuk a fényt érzékelő szenzorokhoz tartozó elfordulás mértékét, amihez itt hozzárendeltük, hogy melyik égtáj irányából jön a világosság, például:
kiindulóérték kelet - 0
|
v
a délhez rendelt szenzor értéke nagyobb a keleti és nyugati szenzornál
|
v
a délhez rendelt elfordulás mértéke 90
|
v
a 90-es elforduláshoz rendelt szöveg: Fény délről
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
lcd.clear(); if (maximum == 0) { lcd.write ("Sotet van"); } else { if (elfordulas == 0){ lcd.write ("Feny keletrol"); } if (elfordulas == 90){ lcd.write ("Feny delrol"); } if (elfordulas == 180){ lcd.write ("Feny nyugatrol"); } } delay(1000); } |
Még alá odaírtunk egy 1 mp-es késleltetést is, hogy legyen egy kis szünet a folyamatos újramérés közben, így nem vibrál egyfolytában a led és az LCD, ha épp két szenzor között billeg a fényerő nagysága.
A rossz hír az, hogy több változó összehasonlításával kellett játszani, úgyhogy ML néha tollbamondta a függvényeket, főként, mikor bekerült a maximum is a képbe, viszont a jó hír az, hogy most már nem kell órákat magyarázni, hogy mit miért írunk meg, az if-else is már nagyjából megy, viszont, hogy azoknak a specifikációja, hogy pontosan mit tartalmazzon, még eléggé kihívás.
E.