IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Entrée/Sortie Java Discussion :

RS232 via UartBridge CP2101: vitesse maximale Java en ecriture


Sujet :

Entrée/Sortie Java

  1. #1
    Membre averti
    Inscrit en
    Février 2004
    Messages
    17
    Détails du profil
    Informations forums :
    Inscription : Février 2004
    Messages : 17
    Par défaut RS232 via UartBridge CP2101: vitesse maximale Java en ecriture
    bonjour,

    Je dois réaliser un projet pour terminer mes etudes et je bloque sur un probleme de vitesse d'ecriture et de lecture des buffers:

    Je developpe en JAVA sous Eclipse (j'ai débuté il y a 2-3 mois) et je communique avec une carte sur laquelle est implanté un Spartan III de Xilinx et un composant permettant de transformer une liaison serie en liaison USB le CP2101. Mon FPGA envoie en permanence les octets : 0,1,2,3,...,13, 0,1,.....(ce qui me permet de tester ma communication)
    Le système fonctionne tres bien a la base: j'envoie et je recois mes données a la vitesse de 921600 bauds pour une frequence de 82 304 Hz environ (je pense avoir atteint la limite max du débit). Donc au final, la comm s'effectue via USB mais je ne vois que de la liaison serie.

    Ce qui ne fonctionne pas: je ne stocke pas toutes les valeurs sur mon fichier texte. Il y a des paquet de 512 valeurs (ou un multiple de 256 valeurs) qui partent a la poubelle !!!
    Alors sur une reception de 10sec je recois environ 788 000 valeurs (au lieu de 823 040) donc on peut penser que ce n'est rien mais je ne peux pas me permettre d'en perdre...
    De plus je dois gerer une interface graphique qui, si elle est lancée, me pourri ma communication ce qui a pour consequence de perdre la moitiée des valeurs !!!!


    j'ai donc plusieurs questions aux plus professionnels que moi

    * quelle est la vitesse max d'ecriture sur un fichier texte d'un programme JAVA?
    *Quel serait le flux le plus efficace pour le stockage? (ce sont des octets uniquement et attention pas des caracteres )?
    (J'utilise
    private BufferedInputStream buffer_read;
    buffer_read = new BufferedInputStream(sPort.getInputStream(),4096) )
    en faisant varier la taille j'obtiens des resultats tres diff:
    buffer de 100 => stockage de 177 501 valeurs
    buffer de 512 => stockage de 698 369 valeurs
    buffer de 1024 => stockage de 616 449 valeurs
    buffer de 1 000 000 => stockage de 786 289 valeurs
    je lit a partir d'un thred et RS232 n'en n'est pas un mais possede une methode que j'appelle :
    mesure = rs232.read_int();
    tampon.write(mesure+" ");

    *comment allouer plus de ressources a la tache qui sauvegarde les donnees et comment faire pour eviter q'une tache type affichage graphique (j'utilise JfreeChart) ne perturbe pas cette premiere?

    *J'ai fais des tests global de mon projet meme avec pertes de donnees et j'ai l'impression qu'il a du mal a suivre... il rame tout simplement... comment faire pour que ce ne soit plus le cas? y a t-il des methodes (la majorité de mes .java sont des thread) spécifiques pour gagner en puissance?

    Merci bcp a ceux qui prendront le temps de lire et repondre a mes questions !

    PS: je ne peux joindre le fichier fait car le serveur le bloque et comme il est gros je peux pas le mettre tel quel (sauf si vous avez une sol ^^)!

  2. #2
    Membre Expert
    Avatar de CheryBen
    Inscrit en
    Mai 2005
    Messages
    1 599
    Détails du profil
    Informations personnelles :
    Âge : 43

    Informations forums :
    Inscription : Mai 2005
    Messages : 1 599
    Par défaut
    Bonjour, je ne crois pas qu'il y ait de vitesse maximale d'écriture limitée par java, ce serait plutôt limité par le processeur, le disque dur et l'algorithme utilisé.

    Par contre, voici 2 petites idées :

    étant donné que tu as des threads, tu as sûrement mis des méthodes synchronized, sache que ce n'est pas très bon pour les performances, il ne faut en mettre que sur les méthodes qui ont vraiment besoin d'être synchronisées.

    je ne sais pas ce que tu as fait au niveau conception, je vois ça comme ça :
    • un thread qui lit les données sur le port et qui les place dans 2 files synchronisées (une pour l'ihm, une pour la suite du traitement)
    • un thread qui lit la file destinée à l'ihm, met à jour l'ihm et supprime les données de la file au fur et à mesure.
    • un thread qui lit l'autre file et les écrits dans le fichier.

    (c'est uniquement d'après ce que j'ai compris, désolé si ça ne tient pas la route ce que je dis )
    Je n'ai jamais fait de traitement aussi rapide, mon expérience porte sur une liaison port COM recevant des trames d'un GPS à 9600 bauds.

  3. #3
    Membre averti
    Inscrit en
    Février 2004
    Messages
    17
    Détails du profil
    Informations forums :
    Inscription : Février 2004
    Messages : 17
    Par défaut
    Citation Envoyé par morph41 Voir le message
    Bonjour, je ne crois pas qu'il y ait de vitesse maximale d'écriture limitée par java, ce serait plutôt limité par le processeur, le disque dur et l'algorithme utilisé.

    Par contre, voici 2 petites idées :

    étant donné que tu as des threads, tu as sûrement mis des méthodes synchronized, sache que ce n'est pas très bon pour les performances, il ne faut en mettre que sur les méthodes qui ont vraiment besoin d'être synchronisées.

    je ne sais pas ce que tu as fait au niveau conception, je vois ça comme ça :
    • un thread qui lit les données sur le port et qui les place dans 2 files synchronisées (une pour l'ihm, une pour la suite du traitement)
    • un thread qui lit la file destinée à l'ihm, met à jour l'ihm et supprime les données de la file au fur et à mesure.
    • un thread qui lit l'autre file et les écrits dans le fichier.

    (c'est uniquement d'après ce que j'ai compris, désolé si ça ne tient pas la route ce que je dis )
    Je n'ai jamais fait de traitement aussi rapide, mon expérience porte sur une liaison port COM recevant des trames d'un GPS à 9600 bauds.
    humhum !
    méthodes synchronized ... c la ou on voit que je suis encore un débutant puisque j'en utilise aucune ne connaissant pas ce truc ^^ mais en fait je me suis débrouillé dans la conception de l'architecture pour justement eviter des ecritures simultanées ou problemes du genre...
    Sinon pour la conception, dans le cas de la lecture je n'ai pas fait ce que tu decris:
    j'ai une classe RS232 non thread qui possede une methode read_int() qui est appelée par la classe principale qui elle est un thread. faut peut etre ameliorer ca mais en quoi mettre un thread supplementaire va t-il améliorer les choses ?
    Est-ce que l'appel de read_int peut prendre trop de ressources ?
    j'ai parcouru internet et ait trouvé une histoire avec des tubes entre thread. Serait-il interessant de l'utiliser ?

    En fait je me demandais ce qui serait le plus efficace en terme de réception de données et de stockage: le tube ou un buffer ?

  4. #4
    Membre Expert
    Avatar de CheryBen
    Inscrit en
    Mai 2005
    Messages
    1 599
    Détails du profil
    Informations personnelles :
    Âge : 43

    Informations forums :
    Inscription : Mai 2005
    Messages : 1 599
    Par défaut
    Tout d'abord, tu auras quelques explications sur les threads dans ce tutoriel.
    On parle des tubes également dans ce tutoriel, ça m'a l'air pas mal, mais je ne connaissais pas.

    Citation Envoyé par suppilou69 Voir le message
    méthodes synchronized ... c la ou on voit que je suis encore un débutant puisque j'en utilise aucune ne connaissant pas ce truc ^^ mais en fait je me suis débrouillé dans la conception de l'architecture pour justement eviter des ecritures simultanées ou problemes du genre...
    en évitant de faire appel à des boucles, Thread.wait() ou Thread.notify() ?

    Citation Envoyé par suppilou69 Voir le message
    Sinon pour la conception, dans le cas de la lecture je n'ai pas fait ce que tu decris:
    j'ai une classe RS232 non thread qui possede une methode read_int() qui est appelée par la classe principale qui elle est un thread. faut peut etre ameliorer ca mais en quoi mettre un thread supplementaire va t-il améliorer les choses ?
    c'est surtout pour séparer la lecture du port COM de tout autre traitement métier ou de la mise à jour de l'IHM qui pourrait prendre du temps.

    Citation Envoyé par suppilou69 Voir le message
    Est-ce que l'appel de read_int peut prendre trop de ressources ?
    j'ai parcouru internet et ait trouvé une histoire avec des tubes entre thread. Serait-il interessant de l'utiliser ?

    En fait je me demandais ce qui serait le plus efficace en terme de réception de données et de stockage: le tube ou un buffer ?
    Là honnêtement je ne sais pas...

  5. #5
    Modérateur
    Avatar de dinobogan
    Homme Profil pro
    ingénieur
    Inscrit en
    Juin 2007
    Messages
    4 073
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations professionnelles :
    Activité : ingénieur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 4 073
    Par défaut
    Le problème de perte de données viendrait peut-être d'un remplissage du buffer du port RS232. As-tu un moyen de lire un tableau de byte via le port au lieu d'un seul int à la fois ? Ca sera déjà plus rapide pour le dépilage.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java
    Que la force de la puissance soit avec le courage de ta sagesse.

  6. #6
    Membre averti
    Inscrit en
    Février 2004
    Messages
    17
    Détails du profil
    Informations forums :
    Inscription : Février 2004
    Messages : 17
    Par défaut
    hum je ne pense pas que ce soit possible de lire des ByteArray... en tout cas je n'ai pas trouvé.
    Y-a t-il un moyen de savoir si le buffer du port serie a debordé ? comment peut-on faire?

    tient ! je viens de voir qqch d'interessant : http://www.developpez.net/forums/sho...d.php?t=245213
    sur le post n°13 edam parle de la valeur 8192 or avec mon programme je detecte si je perds des donnees et qques soit la taille du buffer situé juste apres le rs232, j'ai tjs une erreur au moment du stockage 8192... y'aurait donc bien un debordement? ... hum ce qui voudrait dire que l'ecriture est trop lente...

    PS; pour mon info perso, certaines personnes arrivent a mettre du code dans des petites fenetres dans le forum.. comment faire ?

  7. #7
    Membre Expert
    Homme Profil pro
    Dév. Java & C#
    Inscrit en
    Octobre 2002
    Messages
    1 414
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Dév. Java & C#
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2002
    Messages : 1 414
    Par défaut
    Bonjour,

    Citation Envoyé par suppilou69 Voir le message

    PS; pour mon info perso, certaines personnes arrivent a mettre du code dans des petites fenetres dans le forum.. comment faire ?
    Pour celà, clique sur l'icône représentant un dièse #

  8. #8
    Membre Expert
    Homme Profil pro
    Dév. Java & C#
    Inscrit en
    Octobre 2002
    Messages
    1 414
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Dév. Java & C#
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2002
    Messages : 1 414
    Par défaut
    Bonjour,

    J'ai une question à propos de ta liaison sérielle. Est-ce qu'elle possède un contrôle de flux (hardware ou software)?

    Si il y a aucun contrôle de flux, il est fort probable que tu perdes des données.

  9. #9
    Membre averti
    Inscrit en
    Février 2004
    Messages
    17
    Détails du profil
    Informations forums :
    Inscription : Février 2004
    Messages : 17
    Par défaut
    non il n'y a aucun controle de flux. Ca parait curieux je sais mais les données arrivent en continue, je ne peux pas dire stoop! renvoie moi la donnée j'ai pas suivi. et si le buffer est trop plein c que le programme derriere est trop lent pour le vider de toute maniere donc j'ai fait le choix de ne pas developper de controle pour l'instant car ça prendrait bcp de temps
    Maintenant si ce n'etait qu'une valeur ça poserais pas trop de probleme mais la ce sont des paquets d'un multiple de 256 valeurs !

    merci pour le diese :p

  10. #10
    Membre Expert
    Homme Profil pro
    Dév. Java & C#
    Inscrit en
    Octobre 2002
    Messages
    1 414
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Dév. Java & C#
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2002
    Messages : 1 414
    Par défaut
    Si tu n'as aucun contrôle de flux, il ne faut pas venir te plaindre si tu perds des données à une vitesse de 921600bauds

    En plus, il suffit de d'utiliser la méthode setFlowControlMode avec le paramètre FLOWCONTROL_RTSCTS_IN pour avoir un contrôle matériel du flux en entrée.

    Je te conseille d'utiliser une programmation par évènement (asynchrone) afin de pouvoir vider au plus vite le buffer de ton UART.

  11. #11
    Membre averti
    Inscrit en
    Février 2004
    Messages
    17
    Détails du profil
    Informations forums :
    Inscription : Février 2004
    Messages : 17
    Par défaut
    bon je vais faire un controle de flux ... (si qqun a un prog VHDL qui fait la liaison serie avec control de flux suis preneur )

    mais honnetement je pense pas que ce soit lié... si j'avais des erreurs, je perdrais un certain nombre de données, aléatoirement, or il se trouve que je les perds par multiple de 256 valeurs... si ça c pas une histoire de buffer !

    (si je lance un thread lourd a cote , je perds la moitié des données et tjs par multiple de 256 (enfin c'est ce qu'il me semble)), les autres données recues etant parfaitement recues dans l'ordre sans aucun probleme de transmission

  12. #12
    Membre Expert
    Homme Profil pro
    Dév. Java & C#
    Inscrit en
    Octobre 2002
    Messages
    1 414
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Dév. Java & C#
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2002
    Messages : 1 414
    Par défaut
    Je te prie de m'excuser. Je n'avais pas une bonne vue sur ton environnement.

    Pourrais-tu afficher que le code Java de ton lecteur sériel?

  13. #13
    Membre averti
    Inscrit en
    Février 2004
    Messages
    17
    Détails du profil
    Informations forums :
    Inscription : Février 2004
    Messages : 17
    Par défaut
    pas de soucis ^^ .
    Voici le code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    public class ComRS232 //implements SerialPortEventListener 
    {
     
    	private  BufferedInputStream buffer_read;
    	private OutputStream outStream; //flux d'écriture du port
    	private CommPortIdentifier portId; //identifiant du port
    	private SerialPort sPort; //le port série
     
    	/** Creates a new instance of ComRS232 */
    	public ComRS232(String port) {
    		//initialisation du driver
    		Win32Driver w32Driver = new Win32Driver();
    		w32Driver.initialize();
    		//récupération de l'identifiant du port
    		try {
    			portId = CommPortIdentifier.getPortIdentifier(port);
    		} catch (NoSuchPortException e) {
    			System.out.println("probleme avec le port serie");
    		}
    		//ouverture du port
    		try {
    			sPort = (SerialPort) portId.open("UtilisationFlux", 30000);//le délai d'attente pour l'obtention du port en millisecondes 
    		} catch (PortInUseException e) {
    			System.out.println("PortInUseException");
    		}
     
    		try {
    			sPort.setFlowControlMode(SerialPort.FLOWCONTROL_NONE);
    			sPort.setSerialPortParams(
    					921600,
    					SerialPort.DATABITS_8,
    					SerialPort.STOPBITS_1,
    					SerialPort.PARITY_NONE);
    			//sPort.setInputBufferSize(512);
    		} catch (UnsupportedCommOperationException e) {
    		}
    		//récupération du flux de lecture et écriture du port
    		try {
    			outStream = sPort.getOutputStream();
    	//		 bufRead = new BufferedReader(
    	//		    new InputStreamReader(sPort.getInputStream()));
    			buffer_read = new BufferedInputStream(sPort.getInputStream(),1000000);//ici je change la taille du buffer
    		} catch (IOException e) {
    			System.out.println("buffer mark reset exception");
    		}
    		/**Le bloc ci-dessous permet de vider le buffer du port serie avant de commencer a lire 
                     * les valeurs*/
    		try {
    			while (buffer_read.available() > 0) {
    				read_byte();
    			}
     
    		} catch (IOException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
     
     
    	}
     
     
    	/**
             * Méthode de fermeture des flux et port.
             */
    	public void close(){
    		try {
    			buffer_read.close();
    			outStream.flush();
    			outStream.close();
    		} catch (IOException e) {
    			System.out.println("pb fermeture buffer port serie");
    		}
    		sPort.close();
    		System.out.println("port serie fermé");
    	}
     
    	/** 
             * envoie un byte (octet) sur le port RS232
             */
    	public void send_byte(byte envoie) {
    		try {
    			outStream.write(envoie);	
    			outStream.flush();
    		} catch (IOException e) {
    			System.out.println("envoie marche pas");
    		}
    	}
    	/**
             *Lit un octet (8 bits)sur le port RS232
             *@return entier entre 0 et 255;
             **/   
    	public int read_byte(){
    		int i=0;
    		try{
    			int mes = (byte)buffer_read.read();
    			return mes;
     
    		}catch (IOException e) {
    			System.out.println("lecture marche pas");
    			return this.read_byte();
    		}
    	}
    et j'appelle read_byte à partir d'un thread Acquisition qui en gros fait ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    while(para_mes.get_running()) //condition vrai pendant que l'on doit ecrire
    {	mesure = rs232.read_byte();			
    	tampon.write(mesure+"	");
    	position++;
    }

  14. #14
    Membre averti
    Inscrit en
    Février 2004
    Messages
    17
    Détails du profil
    Informations forums :
    Inscription : Février 2004
    Messages : 17
    Par défaut
    Citation Envoyé par jowo Voir le message
    Je te conseille d'utiliser une programmation par évènement (asynchrone) afin de pouvoir vider au plus vite le buffer de ton UART.
    humhum
    ça irait plus vite? pour quelles raisons ? (je penserais que le flux est plus rapide car pas d'appel ou de renvoi a chaque reception si ?)

  15. #15
    Modérateur
    Avatar de dinobogan
    Homme Profil pro
    ingénieur
    Inscrit en
    Juin 2007
    Messages
    4 073
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations professionnelles :
    Activité : ingénieur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 4 073
    Par défaut
    Pour gagner en performances, utilise des tableaux de byte, au lieu de traiter byte par byte.

    "java.io.BufferedInputStream.read(byte[] b, int off, int len)" : renvoie le nombre d'octets écrit dans le tableau
    Idem pour écrire avec ton outputStream.

    "read_byte( int[] tab )" va donc remplir un tableau passé en paramètre. L'objet utilisant cette méthode pourra déclarer son tableau d'entier une fois pour toute et réutiliser toujours le même.
    "send_byte( int[] tab, int length )" va envoyer les données du tableau en paramètre. L'objet utilisant cette méthode pourra également utiliser toujours le même tableau.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java
    Que la force de la puissance soit avec le courage de ta sagesse.

  16. #16
    Membre averti
    Inscrit en
    Février 2004
    Messages
    17
    Détails du profil
    Informations forums :
    Inscription : Février 2004
    Messages : 17
    Par défaut
    humhum ! je vais tenter ça
    Mais j'ai comme un doute la... et si ça venait du CP2101 qui possede une memoire interne de 512 byte ? et qu'il n'arrivait pas a suivre ? normalement il est prevu pour ça !

  17. #17
    Membre averti
    Inscrit en
    Février 2004
    Messages
    17
    Détails du profil
    Informations forums :
    Inscription : Février 2004
    Messages : 17
    Par défaut
    bon ben ça me fait qqch de curieux en evenementiel...
    Je pars en routine d'evenement trois fois environ...puis plus rien... pas terrible ^^.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    public class ModeEvenement extends Thread implements SerialPortEventListener {
     
    	private CommPortIdentifier portId;
    	private SerialPort serialPort;
    	private OutputStream outStream; //flux d'écriture du port
    	//private BufferedReader fluxLecture;
    	private BufferedInputStream fluxLecture;
    	private byte[] byte_buffer;
    	private FileWriter mon_fichier = null;
    	private BufferedWriter tampon = null;
    	private int r=0;
    	private int t=0;
    	private int position=0;
    	private ParamMesure para_mes;
     
    	/**
             * Constructeur qui récupère l'identifiant du port, l'objet ParamMesure, et lance l'ouverture.
             */
    	public ModeEvenement(String port, ParamMesure pm) {
    		para_mes=pm;
    		byte_buffer=new byte[512];
    		//initialisation du driver
    		Win32Driver w32Driver = new Win32Driver();
    		w32Driver.initialize();
    		//récupération de l'identifiant du port
    		try {
    			portId = CommPortIdentifier.getPortIdentifier(port);
    		} catch (NoSuchPortException e) {
    		}
     
    		//ouverture du port
    		try {
    			serialPort = (SerialPort) portId.open("ModeEvenement", 2000);
    		} catch (PortInUseException e) {
    		}
    		//récupération du flux
    		try {
     
    			fluxLecture = new BufferedInputStream(serialPort.getInputStream());
    			//	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.setFlowControlMode(SerialPort.FLOWCONTROL_NONE);
    			serialPort.setSerialPortParams(
    				921600,
    				SerialPort.DATABITS_8,
    				SerialPort.STOPBITS_1,
    				SerialPort.PARITY_NONE);
    		} catch (UnsupportedCommOperationException e) {
    		}
     
    		try {
    			outStream = serialPort.getOutputStream();
    		} catch (IOException e1) {
    			// TODO Auto-generated catch block
    			e1.printStackTrace();
    		}		
     
    		System.out.println("port ouvert");
     
     
    	//ouverture du fichier
    		try {
    			mon_fichier = new FileWriter(para_mes.get_folder_path()+
    			'\\'+para_mes.get_nom_fichier(),true);
    			tampon = new BufferedWriter(mon_fichier);
    			System.out.println("fichier cree");
     
    		} catch (IOException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    //		lancement de l'appli
    		this.start();
     
    	}
    	public void run() {
    		//running = true;
    //		lancement du prog dans FPGA
    		send_byte((byte)0);
    		System.out.println("reception lancée");
    		while (para_mes.get_running()) {
    			try {
    				Thread.sleep(2000);
    			} catch (InterruptedException e) {
    			}
    		}
    		//fermeture du flux et port
    		try {
    			fluxLecture.close();
    			outStream.flush();// a revoir
    			outStream.close();
    			tampon.newLine();
    			tampon.write("FIN MESURES				");
    			tampon.newLine();
    			tampon.flush();
    			tampon.close();
    			mon_fichier.close();
    			System.out.println("Fermeture OK. POSITION: "+position);
     
    		} catch (IOException e) {
    		}	
    		serialPort.close();
     
    	}
    	/**
             * Méthode de gestion des événements.
             */
    	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.BI :System.out.println("event2");
    			case SerialPortEvent.OE :System.out.println("event2");
    			case SerialPortEvent.FE :System.out.println("event2");
    			case SerialPortEvent.PE :System.out.println("event2");
    			case SerialPortEvent.CD :System.out.println("event2");
    			case SerialPortEvent.CTS :System.out.println("event2");
    			case SerialPortEvent.DSR :System.out.println("event2");
    			case SerialPortEvent.RI :System.out.println("event3");
    			case SerialPortEvent.OUTPUT_BUFFER_EMPTY :
    				break;
    			case SerialPortEvent.DATA_AVAILABLE :
     
    				try {
     
    					fluxLecture.read(byte_buffer,0,512);
    					System.out.println("event"+fluxLecture.available());
     
    					for(int i=0;i<byte_buffer.length;i++)
    					{
    						//System.out.println(byte_buffer[i]);
    						//mesure = byte_buffer[i];
    						tampon.write(byte_buffer[i]+"	");
    						position++;
    					}
     
    				} catch (IOException e) {
    					System.out.println("pb dans ecriture");
    				}
    				break;
    		}
    	}
    et le resultat:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    port ouvert
    fichier cree
    reception lancée
    event6656
    event13312
    event13312
    Fermeture OK. POSITION: 1536

  18. #18
    Membre Expert
    Homme Profil pro
    Dév. Java & C#
    Inscrit en
    Octobre 2002
    Messages
    1 414
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Dév. Java & C#
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2002
    Messages : 1 414
    Par défaut
    Bonjour,

    Connais-tu le volume d'information envoyé par ta carte 'Spartan III'?

    Ton convertisseur série-USB CP2101 arrive-t-il à transmettre dans un flux continu de 921600 bit/s?

    Une vitesse de 921600bit/s correspond une transmission de 92160 byte/s donc environ 100k/s. Il faut prévoir un tampon assez grand pour soutenir une telle transmission sans contrôle de flux.

    Ton programme JAVA ne doit pas utiliser des strings ou tout objet qui alloue des ressources dans le heap. GC ne devrait pas appeler durant la transmission.

    Voici ton programme corrigé (pas testé et pas compilé).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    public class ModeEvenement extends Thread implements SerialPortEventListener {
     
      /* Un 'baud rate' de 921600 correspond à environ 92'160 caractères par seconde.
         On prévoit alors un tampon d'entrée assez grand pour pouvoir soutenir 1s
         de transmission permanebte(transmission san contrôel de flux)
      */
      private static final int SPEED_PORT = 921600;
      private static final int INPUT_BUFFER_SIZE = 90 * 1024;  
      private static final int BUFFER_SIZE = INPUT_BUFFER_SIZE;
     
    	private CommPortIdentifier portId;
    	private SerialPort serialPort;
    	private OutputStream outStream; //flux d'écriture du port
    	//private BufferedReader fluxLecture;
    	private BufferedInputStream fluxLecture;
    	private byte[] byte_buffer;
    	private FileWriter mon_fichier = null;
    	private BufferedWriter tampon = null;
    	private int r=0;
    	private int t=0;
    	private int position=0;
    	private ParamMesure para_mes;
     
     
     
    	/**
             * Constructeur qui récupère l'identifiant du port, l'objet ParamMesure, et lance l'ouverture.
             * En cas d'erreur,  on affiche un message et on devrait libérer toutes les
             * ressources.   
             */
    	public ModeEvenement(String port, ParamMesure pm) {
     
        para_mes=pm;
    		byte_buffer=new byte[BUFFER_SIZE];
     
    		//initialisation du driver
    		Win32Driver w32Driver = new Win32Driver();
    		w32Driver.initialize();
    		//récupération de l'identifiant du port
    		try {
    			portId = CommPortIdentifier.getPortIdentifier(port);
    		} catch (NoSuchPortException e) {
    			e.printStackTrace(System.err);
    			return;
    		}
     
    		//ouverture du port
    		try {
    			serialPort = (SerialPort) portId.open("ModeEvenement", 2000);
    		} catch (PortInUseException e) {
    			e.printStackTrace(System.err);
    			return;
    		}
    		//récupération du flux
    		try {
     
    			fluxLecture = new BufferedInputStream(serialPort.getInputStream(), INPUT_BUFFER_SIZE);
    			//	new BufferedReader(
    			//		new InputStreamReader(serialPort.getInputStream()));
    		} catch (IOException e) {
    			e.printStackTrace(System.err);
    			return;
    		}
    		//ajout du listener
    		try {
    			serialPort.addEventListener(this);
    		} catch (TooManyListenersException e) {
    			e.printStackTrace(System.err);
    			return;
    		}
    		//paramétrage du port
     
    		serialPort.notifyOnDataAvailable(true);
    		try {
    			serialPort.setFlowControlMode(SerialPort.FLOWCONTROL_NONE);
    			serialPort.setSerialPortParams(
    				SPEED_PORT,
    				SerialPort.DATABITS_8,
    				SerialPort.STOPBITS_1,
    				SerialPort.PARITY_NONE);
    		} catch (UnsupportedCommOperationException e) {
    			e.printStackTrace(System.err);
    			return;
    		}
     
    		try {
    			outStream = serialPort.getOutputStream();
    		} catch (IOException e1) {
    			// TODO Auto-generated catch block
    			e1.printStackTrace(System.err);
    			return;
    		}		
     
    		System.out.println("port ouvert");
     
     
    	//ouverture du fichier
    		try {
    			mon_fichier = new FileWriter(para_mes.get_folder_path()+
    			'\\'+para_mes.get_nom_fichier(),true);
    			tampon = new BufferedWriter(mon_fichier);
    			System.out.println("fichier cree");
     
    		} catch (IOException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace(System.err);
    			return;
    		}
    //		lancement de l'appli
    		this.start();
     
    	}
    	public void run() {
    		//running = true;
    //		lancement du prog dans FPGA
    		send_byte((byte)0);
    		System.out.println("reception lancée");
    		while (para_mes.get_running()) {
    			try {
    				Thread.sleep(2000);
    			} catch (InterruptedException e) {
    			}
    		}
    		//fermeture du flux et port
    		try {
    			fluxLecture.close();
    			outStream.flush();// a revoir
    			outStream.close();
    			tampon.newLine();
    			tampon.write("FIN MESURES				");
    			tampon.newLine();
    			tampon.flush();
    			tampon.close();
    			mon_fichier.close();
    			System.out.println("Fermeture OK. POSITION: "+position);
     
    		} catch (IOException e) {
    		}	
    		serialPort.close();
     
    	}
    	/**
             * Méthode de gestion des événements.
             */
    	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.BI :System.out.println("event2");
    			case SerialPortEvent.OE :System.out.println("event2");
    			case SerialPortEvent.FE :System.out.println("event2");
    			case SerialPortEvent.PE :System.out.println("event2");
    			case SerialPortEvent.CD :System.out.println("event2");
    			case SerialPortEvent.CTS :System.out.println("event2");
    			case SerialPortEvent.DSR :System.out.println("event2");
    			case SerialPortEvent.RI :System.out.println("event3");
    			case SerialPortEvent.OUTPUT_BUFFER_EMPTY :
    				break;
    			case SerialPortEvent.DATA_AVAILABLE :
     
    				try {
     
    					System.out.println("event " + fluxLecture.available());
    					int read; = fluxLecture.read(byte_buffer,0,BUFFER_SIZE);
              while ((read = fluxLecture.read(byte_buffer,0,BUFFER_SIZE) != -1) {
    					  for (int i=0; i<read; ++i) {
    						  //System.out.println(byte_buffer[i]);
      						//mesure = byte_buffer[i];
    	 					  /* On évite de travailler avec des strings */
    						  tampon.write(byte_buffer[i]);
    						  tampon.write(' ');
    						  position++;
    					 }            
              }
     
    				} catch (IOException e) {
    					System.out.println("pb dans ecriture");
    				}
    				break;
    		}
    	}

  19. #19
    Membre averti
    Inscrit en
    Février 2004
    Messages
    17
    Détails du profil
    Informations forums :
    Inscription : Février 2004
    Messages : 17
    Par défaut
    Bonjour,
    Alors je commence à y voir plus clair heureusement !
    au niveau du volume d'info, je reçois des octets à une frequence de 78247 Hz. Je pense que le CP2101 n'est pas débordé. En revanche, je peux explorer plusieurs possibilitées:
    *ecrire en C le code pour la reception des données => plus optimal mais je ne sais pas faire (le moment d'apprendre ?)
    *faire un acces disque pour un transfert de grande quantité seulement. Apres plusieurs tests, j'ai compris que mon probleme etait l'acces au disque et que l'ecriture est ultra rapide (X10 par rapport a ma reception) donc la solution serait de mettre des grosses memoires tampon et ecrire tout d'un coup mais en flux continu et non en evenementiel.
    *changer le drivers qui convertit l'usb en RS232 virtuel sur le PC: j'ai trouvé un drivers qui resterais en USB mais est-ce simple de programmer en java ?

    je vais tenter le coup des buffers de grande capacite qui se deversent sur le pc pendant qu'un deuxieme se rempli !

  20. #20
    Membre averti
    Inscrit en
    Février 2004
    Messages
    17
    Détails du profil
    Informations forums :
    Inscription : Février 2004
    Messages : 17
    Par défaut
    NOTE: je voulais vous remercier pour l'aide que vous m'apportez

    J'ai avancé ! enfin un peu... lol j'ai fait un thread qui tourne en permanence, qui copie les donnees du port serie par tableau et je copie ces tableaux (512 valeurs environ) les uns a la suite des autres dans un buffer de 55 000 bytes puis j'en rempli un second. Pendant le remplissage du premier j'ecris le contenu du second (un autre thread ecriture) et vice versa et.... CA MARCHE ! je ne perds pas de valeurs a priori !

    MAIS ! parce qu'il y a tjs un mais ...!!! je ne peux faire que ça... et on me demande un affichage temps reel des donnees (pas toutes parce que c impossible mais genre 1000 valeurs toutes les 50ms => a moi de faire le maximum d'affichage possible) et ils veulent egalement un petit traitement temps reel genre un filtre et une FFT sur ce que j'affiche.
    J'ai essayé juste de lancer un thread d'affichage sans rien afficher dedans, juste la fenetre graphique et... je perds la moitié de mes valeurs...

    en fait mon probleme n'est pas un probleme de communication (meme si ça l'etait a la base) mais un probleme de performance... on m'a dit que JAVA dans ce cadre a n'etait pas adapté. Qu'en pensez vous ?
    Est-ce que je gagnerais suffisamment en performance si j'écris du code C pour faire les traitements et JAVA uniquement la partie graphique? (par exemple je commence en C ou C++ et lance une appli JAVA)

    merci pour vos reponses !

Discussions similaires

  1. liaison rs232 via excel
    Par ezbessem dans le forum Excel
    Réponses: 1
    Dernier message: 18/04/2010, 09h16
  2. accès internet via un proxy dans application java
    Par Tiéry dans le forum Développement Web en Java
    Réponses: 1
    Dernier message: 23/07/2009, 13h36
  3. Acquisition de données RS232 via USB
    Par woimanu dans le forum LabVIEW
    Réponses: 0
    Dernier message: 11/06/2009, 11h25
  4. [Java] Lecture/Ecriture PDF
    Par steeves5 dans le forum Général Java
    Réponses: 2
    Dernier message: 06/05/2009, 19h59
  5. java card ecriture/lecture de fichier
    Par rojina29 dans le forum Développement Mobile en Java
    Réponses: 0
    Dernier message: 14/11/2008, 14h12

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo