Test ecriture / Lecture en Java : Port Serie RS232

Résolu
lionkid007 Messages postés 4 Date d'inscription dimanche 17 février 2008 Statut Membre Dernière intervention 22 mars 2008 - 19 févr. 2008 à 11:13
 dms006gn - 16 mars 2011 à 12:56
Bonjour,

Je dois faire un programme permettant de communiquer sur le port serie RS232 en Java.
Je dois donc pouvoir lire et ecrire. J'ai bien regardé les différents fichiers dispo, mais j'arrive pas à faire ce que je veux.
J'ai relié la patte TX à RX de mon port série et je veux pouvoir avec mon programme java, afficher ce que j'ai envoyé via mon programme en java.
Je suis débutant en java et j'ai du mal...
Si vous pouviez m'aider, merci!!!!

Voilà le code que j'ai déjà utilisé :
import javax.comm.*;
import java.io.*;
import java.util.*;

/*
Cette classe permet de tester les ports séries disponibles
en les listant puis en créant un stream d'entrée et de sortie
*/
public class TesteJavaComm
{
CommPortIdentifier portId;
BufferedReader in;
PrintWriter out;
SerialPort serialPort;

/*
Constructeur de la classe TesteJavaComm qui prend en paramètre le port série à utiliser.
Dans un premier temps on liste les ports disponibles sur le pc
*/
public TesteJavaComm (String com)
{
System.out.println("listage des ports série disponibles:");
listePortsDispo();
try
{
//ouverture du port série:
portId=CommPortIdentifier.getPortIdentifier(com);
serialPort=(SerialPort)portId.open("Envoi",2000);

//on sélectionne tous les paramètres de la connexion série:
serialPort.setSerialPortParams(9600,SerialPort.DATABITS_8,
SerialPort.STOPBITS_1,SerialPort.PARITY_NONE);
System.out.println("Ouverture du port "+com);

//pour lire et écrire avec des streams:
in=new BufferedReader(
new InputStreamReader(serialPort.getInputStream()));
out=new PrintWriter(serialPort.getOutputStream());

//Teste de lecture/ecriture sur le port série

String originalText="une chaine de caractere";
outputArray = originalText.getBytes( );
out.write ( outputArray, 0 , length );
int b = in.read()
in.close();
out.close();

}
catch (Exception e)
{
e.printStackTrace();
}
}//fin constructeur

public void listePortsDispo()
{
System.err.println("recherche...");
Enumeration portList=CommPortIdentifier.getPortIdentifiers();
if (portList==null)
{
System.err.println("Aucun port de communication détecté");
return;
}
while (portList.hasMoreElements())
{
portId=(CommPortIdentifier)portList.nextElement();
System.out.println("* "+portId.getName());
} // while
} //fin de la methode listePortsDispo()

/*
Methode main qui permet de tester notre classe de teste en ouvrant une connexion sur le port COM1.
*/
public static void main(String args[])
{
new TesteJavaComm ("COM1");
}//fin du main

}//fin de la classe



PS : Quand j'ai essayé ce bout de code, j'ai des erreurs comme quoi : OutputArray et length ne sont pas définis?? Il faut faire un String OutputArray et un int length?

merci encore, A++

68 réponses

PY01A0080 Messages postés 24 Date d'inscription mardi 21 novembre 2006 Statut Membre Dernière intervention 15 mars 2011 1
31 déc. 2010 à 12:17
Bonjour à tous,

je suis débutant en java.
j'ai fait des recherches sur internet sur la communication port série en java et j'ai trouvé pas mal d'infos.
Donc mon projet est de lire les trames envoyés par une station météo.
J'arrive biensur à communiquer avec HyperTerminal ex je tape 0R0 et la station me répond par une trame donc une ligne avec des infos comme température, vent...

Donc j'airécupéré un code sur le net, quand je le lance, il énumère bien tous les ports puis à la fin ouvre le port COM1 puis plus rien, je ne vois pas la trame. pourquoi?

voici le code


[CODE]

package TesteJavaComm;
import javax.comm.*;
import java.io.*;
import java.util.*;
import com.sun.comm.Win32Driver;

