Reaali Robootika.COM

NXT robotimaailm ja programmeerimine C-keeles

4 tund: Kahe lülitiga roboti juhtimine

Õppematerjal:
3 tund- Lülititega roboti juhtimine
Juhend- while, until tsüklite kasutamine
Juhend- IF ELSE ja SWITCH kasutamine
Juhend- Andurite defineerimine ja lugemine

Sisuliselt on selleks tunniks 2 ülesannet.

Alljärgnevate ülesannete juurde on lisatud ka nende olekudiagrammid, mille abil on programmiosade töö selgitamine lihtsam. Samuti annavad programmist tervikliku ülevaate.

Ülesanne 2. Robotil on küljes kaks lülitiandurit.

roboti programmi olekudiagrammVariant a) Robot sõidab edasi, kuid vajutades ühte lülitit keerab sujuvalt paremale ning teise lüliti korral vasakule.

Lahendus. Iseenesest lihtne IF ELSE lausete jada. Esiteks täidetakse lõpmatult tsüklit, mille sees kontrollitakse iga tsükli käigus kas üks või teine lüliti on vajutatud.  Siin on kasutatud edasiliikumiseks OnRevSync funktsiooni, kuna antud BOT-l olid mootorid teisipidi peal.

task main(){
SetSensorTouch(S2);
SetSensorTouch(S1);
while(TRUE){
  if (Sensor(S2)){
    OnRevSync(OUT_BC, 50, -10);
  }
  else if(Sensor(S1)){
    OnRevSync(OUT_BC, 50, 10);
  }
  else{
    OnRev(OUT_BC, 50);
  }
}
}

roboti programmi olekudiagrammVariant b) Robot hakkab edasi sõitma siis kui mõlemad lülitid on korraga alla vajutatud ja lahti lastud. Üksikult kasutades toimivad lülitid paremale-vasakule keeramisena. Teistkordsel üheaegsel vajutamisel jääb robot seisma.

Lahendus.

Alguses robot seisab ja ootab kuni mõlemad lülitid on bumped (ehk vajutatud-lahti lastud).

Peale lülitite vajutamist käivitub funktsioon while, mille tingimuseks on määratud Bumped2Buttons muutuja. Kuna see muutuja on algväärtustatud eelnevalt FALSE-ks siis läheb antud tsükkel käima (kuna tingimuslauses on muutuja ees ! hüüumärk).

Seejärel toimib programm täpselt nii nagu ee on kirjeldatud eelmise variandi korral – ehk keerab paremale-vasakule-sõidab otse.

Kuid lisaks on toodud üks IF lause, mille tingimuseks on kontroll, kas mõlemad lülitid on vajutatud. Kui on alla vajutatud, täidetakse IF lause ning until-funktsioon jääb ootama, kuni lülitid on lahti lastud.

Lülitite lahti laskmisel muudetakse Bumped2Buttons väärtus TRUE-ks ning edasi läheb programm uuele tsüklile ja kontrollib tingimust. Kuna tingimus ei ole tema jaoks tõene, väljutakse while tsüklist lülitatakse mootorid välja ja jäädakse ootama taas nuppude bumped-vajutust roboti käivitamiseks.

Selle programmi loomisel tuli juba päris mitu viga ning algne versioon oli ka sutsu keerukam kui alljärgnev lõplik lahendus.

task main(){
bool Bumped2Buttons;
SetSensorTouch(S1);
SetSensorTouch(S2);
while(true){
  Bumped2Buttons = FALSE;
  until(Sensor(S1) && Sensor(S2));
  until(!Sensor(S1) && !Sensor(S2));
  while(!Bumped2Buttons){
    if (Sensor(S1)== 1){
       OnRevSync(OUT_BC, 50, -10);
    }
    else if(Sensor(S2)== 1){
       OnRevSync(OUT_BC, 50, 10);
    }
    else{
       OnRev(OUT_BC, 50);
    }
    if(Sensor(S1) && Sensor(S2)){
      until(!Sensor(S1) && !Sensor(S2));
      Bumped2Buttons = TRUE;
    }
  }
  Off(OUT_BC);
}
}

