Bonjour,
Je souhaiterais récupérer, dans un programme java, les glycémies conservées par mon lecteur de glycémies (FreeStyle Papillon fabriqué désormais par la société Abbott) via une connexion série.
Le fabriquant de cet appareil propose de relier l’appareil au PC via un câble USB. Il faut installer un driver qui permet de créer un port série virtuel pour communiquer avec l’appareil.
En utilisant le logiciel fournit par Abbott (nommé coPilot) et un logiciel me permettant de sniffer la communication sur le port série virtuel (HDD Serial Monitor), j’ai pu déterminer les commandes à envoyer au lecteur pour récupérer les données :
De plus, je dispose également du paramétrage du port à utiliser :
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 Port ouvert par le processus "CoPilot.exe" (PID: 1268) Requête:02/02/2010 22:13:55.830239064 (+188.8698027000 seconds) 00 . Requête:02/02/2010 22:13:56.160257964 (+0.3300189000 seconds) 00 . Requête:02/02/2010 22:13:56.490276764 (+0.3300188000 seconds) 6D 65 6D mem Réponse:02/02/2010 22:13:56.616283964 (+0.1260072000 seconds) 0D 0A 44 42 47 4D 31 30 36 2D 46 30 39 34 39 0D ..DBGM106-F0949. 0A 31 2E 31 34 20 20 20 20 20 20 20 2D 50 0D 0A .1.14 -P.. 46 65 62 20 20 30 32 20 32 30 31 30 20 32 32 3A Feb 02 2010 22: 31 33 3A 30 31 0D 0A 30 30 36 0D 0A 0A 30 35 36 13:01..006...056 20 20 4A 61 6E 20 20 33 30 20 32 30 31 30 20 31 Jan 30 2010 1 33 3A 33 39 20 30 30 20 30 78 30 30 0D 0A 30 34 3:39 00 0x00..04 37 20 20 4A 61 6E 20 20 33 30 20 32 30 31 30 20 7 Jan 30 2010 31 33 3A 33 31 20 30 30 20 30 78 30 30 0D 0A 31 13:31 00 0x00..1 31 35 20 20 4A 61 6E 20 20 33 30 20 32 30 31 30 15 Jan 30 2010 20 31 33 3A 33 30 20 30 30 20 30 78 30 30 0D 0A 13:30 00 0x00.. 31 35 30 20 20 4A 61 6E 20 20 33 30 20 32 30 31 150 Jan 30 201 30 20 31 31 3A 32 30 20 30 30 20 30 78 30 30 0D 0 11:20 00 0x00. 0A 31 34 35 20 20 4A 61 6E 20 20 33 30 20 32 30 .145 Jan 30 20 31 30 20 31 31 3A 31 39 20 30 30 20 30 78 30 31 10 11:19 00 0x01 0D 0A 31 39 38 20 20 4A 61 6E 20 20 32 37 20 32 ..198 Jan 27 2 30 31 30 20 30 38 3A 34 39 20 30 30 20 30 78 30 010 08:49 00 0x0 30 0D 0A 30 78 33 30 41 41 20 20 45 4E 44 0D 0A 0..0x30AA END.. Port ferméet
.
En java, j’ai essayé d’utiliser les deux APIs disponibles pour interroger le port série (javax.comm et RXTX). En utilisant l’outil pour sniffer la communication entre le PC et le port série virtuel, je ne trouve pas d’écart avec le logiciel fournit par Abbott (j’envoi bien deux fois le caractère hexa 0x00 séparé de 300ms puis les caractères « mem »… mais pourtant, le lecteur de glycémies ne retourne aucune informations…
Voici mon code java avec l’API javax.comm :
En utilisant l'API RXTX :
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 package fr; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStream; import java.nio.charset.Charset; import java.util.TooManyListenersException; import javax.comm.CommPortIdentifier; import javax.comm.NoSuchPortException; import javax.comm.PortInUseException; import javax.comm.SerialPort; import javax.comm.SerialPortEvent; import javax.comm.SerialPortEventListener; import javax.comm.UnsupportedCommOperationException; import com.sun.comm.Win32Driver; public class TesterCommunicationFreeStylePapillon implements SerialPortEventListener { private final String port; private CommPortIdentifier portId; private SerialPort serialPort; private BufferedReader fluxLecture = null; private OutputStream fluxEcriture = null; public TesterCommunicationFreeStylePapillon(String port) throws Exception { this.port = 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) { throw e; } //ouverture du port try { serialPort = (SerialPort) portId.open("ModeEvenement", 2000); } catch (PortInUseException e) { throw e; } //paramétrage du port serialPort.notifyOnDataAvailable(true); serialPort.setRTS(true); serialPort.notifyOnCTS(true); serialPort.setDTR(true); try { serialPort.setSerialPortParams( 9600, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE); serialPort.setFlowControlMode(SerialPort.FLOWCONTROL_NONE); } catch (UnsupportedCommOperationException e) { throw e; } // ajout du listener try { serialPort.addEventListener(this); } catch (TooManyListenersException e) { throw e; } // récupération du flux de lecture et écriture du port try { fluxEcriture = serialPort.getOutputStream(); fluxLecture = new BufferedReader( new InputStreamReader(serialPort.getInputStream()) ); } catch (IOException e) { throw new RuntimeException(e); } System.out.println("port ouvert, flux ouvert, attente opération..."); // Cette solution envoie les 4 premières lignes sendMessage((char)0); Thread.sleep(300); sendMessage((char)0); Thread.sleep(300); sendMessage("mem"); Thread.sleep(10000); System.out.println("8 - Fin du test..."); fluxEcriture.close(); fluxLecture.close(); serialPort.close(); System.out.println("9 - Fermeture du port série."); } private void sendMessage(String s) throws RuntimeException, IllegalArgumentException { try { fluxEcriture.write(s.getBytes()); //fluxEcriture.write(s.getBytes(Charset.forName("UTF-8"))); } catch (IOException e) { e.printStackTrace(); } } private void sendMessage(char envoie) throws RuntimeException { try { fluxEcriture.write((int) envoie); } catch (IOException e) { e.printStackTrace(); } } @Override 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 : case SerialPortEvent.OE : case SerialPortEvent.FE : case SerialPortEvent.PE : case SerialPortEvent.CD : case SerialPortEvent.CTS : case SerialPortEvent.DSR : case SerialPortEvent.RI : case SerialPortEvent.OUTPUT_BUFFER_EMPTY : System.out.println("vide " + event.getEventType()); break; case SerialPortEvent.DATA_AVAILABLE : String reponse = new String(); try { //lecture du buffer et affichage reponse = (String) fluxLecture.readLine(); System.out.println("<--- " + reponse); } catch (IOException e) { e.printStackTrace(); } break; } } /** * @param args */ public static void main(String[] args) throws Exception { new TesterCommunicationFreeStylePapillon("COM12"); } }
Je n’obtiens pas d’erreur java mais le lecteur de glycémies ne réponds pas. Par contre, il s’allume…. donc il reçoit bien quelques signaux…
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 package portCom; import gnu.io.CommDriver; import gnu.io.CommPortIdentifier; import gnu.io.NoSuchPortException; import gnu.io.PortInUseException; import gnu.io.RXTXCommDriver; import gnu.io.SerialPort; import gnu.io.SerialPortEvent; import gnu.io.SerialPortEventListener; import gnu.io.UnsupportedCommOperationException; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStream; import java.text.SimpleDateFormat; import java.util.Date; import java.util.TooManyListenersException; public class TestCommunicationFreeStyle { private CommDriver myDriver = null; private CommPortIdentifier portId = null; private SerialPort serialPort = null; private BufferedReader fluxLecture = null; private OutputStream fluxEcriture = null; public TestCommunicationFreeStyle(String port) { System.out.println("1 - Initialisation du driver RXTX"); myDriver = new RXTXCommDriver(); if (myDriver != null) { myDriver.initialize(); } System.out.println("2 - Détection du port " + port); // détection du port série try { portId = CommPortIdentifier.getPortIdentifier(port); } catch (NoSuchPortException e) { e.printStackTrace(); } if (portId == null) { e.printStackTrace(); } try { System.out.println("3 - Début ouverture du port"); serialPort = (SerialPort) portId.open("FreeStylePapillon", 2000); // on sélectionne tous les paramètres de la connexion série: serialPort.setFlowControlMode(SerialPort.FLOWCONTROL_NONE); serialPort.setSerialPortParams(9600, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE); serialPort.notifyOnDataAvailable(true); serialPort.notifyOnCTS(true); serialPort.setRTS(true); serialPort.setDTR(true); System.out.println("4 - Fin du paramétrage du port"); } catch (PortInUseException e1) { System.out.println(e1); } catch (UnsupportedCommOperationException e1) { System.out.println(e1); } // récupération du flux de lecture et écriture du port try { fluxEcriture = serialPort.getOutputStream(); fluxLecture = new BufferedReader( new InputStreamReader(serialPort.getInputStream()) ); } catch (IOException e) { e.printStackTrace(); } // ajout du listener try { serialPort.addEventListener( new LectureFlux(fluxLecture) ); } catch (TooManyListenersException e) { e.printStackTrace(); } try { // 1 : Lecture du paramétrage System.out.println("\n\n*****************\nLecture des données"); sendMessage((char)0x00); Thread.sleep(300); sendMessage((char)0x00); Thread.sleep(300); sendMessage("mem"); Thread.sleep(10000); System.out.println("\n13 - Fermeture du port série."); serialPort.close(); System.out.println("14 - Fin de l'application."); System.exit(0); } catch (Exception e) { e.printStackTrace(); } } private void sendMessage(char envoie) throws RuntimeException { try { fluxEcriture.write((int) envoie); } catch (IOException e) { e.printStackTrace(); } } private void sendMessage(String s) throws RuntimeException, IllegalArgumentException { byte[] tab = s.getBytes(); try { fluxEcriture.write(tab); } catch (IOException e) { e.printStackTrace(); } } /** * @param args */ public static void main(String[] args) { new TestCommunicationFreeStyle("COM12"); } public class LectureFlux implements SerialPortEventListener { private BufferedReader myFluxLecture = null; public LectureFlux(BufferedReader fluxLecture) throws IllegalArgumentException { myFluxLecture = fluxLecture; } 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 : case SerialPortEvent.OE : case SerialPortEvent.FE : case SerialPortEvent.PE : case SerialPortEvent.CD : case SerialPortEvent.CTS : case SerialPortEvent.DSR : case SerialPortEvent.RI : case SerialPortEvent.OUTPUT_BUFFER_EMPTY : System.out.println("Réponse inaudible !"); break; case SerialPortEvent.DATA_AVAILABLE : String commande = new String(); try { //lecture du buffer et affichage commande = (String) myFluxLecture.readLine(); System.out.println(" <--- " + commande); } catch (IOException e) { e.printStackTrace(); } break; } } } }
Avez-vous une idée de pourquoi cela ne marche po ?
C'est grave docteur ?
Que peut-il se passer ?
Et que puis-je faire ?
Merci d'avance pour votre aide.
A.
Partager