/*
Cette classe permet de tester les ports séries disponibles
en les listant puis en créant un stream d'entrée et de sortie
*/
public class TesteJavaComm
{
CommPortIdentifier portId;
BufferedReader in;
PrintWriter out;
SerialPort serialPort;

/*
Constructeur de la classe TesteJavaComm qui prend en paramètre le port série à utiliser.
Dans un premier temps on liste les ports disponibles sur le pc
*/
public TesteJavaComm (String com)
{
Win32Driver w32Driver= new Win32Driver();
w32Driver.initialize();
System.out.println("listage des ports série disponibles:");
listePortsDispo();
try
{
//ouverture du port série:
portId=CommPortIdentifier.getPortIdentifier(com);
serialPort=(SerialPort)portId.open("Envoi",5000);

int i=0;
do
{
//on sélectionne tous les paramètres de la connexion série:
serialPort.setSerialPortParams(9600,SerialPort.DATABITS_8,SerialPort.STOPBITS_1,SerialPort.PARITY_NONE);
System.out.println("Ouverture du port "+com);

//pour lire avec des streams:
in=new BufferedReader(new InputStreamReader(serialPort.getInputStream()));

//Teste de lecture sur le port série
int b = in.read();
System.out.println(in.read());
System.out.println(b);
in.close();
i++;
}while(i!=3);
}
catch (Exception e)
{
e.printStackTrace();
}
}//fin constructeur

public void listePortsDispo()
{
System.err.println("recherche...");
Enumeration portList=CommPortIdentifier.getPortIdentifiers();
if (portList==null)
{
System.err.println("Aucun port de communication détecté");
return;
}
while (portList.hasMoreElements())
{
portId=(CommPortIdentifier)portList.nextElement();
System.out.println("* "+portId.getName());
} // while
} //fin de la methode listePortsDispo()

/*
Methode main qui permet de tester notre classe de teste en ouvrant une connexion sur le port COM1.
*/
public static void main(String args[])
{
new TesteJavaComm ("COM1");
}//fin du main
}//fin de la classe


[CODE]

Merci à tous et bonne fin d'année.


ZEN
0
lionkid Messages postés 18 Date d'inscription mercredi 27 décembre 2006 Statut Membre Dernière intervention 15 mars 2011
2 janv. 2011 à 18:27
Salut,

Voici ton code - en partie - repris et amélioré :
Sache que tu fais une erreur lorsque tu fais :
//Teste de lecture sur le port série
int b = in.read();
System.out.println(in.read());
System.out.println(b);
in.close(); 

Il ne faut pas lire puis fermer le buffer d'entrée! Sinon comment peux-tu lire les données suivantes? L'ouverture et la fermeture doivent être effectuées de manière unique. Une fois au début et une fois à la fin (sinon tu comprends bien que si tu fermes, tu seras obligé de re-ouvrir...).

Voici donc un code opérationnel pour peu que les indications en javadoc soient suivies pas à pas :
package test_serial_port;

import java.io.DataInputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;
import javax.comm.CommPortIdentifier;
import javax.comm.SerialPort;
import com.sun.comm.Win32Driver;

/**
 * This class allows opening, closing, reading and writing from and to a serial port
 * (using the RS232 protocol) on Windows plateform.
 * In order to work properly, the following procedure MUST already be done :
 * 1. Download the following content from this url :
 * {@link http://www.cs.uml.edu/~fredm/courses/91.305/software/JDK118-javaxcomm.zip}
 * 2. Copy and paste the file "win32com.dll" into the directory : C:\Windows\System32
 * 3. Copy and paste the file "javax.comm.properties" into the directory C:\Program Files\Java\jre\lib
 * 4. Copy and paste the file "comm.jar" into the directory C:\Program Files\Java\jre\lib\ext
 * 5. Open Eclipse and add the "comm.jar" file (found in 4.) into the classPath 
 * (right click on Java project > properties > Java Build Path > Libraries > Add external Jars...)
 * 6. Enjoy!
 * @author lionkid
 */