Teine variant sama ülesande lahendamiseks on alljärgnev.

2 lülitiga pöörav robot

Siin variandis ei ole kasutatud muutujat, mille alusel väljutaks teisest while-tsüklist. Siin on kasutatud ära matemaatilist loogika ning tsüklist väljumise tingimus on sisse kirjutatud while-tsükli enda tingimuseks. Tulemuseks on mõnevõrra lihtsam kood.

 

task main()
{
 SetSensorTouch(S1);
 SetSensorTouch(S2);
 while(TRUE)
 {
	until(Sensor(S1) && Sensor(S2)); //ootab nupu vajutust
	until(!Sensor(S1) && !Sensor(S2)); //ootab nupu lahti laskmist
	//While tsükli stoppimiseks, ootab kuni mõlemad nupud on alla vajutatud 
	while(!Sensor(S1) || !Sensor(S2)) 	{
		if(Sensor(S1))
		{
			OnFwdSync(OUT_BC, 75, 10);
		}
		else if(Sensor(S2))
		{
			OnFwdSync(OUT_BC, 75, -10);
		}
		else
		{
		OnFwdSync(OUT_BC, 75, 0);
		}
	}
	Off(OUT_BC);
	until(!Sensor(S1) && !Sensor(S2)); //ootab nupu lahti laskmist
 }
}

Juhend: IF ELSE ja SWITCH kasutamine

Programmeerimise enimkasutatav funktsioon on ilmselgelt IF ja IF ELSE laused. Tegemist siis tingimuste kontrolliga ning vastavalt sellele tegevuse ette võtmine.

Teise funktsioonina olen alljärgnevalt välja toonud ka SWITCH funktsiooni, kuna selle näol on tegemist nö. pika if-elseif-elseif-else lausendi jadaga.


if ("condition”) {“body” } else {“body” }

if (x == 1) {
   y = 1;
   z = 2;
 }
 else {
   y = 3;
   z = 5;
 }

Kui tingimus on tõene, täidetakse esimene käsk kui tingimus on väär täidetakse alternatiivne käsk.

IF lause sees võib ELSE IF lauseid palju olla, vaata alljärgnevat.

if (x == 1) {
   y = 1;
   z = 2;
 }
 else if (x == 2) {
   y = 3;
   z = 5;
 }
else {
  y = 6;
  z = 7;
 }

 

Sellisel juhul kontrollitakse kõigepealt IF tingimust kui see on väär minnakse edasi ja kontrollitakse ELSE IF tingimust, kui ka see on väär minnakse edasi järgmise kontrolli juurde.

Ehk siis ülaltoodud IF lauset tuleks lugeda järgmiselt: Kui x on võrdne 1-ga, pane y väärtuseks 1 ja z väärtuseks 2, kui aga x on võrdne 2-ga, pane y väärtuseks 3 ja z väärtuseks 5, või muidu pane y väärtuseks 6 ja z väärtuseks 7.


switch ("expression”) {“body” }

switch(x)
 {
        case 1:
         // tee midagi kui x on 1
         break;
        case 2:
        case 3:
         // tee midagi kui x on 2 või 3
         break;
        default:
         // tee midagi kui x pole 1, 2 või 3
         break;
 }

 

Switch kontrollib x väärtust ja vastavalt selle väärtusele teostab operatsiooni. See on sama tulemus kui ELSE IF funktsiooni jada kasutades. Kuid switch konstruktsiooni on oluliselt lihtsam kasutada võrreldes ELSE IF lausete jadaga.

Näiteks värviandurist värvi-info saamise korral, musta värvi korral tehakse ühtemoodi, punase korral teisiti jne.

Või infrapuna seekerist saabuvate numbrite 1..9 korral saan kirjeldada, mida ühel või teisel juhul tehakse.

3 tund: Lülititega roboti juhtimine

Tunniteemaks ülesanded, mille käigus tuleb roboti tööd juhtida lülitite abil. tegemist suhteliselt lihtsate ülesannetega, kuid C-keele õppimiseks täiesti piisava keerukusega.

Õppematerjal:
Juhend- Andurite defineerimine ja lugemine
Juhend- while, until tsüklite kasutamine
Juhend- IF ELSE ja SWITCH kasutamine

Tunni sisu:

Igaühel on oma BOT, millele on vastavalt esimeste ülesannete käigus ühendatud 1 lüliti ning teiste käigus kaks lülitit. Õpime kasutama funktsioone Until, While ja IF ELSE laused.

Tegelikult ei jõudnud keegi neid ülesandeid 2 tunni jooksul ära teha, mistõttu ülesanne nr 2 jääb järgmise tunni teemaks.


Ülesanne 1. Robotil on küljes üks lülitiandur pika juhtmega.

Variant a) Robot sõidab seni kuni lüliti on vajutatud.

Lahendus. Esialgu muutujaid ei kasutanud, jõuame nendeni edaspidi. Õppisime kasutama IF ELSE lauset.

task main(){
SetSensorTouch(S1);                          
while (TRUE)
{ if (Sensor(S1))
{ OnFwd(OUT_BC, 100); } else
{ Off(OUT_BC); } } }

Variant b) Robot seisab kui lüliti on vajutatud.

