Lassan az egész C nyelv összes utasítását megismered (van vagy 10 belőle)! A ciklus, mint már tudod, arról szól, hogy ismételjünk dolgokat.
A for-ciklust általában úgy használjuk, hogy valamit megadott számúszor ismételjünk meg. Azonban sokszor jó lenne, ha nem kellene megadni azt, hogy hányszor ismételjen, mert:
Lássunk erre egy példát! A 0-ás portra tegyél egy gombot (az előző oldalon is ott volt). A feladat egyszerű: amíg a gombot nyomva tartják, addig villogjon a led!
Sajnos bárhogy agyalsz rajta, ezt if-el csak igen esetleges módon lehet megoldani (persze pont ezt a példát még lehet oldani if-el, de a többit már nem). Ehhez olyan ciklus kell, ami addig ismétel, amíg valami feltétel teljesül.
const int ON=1;
const int OFF=0;
void setup() {
pinMode(13, OUTPUT);
pinMode(0, INPUT_PULLUP);
}
bool buttonPressed() {
if (digitalRead(0)==LOW) { // azaz a a gomb meg van nyomva
return true; // most meg van nyomva
}
else {
return false; // most nincs megnyomva
}
}
void led(int state) {
digitalWrite(13,state);
}
void loop() {
while(buttonPressed()) {
led(ON);
delay(100);
led(OFF);
delay(100);
}
}
Hogy is van ez? Egyszerűen! A while ismétli az utána írt utasításblokkot, amíg a feltétel igaz, azaz amíg a gomb meg van nyomva.
Mire jó a végtelen ciklus? Arra, hogy valamit végtelenül sokáig ismételj. Például egy SOS-t morzézó vészjelzőt célszerű úgy csinálni, hogy ahelyett, hogy diszkréten nyom egy SOS-t aztán kikapcsol, ahelyett folyamatosan nyomja hogy SOS, amíg csak tart benne az elem.
Az A-starban a loop() függvényt is egy végtelen ciklusban hívja az Arduino rendszer, így amit oda írsz, azt folyamatosan ismételgeti.
Hogyan lesz egy ciklus végtelen? Hát úgy, hogy a ciklusban maradás feltétele mindig igaz. Például, while (1==1) az remek kezdet, hiszen mióta felfedezték a számokat, 1 értéke mindig egyenlő 1-el.
Ettől kulturáltabb a while (true), hisz ahogy az előző részben láttad, az 1==1 értéke valójában egy összehasonlítás, aminek az értéke egy logikai érték, mégpedig true (azaz "igaz").
Szóval egy örökké menő ciklus ilyen lenne:
while(true) {
led(ON);
delay(100);
led(OFF);
delay(100);
}
Sokszor jó lenne a gomb megnyomását és elengedését is külön érzékelni. Csináljunk egy olyan lámpát, ami egy gombnyomással bekapcsol, és a következő gombnyomással kikapcsol!
No de ha csak arra figyelünk, hogy a gombot megnyomták-e, akkor állandóan be-ki-be-ki fogunk kapcsolgatni, hiszen az ember leggyorsabban elengedve is 0.1 másodpercig nyomja azt a gombot, ennyi idő alatt a programunk meg már sokezerszer lefut.
Csinálhatunk egy olyan while-ciklust, ami addig ismételget, amíg a gombot megnyomták, így nem megy tovább a progi amíg a gombon taposunk:
while(buttonPressed()) {
// nem csinálunk semmit
// és a semmit ismételjük
}
Tehát, amíg a gomb meg van nyomva, ismételjük a semmit - magyarul várunk, hogy elengedjék a gombot.
Szerencsére a semmit nem feltétlen kell leírni, ha olyan ciklust akarunk ami a semmit ismétli, az üres utasításblokk kihagyható:
// vár, amíg nyomják a gombot
while(buttonPressed());
Az előző részben megtanultál egy csomó összehasonlító műveletet, amik számokkal működnek. A logikai (bool) értékekhez is van egy csapat művelet:
Mivel a buttonPressed egy függvény, ami logikai értéket ad vissza, ezért az eredménye megetethető mondjuk a ! műveleti jellel, így lehet gomb megnyomására, és gomb elengedésére váró ciklusunk:
// vár, amíg nyomják a gombot
while(buttonPressed());
// vár, amíg nem nyomják meg a gombot
while(!buttonPressed());
Tegyük akkor össze! Tehát a következő a cél:
Valahogy így:
const int ON=1;
const int OFF=0;
void setup() {
pinMode(13, OUTPUT);
pinMode(0, INPUT_PULLUP);
}
bool buttonPressed() {
delay(100);
if (digitalRead(0)==LOW) { // azaz a a gomb meg van nyomva
return true; // most meg van nyomva
}
else {
return false; // most nincs megnyomva
}
}
void led(int state) {
digitalWrite(13,state);
}
void loop() {
while(!buttonPressed()); // várunk amíg megnyomják
led(ON);
while(buttonPressed()); // várunk amíg elengedik
while(!buttonPressed()); // várunk amíg megnyomják
led(OFF);
while(buttonPressed()); // várunk amíg elengedik
}
Csinálj három-fényű lámpát! Az analogWrite-al kezeld a led fényerejét, és minden gombnyomásra kicsit erősebb legyen a fény: 0%, 50%, 100% között. (Ne feledd, hogy az 50%-os fényhez picit kisebb értéket kell használni az analogWrite-ban, mert az ember szeme nem arányosan érzékeny a fényre.)
Nekem ilyen lett:
const int MAX=255;
const int MID=50;
const int OFF=0;
void setup() {
pinMode(13, OUTPUT);
pinMode(0, INPUT_PULLUP);
}
bool buttonPressed() {
delay(100);
if (digitalRead(0)==LOW) { // azaz a a gomb meg van nyomva
return true; // most meg van nyomva
}
else {
return false; // most nincs megnyomva
}
}
void led(int state) {
analogWrite(13,state);
}
void loop() {
while(!buttonPressed());
led(MAX);
while(buttonPressed());
while(!buttonPressed());
led(MID);
while(buttonPressed());
while(!buttonPressed());
led(OFF);
while(buttonPressed());
}
Csináld meg, hogy minden gombnyomásra csippantson! Sőt, más-mást csippantson az egyes fényerők bekapcsolásakor!