public class RS232
{
private static final String appName = "Envoi";						// Application name that request opening the serial port.
private static final int openTimeOut = 5000; 						// 5seconds.
private CommPortIdentifier portId;
private DataInputStream in;
private PrintWriter out;
private SerialPort serialPort;

private static final int databits = SerialPort.DATABITS_8;			// RS-232 configuration
private static final int stopbit = SerialPort.STOPBITS_1;			// RS-232 configuration
private static final int parity = SerialPort.PARITY_NONE;			// RS-232 configuration
private static final int baudrate = 9600;							// RS-232 configuration
/**
 * Constructor
 * @param com the communication port to open
 * @author lionkid
 */
public RS232(String com, boolean listAvailablePorts) 
{
Win32Driver w32Driver = new Win32Driver();
w32Driver.initialize();

try 
{
// Listing or not available serial and parallel ports found...
if(listAvailablePorts) System.out.println(availableSerialCommPorts());

// Opening com port...
System.out.println("Trying to open serial port '" + com + "'...");
portId = CommPortIdentifier.getPortIdentifier(com);
serialPort = (SerialPort) portId.open(appName, openTimeOut);
System.out.println("Successfully opened serial port '" + serialPort.getName() + "'!");

// Setting the serial connection as requested...
serialPort.setSerialPortParams(baudrate, databits, stopbit, parity);
in = new DataInputStream(serialPort.getInputStream());
}
catch(Exception e)
{
System.out.println(e.getMessage());
System.exit(1);					// Exit application! Adapt if needed!
}
}

/**
 * Read input stream through the RS-232 protocol 
 * (from the serial or parallel communication port)
 * @return
 * @author lionkid
 */
public char read()
{
try 
{
return in.readChar();
} 
catch (IOException e) 
{
System.out.println("Error when trying to read! "+e.getMessage());
System.exit(1);					// Exit application! Adapt if needed!
}
return '0';							// Returns the '0' char caracter if reading fails
}

/**
 * Send a message through the serial port
 * @param sendMsg
 * @author lionkid
 */
public void send(String sendMsg)
{
try
{
out.write(sendMsg);	
}
catch(Exception e)
{
System.out.println("Is port available and opened?\n"+e.getMessage());
System.exit(1);					// Exit application! Adapt if needed!
}
}

/**
 * Close serial connection
 * @param none
 * @return
 * @author lionkid
 */
public void closeConnection()
{
try 
{
in.close();
out.close();
} 
catch (IOException e) 
{
System.out.println("Cannot open and / or close serial connection!Details:\n"+e.getMessage());
System.exit(1);					// Exit application! Adapt if needed!
}
}

/**
 * List all the available serial and parallel communication ports
 * @return the list of all available serial and parallel communication ports.
 */
public String availableSerialCommPorts() 
{
System.err.println("Searching...");
String list = "";
Enumeration<Object> portList = CommPortIdentifier.getPortIdentifiers();

if (portList == null) 											// port(s) not found
{
System.err.println("No communication port detected!");		// notify it in the console
return null;												
}
else															// port(s) found
{
System.err.println("Detected serial communication ports !\n");
while (portList.hasMoreElements()) 
{
portId = (CommPortIdentifier) portList.nextElement();	// get the found port
System.out.println("Found : "+portId.getName());		// notify it in the console
list += portId.getName()+"\n";							// add it in the String list
}
return list;												// Return the full list
}
}

/**
 * Typical example of use of the RS232 class
 * @param args
 * @author lionkid
 */
public static void main(String args[])
{
RS232 example = new RS232("COM1", true);	// List all the available and found port com and try opening "COM1".
example.send("Hello world!");				// Send the "Hello world!" string through the RS-232
System.out.println(example.read());			// Get the message sent by the remote device through the RS-232 protocol.
example.closeConnection();					// Close the connection.
}
}


Voilà!

@+ and Enjoy!

~ Be good. Share the knowledge and enjoy life! ~
0
lionkid Messages postés 18 Date d'inscription mercredi 27 décembre 2006 Statut Membre Dernière intervention 15 mars 2011
2 janv. 2011 à 18:41
Petite rectification (plutôt un ajout d'une instruction manquante) pour la méthode send() :

/**
 * Send a message through the serial port
 * @param sendMsg
 * @author lionkid
 */
public void send(String sendMsg)
{
try
{
out.write(sendMsg);
out.flush();
}
catch(Exception e)
{
System.out.println("Is port available and opened?\n"+e.getMessage());
        System.exit(1);		// Exit application! Adapt if needed!
}
}
0
PY01A0080 Messages postés 24 Date d'inscription mardi 21 novembre 2006 Statut Membre Dernière intervention 15 mars 2011 1
2 janv. 2011 à 19:20
Bonjour LionKid,

merci infiniment de ton aide.
demain matin j'essaie le code puis te tiens au courant.
Je pense être sur la bonne voie grace à toi.
je reviendrai vers toi

@plus et bonne année 2011!

ZEN
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
PY01A0080 Messages postés 24 Date d'inscription mardi 21 novembre 2006 Statut Membre Dernière intervention 15 mars 2011 1
3 janv. 2011 à 11:02
Bonjour LionKid,

je viens d'essayer le code modifié sur Netbeans avec mon appareil connecté sur le port série.

Ce que je ne comprends pas c'est à la fin, il me dit :
"Is port available and opened?
null
"

J'ai remplacé le mot "Hello World!" par 0R0 car c'est la ligne de commande que je tape sur lien Hyper Terminal et l'appareil me répond par une trame et là je ne vois pas la trame.

Pourquoi?


Voici le résultat:
"
run:
Searching...
Found : COM6
Detected serial communication ports !
Found : COM7

Found : COM10
Found : COM11
Found : COM12
Found : COM13
Found : COM14
Found : COM20
Found : COM21
Found : COM22
Found : COM3
Found : COM1
Found : LPT1
Found : LPT2
Found : COM6
Found : COM7
Found : COM10
Found : COM11
Found : COM12
Found : COM13
Found : COM14
Found : COM20
Found : COM21
Found : COM22
Found : COM3
Found : COM1
Found : LPT1
Found : LPT2
COM6
COM7
COM10
COM11
COM12
COM13
COM14
COM20
COM21
COM22
COM3
COM1
LPT1
LPT2
COM6
COM7
COM10
COM11
COM12
COM13
COM14
COM20
COM21
COM22
COM3
COM1
LPT1
LPT2

Trying to open serial port 'COM1'...
Successfully opened serial port 'COM1'!
Is port available and opened?
null
Java Result: 1
GÉNÉRATION TERMINÉE (durée totale  0 secondes)
"


Merci
ZEN
0
Twinuts Messages postés 5375 Date d'inscription dimanche 4 mai 2003 Statut Modérateur Dernière intervention 14 juin 2023 111
3 janv. 2011 à 12:13
Salut,

Dans le code de "lionkid" la variable 'out' est bien déclarée mais n'est jamais initialisée.
Apres la ligne "in new DataInputStream(serialPort.getInputStream());" tu peux ajouter l'initialisation de la variable 'out' avec par exemple "out new PrintWriter(serialPort.getOutputStream());"

Si tu passes la valeur 'autoFlush' à true dans le constructeur du PrintWriter pense à supprimer la ligne "out.flush();" de la méthode write proposée

------------------------------------
"On n'est pas au resto : ici on ne fait pas dans les plats tout cuits ..."

OoWORAoO
0
lionkid Messages postés 18 Date d'inscription mercredi 27 décembre 2006 Statut Membre Dernière intervention 15 mars 2011
3 janv. 2011 à 15:50
Salut PY01A0080,

Le dernier post de Twinuts devrait répondre à toutes tes interrogations. Merci - au passage - pour ton intervention Twinuts. ;)
Effectivement, il manque l'initialisation du stream de sortie. Il faut donc ajouter la ligne proposée par Twinuts et tout devrait rentrer dans l'ordre.

