Reaali Robootika.COM

NXT robotimaailm ja programmeerimine C-keeles

Robomiku finaal 3. koht

Üle Eesti tuli kokku 22 võistkonda erinevatest koolidest, kes kõik katsusid jõudu ühe Karupäästmise ülesandega. www.robomiku.ee

Nimelt robot pidi liikuma mööda musta joont läbi keerulise kolmekorruselise maja, tuvastama majas olevaid kannatanuid ning ülemiselt korruselt karumõmmi majast välja tooma.

Ütlen kohe ette ära, et karu jäigi majja, kuid meie tiim sai karu sellegipoolest kõige kaugemale. Esimene ja teine koht läksid aga Narva kuna nemad jõudsid oma robotiga põlevast majast ka välja – kuigi ilma karuta.

Vaata 3. koha ehk siis meie roboti videot:

Robomikufinaal–Robojalg 3. koht

Juhend: HiTechnic prototüüpimislaud

HiTechnic NXT andurite tootjana on teinud ka ühe väga laheda asja – nimelt prototüüpimislaud.

http://www.hitechnic.com/cgi-bin/commerce.cgi?preadd=action&key=NPK1056 

Sellel on 5 analoogsisendit (1024 astet pingega 0..3,3 V) ning 6 digitaalset sisendit/väljundit, mille abil saab kõikvõimalikke keerukaid asju teha. Alljärgnevalt kaks lihtsat näidisprogrammi: a) jooksvad tuled ja b) KITT tuled.

Jooksvad tuled ja KITT tuled HiTechnic Prototype Board abil

Jooksvad tuled

Käesoleva juhendi käigus vaatame ainult prototüüpimislaua digitaalsete väljunditesse kirjutamise osa.

Prototüüpimislaual on 6 digitaalset väljundit B0…B5. Neid saab kasutada nii sisendi kui ka väljundi režiimis. Register “Digital Control” määrab ära millised pordid on sisendid ja millised väljundid. Näiteks “Digital Control” registris number 63 (kahendsüsteemis 111111) muudab kõik väljunditeks.

Digital Out registrisse antud number määrab ära milline väljundportidest on aktiveeritud 1-ga. 1 tähendab siis 3,3V ja 12mA. Näiteks Digital Out numbriga 63 (ehk 0x3F) tähendab, et kõik valgusdioodid põlevad.

Alljärgnev programm suunab DigitalOut registrisse järjest numbrid 1,2, 4, 8, 16, 32 (0x01, 0x02, 0x04, 0x08, 0x10, 0x20).

Alljärgnevalt näidisprogramm kuidas teha prototüüpimislaua abil jooksvad tuled NXC programmeerimiskeeles.

/*
Leivo Sepp 12.02.2011
See programm kasutab HiTechnicu prototüübi plaati
Paneb plaadi taha ühendatud valgusdioodid järjekorras põlema
Ehk teisisõnu "jooksvad tuled"
*/


#define PROTO_PORT S1

int count;
int light = 0x01;
byte cmndbuf[];
byte respbuf[];                 

/* protoboard I/O map
   42,43 - A0 input
   44,45 - A1 input
   46,47 - A2 input
   48,49 - A3 input
   4A,4B - A4 input
   4C    - B inputs
   4D    - B outputs
   4E    - B controls
*/

//see alamprogramm teostab reaalse kirjutamise protolaua registrisse
//aktiveerides kindla pordi (B0..B5), mille taga peab süttima valgusdiood
void writedata(int outputdata)
  {
  //loo 3 väärtusega massiiv
  ArrayInit(cmndbuf, 0, 3);
  //protolaua aadress
  cmndbuf[0] = 0x02;
  //register kuhu kirjutatakse 4D on output
  cmndbuf[1] = 0x4D;
  //output registrisse kirjutatakse number mis aktiveerib kindla väljundi
  cmndbuf[2] = outputdata;
  count=0;
	//Käivitada eelnevate andmete põhjal protolauda kirjutamine
  I2CBytes(PROTO_PORT, cmndbuf, count, respbuf);  
  }

task main()
  {
  SetSensorLowspeed(PROTO_PORT); 
  Wait(100);

  //massiivi initsialiseerimine, 3 väärtust
  ArrayInit(cmndbuf, 0, 3);
  //esimene väärtus massiivis, prototüüpimislaua aadress
  cmndbuf[0] = 0x02;
  //teine väärtus massiivis, registri Control valimine (sisendid/väljundid)
  cmndbuf[1] = 0x4E;
  //kirjutada registrisse Control number 63 ehk 111111
  //st. et kõik B0..B5 on väljundid
  cmndbuf[2] = 0x3F;
  //mitu baiti peab I2C protolaud tagastama, meie puhul 0
  count=0;
  //Käivitada eelnevate andmete põhjal protolauda kirjutamine
  I2CBytes(PROTO_PORT, cmndbuf, count, respbuf);
  Wait(100);

  while (TRUE)
    {
    //kutsutakse välja alamprogramm, kuhu kirjutatakse number
    //numbrid on 1, 2, 4, 8, 16, 32
    writedata(light);
     light = light * 0x02;
     if (light == 0x40)
        light = 0x01;
    Wait(100);
    }
}

KITT tuled.

Ja teine programm, mis paneb tuled edasi-tagasi liikuma, ehk nagu KITT
/*
Leivo Sepp 12.02.2011
See programm kasutab HiTechnicu prototüübi plaati
Paneb plaadi taha ühendatud valgusdioodid edasi/tagasi põlema
Ehk teisisõnu "KITT tuled"
*/


#define PROTO_PORT S1

int count;
int light = 0x01;
byte cmndbuf[];
byte respbuf[]; 
bool kitt=TRUE;                

