Robottiohjelmoinnin harjoitustyö : Bluetooth

 

Bluetooth

Bluetooth on joskus hieman ongelmallinen, mutta jos onni on myötä, kaikki saattaa sujua näinkin hyvin:

 

Paritus

1. Varmista, että Bluetooth näkyy:

Bluetooth-adapteri näkyväksi

 

2. Laita NXT:n Bluetooth-asetuksista näkyvyys päälle ja varmista "Change PIN"-kohdasta, että pin-koodi on asetettu 0000:ksi (suoraviivaisinta). Valitse Set up new device...

Etsi uusi laite

 

3. Odota kunnes NXT löytyy:

Etsi NXT

4. Avaa PIN options ja valitse Fixed PIN '0000'

Valitse Fixed PIN '0000'


5. Aloita pariutuminen painamalla Forward. Jos kaikki meni hyvin, seuraavanlainen ruutu ilmestyy:

Onnistunut paritus

 

6. Kun NXT on paritettu, voidaan sille lähettää ohjelmia ja käskyttää ilman USB-johtoa, testata voi vaikka ohjelmalla nxjcontrol:

nxjcontrol Bluetoothin yli

 

NXT-NXT -paritus

Kytke molempien palikoiden bluetooth päälle Bluetooth-valikosta, sitten:

  1. Ensimmäisellä palikalla, aseta/tarkista PIN-koodi kohdasta Bluetooth → Change PIN. Kun paritusyritys tapahtuu, tällä koodilla NXT vastaa.
  2. Toisella palikalla, valitse Bluetooth → Search and Pair → valitse löydetty NXT → Pair → valitse sama koodi jonka asetit ensimmäiseen palikkaan. Ruudulle pitäisi tulla Paired!

Jos/kun vaihdat bluetooth-nimen, poista tiedosto ~/nxj.cache, jotta ohjelmat kuten nxjbrowse etsivät NXT:t uusilla nimillään.

 

Kahden NXT:n välinen Bluetooth-kommunikaatio

Kun palikat on paritettu keskenään, voidaan niitä hyödyntää eri tavoin.

Toinen NXT kauko-ohjauksessa

Toisen NXT:n käyttäminen ikään kuin päärobotin jatkeena on yksinkertaista. Luokka RemoteNXT mahdollistaa toisen yksikön moottori- ja sensoriporttien käyttämisen kuin ne olisivat paikallisia portteja. Käskytettävään yksikköön ei tarvita erityistä ohjelmaa - komentoyhteyden kuuntelu kuuluu leJOSin toimintoihin. Huomattavaa on (tutoriaalista): Currently, the class is limited and I2C and RCX sensors are not supported, and the motors must be used in a simple way as the regulation thread is not used. Kannattaa myös ottaa viive (sekunnin osia) huomioon.

Esimerkki ohjelmasta, joka tulostaa toisen NXT:n sensoriarvoja ja liikuttaa sen moottoria:

import java.io.IOException;
import lejos.nxt.*;
import lejos.nxt.comm.*;
import lejos.nxt.remote.*;

public class Remote {
    public static void main(String[] args) {
        RemoteNXT remote = null;
        try {
            System.out.println("Connecting...");
            // ota yhteys NXT:hen nimeltä "NXT1"
            remote = new RemoteNXT("NXT1", Bluetooth.getConnector());
            System.out.println("Connected.");

        } catch (IOException ioe) {
            System.out.println("Connection failed.");
            Button.waitForPress();
            System.exit(1);
        }
        // viitataan etäyksikön valosensoriin
        LightSensor light = new LightSensor(remote.S1);

        // ala liikuttamaan etäyksikön moottoria A
        RemoteMotor motor = remote.A;
        motor.setSpeed(100);
        motor.forward();

        while(!Button.ENTER.isPressed()) {
            System.out.println("Light: "+light.readNormalizedValue());
        }

    }

}


Viestien vaihtaminen

Sen sijaan, että toinen robotti olisi passiivisesti käskytettävänä, voidaan bluetoothilla lähettää viestejä myös itsenäisten yksiköiden välillä. Yhteydelle voidaan avata DataInputStream ja DataOutputStream, joista luetaan ja joihin kirjoitetaan arvoja. Kommunikaatiota varten voi olla tarpeen kehittää jonkinlainen protokolla roboteille.

Simppeli ping-ohjelma, jonka alussa voi valita toimiiko kuuntelevana vai yhteyden aloittavana osapuolena, kätevä parituksen onnistumisen testaamiseen:

import java.io.*;
import java.util.Vector;
import javax.bluetooth.RemoteDevice;
import lejos.nxt.Button;
import lejos.nxt.comm.*;