Lahendus. Selle ülesande lahendamisel lähtus enamik sellest, et vahetati IF ja ELSE laused omavahel ära ning suur oli poiste üllatus kui selgus, et seda on võimalik lahendada vaid ühe hüüumärgi lisamisega. Kui näiteks IF ja ELSE lausete sisu on väga mahukas, on nende vahetamine igal juhul ajamahukam ja mõningate ohtudega seotud vs. hüüumärgi lisamine.

task main(){
SetSensorTouch(S1);                          
while (TRUE)
{ if (!Sensor(S1))
{ OnFwd(OUT_BC, 100); } else
{ Off(OUT_BC); } } }

Variant c) Robot hakkab sõitma kui lülitit on korra vajutatud ja lahti lastud ning peatub kui teist korda vajutatakse/lahti lastakse (bumped).

Lahendus. Õppisime kasutama until funktsiooni, mille abil on lihtne teha lülitile bumped-tüüpi vajutuse kontroll. Esimene until ootab kuni lüliti on vajutatud ning järgmine until ootab kuni lüliti on lahti lastud.

task main(){
SetSensorTouch(S1);
while(TRUE){
  until(Sensor(S1));
  until(!Sensor(S1));
  OnRev(OUT_BC, 100);
  until(Sensor(S1));
  until(!Sensor(S1));
  Off(OUT_BC);
}
}

Ülesanne 2. Robotil on küljes kaks lülitiandurit.

Variant a) Robot sõidab edasi, kuid vajutades ühte lülitit keerab sujuvalt paremale ning teise lüliti korral vasakule.
Variant b) Robot hakkab edasi sõitma siis kui mõlemad lülitid on korraga alla vajutatud ja lahti lastud. Üksikult kasutades toimivad lülitid paremale-vasakule keeramisena. Teistkordsel üheaegsel vajutamisel jääb robot seisma.

Juhend: while, until tsüklite kasutamine

Programmeerimise peamised konstruktsioonid seisnevad tsüklites ning tingimuslausetes. Tsükkel on  tegevus mida korratakse seni, kuni etteantud tingimus vastab tsükli konstruktsioonile. Alljärgnevalt vaatame tsükleid while ning until ja seda mille poolest need erinevad.

Väga levinud on robootikas kasutada lõpmatult täidetavat tsüklit, seda läheb praktiliselt tarvis iga lõputult toimiva programmi korral.


while("tingimus")

while(x < 10)
 {
        x += 1;
        y *= 2;
 }

