Hauptpost – Klick!

 

Changelog:

  • Das Programm sollte jetzt auf jedem Windows-Rechner funktionieren, ohne zusätzliche Programme (außer natürlich dem Java Runtime Environment) zu benötigen. Der Befehl zum Ausführen des Programms lautet: “java -jar NXTRFID_vx.x”.
  • Wenn Einstellungen (NXT-Name, Com-Port, usw.) geändert werden sollen, muss jetzt nicht mehr der Code modifiziert werden. Es liegen 2 Config-Files bei, aus denen die Inputs ausgelesen werden.
  • Minor Bugfixes
  • Wir stellen jetzt ein WinRAR-Verzeichnis mit den ausführbaren Dateien (StandAlone-Version) zur Verfügung: Download v4.4.2
     

    Die neuen Codes:

     

    Java PC-Programm:

    //Written by Peter Por
    //Last edited: 17.07.13
     
    package nxtrfid;
     
    import lejos.pc.comm.*;
    import java.io.*;
     
     
    public class NXTRFID {	
     
      public static void main(String[] args) throws IOException, InterruptedException 
      {
    	  String nxtName = "NXT";   //Name of the specific NXT brick; "NXT" is default
    	  int COMPort = 8;      //The COM-Port of the RFID Reader	
    	  String RFIDScanLocation = "RRFIDScan_v.2.0.1.exe";    //The Location of the ".exe" file for the RFID Reader
    	  String Music = "vlc/vlc.exe --play-and-exit --novideo Music.mp3";     //Commandline promt opening VLC and the sound file
    	  String InputLocation = "NXTRFID.conf";    //Location of the config file
    	  int keypressOld = 9999;   //the last read RFID tag's ID will be saved here
     
    	  //You may change the location of the conf file by sensing a command line argument
    	if(args.length!=0)
    	{
    		InputLocation = args[0];
    	}
     
    	//Read the config file
    	try 
    	{
    		BufferedReader in = new BufferedReader(new FileReader(InputLocation));
    		String zeile1 = in.readLine();
    		String zeile2 = in.readLine();
    		String zeile3 = in.readLine();
    		String zeile4 = in.readLine();
     
    		nxtName = zeile1;
    		COMPort = Integer.parseInt(zeile2);
    		RFIDScanLocation = zeile3;
    		Music = zeile4;
     
    		in.close();
    	} 
    	catch (IOException err) 
    	{
    		err.printStackTrace();
    	}
     
        //Necessary declarations for establishing the connection
        NXTInfo[] nxts;
        NXTConnector connect = new NXTConnector();
     
        nxts = connect.search(nxtName,null,NXTCommFactory.BLUETOOTH);    //Searches for nearby NXTs
     
        if(nxts.length == 0)
        { //The NXT was not in range
          System.out.print(nxtName + " nicht gefunden!");
        }
        else{
          if(!connect.connectTo(nxts[0].name,nxts[0].deviceAddress,NXTCommFactory.BLUETOOTH))
          { //Connection failed
            System.out.println("Verbindungsaufbau zu " + nxtName + " fehlgeschlagen!");
          }
          else
          { //now there is a connection
            System.out.println("Verbindung zu " + nxtName + " aufgebaut!");
            DataOutputStream dos = new DataOutputStream(connect.getOutputStream());
     
            while(true){
             try
             {
              Process p = Runtime.getRuntime().exec(RFIDScanLocation + " " + COMPort);   //This declaration starts the ".exe" file for the RFID Reader; The number following specifies the COM port
              p.waitFor();    //Waits until the ".exe" has finished
              dos.writeInt(p.exitValue());    //Writes the exitValue of the RFIDScan program to the NXT
              dos.flush();
     
              //Starts VLC and opens the sound file - 3 is the Code for "Dance"
              if(p.exitValue()==3 && p.exitValue() != keypressOld)
              {
            	  Thread.sleep(10);
            	  try
            	  {
            		 Runtime.getRuntime().exec(Music);
            	  }
            	  catch(Exception ex)
            	  {
      		        System.out.println("Error with playing sound.");
      		        ex.printStackTrace();
      		      }
              }
     
              if(p.exitValue()==-1)   // -1 is the code for "Terminate"
              {
            	  System.out.println("Das Programm wird nun beendet.");
            	  break;
              }
              if(p.exitValue()==-2)   // -2 is the Error-Code
              {
            	  System.out.println("Fehler beim Einlesen des RFID Tags.");
            	  break;
              }
     
              keypressOld=p.exitValue();
             }
             catch(Exception err)
             {
            	 System.out.println("Error.");
            	 break;
             }
            }// end of loop       
     
        	dos.close();    //Closes the DataOutputStream
            connect.close();    //Closes the Connection to the NXT
            System.out.println("Programm beendet.");
          }
         }
     
        }// end of main
       } // end of class Main

    C++ PC-Programm (RFID):

    // RFIDScan.cpp : Defines the entry point for the console application.
    // Written by Andreas Mieke
    // Date: 17.07.13
     
    #define VERSION "2.0.2"
    //#define DEBUG		//Uncomment this to see what is scanned from RFIDScan.conf and what is the TagID on the scanner
    #define MAX_TAGS (20)	//Defines the maximum number of RFID tags to be scanned
     
    #include "std_inc.h"
    #include "comm.h"
    #include "protocol.h"
    #include "std_readwrite.h"
     
    //General purpose buffer
    char buffer[1000];
    char code[17];
    int tagCounter = 0;
    int tagCounterMax = 0;
    char tagIDs[17][MAX_TAGS];
    int tagReturns[MAX_TAGS];
     
    //This function closes the reader and communication handle
    //If not connected the two variables are set to zero
    void CloseComm() {
        //If the reader handle is set, close the reader
        if(reader_handle) {
            RDR_CloseReader(reader_handle);
            reader_handle = NULL;
        }
     
        //If the COM handle is set, close the COM port
        if(comm_handle) {
            RDR_CloseComm(comm_handle);
            comm_handle = NULL;
        }
    }
     
    bool OpenComm() {
        char input_buffer[50], detect_buffer[256];
     
         //Close any possible open connection
        CloseComm();
     
        comm_handle = RDR_OpenComm(com_port, 1, NULL);
     
        if(comm_handle == 0) { //zero indicates error while opening the com port
            printf("\n\nError opening reader(com).\n");
     
            return false;
        }
     
        //After sucessfully opening the com port, try to open the reader
     
        //First detect the station ID of the reader
        RDR_DetectReader(comm_handle, detect_buffer);
     
        //Open the reader with the first detected station ID
        reader_handle = RDR_OpenReader(comm_handle, detect_buffer[0], 0);
     
        if(reader_handle == 0) { //zero indicates error while opening reader
            //Since the com port is allready open, close it on error contition
            CloseComm();
     
            printf("\n\nError opening reader.\nPress any key to continue...");
            getch();
     
            return false;
        }
     
        //Stop the maybe activated continous read (should only be done after opening the reader)
        //RDR_EmptyCommRcvBuffer is not needed because this is implicit done with RDR_AbortContinuousRead
        RDR_AbortContinuousRead(comm_handle);
        return true;
    }
     
    //This function expalains the standard read/write sequence for a standard MIFARE card [ASCII]
    //If the default key is not valid you have to change the line in the source code below
    void DoASCIIReadWrite() {
        //The first action is to select the card
        //The select command has no data
        RDR_SendCommandGetData(reader_handle, "select", "", buffer);
    	sprintf(code, "%s", buffer);
    	strcpy(buffer,"");
    }
     
    //Main programm entry point
    int main(int args, char* argv[]) {
    	char* filepath;
    	if(args < 2)
    	{
    		printf("[ERROR]\tPlease provide the right COM port <name_of_file.exe {portnumer} [path_to_config]>\n");
    		return -2;
    	}
    	printf("RFIDScan Version: %s; Coded by Andreas Mieke\n\n[JOB]\t\tLoading config file...\n\n",VERSION);
    	if(argv[2] != NULL)
    		filepath = argv[2];
    	else
    		filepath = "RFIDScan.conf";
    	FILE *configFile = fopen(filepath,"r");
    	if(configFile != NULL)
    	{
    		fgets(buffer, sizeof(buffer), configFile);
    		tagCounterMax = atoi(buffer);
    		if(tagCounterMax > MAX_TAGS)
    		{
    			printf("[ERROR]\tYour specification of tags has too much elements! Max: %d",MAX_TAGS);
    			return -3;
    		}
    		for(; tagCounter < tagCounterMax; tagCounter++)
    		{
    			fscanf(configFile,"%s%d", tagIDs[tagCounter], &tagReturns[tagCounter]);
    #ifdef DEBUG
    			printf("[DEBUG]\t%s : %d\n", tagIDs[tagCounter], tagReturns[tagCounter]);
    #endif
    		}
    		fclose(configFile);
    		printf("[SUCCESS]\tConfig file successfully loaded. Program started.\n\n");
    	}
    	else
    	{
    		printf("[FATAL ERROR]\tConfig file \"%s\" could not be opened!\n", filepath);
    		return -4;
    	}
    	sprintf(com_port,"COM%d",atoi(argv[1])); //Sets the content of argv[1] as COM port
     
    	do { //Continues until a valid ID was scanned.
    		if(OpenComm() == false) //Opens the connection to the RFID reader (comm.cpp)
    		{
    			printf("[FATAL ERROR]\tCould not connect to the RFID Reader!\n");
    			return -5;
    		}
     
    		do { //Tries as long to scan a Tag as it doesn't find one.
    			DoASCIIReadWrite(); // (std_readwrite.cpp)
    		} while ((strlen(code) == 0) || (strlen(code) == 1)); //Strlen of 0 or 1 indicates error
     
    #ifdef DEBUG
    		printf("[DEBUG] %s\n",code); //Prints the HEX-Code (TAGID) to the screen
    #endif
    		CloseComm(); //Closes connection to Reader (comm.cpp)
     
    		for(tagCounter = 0; tagCounter < tagCounterMax; tagCounter++)
    		{
    			if(strcmp(code,tagIDs[tagCounter]) == 0)
    			return tagReturns[tagCounter];
    		}
    		strcpy(code,"");
    	} while(true);
    }
    //EOF

    Java NXT-Programm:

    //Written by Peter Por
    //Last edited: 17.07.13     
     
    import java.io.IOException;
    import lejos.nxt.*;
    import lejos.nxt.comm.*;
    import java.io.*;
    import javax.bluetooth.*;
    import lejos.util.Delay;
    import lejos.nxt.UltrasonicSensor;
     
     
     
    public class BluetoothNXT_v4 {
     
      //globally accessable variables
      public static int keypress = 0, keypressOld = 9999;
      public static boolean mayDriveForward=true, mayDriveBackward = true, clawsOpen=false;
     
      public static void main(String [] args) throws Exception
      {
        String connected = "Connected";
        String waiting = "Waiting...";
        String closing = "Closing...";
     
        //Starting the Thread using the ultrasonic sensors
        Indicators ussf = new Indicators();
        ussf.setDaemon(true); 
        ussf.start();
     
        //Waiting for, and establishing, the bluetooth connection
        LCD.drawString(waiting,0,0);
        LCD.refresh();
        BTConnection btc = Bluetooth.waitForConnection();
        LCD.clear();
        LCD.drawString(connected,0,0);
        LCD.refresh();
        Sound.beepSequenceUp();
        DataInputStream dis = btc.openDataInputStream();
        DataOutputStream dos = btc.openDataOutputStream();
        ///////////////////////////////////////////////////////////////////////  
        mayDriveForward=true;
        mayDriveBackward=true;
     
     
        while(true)
        {//start loop
     
          try{//waiting for the order-ID from the PC program
            keypress=dis.readInt();
          }
          catch(IOException e)
          {
            LCD.drawString("Error:",0,0);
            LCD.drawString("Datastream Invlaid.",0,1);
            LCD.refresh();
            break;
          }
          Thread.sleep(100);
     
     
          //Forward
          if (keypressOld!=8 && keypress ==8 && mayDriveForward) 
          {
            Motor.A.setSpeed(1200);
            Motor.C.setSpeed(1200);
            Motor.A.forward();
            Motor.C.forward();
            mayDriveBackward=true;
          } // end of if
          else
          //Backward
          if (keypressOld!=2 && keypress ==2 && mayDriveBackward) 
          {
            Motor.A.setSpeed(1200);
            Motor.C.setSpeed(1200);
            Motor.A.backward();
            Motor.C.backward();
            mayDriveForward=true;
          } // end of if
          else
          //Turn right
          if (keypressOld!=6 && keypress ==6) 
          {
            Motor.A.setSpeed(150);
            Motor.C.setSpeed(150);
            Motor.A.forward();
            Motor.C.backward();
            mayDriveForward=true;
            mayDriveBackward=true;
          } // end of if
          else
          //Turn left
          if (keypressOld!=4 && keypress ==4) 
          {         
            Motor.A.setSpeed(150);
            Motor.C.setSpeed(150);
            Motor.A.backward();
            Motor.C.forward();
            mayDriveForward=true;
            mayDriveBackward=true;
          } // end of if
          else
          //Stop
          if (keypress ==5) 
          {
            if (keypressOld==8||keypressOld==2)
            SoftStop();
            Motor.A.stop();
            Motor.C.stop();
          } // end of if
          else
          //Close Claws
          if (keypressOld!=keypress && clawsOpen && keypress==9) 
          {
            if (keypressOld==8||keypressOld==2)
            {SoftStop();}
            Motor.A.stop();
            Motor.C.stop();
            Motor.B.setSpeed(100);
            Motor.B.backward();
            Thread.sleep(1000);
            Motor.B.stop();
            clawsOpen=false;
          } // end of if
          else
          //Dance like nobody's watching
          if (keypressOld!=keypress && keypress==3)
          {
            SoftStop();
            Motor.A.stop();
            Motor.C.stop();
            if (!clawsOpen) 
            {                               
              Motor.B.setSpeed(100);
              Motor.B.forward();
              Thread.sleep(1000);
              Motor.B.stop();
              clawsOpen=true;
            }
            Dance.startDance();
          } // end of if  
          //Open claws
          else
          if (true) 
          {
            if (keypressOld!=keypress && !clawsOpen && keypress==7) 
            {
              if (keypressOld==8||keypressOld==2)
              SoftStop();
              Motor.A.stop();
              Motor.C.stop();
              Motor.B.setSpeed(100);
              Motor.B.forward();
              Thread.sleep(1000);
              Motor.B.stop();
              clawsOpen=true;
            } // end of if   
            mayDriveForward=true;
          }      
          keypressOld=keypress;
        }//end loop
     
     
        ///Terminating the program
     
        //closes claws in case they were open
        if (clawsOpen) 
        {                               
          SoftStop();
          Motor.A.stop();
          Motor.C.stop();
          Motor.B.setSpeed(100);
          Motor.B.backward();
          Thread.sleep(1000);
          Motor.B.stop();
          clawsOpen=false;
        }
     
        //closes the bluetooth connection
        dis.close();
        dos.close();
        Thread.sleep(90); // wait for data to drain
        LCD.clear();
        LCD.drawString(closing,0,0);
        LCD.refresh();
        btc.close();
        LCD.clear();
      }
     
     
      //Due to a hardware problem regarding the NXT's motors, this method was necessary in order to stop both motors at the same time
      static void SoftStop()
      {
        int i = 1200;
        while(i>0)
        {
          Motor.A.setSpeed(i);
          Motor.C.setSpeed(i);
          Delay.msDelay(10);
          i=i-100;
        }
      }
    }
     
     
    //Ultrasonic-Thread
    class Indicators extends Thread 
    {
      //Declaring the sensor-ports
      UltrasonicSensor sonicF = new UltrasonicSensor(SensorPort.S1);
      UltrasonicSensor sonicB = new UltrasonicSensor(SensorPort.S2);
      int safetyDistanceF=30,safetyDistanceB=27;
     
      //Workerthread
      public void run() 
      {
        while (true) 
        {
          //If the claws are open, the safety-distance is smaller
          if (BluetoothNXT_v4.clawsOpen)
          safetyDistanceF=23;
          else
          safetyDistanceF=30;
     
     
          try
          {
            if (sonicF.getDistance()<safetyDistanceF && BluetoothNXT_v4.keypress==8) 
            {//The NXT is currently driving forwards and faces an obstacle
              Motor.B.stop();
              BluetoothNXT_v4.SoftStop();
              Motor.A.stop();
              Motor.C.stop();       
              BluetoothNXT_v4.mayDriveForward = false;                  
            }
          }      
          catch(Exception err)
          { }
     
     
          try
          {
            if (sonicB.getDistance()<safetyDistanceB && BluetoothNXT_v4.keypress==2) 
            {//The NXT is currently driving backwards and faces an obstacle
              Motor.B.stop();
              BluetoothNXT_v4.SoftStop();
              Motor.A.stop();
              Motor.C.stop();     
              BluetoothNXT_v4.mayDriveBackward = false;                  
            }
          }      
          catch(Exception err)
          { }     
        }     
      }
    }
     
     
    class Dance {
     
      public static void startDance()
      {
        try{
          //Declaring the sensor-ports
          UltrasonicSensor sonicF = new UltrasonicSensor(SensorPort.S1);
          UltrasonicSensor sonicB = new UltrasonicSensor(SensorPort.S2);
          //Getting the current time
          long startTime = System.currentTimeMillis();
          Thread.sleep(50);
          long endTime = System.currentTimeMillis();
     
          //The program may only run for 29seconds (30seconds is the duration of the music we chose, the last second is used to close the claws and beep)
          while (endTime-startTime < 29500)
          { 
            //Set the motor-speed to a random number between 20 and 400
            Motor.A.setSpeed(myRandom(100,400));
            Motor.C.setSpeed(myRandom(100,400));
     
            //If the NXT is facing an obstacle, the the motors are only allowed to turn backward
            if (sonicF.getDistance()<50)
            { 
              Motor.A.backward();
              Motor.C.backward();   
              Delay.msDelay(100);
            }
            //If the NXT's back is facing an obstacle, the the motors are only allowed to turn forward
            else if (sonicB.getDistance()<40) 
            {
              Motor.A.forward();
              Motor.C.forward();
              Delay.msDelay(100);   
            }
            //If there is no obstacle in the way, the directions are chosen randomly
            else
            {
              if (myRandom(0,1)==0) 
              {                   
                Motor.A.forward();
              } // end of if
              else
              {              
                Motor.A.backward();
              }
     
              if (myRandom(0,1)==0) 
              {                   
                Motor.C.forward();
              } // end of if
              else
              {              
                Motor.C.backward();
              }
            }
            //Perform the action for a duration of 100 to 500 milliseconds
            Delay.msDelay(myRandom(100,400));
     
            //reading the current time
            endTime = System.currentTimeMillis();
          } // end of while
     
          //Stopping, closing the claws and beeping
          BluetoothNXT_v4.SoftStop();
          Motor.A.stop();
          Motor.C.stop();
          Motor.B.setSpeed(100);
          Motor.B.backward();
          Thread.sleep(1000);
          Motor.B.stop();
          BluetoothNXT_v4.clawsOpen=false;
          Sound.twoBeeps();
        }
        catch(Exception err) {}
      }
     
      //Random number generator
      static int myRandom(int low, int high) 
      {
        high++;
        return (int) (Math.random() * (high - low) + low);
      }
    }//End of file
Praktikaten: Andreas Mieke, Peter Por
Betreuer: Patrik Grausberg

Leave a Reply