9
9
import it .baeyens .arduino .common .ArduinoConst ;
10
10
import it .baeyens .arduino .common .Common ;
11
11
12
+ import java .util .Arrays ;
12
13
import java .util .Vector ;
13
14
14
15
import org .eclipse .core .resources .IProject ;
15
16
import org .eclipse .core .runtime .IStatus ;
16
17
import org .eclipse .core .runtime .Status ;
17
18
18
19
public class ArduinoSerial {
20
+
19
21
/**
20
- * This method resets arduino based on setting the baud rate. Used for due, leonardo and others
22
+ * This method resets Arduino based on setting the baud rate and disconnecting from the port.
23
+ * Used for due, leonardo, esplora, and others. Here is from Esplora documentation:
24
+ *
25
+ * Rather than requiring a physical press of the reset button before an upload, the Esplora is
26
+ * designed in a way that allows it to be reset by software running on a connected computer.
27
+ * The reset is triggered when the Esplora's virtual (CDC) serial / COM port is opened at
28
+ * 1200 baud and then closed. When this happens, the processor will reset, breaking the USB
29
+ * connection to the computer (meaning that the virtual serial / COM port will disappear).
30
+ * After the processor resets, the bootloader starts, remaining active for about 8 seconds
21
31
*
22
- * @param ComPort
32
+ * @param comPort
23
33
* The port to set the baud rate
24
- * @param bautrate
34
+ * @param baudRate
25
35
* The baud rate to set
36
+ * @param keepOpenPeriod
37
+ * How long to keep the port open (ms)
38
+ *
26
39
* @return true is successful otherwise false
27
40
*/
28
- public static boolean reset_Arduino_by_baud_rate (String ComPort , int baudrate , long openTime ) {
41
+ public static boolean resetArduinoByBaudRate (String comPort , int baudRate , long keepOpenPeriod ) {
29
42
Serial serialPort ;
43
+
30
44
try {
31
- serialPort = new Serial (ComPort , baudrate );
45
+ serialPort = new Serial (comPort , baudRate );
32
46
} catch (Exception e ) {
33
47
e .printStackTrace ();
34
- Common .log (new Status (IStatus .WARNING , ArduinoConst .CORE_PLUGIN_ID , "Unable to open Serial port " + ComPort , e ));
48
+ Common .log (new Status (IStatus .WARNING , ArduinoConst .CORE_PLUGIN_ID , "Unable to open Serial port " +
49
+ comPort + " and baudRate " + baudRate , e ));
35
50
return false ;
36
51
}
37
52
38
- try {
39
- Thread .sleep (openTime );
40
- } catch (InterruptedException e ) {// Jaba is not going to write this
41
- // code
42
- }
43
- serialPort .dispose ();
53
+ waitFor (keepOpenPeriod );
54
+
55
+ if (serialPort != null )
56
+ serialPort .dispose ();
57
+
44
58
return true ;
45
59
}
46
60
47
61
/**
48
62
* Waits for a serial port to appear. It is assumed that the default comport is not available on the system
49
63
*
50
- * @param OriginalPorts
64
+ * @param originalPorts
51
65
* The ports available on the system
52
- * @param defaultComPort
66
+ * @param comPort
53
67
* The port to return if no new com port is found
54
68
* @return the new comport if found else the defaultComPort
55
69
*/
56
- public static String wait_for_com_Port_to_appear (Vector <String > OriginalPorts , String defaultComPort ) {
57
-
58
- Vector <String > NewPorts ;
59
- Vector <String > OriginalPortsCopy ;
60
-
70
+ public static String waitForComPortsToReappear (Vector <String > originalPorts , String comPort , String boardName ) {
61
71
62
72
// wait for port to disappear
63
- int NumTries = 0 ;
64
- int MaxTries = 200 ; // wait for 2 seconds, leaves us 6secs in case we are not seeing disappearing ports but reset worked
65
- int delayMs = 10 ; // on faster computers Esplora reconnects *extremely* quickly and we can't catch this
66
- do {
67
- OriginalPortsCopy = new Vector <String >(OriginalPorts );
68
- if (NumTries > 0 ) {
69
- try {
70
- Thread .sleep (delayMs );
71
- } catch (InterruptedException e ) {// Jaba is not going to write this
72
- // code
73
- }
74
- }
75
- if (NumTries ++ > MaxTries ) {
76
- Common .log (new Status (IStatus .WARNING , ArduinoConst .CORE_PLUGIN_ID , "Leonardo upload port is not disappearing after reset and " + NumTries + " checks" ));
77
- return defaultComPort ;
78
- }
79
- NewPorts = Serial .list ();
80
- for (int i = 0 ; i < NewPorts .size (); i ++) {
81
- OriginalPortsCopy .remove (NewPorts .get (i ));
73
+ int maxAttempts = 200 ;
74
+ int pauseForMs = 5 ;
75
+ int attemptsCount ;
76
+
77
+ Vector <String > disconnectedPorts = null ;
78
+
79
+ for (attemptsCount = 0 ; attemptsCount < maxAttempts ; attemptsCount ++) {
80
+ Vector <String > currentPorts = Serial .list ();
81
+ if (currentPorts .size () < originalPorts .size ()) {
82
+ disconnectedPorts = new Vector <String >(originalPorts );
83
+ disconnectedPorts .removeAll (currentPorts );
84
+ Common .log (new Status (IStatus .INFO , ArduinoConst .CORE_PLUGIN_ID ,
85
+ boardName + " port(s) disconnected [" + disconnectedPorts .toString () + "] after " + attemptsCount * pauseForMs +"ms" ));
86
+ break ;
82
87
}
83
88
84
- } while (OriginalPortsCopy .size () != 1 );
85
- OriginalPorts .remove (OriginalPortsCopy .get (0 ));
89
+ if (attemptsCount > 0 )
90
+ waitFor (pauseForMs );
91
+ }
86
92
87
- NumTries = 0 ;
88
- do {
89
- if (NumTries ++ > MaxTries ) {
90
- Common .log (new Status (IStatus .ERROR , ArduinoConst .CORE_PLUGIN_ID , "Leonardo upload port is not appearing after reset" ));
91
- return defaultComPort ;
92
- }
93
- NewPorts = Serial .list ();
94
- for (int i = 0 ; i < OriginalPorts .size (); i ++) {
95
- NewPorts .remove (OriginalPorts .get (i ));
96
- }
97
- try {
98
- Thread .sleep (delayMs );
99
- } catch (InterruptedException e ) {// Jaba is not going to write this
100
- // code
93
+ if (attemptsCount == maxAttempts && (disconnectedPorts == null || disconnectedPorts .isEmpty ())) {
94
+ Common .log (new Status (IStatus .WARNING , ArduinoConst .CORE_PLUGIN_ID , boardName + " upload port is not disappearing after reset and " + attemptsCount * pauseForMs + "ms" ));
95
+ return comPort ;
96
+ }
97
+
98
+ for (attemptsCount = 0 ; attemptsCount < maxAttempts ; attemptsCount ++) {
99
+ if (Serial .list ().contains (comPort )) {
100
+ Common .log (new Status (IStatus .INFO , ArduinoConst .CORE_PLUGIN_ID ,
101
+ boardName + " port " + comPort + " reconnected after " + attemptsCount * pauseForMs ));
102
+ return comPort ;
101
103
}
102
- } while (NewPorts .size () != 1 );
103
- return NewPorts .get (0 );
104
+ if (attemptsCount > 0 )
105
+ waitFor (pauseForMs );
106
+ }
107
+
108
+ if (attemptsCount == maxAttempts ) {
109
+ Common .log (new Status (IStatus .WARNING , ArduinoConst .CORE_PLUGIN_ID , boardName + " upload port is not appearing after reset" ));
110
+
111
+ }
112
+
113
+ return comPort ;
104
114
}
105
115
106
116
/**
@@ -116,11 +126,7 @@ public static boolean ToggleDTR(Serial serialPort, long delay) {
116
126
serialPort .setDTR (false );
117
127
serialPort .setRTS (false );
118
128
119
- try {
120
- Thread .sleep (delay );
121
- } catch (InterruptedException e ) {// Jaba is not going to write this
122
- // code
123
- }
129
+ waitFor (delay );
124
130
125
131
serialPort .setDTR (true );
126
132
serialPort .setRTS (true );
@@ -136,16 +142,12 @@ public static boolean ToggleDTR(Serial serialPort, long delay) {
136
142
public static void flushSerialBuffer (Serial serialPort ) {
137
143
while (serialPort .available () > 0 ) {
138
144
serialPort .readBytes ();
139
- try {
140
- Thread .sleep (100 ); // TOFIX I think this is bad; not to bad as
141
- // readBytes reads all info but
142
- // if the boards sends data at a speed higher
143
- // than 1 ever 100ms we will never get out of
144
- // this loop
145
- } catch (InterruptedException e ) { // we can safely ignore all
146
- // errors here as we are throwing
147
- // everything away anyway
148
- }
145
+ // TOFIX I think this is bad; not to bad as
146
+ // readBytes reads all info but
147
+ // if the boards sends data at a speed higher
148
+ // than 1 ever 100ms we will never get out of
149
+ // this loop
150
+ waitFor (100 );
149
151
}
150
152
}
151
153
@@ -157,54 +159,58 @@ public static void flushSerialBuffer(Serial serialPort) {
157
159
*
158
160
* @param project
159
161
* The project related to the com port to reset
160
- * @param ComPort
162
+ * @param comPort
161
163
* The name of the com port to reset
162
164
* @return The com port to upload to
163
165
*/
164
- public static String makeArduinoUploadready (IProject project , String configName , String ComPort ) {
166
+ public static String makeArduinoUploadready (IProject project , String configName , String comPort ) {
165
167
if (Common .RXTXDisabled ())
166
- return ComPort ;
167
- // ArduinoProperties arduinoProperties = new ArduinoProperties(project);
168
- String use_1200bps_touch = Common .getBuildEnvironmentVariable (project , configName , ArduinoConst .ENV_KEY_upload_use_1200bps_touch , "false" );
168
+ return comPort ;
169
+
170
+ boolean use1200bpsTouch = Common .getBuildEnvironmentVariable (project , configName , ArduinoConst .ENV_KEY_upload_use_1200bps_touch , "false" )
171
+ .equalsIgnoreCase ("true" );
169
172
boolean bDisableFlushing = Common .getBuildEnvironmentVariable (project , configName , ArduinoConst .ENV_KEY_upload_disable_flushing , "false" )
170
- .equalsIgnoreCase ("true" );
171
- boolean bwait_for_upload_port = Common .getBuildEnvironmentVariable (project , configName , ArduinoConst .ENV_KEY_wait_for_upload_port , "false" )
172
- .equalsIgnoreCase ("true" );
173
- String boardName = Common .getBuildEnvironmentVariable (project , configName , ArduinoConst .ENV_KEY_JANTJE_BOARD_NAME , "" );
173
+ .equalsIgnoreCase ("true" );
174
+ boolean bwaitForUploadPort = Common .getBuildEnvironmentVariable (project , configName , ArduinoConst .ENV_KEY_wait_for_upload_port , "false" )
175
+ .equalsIgnoreCase ("true" );
174
176
175
- if (boardName .equalsIgnoreCase ("Arduino leonardo" ) || boardName .equalsIgnoreCase ("Arduino Micro" )
176
- || boardName .equalsIgnoreCase ("Arduino Esplora" ) || boardName .startsWith ("Arduino Due" ) || use_1200bps_touch .equalsIgnoreCase ("true" )) {
177
- Vector <String > OriginalPorts = Serial .list ();
178
- // OriginalPorts.remove(ComPort);
177
+ String boardName = Common .getBuildEnvironmentVariable (project , configName , ArduinoConst .ENV_KEY_JANTJE_BOARD_NAME , "" );
179
178
180
- if (!reset_Arduino_by_baud_rate (ComPort , 1200 , 100 ) || boardName .startsWith ("Arduino Due" ) || boardName .startsWith ("Digistump DigiX" )) {
179
+ if (boardRequiresBaudReset (boardName ) || use1200bpsTouch ) {
180
+ Vector <String > serialPorts = Serial .list ();
181
+ if (!resetArduinoByBaudRate (comPort , 1200 , 0 ) || boardRequiresResetPause (boardName )) {
181
182
// Give the DUE/DigiX Atmel SAM-BA bootloader time to switch-in after the reset
182
- try {
183
- Thread .sleep (2000 );
184
- } catch (InterruptedException ex ) {
185
- // ignore error
186
- }
187
- return ComPort ;
183
+ waitFor (2000 );
184
+ return comPort ;
188
185
}
189
- if (boardName .equalsIgnoreCase ("Arduino leonardo" ) || boardName .equalsIgnoreCase ("Arduino Micro" )
190
- || boardName .equalsIgnoreCase ("Arduino Esplora" ) || bwait_for_upload_port ) {
191
- return wait_for_com_Port_to_appear (OriginalPorts , ComPort );
186
+ if (boardNeedsToWaitForPorts (boardName ) || bwaitForUploadPort ) {
187
+ return waitForComPortsToReappear (serialPorts , comPort , boardName );
192
188
}
193
189
}
194
190
191
+ reconnectAndFlushSerialPort (comPort , bDisableFlushing );
192
+
193
+ return comPort ;
194
+ }
195
+
196
+
197
+ // ____________________________________________________________________________
198
+ //
199
+ // private helpers
200
+
201
+
202
+ private static void reconnectAndFlushSerialPort (String comPort , boolean bDisableFlushing ) {
195
203
// connect to the serial port
196
- Serial serialPort ;
204
+ Serial serialPort = null ;
197
205
try {
198
- serialPort = new Serial (ComPort , 9600 );
206
+ serialPort = new Serial (comPort , 9600 );
199
207
} catch (Exception e ) {
200
208
e .printStackTrace ();
201
- Common .log (new Status (IStatus .WARNING , ArduinoConst .CORE_PLUGIN_ID , "Unable to open Serial port " + ComPort , e ));
202
- return ComPort ;
203
- // throw new RunnerException(e.getMessage());
209
+ Common .log (new Status (IStatus .WARNING , ArduinoConst .CORE_PLUGIN_ID , "Unable to open Serial port " + comPort , e ));
204
210
}
205
- if (! serialPort . IsConnected ()) {
206
- Common . log ( new Status ( IStatus . WARNING , ArduinoConst . CORE_PLUGIN_ID , "Unable to open Serial port " + ComPort , null ));
207
- return ComPort ;
211
+
212
+ if ( serialPort == null || ! serialPort . IsConnected ()) {
213
+ Common . log ( new Status ( IStatus . WARNING , ArduinoConst . CORE_PLUGIN_ID , "Unable to open Serial port " + comPort , null )) ;
208
214
}
209
215
210
216
if (!bDisableFlushing ) {
@@ -215,9 +221,32 @@ public static String makeArduinoUploadready(IProject project, String configName,
215
221
}
216
222
// reset arduino
217
223
ToggleDTR (serialPort , 100 );
218
-
219
224
serialPort .dispose ();
220
- return ComPort ;
225
+ }
221
226
227
+ private static void waitFor (long delayMs ) {
228
+ try {
229
+ Thread .sleep (delayMs );
230
+ } catch (InterruptedException e ) {
231
+ }
232
+ }
233
+
234
+ private static final String [] BOARDS_RESET_BY_BAUD = {"arduino leonardo" , "arduino micro" , "arduino esplora" , "arduino due" };
235
+ private static final String [] BOARDS_NEEDING_RESET_PAUSE = {"arduino due" , "digistump digix" };
236
+ private static final String [] BOARDS_NEEDING_TO_WAIT_FOR_PORTS = {"arduino leonardo" , "arduino micro" , "arduino esplora" };
237
+
238
+ private static boolean boardRequiresBaudReset (String board ) {
239
+ return Arrays .asList (BOARDS_RESET_BY_BAUD ).contains (board .toLowerCase ());
240
+ }
241
+
242
+ private static boolean boardRequiresResetPause (String board ) {
243
+ return Arrays .asList (BOARDS_NEEDING_RESET_PAUSE ).contains (board .toLowerCase ());
244
+ }
245
+
246
+ private static boolean boardNeedsToWaitForPorts (String board ) {
247
+ return Arrays .asList (BOARDS_NEEDING_TO_WAIT_FOR_PORTS ).contains (board .toLowerCase ());
222
248
}
249
+
250
+
251
+
223
252
}
0 commit comments