Kontrollitakse tingimust x<10 kui see on tõene, täidetakse while tsükli sisu ning siis kontrollitakse taas tingimust. Toimub seni kuni tingimus on väär - siis väljutakse tsüklist. Seega antud näite korral läbitakse tsüklit 9 korda, sest 10-dal korral on x = 10, seega tingimus pole tõene ja väljutakse tsüklist ehk minnakse programmiga edasi. 

while(TRUE) see on lõpmatult kestev tsükkel. Kuna TRUE tähendab seda, et avaldise väärtus on alati tõene siis selline tsükkel täidab oma sisu lõpmatu arv kordi.

Alljärgnev on näide nupu “bumped” funktsiooni teostamine:

while(!Sensor(S1));        // ootab nupule vajutamist
while(Sensor(S1));         // ootab nupu lahti laskmist


Ülalkirjeldatud bumped-funktsionaalsus töötab järgmiselt. Kui nupp on lahti siis see tähendab, et esimene tsükkel on tõene. Kui nupp vajutatakse alla, muutub esimese tsükli tingimus vääraks ning tõeseks muutub teise tsükli tingimus. Kui nuppu hoitakse all ei lähe programm edasi, kuna täidetakse teist tsüklit. Nupu lahti laskmise korral muutub tingimus vääraks ning programm läheb edasi.

 


until(EVENT_OCCURS);

until(SensorUS(S1) > 50);

until käitub vastupidiselt while tsüklile, st. see funktsioon ootab kuni tema tingimus saab tõeseks. Seda saab kasutada edukalt programmi seiskamiseks ning andurist kindla signaali ootamiseks.

Alljärgnev on näide nupu “bumped” funktsiooni teostamine, võrdle while tsükliga:

until(Sensor(S1));         // ootab nupule vajutamist
until(!Sensor(S1));        // ootab nupu lahti laskmist

Kui nupp on avatud siis esimese until funktsiooni tingimus on FALSE ja seega programm ootab selle taga. Nupu allavajutamisel muutub tingimus TRUE-ks ning programm läheb edasi, jäädes ootama teise until funktsiooni taha. Kui nüüd nupp lahti lasta ehk nupu väljund on FALSE, muutub teise until funktsiooni tingimus TRUE-ks ning programm liigub edasi

Juhend: Lihtne matemaatika

lihtne matemaatikaAegajalt tuleb robootikas ette olukordi, kus on vaja muuta mingist andurist tulev signaal märgiliselt vastupidiseks või mingil muul moel lihtsalt teisendada.

Näide 1

Kaugusandurist tulevad välja numbrid 0..100, kuid mootorile oleks vaja sisse anda vastupidine väärtus 100 .. 0. Ehk kui robot on seina lähedal siis eemaldub sellest kiiresti, kuid mida kaugemal on sein seda aeglasemalt robot liigub.

Lihtne matemaatiline tehe: 100 - algne arv = soovitud arv

 


Näide 2

lihtne matemaatikaInfrapuna otsijast (IR seekerist) tulevad välja numbrid 1..9. Nüüd oleks vaja luua keskkoht (5), mis võrdub nulliga ning 6-9 korral lasta robotil paremale keerata ning 1-4 korral lasta robotil vasakule keerata. 0 korral sõidab otse.

Lihtne matemaatika:

esmalt keskkoha arvutamiseks: algne arv – keskkoht (5) = soovitud arv

seejärel võimendus mootorile pööramise jaoks: algne arv x 25 = soovitud arv


Näide 3

lihtne matemaatikaKompassist saame relatiivse nurga mõõtmise korral väljundisse –90 .. 0 .. 90. Nüüd oleks vaja see number muundada vastupidiseks, et kui kompassist saame väljundi –90 siis roboti keeramiseks anname mootori sisendisse 90 ja vastupidi, kui kompass väljastab 90 kraadi siis roboti pööramiseks anname mootori sisendisse –90.

Lihtne matemaatika: 0 – algne arv = soovitud arv

Juhend: Mootorite peamised käsud NXC-s

Alljärgnevalt peamised NXC käsud, mille abil robot liikuma või seisma panna.