@+

lionkid.

PS: Code mis à jour :

package test_serial_port;

import java.io.DataInputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;
import javax.comm.CommPortIdentifier;
import javax.comm.SerialPort;
import com.sun.comm.Win32Driver;

/**
 * This class allows opening, closing, reading and writing from and to a serial port
 * (using the RS232 protocol) on Windows plateform.
 * In order to work properly, the following procedure MUST already be done :
 * 1. Download the following content from this url :
 * {@link http://www.cs.uml.edu/~fredm/courses/91.305/software/JDK118-javaxcomm.zip}
 * 2. Copy and paste the file "win32com.dll" into the directory : C:\Windows\System32
 * 3. Copy and paste the file "javax.comm.properties" into the directory C:\Program Files\Java\jre\lib
 * 4. Copy and paste the file "comm.jar" into the directory C:\Program Files\Java\jre\lib\ext
 * 5. Open Eclipse and add the "comm.jar" file (found in 4.) into the classPath 
 * (right click on Java project > properties > Java Build Path > Libraries > Add external Jars...)
 * 6. Enjoy!
 * @author lionkid
 */
public class RS232
{
private static final String appName = "Envoi";						// Application name that request opening the serial port.
private static final int openTimeOut = 5000; 						// 5seconds.
private CommPortIdentifier portId;
private DataInputStream in;
private PrintWriter out;
private SerialPort serialPort;

private static final int databits = SerialPort.DATABITS_8;			// RS-232 configuration
private static final int stopbit = SerialPort.STOPBITS_1;			// RS-232 configuration
private static final int parity = SerialPort.PARITY_NONE;			// RS-232 configuration
private static final int baudrate = 9600;							// RS-232 configuration
/**
 * Constructor
 * @param com the communication port to open
 * @author lionkid
 */
public RS232(String com, boolean listAvailablePorts) 
{
Win32Driver w32Driver = new Win32Driver();
w32Driver.initialize();

try 
{
// Listing or not available serial and parallel ports found...
if(listAvailablePorts) System.out.println(availableSerialCommPorts());

// Opening com port...
System.out.println("Trying to open serial port '" + com + "'...");
portId = CommPortIdentifier.getPortIdentifier(com);
serialPort = (SerialPort) portId.open(appName, openTimeOut);
System.out.println("Successfully opened serial port '" + serialPort.getName() + "'!");

// Setting the serial connection as requested...
serialPort.setSerialPortParams(baudrate, databits, stopbit, parity);
in = new DataInputStream(serialPort.getInputStream());
                        out = new PrintWriter(serialPort.getOutputStream());
}
catch(Exception e)
{
System.out.println(e.getMessage());
System.exit(1);					// Exit application! Adapt if needed!
}
}

/**
 * Read input stream through the RS-232 protocol 
 * (from the serial or parallel communication port)
 * @return
 * @author lionkid
 */
public char read()
{
try 
{
return in.readChar();
} 
catch (IOException e) 
{
System.out.println("Error when trying to read! "+e.getMessage());
System.exit(1);					// Exit application! Adapt if needed!
}
return '0';						// Returns the '0' char caracter if reading fails
}

/**
 * Send a message through the serial port
 * @param sendMsg
 * @author lionkid
 */
public void send(String sendMsg)
{
try
{
out.write(sendMsg);
                out.flush();
}
catch(Exception e)
{
System.out.println("Is port available and opened?\n"+e.getMessage());
System.exit(1);					// Exit application! Adapt if needed!
}
}

/**
 * Close serial connection
 * @param none
 * @return
 * @author lionkid
 */
public void closeConnection()
{
try 
{
in.close();
out.close();
} 
catch (IOException e) 
{
System.out.println("Cannot open and / or close serial connection!Details:\n"+e.getMessage());
System.exit(1);					// Exit application! Adapt if needed!
}
}

/**
 * List all the available serial and parallel communication ports
 * @return the list of all available serial and parallel communication ports.
 */
public String availableSerialCommPorts() 
{
System.err.println("Searching...");
String list = "";
Enumeration<Object> portList = CommPortIdentifier.getPortIdentifiers();

if (portList == null) 							// port(s) not found
{
System.err.println("No communication port detected!");		// notify it in the console
return null;												
}
else									// port(s) found
{
System.err.println("Detected serial communication ports !\nFound:\n");
while (portList.hasMoreElements()) 
{
portId = (CommPortIdentifier) portList.nextElement();	// get the found port
list += portId.getName()+"\n";				// add it in the String list
}
return list;							// Return the full list
}
}

/**
 * Typical example of use of the RS232 class
 * @param args
 * @author lionkid
 */
public static void main(String args[])
{
RS232 example = new RS232("COM1", true);	               // List all the available and found port com and try opening "COM1".
example.send("Hello world!");			               // Send the "Hello world!" string through the RS-232
System.out.println("Received message = '"+example.read()+"'"); // Get the message sent by the remote device through the RS-232 protocol.
example.closeConnection();			               // Close the connection.
}
}
0
PY01A0080 Messages postés 24 Date d'inscription mardi 21 novembre 2006 Statut Membre Dernière intervention 15 mars 2011 1
3 janv. 2011 à 16:14
Merci LionKid,

