Hauptpost – Klick!

 

Changelog:

  • Es liegen jetzt Treiber für sowohl den NXT, als auch den RFID Reader bei.
  • Die Programme wurden überarbeitet, um den NXT responsiver zu machen.
  • Bugfixes

Download v5.0

 

Die neuen Codes:

Java PC-Programm:

//Written by Peter Por
//Last edited: 30.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 sending a command line argument
	if(args.length!=0)
	{
		InputLocation = args[0];
	}
 
	//Read the config file
	try 
	{
		BufferedReader in = new BufferedReader(new FileReader(InputLocation));
		String line1 = in.readLine();
		String line2 = in.readLine();
		String line3 = in.readLine();
		String line4 = in.readLine();
 
		nxtName = line1;
		COMPort = Integer.parseInt(line2);
		RFIDScanLocation = line3;
		Music = line4;
 
		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 + " not found!");
    }
    else{
      if(!connect.connectTo(nxts[0].name,nxts[0].deviceAddress,NXTCommFactory.BLUETOOTH))
      { //Connection failed
        System.out.println("Connecting to " + nxtName + " failed!");
      }
      else
      { //now there is a connection
        System.out.println("Successfully connected to " + nxtName + " !");
        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("The Program will now shut down.");
        	  break;
          }
          if(p.exitValue()==-2)   // -2 is the Error-Code
          {
        	  System.out.println("Error reading the RFID Tag.");
        	  break;
          }
 
          keypressOld=p.exitValue();
         }
         catch(Exception err)
         {
        	 System.out.println("An unknown Error occured.");
        	 break;
         }
        }// end of loop       
 
    	dos.close();    //Closes the DataOutputStream
        connect.close();    //Closes the Connection to the NXT
        System.out.println("Program was terminated successfully.");
      }
     }
 
    }// 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: 30.07.13
 
#define VERSION "3"
//#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;
		}
		if(tagCounterMax < 1)
		{
			printf("[WARNING]\tFailed to read the config file (maybe because encoding is not ANSI?)");
			return -6;
		}
		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
 
	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 { //Continues until a valid ID was scanned.
		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
 
		for(tagCounter = 0; tagCounter < tagCounterMax; tagCounter++)
		{
			if(strcmp(code,tagIDs[tagCounter]) == 0)
			{
#ifdef DEBUG
				printf("%s return %d\n",tagIDs[tagCounter],tagReturns[tagCounter]);
#endif
				CloseComm(); //Closes connection to Reader (comm.cpp)
				return tagReturns[tagCounter];
			}
#ifdef DEBUG
			else
			{
				printf("no match\n");
			}
#endif
		}
		strcpy(code,"");
	} while(true);
}
//EOF

Java NXT-Programm:

//Written by Peter Por
//Last edited: 30.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_v5 {
 
  //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 which controls 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 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!=3 && 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_v5.clawsOpen)
      safetyDistanceF=23;
      else
      safetyDistanceF=30;
 
 
      try
      {
        if (sonicF.getDistance()<safetyDistanceF && BluetoothNXT_v5.keypress==8) 
        {//The NXT is currently driving forwards and faces an obstacle
          Motor.B.stop();
          BluetoothNXT_v5.SoftStop();
          Motor.A.stop();
          Motor.C.stop();       
          BluetoothNXT_v5.mayDriveForward = false;                  
        }
      }      
      catch(Exception err)
      { }
 
 
      try
      {
        if (sonicB.getDistance()<safetyDistanceB && BluetoothNXT_v5.keypress==2) 
        {//The NXT is currently driving backwards and faces an obstacle
          Motor.B.stop();
          BluetoothNXT_v5.SoftStop();
          Motor.A.stop();
          Motor.C.stop();     
          BluetoothNXT_v5.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();
      Delay.msDelay(20);
      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 < 29000) 
      { 
        //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_v5.SoftStop();
      Motor.A.stop();
      Motor.C.stop();
      Motor.B.setSpeed(100);
      Motor.B.backward();
      Thread.sleep(1000);
      Motor.B.stop();
      BluetoothNXT_v5.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);
  }
}//EOF
Praktikaten: Andreas Mieke, Peter Por
Betreuer: Patrik Grausberg

Leave a Reply