OnFwd("ports", "pwr"); OnRev(..)

OnFwd(OUT_A, 75);

Mootor A liigub edasi kiirusega 75


OnFwdSync("ports", "pwr", “turn”); OnRevSync(..)

OnFwdSync(OUT_AB, 75, -100);

Mootorid A ja B liiguvad edasi ning neid hoitakse sünkroonis. Turn ehk keeramine -100 määrab ära kummale poole keeratakse. 0 – sõidab otse, 50 – üks ratas seisab, 100 – rattad liiguvad vastassuundades.


OnFwdReg("ports", "pwr", OUT_REGMODE_SPEED); OnRevReg(..)

OnFwdReg(OUT_AB, 100, OUT_REGMODE_SPEED);

Mootorid A ja B sõidavad otse ning rakendavad lisajõudu kui ette satub takistus.


Off(OUT_AB);

Off(OUT_AB);

Lülitab mootorid A ja B välja


RotateMotor("ports", "pwr", “degrees”);

RotateMotor(OUT_A, 75, 360);

Pöörab mootorit A 360 kraadi kiirusega 75.


RotateMotorEx("ports", "pwr", “degrees”, “turn”, “sync”, “stop”);

RotateMotorEx(OUT_AB, 75, 360, 50, TRUE, TRUE);

Keerab mootoreid A ja B 360 kraadi kiirusega 75. Turn määrab ära kummale poole keeratakse (0 – sõidab otse, 50 – üks ratas seisab, 100 – rattad liiguvad vastassuundades), sync määrab et mootorid on sünkroonis ja stop määrab kas lõpus on vaja pidurdada või mitte.


Coast("ports”);

Coast(OUT_AB);

Laseb määratud mootorid vabajooksuga seismiseni.

Juhend: Andurite defineerimine ja lugemine

Roboti juures andurite kasutamine on seotud kahe tegevusega: a) defineerimine b) lugemine.
Selleks, et programmis andureid kasutada (lugeda), tuleb robotile kõigepealt selgeks õpetada millised andurid ja kus pordis asuvad.

Alljärgnevas tabelis on andurite initsialiseerimisega seotud funktsioonid. Erinevaid andureid tuleb erineval moel initsialiseerida.

SetSensorLight("port");

SetSensorLight(S1);
Valgussensori initsialiseerimine pordis 1.

SetSensorTouch("port")

SetSensorTouch(S1);
Puuteanduri initsialiseerimine pordis 1.

SetSensorSound("port");

SetSensorSound(S1);
Helianduri initsialiseerimine pordis 1.

SetSensorHTEOPD("port");

SetSensorHTEOPD(S1);
Hitechnic EOPD sensori initsialiseerimine.

SetSensorHTGyro("port");

SetSensorHTGyro(S1);
Hitechnic Gyro sensori initsialiseerimine.

SetSensorLowspeed("port");

SetSensorLowspeed(S1);
Ultrasonic ja Hitechnic IRSeeker, Color, Compass sensori initsialiseerimine pordis 1.

Anduritelt andmete lugemiseks kasutatavad funktsioonid on alljärgnevas tabelis. Jällegi tuleb tähele panna, et osade andurite jaoks saab kasutada sama funktsiooni lugemiseks, kuid osade jaoks on spetsiifilised funktsioonid.

Sensor("port");

Sensor(S1);
Andmete lugemine Touch, Light, Sound sensorist.

SensorUS("port");

SensorUS(S1);
Andmete lugemine Ultrasonic sensorist.

SensorHTGyro("port", “Offset”);

SensorHTGyro(S1, 2);
Andmete lugemine Gyro sensorist. Ette on antud offset ehk nulli hälve.

SensorHTEOPD("port");

SensorHTEOPD(S1);
Andmete lugemine EOPD sensorist.

SensorHTCompass("port");

SensorHTCompass(S1);
Andmete lugemine Compass sensorist.

SensorHTIRSeekerDir("port");

