|
|
|
|
Bonjour à tous!
J'utilise dans un programme java l'API javax.comm pour lire des infos venant d'un recepteur gps USB (détecté sur un port série virtuel).
Etant donné que le numéro du port COM attribué au recepteur GPS peut changer et que l'utilisateur du programme ne doit pas s'occuper de ça, je scanne tous les ports série et test si il y a des datas format NMEA (trames du recepteur GPS) qui arrivent du port COM en question. (Je n'ai pas trouver mieux!)
Donc j'essaye de faire une lecture du port série sur évènements comme dans ce tutoriel :
http://christophej.developpez.com/tutoriel/java/javacomm/#L2.3.3
J'ai juste un petit souci maintenant : j'arrive bien a trouver mon recepteur GPS mais mon prog plante une fois les trames lues! Je crois que le prog reste bloqué dans la structure switch qui gère les évènements du port série!
import javax.comm.*;
import java.util.*;
import java.math.*;
import java.net.*;
import com.sun.comm.Win32Driver;
import java.io.*;
public class testCOM implements SerialPortEventListener {
private String portCOM;
private CommPortIdentifier portID = null; //identifiant du port
private SerialPort serialPort; //le port série
private BufferedReader fluxLecture; //flux de lecture du port
/*
* Methode qui initialise le port série en evenementiel
*/
public void ModeEvenement(String portCOM) {
//récupération de l'identifiant du port
try {
portID = CommPortIdentifier.getPortIdentifier(portCOM);
} catch (NoSuchPortException e) {
}
//ouverture du port
try {
serialPort = (SerialPort) portID.open("ModeEvenement", 2000);
} catch (PortInUseException e) {
}
//récupération du flux
try {
fluxLecture =
new BufferedReader(
new InputStreamReader(serialPort.getInputStream()));
} catch (IOException e) {}
//ajout du listener
try {
serialPort.addEventListener(this);
} catch (TooManyListenersException e) {
}
//paramétrage du port
serialPort.notifyOnDataAvailable(true);
try {
serialPort.setSerialPortParams(
4800,
SerialPort.DATABITS_8,
SerialPort.STOPBITS_1,
SerialPort.PARITY_NONE);
} catch (UnsupportedCommOperationException e) {}
System.out.println("port ouvert, attente de lecture");
}
/*
* Methode qui effectue la lecture de 7 trames sur le port série
* Une fois la lecture faite on ferme le flux de lecture et le port COM
*/
public void ReadSerialPort(){
int i=7;
String reponse = new String();
try {
System.out.println("i="+i);
while(i!=0){
System.out.println("On lit sur le port COM\n");
reponse = (String) fluxLecture.readLine();
System.out.println(reponse);
i--;
System.out.println("i="+i);
}
} catch (IOException e) {}
//fermeture du flux de lecture
try {
fluxLecture.close();
} catch (IOException e) {}
//fermeture du port COM
serialPort.close();
}
public void serialEvent(SerialPortEvent event) {
//gestion des événements sur le port :
//on ne fait rien sauf quand les données sont disponibles
switch (event.getEventType()) {
case SerialPortEvent.DATA_AVAILABLE :
this.ReadSerialPort();//si data dispo on lance la lecture
break;
default:
break;//on ne fait rien pour les autres evenements
}
}
/*
* Methode qui scanne tous les ports COM et test si des données viennent du port COm scanné
*/
public void listPort(){
Enumeration listePorts = CommPortIdentifier.getPortIdentifiers();
int typePort;
String GPSPortCOM;
while (listePorts.hasMoreElements()){
portID = (CommPortIdentifier) (CommPortIdentifier) listePorts.nextElement();
if(portID.getPortType()==CommPortIdentifier.PORT_SERIAL){
System.out.println("Nom du PORT :"+portID.getName());
System.out.println("User :"+portID.getCurrentOwner());
System.out.println("Use ? :"+portID.isCurrentlyOwned());
System.out.println("Type du PORT :"+portID.getPortType());
// On lance la gestion des évènements sur portID
this.ModeEvenement(portID.getName());
}
}
}
public static void main(String[] args) {
//initialisation du driver
Win32Driver w32Driver = new Win32Driver();
w32Driver.initialize();
testCOM test = new testCOM();
test.listPort();
}
}
Configuration: Windows XP Firefox 2.0.0.3
Salut!
private int nbreTramesLues = 0; private final int NBRE_TRAMES_A_LIRE = 7; et au lieu de mettre dans le run(), while(running) comme dans le tuto, tu mets while(this.nbreTramesLues < this.NBRE_TRAMES_A_LIRE) - et puis pour les trames, lis trame par trame et pas les sept d'un coup: public void serialEvent(SerialPortEvent event) {
//gestion des événements sur le port :
//on ne fait rien sauf quand les données sont disponibles
switch (event.getEventType()) {
case SerialPortEvent.DATA_AVAILABLE :
try{
System.out.println("On lit sur le port COM\n");
reponse = (String) fluxLecture.readLine();
System.out.println(reponse);
this.nbreTramesLues++;
}catch(IOException e){
}
break;
default:
break;//on ne fait rien pour les autres evenements
}
}
Dans le main tu lances juste ton thread en appelant la méthode start() (attention, pas run()directement!), si tout vas bien, le thread s'arrête de lui même une fois les sept trames reçues et le port est fermé, plus de problème! Enfin ça c'est si tout va bien, même comme ça si t'as pas tes sept trames, ton thread va rester bloqué indéfiniment dans le while, il faudra arranger ça, mais c'est déjà un début. Voilà, après j'ai pas bien compris, tu fais ça pour chaque port série? Qu'est ce que tu fais si tu reçois rien sur un port? T'attends indéfiniment qu'il y ait des données qui arrivent? Un truc encore, les méthodes commencent par une minuscule en java et les classes par une majuscule, là t'as fait exactement l'inverse! c'est plus facile de se repérer si tu suis ces conventions d'écriture. Voilà ce n'est que mon avis sur la question, j'éspère que ça pourra t'aider un peu! bye!
|
Je m'adresse en fait a goddet,je suis entrain de developper une application qui permet la navigation gps sur un pocket pc,comme première étape j'ai besoin de capter les trames nmea provenant du gps sur un port série,j'ai essayé de faire sa avec l'hyperterminal,et je vois que votre code va bien avec mon application?
|