/* protoboard I/O map
   42,43 - A0 input
   44,45 - A1 input
   46,47 - A2 input
   48,49 - A3 input
   4A,4B - A4 input
   4C    - B inputs
   4D    - B outputs
   4E    - B controls
*/

//see alamprogramm teostab reaalse kirjutamise protolaua registrisse
//aktiveerides kindla pordi (B0..B5), mille taga peab süttima valgusdiood
void writedata(int outputdata)
  {
  //loo 3 väärtusega massiiv
  ArrayInit(cmndbuf, 0, 3);
  //protolaua aadress
  cmndbuf[0] = 0x02;
  //register kuhu kirjutatakse 4D on output
  cmndbuf[1] = 0x4D;
  //output registrisse kirjutatakse number mis aktiveerib kindla väljundi
  cmndbuf[2] = outputdata;
  count=0;
	//Käivitada eelnevate andmete põhjal protolauda kirjutamine
  I2CBytes(PROTO_PORT, cmndbuf, count, respbuf);  
  }

task main()
  {
  SetSensorLowspeed(PROTO_PORT); 
  Wait(100);

	//massiivi initsialiseerimine, 3 väärtust
  ArrayInit(cmndbuf, 0, 3);
  //esimene väärtus massiivis, prototüüpimislaua aadress
  cmndbuf[0] = 0x02;
  //teine väärtus massiivis, registri Control valimine (sisendid/väljundid)
  cmndbuf[1] = 0x4E;
  //kirjutada registrisse Control number 63 ehk 111111
  //st. et kõik B0..B5 on väljundid
  cmndbuf[2] = 0x3F;
  //mitu baiti peab I2C protolaud tagastama, meie puhul 0
  count=0;
  //Käivitada eelnevate andmete põhjal protolauda kirjutamine
  I2CBytes(PROTO_PORT, cmndbuf, count, respbuf);
  Wait(100);

    while (TRUE)
    {
    //kutsutakse välja alamprogramm, kuhu kirjutatakse number
    //numbrid on 1, 2, 4, 8, 16, 32
    writedata(light);
    if (kitt){
    	 //numbrid jooksevad väiksemast suuremaks
       light = light * 0x02;
       if (light == 0x20){
          kitt = FALSE;
          }
       }
    else {
    	  //numbrid jooksevad suuremast väiksemaks
        light = light / 0x02;
        if (light == 0x01)
           kitt = TRUE;
        }
    Wait(200);
    }
}

Kahe seina vahel roniv robot

Ma tegin ühe roboti mis ronib kahe seina vahel üles-alla. Seda ehitades mul polnud mitte mingit probleemi. Kuid kui ma jõudsin programmeerimise juurde siis tekkis mul küll mõningaid probleeme. Kuid enne räägin milline oli mu roboti programmeerimise järjekord. Kõigepealt kui robot oli valmis siis polnud mingit muret esimese kolmandikuga alustada. Esimeses kolmandikus ma panin ta lihtsalt üles sõitma seni kuni ta näeb lähedamal kui 10 cm lage. Sellega erilisi probleeme ei tekkinud kuna see oli üpriski lihtne programm. Teise kolmandiku programmist ma panin roboti sõitma küll pikema programmiga kuid mõne algaja jaoks ka kergem ning seekord sõitis robot lõpmatuseni üles-alla. Minu viimane kolmandik programmist sõitis robot ka muidugi lõpmatusein üles alla kuid nüüd on see lühem ja kergem kui eelmine kord.

Mu isa tegi sellest ka video:

Kahe seina vahel ronija robot

Programm näeb välja selline:

/*
Autor:Ramses Sepp 09.02.2011
See programm võimaldab robotil sõita kahe seina vahelt üles
*/

//See alamprogramm juhib roboti mootoreid üles-alla sõidul
void Liikumine(bool Yles, int KiirusSeinal){
	//Järgnev if lause peatab ühe või teise mootori kui robot on balansist väljas
	//Siin if-i lauses korrgeerib balanssi robot siis kui ta näeb oranþi
	if (Sensor(S2) > 50){
		//Need kaks järgmist rida suunavad kumb mootor peatub 
		//siis kui läheb üles-alla ja näeb oranþi
		if (Yles) Off(OUT_B);
		else Off(OUT_C);
		until(Sensor(S2) < 50);
		}
	//Siin else if-i lauses korrigeerib balanssi robot siis kui ta näeb musta
	else if(Sensor(S2) < 40){
		//Need kaks järgmist rida suunavad kumb mootor peatub 
		//siis kui läheb üles-alla ja näeb musta
		if (Yles) Off(OUT_C);
		else Off(OUT_B);
		until(Sensor(S2) > 40);
		}
	else{
		//Muidu sõidab robot lihtsalt kahe seina vahelt alla
		OnRevReg(OUT_BC, KiirusSeinal, OUT_REGMODE_SPEED);
		OnRev(OUT_A, 20);
		}
}
task main(){
SetSensorLowspeed(S4);
SetSensorLight(S2);
SetSensorLowspeed(S3);
bool TOP;
//Järgnev mootori programmi osa laiendab mõlemad mootorid seinte vastu
OnFwd(OUT_A, -75);
Wait(1000);
while (TRUE){
	//Siin vaatab kas lagi on lähedamal kui 10 cm
	if(SensorUS(S4) < 10){
		Off(OUT_BC);
		TOP = TRUE;
		}
	//Siin vaatab kas põrand on lähedamal kui 10 cm
	if(SensorUS(S3) < 10){
		Off(OUT_BC);
		TOP = FALSE;
		}
	//See pool paneb roboti alla sõitma
	if(TOP){
		Liikumine(FALSE, -15);
	}
	//See pool paneb roboti üles sõitma
	else{
		Liikumine(TRUE, 30);
	}
}
}