SensorHTIRSeekerDir(S1);
IR Seeker sensorist suuna lugemine.

SensorHTColorNum("port");

SensorHTColorNum(S1);
Värviandurist vastava värvi numbri lugemine.

Juhend: Lego rattad ja matemaatika

Alljärgnevalt juhis, kuidas arvutada erinevate Lego rataste korral välja otseliikumiseks või pööramiseks vajalik rattanurk kraadides.
 
Need kolm on peamised rattad mida kasutatakse Lego Mindstorm robotite ehitamisel.
Ratas
Diameeter
Ümbermõõt
Väike ratas
clip_image002
43,2 mm
135,7 mm
Keskmine ratas
clip_image004
56 mm
175,9 mm
Suur ratas
clip_image006
82 mm
257,6 mm
Alljärgnevalt on ära kirjeldatud moodused, kuidas arvutada välja mootori pöörded kraadides kui robot peab a) kindla maa edasi liikuma b) pöörama teatud nurga võrra nii, et üks ratas seisab c) pöörama teatud nurga võrra kohapeal.
Kraadides on tarvis tulemust seetõttu, et NXC-s ehk C-keeles programmeerides saab kasutada funktsiooni RotateMotorEx, mille abil saab roboti väga täpselt liikuma panna.
Huvitav nüanss on see, et peale keeramist funktsiooniga RotateMotorEx on vaja panna kasvõi 10ms pikkune wait, kuna muidu lähevad mootorid peast segi.
Kui näiteks alljärgnevas näites Wait lõpust ära võtta on tulemuseks mõõdetamatu segadus. Õigupoolest üritab robot oma mootorid sünkroonis panna liikuma esialgses suunas. Seega peale kolmandat repeati robot ainult keerleb kohapeal.

repeat(4){
RotateMotorEx(OUT_AB, 50, 500, 0, TRUE, TRUE);
RotateMotorEx(OUT_AB, 50, 365, 0, TRUE, TRUE);
Wait(MS_10);
}

 

Otseliikumine

Roboti otseliikumise korral teepikkuse väljendamine mootori pöörded kraadides.
image
Distants - vahemaa, mille robot peab läbima. Näiteks 200 mm (20 cm)
Ümbermõõt – roboti ratta ümbermõõt
x kraadi – mootori pöörded kraadides
 

Pööramine ühe rattaga

clip_image010Roboti keeramisel ühe rattaga (st. teine ratas on paigal) liikumise väljendamine mootori pööretes mis on antud kraadides.
image
Roboti pööramise nurk – see on kraadides väljendatud nurk, mille robot peab pöörama. Näiteks 90*
Rataste vahe – rataste keskkohast mõõdetud nende omavaheline kaugus. Näiteks 135 mm
x kraadi – mootori pöörded kraadides
 

Pööramine kohapeal

clip_image014Roboti keeramisel mõlema rattaga (st. rattad liiguvad vastassuundades) liikumise väljendamine mootori pööretes mis on antud kraadides.
image
Roboti pööramise nurk – see on kraadides väljendatud nurk, mille robot peab pöörama. Näiteks 90*
Rataste vahe – rataste keskkohast mõõdetud omavaheline kaugus. Näiteks 135 mm
x kraadi – mootori pöörded kraadides

2 tund: Ratta läbimõõt ja mootori pöörete arv

Eelmisel tunnil õppisime arvutama roboti pööramiseks vajalikku mootori pöördenurka. Täna tuleb seda kasutada praktikas.

Kasutatavad materjalid:
Juhend- Lego rattad ja matemaatika
Juhend- Mootorite peamised käsud NXC-s

Tunni sisu:

Igaühel oli vaja endale BOT teha. Mõni oli juba valmis ja puuduolevad valmisid kiirelt.

Edasi oli vaja mõõta roboti andmed, ratta diameeter (lasin kõigil BOT-del erinevate suurustega rattad panna) ning ratastevaheline kaugus.

Enne programmeerimise juurde asumist tuli välja arvutada ülesandes vajaminevad numbrid.