j'ai même ajouter ceci:

RS232 example = new RS232("COM1", true);	
example.send("0R0");
                                   System.out.println("test ecriture OK");
System.out.println(example.read());
                                   System.out.println("test lecture OK");
example.closeConnection();


Donc le résulat est:
....
COM21
COM22
COM3
COM1
LPT1
LPT2

Trying to open serial port 'COM1'...
Successfully opened serial port 'COM1'!
test ecriture OK


Mais je n'obtiens pas de trame venant de mon appareil.
Je suis débutant, je ne comprends pas:
- en Hyper Terminal l'appareil me répond par une trame quand je tape la commande "0R0" donc c'est parfait.

par contre avec le code RS232, y a rien.

je réfléchis encore...
il faut que j'arrive.

merci LionKid et Twinuts
ZEN
0
sid002 Messages postés 30 Date d'inscription dimanche 16 avril 2006 Statut Membre Dernière intervention 4 janvier 2011
3 janv. 2011 à 16:21
Bonjour PY01A0080

Comment fais tu pour communiquer avec ton peripherique en hyperterminal ?
Je pensais que ça servait seulement à communiquer avec un modem !

D'avance merci

sidus
0
PY01A0080 Messages postés 24 Date d'inscription mardi 21 novembre 2006 Statut Membre Dernière intervention 15 mars 2011 1
3 janv. 2011 à 16:33
Salut,


en fait:
je connecte mon appareil sur le port série de mon pc.
j'ouvre Hyper terminal
je configure à 9600 bauds, Databits8, Stopbits à 1, sans parité at pas de controle de flux.
puis je tape les differents commande et l'appreil me répond par une trame.
voilà

ZEN
0
sid002 Messages postés 30 Date d'inscription dimanche 16 avril 2006 Statut Membre Dernière intervention 4 janvier 2011
3 janv. 2011 à 16:37
Merci pour ta réponse.

Est ce qu'il y a des commandes standard ou est ce bien specifique à chaque machine ?

sidus
0
Twinuts Messages postés 5375 Date d'inscription dimanche 4 mai 2003 Statut Modérateur Dernière intervention 14 juin 2023 111
3 janv. 2011 à 16:47
Salut,

Tu fais un send("0R0") mais après tu fais un simple read() ce qui n'est pas réellement correct car la méthode read appel la méthode readChar de l'inputstream ce qui fait qu'ici tu ne read qu'un char de la réponse, qui plus est, ce char peut ne pas être affichable (char d’échappement)...

Pourquoi faire une lecture char/char et non une lecture de type block avec un bon vieux buffer et ensuite retourner la chaîne complète ?



------------------------------------
"On n'est pas au resto : ici on ne fait pas dans les plats tout cuits ..."