public class Ping {
    public static void delay (int ms) {
        try{Thread.sleep(ms);}catch(Exception e) {}
    }

    // boolean-arvo initiate määrittää, aloitetaanko
    // kuuntelulla vai luodaanko yhteys
    public static void pingloop (boolean initiate) {

        NXTConnection conn;
        int counter = 0;

        if(initiate) {
            // yhdistä ensimmäiseen löydettyyn NXT:hen
            Vector device = Bluetooth.inquire(1, 10, new byte[]{0,0,0,0});
            RemoteDevice remote = ((RemoteDevice) device.elementAt(0));
            conn = Bluetooth.connect(remote);
        } else {
            // odota yhteydenottoa
            conn = Bluetooth.waitForConnection();
        }

        if(conn == null) {
            System.out.println("Error connecting.");
            return;

        }
        DataInputStream input = conn.openDataInputStream();
        DataOutputStream output = conn.openDataOutputStream();

        // lähetellään edestakaisin dataa
        while(true) {
            try {
                if(initiate) {
                    // pingaa
                    output.writeInt(counter);
                    output.flush();
                    System.out.println("Recvd pong: "+input.readInt());
                    delay(1000);
                } else {
                    System.out.println("Recvd ping: "+input.readInt());
                    // pongaa
                    output.writeInt(counter);
                    output.flush();
                } counter++;
            } catch (IOException e) {
                System.out.println("Error.");
                break;
            }
        }
    }

    public static void main(String[] args) {
        int selection=0;
        delay(1000);
        System.out.println("ENTER=initiate\nESCAPE=listen");

        while(selection != 8 && selection != 1)
            selection = Button.waitForPress();
        if(selection == 1) {
            System.out.println("Initiating");
            pingloop(true);
        } else {
            System.out.println("Listening");
            pingloop(false);
        }
        Button.ENTER.waitForPressAndRelease();
    }
}

Laita kuunteleva osapuoli valmiuteen ennen kuin toinen osapuoli muodostaa yhteyden.

 

PC:n ja NXT:n välinen Bluetooth-kommunikaatio

Suorita ensin paritus tietokoneen ja NXT:n välillä.

Esimerkkikoodissa yhteys muodostetaan niin, että NXT odottaa PC:n ottavan yhteyden siihen, minkä jälkeen NXT voi pyytää PC:tä joko vastaanottamaan tai lähettämään tietoja.

  • PC käyttäytyy NXT:n palvelijana.

Luokka RfcommPC on PC:llä ajettava ohjelma (käännä javac:llä), joka ottaa komentoriviparametrina NXT:n bluetooth-nimen, johon muodostaa yhteyden. RfcommTest on NXT:llä ajettava testiohjelma, joka lähettää taulukon tietokoneelle ja pyytää siitä prosessoidun version takaisin. Rfcomm on NXT:lle luokka, joka tekee yhteyden käyttämisestä helppoa.

Huom.! Ilmeisesti leJOSin jar-tiedostoissa on päällekkäinen nimi lejos.nxt.NXT tiedostoissa classes.jar ja pccomms.jar. Jotta RfcommPC toimii, ota CLASSPATHista classes.jar pois.

 

NXT-osapuoli

Esimerkki (RfcommTest):

import lejos.nxt.Button;

public class RfcommTest {
    public static void main(String[] args) {
        // odota yhteyttä
        Rfcomm comm = new Rfcomm();

        // lähetä koneelle
        if(!comm.transmit(new int[] {1,2,3})) 
            System.out.println("Error transmitting.");

        // lue koneelta
        int[] pcdata = comm.receive();
        if(pcdata == null) System.out.println("Error receiving.");
        else {
            // tulosta saatu taulukko
            System.out.print("PC sent [ ");
            for(int i = 0; i < pcdata.length; i++) 
                System.out.print(""+pcdata[i]+" ");
            System.out.println("]");
        }
        comm.disconnect();
        Button.ENTER.waitForPressAndRelease();
    }
}



PC-osapuoli

Katso luokan RfcommPC koodia, etenkin listen()-metodia, jossa NXT:n käskyihin vastataan.

Käynnistä ensin NXT:n ohjelma odotustilaan ja sitten:

java RfcommPC "NXT"

Missä NXT on palikkasi bluetooth-nimi. Esimerkissä RfcommPC tulostaa sille NXT:n lähettämät tiedot ja vastaa pyyntöihin lähettämällä näistä muokatun taulukon.

Esimerkissä NXT lähettää PC:lle taulukon [1,2,3] ja pyytää PC:ltä taulukon, johon PC vastaa [21,22,23].

 

Lisätietoa