Kõige rohkem tekitas probleeme viimase ülesande nurga arvutus. Antud on sisenurk, kuid robot pidi tegelikkuses keerama 180’ – 36’ = 144’

Lisaks tekitas probleeme funktsioon RotateMotorEx, mille keeramise järele tuli kirjutada Wait(10), kuid sellest on täpsemalt juttu pööramise arvutamise juhendis. Sisuliselt oli nende kolme ülesande lahendamisega poistel tegemist terveks tunniks (2h).


Arvuta välja ning kirjuta programm roboti liigutamiseks.

Roboti andmed.

·         Roboti ratta diameeter DR = ….   cm

·         Rataste vahe LR = ….  cm

Kirjuta alati välja valem arvutuskäigu kohta ja arvuta roboti liikumine.

Ülesanne 1.

Robot sõidab mööda joont edasi tagasi. Joone pikkus on 1m.

image

Esimese ülesande lahendus, numbrid sõltuvad konkreetsest BOT-st:

task main(){
repeat(2){                                     
RotateMotorEx(OUT_BC, 50, -1400, 0, TRUE, TRUE);
RotateMotorEx(OUT_BC, 17, 333, 100, TRUE, TRUE);
Wait(10);
} }

imageÜlesanne 2.

Robot sõidab ruudu, mille küljepikkus on 30cm. Nurk = 90’

 

Teise ülesande lahendus, kolmanda oma on analoogiline.

task main(){
repeat(4){
RotateMotorEx(OUT_BC, 50, -420, 0, TRUE, TRUE);
RotateMotorEx(OUT_BC, 17, 166, 100, TRUE, TRUE);
Wait(10);
}
}

image

Ülesanne 3.

Robot sõidab viisnurga, mille küljepikkus on 50cm. Nurk = 36’

 

 

 

.

Juhend: Loogika kasutamine

Loogikalülitused omavad NXT-maailmas alati ja ainult kahte väärtust: true või false (1 või 0).
1 ja 0 abil saab teha hulgaliselt tehteid ning lahendada erinevaid ülesandeid. Programmis tähistatakse seda tüüpi muutujat sõnaga bool (tuletatud sõnast Boolean ehk kahendmuutuja).
C-keeles muutuja defineerimine ja algväärtustamine:
bool ShootBall = FALSE;
Enimkasutatavad kahendmuutujatega tehtavad tehted on AND (JA), OR (VÕI), XOR (välistav VÕI), NOT (EI).
Kahendmuutujate tabelid
Loogikatehete vasted NXC-s:
AND tehte korral kasuta kahte ja märki &&
Alltoodud avaldistes muutub if lause tõeseks ainult siis kui mõlemad muutujad on tõesed. Kõik toodud kolm kombinatsiooni on õiged, kuid soovituslik on kasutada esimest kui kõige lühemat varianti.
if(ShootBall && ShootButton)
if(ShootBall == TRUE && ShootButton == TRUE)
if(ShootBall == 1 && ShootButton == 1)

OR tehte korral kasuta kahte püstist kriipsu ||
Alltoodud avaldistes muutub if lause tõeseks juba siis kui vaid üks muutuja on tõene ja jääb ka tõeseks kui mõlemad on 1-d. Kõik toodud kolm kombinatsiooni on õiged, kuid soovituslik on kasutada esimest kui kõige lühemat varianti.
if(ShootBall || ShootButton)
if(ShootBall == TRUE || ShootButton == TRUE)
if(ShootBall == 1 || ShootButton == 1)

NOT tehte korral kasuta hüüumärki !
Alltoodud avaldise sees muudab hüüumärk muutuja väärtuse vastupidiseks. If lause muutub tõeseks sel juhul kui muutuja on FALSE ehk 0. Kuigi kõik alljärgnevad avaldised annavad sama tulemuse, on soovituslik kasutada esimest kui lühimat.
if(!ShootBall)
if(ShootBall == FALSE)
if(ShootBall == 0)