OoWORAoO
0
PY01A0080 Messages postés 24 Date d'inscription mardi 21 novembre 2006 Statut Membre Dernière intervention 15 mars 2011 1
3 janv. 2011 à 21:15
Merci OoWORAoO,
je reviendrai vers vous dans deux jours car obligé de partie en déplacement.
à plus
ZEN
0
lionkid Messages postés 18 Date d'inscription mercredi 27 décembre 2006 Statut Membre Dernière intervention 15 mars 2011
4 janv. 2011 à 13:31
Salut PY01A0080,

Twinuts a raison et je pensais exactement à la même chose.
Si tu jettes un oeil à la javadoc de l'InputStream :
InputStream

Tu verras que t'as 2 méthodes utiles :
available() et read(byte[] b, int off, int len).

Je te conseillerais d'utiliser la premiere (available()) si tu ne sais pas exactement combien d'octets de données tu dois lire. En revanche, si tu connais la taille du message à lire, utilise la seconde méthode (read(...)).

Avec la première tu pourrais simplement faire un truc du genre :

while(in.available()>0)  // Sors du while, lorsqu'il n'y a plus de données à lire
{
   msg+=msg+in.read();
}
return msg;


Là tu seras sûr de ne pas tomber sur des \n, \r, etc... invisible puisque c'est des retour chariot etc...

Bon courage.

@+
0
Twinuts Messages postés 5375 Date d'inscription dimanche 4 mai 2003 Statut Modérateur Dernière intervention 14 juin 2023 111
4 janv. 2011 à 14:01
Salut,

attention tu fais : msg+=msg+in.read(); qui veut dire que tu concatènes dans msg lui même + la lecture... tu voulais pas plutôt écrire msg+= msg+ in.read(); donc msg+ =in.read(); ?


Sinon je pense plutôt que de concaténer à ta variable la lecture octet / octet ce qui est assez lourd (manipulation de strings) de rester sur les read par block avec par exemple un truc du style :

public byte[] readBytes() {
  try {
    byte buffer[] = new byte[1024];
    int n=0, offset=0, i=0;
    while(true) {
      i = in.available();
      n = in.read(buffer, offset, i);
      if (n<=0 || n == i) break;
      offset+=n;
    }
    return buffer;
  } catch (IOException e) {
    return null;
  }
}


------------------------------------
"On n'est pas au resto : ici on ne fait pas dans les plats tout cuits ..."

OoWORAoO
0
PY01A0080 Messages postés 24 Date d'inscription mardi 21 novembre 2006 Statut Membre Dernière intervention 15 mars 2011 1
4 janv. 2011 à 15:56
Salut OoWORAoO,

j'ai éssayé avec ta méthode.
je n'obtiens toujours rien en réponse

résultat:
....
Trying to open serial port 'COM1'...
Successfully opened serial port 'COM1'!
test ecriture OK
test lecture OK
GÉNÉRATION TERMINÉE (durée totale  1 seconde)

Soit je révise mon cours sur IO sinon je passe sur un autre langage.
je sais qu'il y a juste quelques lignes à ajouter/supprimer.

merci
ZEN
0
Twinuts Messages postés 5375 Date d'inscription dimanche 4 mai 2003 Statut Modérateur Dernière intervention 14 juin 2023 111
4 janv. 2011 à 16:50
Ptite question,

Quand tu fais ton test, ton device à bien boot ou il est en process de boot ?
Ce qu'il peut se produire aussi c'est qu'il est en chargement en ram de l'os (cas des bzimages unix) et qu'il n’écrive pas encore, du coup tu n'auras rien et il ne répondra pas à ta commande...

Sinon peux tu stp faire une copie de ta classe RS232 (celle que tu utilises) ainsi que le petit bout de code qui te permet d'effectuer tes tests et le tout dans une petite balise code java (pour conserver l'indentation and co) qu l'on puisse voir si tu ne t'en pas embrouillé dans ton coin ;)

Tu peux également réviser tes cours I/O ça ne fait jamais de mal, pour ce qu'y est du passage à un autre langage... comment dire... il y a casi 100% de chances que tu ais le même problème.


Autre point, en regardant le code proposé par 'lionkid' (c'est bien celui que tu utilises ?) je remarque que généralement j'ajoute ça en plus (apres la ligne 'serialPort.setSerialPortParams(baudrate, databits, stopbit, parity);') :

serialPort.notifyOnFramingError(false);
serialPort.notifyOnOverrunError(false);
serialPort.notifyOnParityError(false);

// Set notifyOnDataAvailable to true to allow event driven input.
serialPort.notifyOnDataAvailable(true);

serialPort.notifyOnOutputEmpty(true);

// Set notifyOnBreakInterrup to allow event driven break handling.
serialPort.notifyOnBreakInterrupt(true);

// Set receive timeout to allow breaking out of polling loop during
// input handling.
try {
  serialPort.enableReceiveTimeout(timeoutRx); // perso je place timeoutRx = 5000
} catch (javax.comm.UnsupportedCommOperationException e) {
  e.printStackTrace();
}




------------------------------------
"On n'est pas au resto : ici on ne fait pas dans les plats tout cuits ..."

OoWORAoO
0
PY01A0080 Messages postés 24 Date d'inscription mardi 21 novembre 2006 Statut Membre Dernière intervention 15 mars 2011 1
4 janv. 2011 à 17:00
OK,

je t'envoie tout le code.

package RS232;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;
import javax.comm.CommPortIdentifier;
import javax.comm.SerialPort;
import com.sun.comm.Win32Driver;

/**
 * This class allows opening, closing, reading and writing from and to a serial port
 * (using the RS232 protocol) on Windows plateform.
 * In order to work properly, the following procedure MUST already be done :
 * 1. Download the following content from this url :
 * {@link http://www.cs.uml.edu/~fredm/courses/91.305/software/JDK118-javaxcomm.zip}
 * 2. Copy and paste the file "win32com.dll" into the directory : C:\Windows\System32
 * 3. Copy and paste the file "javax.comm.properties" into the directory C:\Program Files\Java\jre\lib
 * 4. Copy and paste the file "comm.jar" into the directory C:\Program Files\Java\jre\lib\ext
 * 5. Open Eclipse and add the "comm.jar" file (found in 4.) into the classPath 
 * (right click on Java project > properties > Java Build Path > Libraries > Add external Jars...)
 * 6. Enjoy!
 * @author lionkid
 */

public class RS232
{
private static final String appName = "Envoi";						// Application name that request opening the serial port.
private static final int openTimeOut = 5000; 						// 5seconds.
private CommPortIdentifier portId;
private DataInputStream in;
private PrintWriter out;
private SerialPort serialPort;


        private static final int baudrate = 9600;                                       // RS-232 configuration
private static final int databits = SerialPort.DATABITS_8;			// RS-232 configuration
private static final int stopbit = SerialPort.STOPBITS_1;			// RS-232 configuration
private static final int parity = SerialPort.PARITY_NONE;			// RS-232 configuration

/**
 * Constructor
 * @param com the communication port to open
 * @author lionkid
 */
public RS232(String com, boolean listAvailablePorts)
{
Win32Driver w32Driver = new Win32Driver();
w32Driver.initialize();

try
{
// Listing or not available serial and parallel ports found...
if(listAvailablePorts) System.out.println(availableSerialCommPorts());

// Opening com port...
System.out.println("Trying to open serial port '" + com + "'...");
portId = CommPortIdentifier.getPortIdentifier(com);
serialPort = (SerialPort) portId.open(appName, openTimeOut);
System.out.println("Successfully opened serial port '" + serialPort.getName() + "'!");

// Setting the serial connection as requested...
serialPort.setSerialPortParams(baudrate, databits, stopbit, parity);
in = new DataInputStream(serialPort.getInputStream());
                        out = new PrintWriter(serialPort.getOutputStream());
}
catch(Exception e)
{
System.out.println(e.getMessage());
System.exit(1);					// Exit application! Adapt if needed!
}
}

/**
 * Read input stream through the RS-232 protocol
 * (from the serial or parallel communication port)
 * @return
 * @author lionkid
 */
public char read()
{
try
{
return in.readChar();
}
catch (IOException e)
{
System.out.println("Error when trying to read! "+e.getMessage());
System.exit(1);					// Exit application! Adapt if needed!
}
return '0';							// Returns the '0' char caracter if reading fails
}

/**
 * Send a message through the serial port
 * @param sendMsg
 * @author lionkid
 */
public void send(String sendMsg)
{
try
{
out.write(sendMsg);
                      
}
catch(Exception e)
{
System.out.println("Is port available and opened?\n"+e.getMessage());
System.exit(1);					// Exit application! Adapt if needed!
}
}

/**
 * Close serial connection
 * @param none
 * @return
 * @author lionkid
 */
public void closeConnection()
{
try
{
in.close();
out.close();
}
catch (IOException e)
{
System.out.println("Cannot open and / or close serial connection!Details:\n"+e.getMessage());
System.exit(1);					// Exit application! Adapt if needed!
}
}

/**
 * List all the available serial and parallel communication ports
 * @return the list of all available serial and parallel communication ports.
 */
public String availableSerialCommPorts()
{
System.err.println("Searching...");
String list = "";
Enumeration<Object> portList = CommPortIdentifier.getPortIdentifiers();

if (portList == null) 											// port(s) not found
{
System.err.println("No communication port detected!");		// notify it in the console
return null;
}
else															// port(s) found
{
System.err.println("Detected serial communication ports !\n");
while (portList.hasMoreElements())
{
portId = (CommPortIdentifier) portList.nextElement();	// get the found port
System.out.println("Found : "+portId.getName());		// notify it in the console
list += portId.getName()+"\n";							// add it in the String list
}
return list;												// Return the full list
}
}
public byte[] readBytes() {
  try {
    byte buffer[] = new byte[1024];
    int n=0, offset=0, i=0;
    while(true) {
      i = in.available();
      n = in.read(buffer, offset, i);
      if (n<=0 || n == i) break;
      offset+=n;
    }
    return buffer;
  } catch (IOException e) {
    return null;
  }
}
/**
 * Typical example of use of the RS232 class
 * @param args
 * @author lionkid
 */
public static void main(String args[])
{
RS232 example = new RS232("COM1", true);	// List all the available and found port com and try opening "COM1".
example.send("0R0");
                System.out.println("test ecriture OK");// Send the "Hello world!" string through the RS-232
//System.out.println(example.read());
                System.out.println("test lecture OK");// Get the message sent by the remote device through the RS-232 protocol.
example.closeConnection();					// Close the connection.
}
}



t'as peut-être raison il est bien possible que je m'embrouille tout seul dans mon coin.
C'est la première que j'eesaie le port série en java.

ZEN
0
Twinuts Messages postés 5375 Date d'inscription dimanche 4 mai 2003 Statut Modérateur Dernière intervention 14 juin 2023 111
4 janv. 2011 à 17:42
Salut,

Si tu laisses la ligne System.out.println(example.read()); (de ton main) en commentaire tu n'auras rien en lecture ...


il faudrait que tu change ton main comme suit :
public static void main(String args[]) {
  RS232 example = new RS232("COM1", true); // List all the available and found port com and try opening "COM1".
  example.send("0R0");
  System.out.println("test ecriture OK");// Send the "Hello world!" string through the RS-232
  byte buffer = example.readBytes();
  if(buffer == null)
    System.err.println("Read error, see the stack trace for more details...");
  else {
    // on demande à java de transformer la chaîne bytes en String.
    // Attention il se peut que la chaîne contienne des données non affichables
    System.out.println(new String(b, 0, b.length); 
    System.out.println("test lecture OK");// Get the message sent by the remote device through the RS-232 protocol.
  }
  example.closeConnection(); // Close the connection.
}





------------------------------------
"On n'est pas au resto : ici on ne fait pas dans les plats tout cuits ..."

OoWORAoO
0
lionkid Messages postés 18 Date d'inscription mercredi 27 décembre 2006 Statut Membre Dernière intervention 15 mars 2011
4 janv. 2011 à 18:24
Salut Twinuts,

Oui effectivement, une petite erreur s'est glissée dans mon code tapée à la va-vite. Merci. :)

Il s'agit donc bien de

while(in.available()>0) // while data is available, keep reading...
{
   msg+=in.read();
}
return msg;


'PY01A0080', concernant la méthode de Twinuts, si tu ajoutes sa méthode, il faut effectivement l'utiliser en conséquence dans le main pour pouvoir constater les modifs... :)

Pense donc à l'utiliser comme Twinuts te l'as proposé (Supprime le :
//System.out.println(example.read());
)

@Twinuts : Ta méthode readBytes() renvoie un tableau de byte. Donc, ce serait plutôt :
byte[] buffer
, non?
Enfin, plutôt que de convertir les bytes en String, on aurait directement pu initialiser la variable 'in' tel que suit :

private InputStreamReader in = new InputStreamReader(serialPort.getInputStream());

private BufferedReader data_in = new BufferedReader(in);


Et ensuite, on aurait fait une nouvelle méthode, du genre :

public String readString()
{
   String msg = "";
   try
   {
       while(data_in.available() > 0) 
       {
          msg+=data_in.readLine();
       } 
       return msg;
   }
   catch(IOException ioe)
   {
       System.out.println("Reading error : "ioe.getMessage());
   System.exit(1);
   }
}


pour que dans le main il n'y ait plus qu'un simple :

System.out.println(example.readString()); // :)


Enfin, concernant ces bouts de code :
// Set notifyOnDataAvailable to true to allow event driven input.
serialPort.notifyOnDataAvailable(true);

serialPort.notifyOnOutputEmpty(true);

// Set notifyOnBreakInterrup to allow event driven break handling.
serialPort.notifyOnBreakInterrupt(true);

// Set receive timeout to allow breaking out of polling loop during
// input handling.
try {
  serialPort.enableReceiveTimeout(timeoutRx); // perso je place timeoutRx = 5000
} catch (javax.comm.UnsupportedCommOperationException e) {
  e.printStackTrace();
}

je les trouve intéressants, surtout le timeout qu'on aurait très bien pu intégrer dans la méthode readString()! ;)

@+
0
Rejoignez-nous