From 617f9ce7ef0be9adcec70c6c960abfa0077719e3 Mon Sep 17 00:00:00 2001 From: Konstantin Gredeskoul Date: Fri, 11 Jul 2014 18:36:05 -0700 Subject: [PATCH 1/6] Adding explicit instructions about /var/lock * this cost me at least 2 hours of wrestling until I stumbled upon this thread: https://github.com/jantje/arduino-eclipse-plugin/issues/129 Adding a check for for MacOS and /var/lock being accessible so that nobody has to waste anymore time :) Once you run the command, subsequent upload succeeds. --- .../src/it/baeyens/arduino/arduino/Serial.java | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/it.baeyens.arduino.common/src/it/baeyens/arduino/arduino/Serial.java b/it.baeyens.arduino.common/src/it/baeyens/arduino/arduino/Serial.java index 44c693361..a3d7c8fb8 100644 --- a/it.baeyens.arduino.common/src/it/baeyens/arduino/arduino/Serial.java +++ b/it.baeyens.arduino.common/src/it/baeyens/arduino/arduino/Serial.java @@ -33,6 +33,7 @@ import it.baeyens.arduino.common.ArduinoConst; import it.baeyens.arduino.common.Common; +import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -190,8 +191,20 @@ public void connect() { } } } catch (PortInUseException e) { - Common.log(new Status(IStatus.ERROR, ArduinoConst.CORE_PLUGIN_ID, "Serial port " + PortName + String OS = System.getProperty("os.name", "generic").toLowerCase(); + boolean isMac, haveVarLock = false; + isMac = ((OS.indexOf("mac") >= 0) || (OS.indexOf("darwin") >= 0)); + if (isMac) { + File varLock = new File("/var/lock"); + haveVarLock = varLock.exists() && varLock.canWrite(); + } + if (isMac && !haveVarLock) { + Common.log(new Status(IStatus.ERROR, ArduinoConst.CORE_PLUGIN_ID, "Serial port " + PortName + + " not accessible: please run the following command: 'sudo mkdir -p /var/lock && sudo chmod 777 /var/lock'")); + } else { + Common.log(new Status(IStatus.ERROR, ArduinoConst.CORE_PLUGIN_ID, "Serial port " + PortName + " already in use. Try quiting any programs that may be using it", e)); + } return; } catch (Exception e) { Common.log(new Status(IStatus.ERROR, ArduinoConst.CORE_PLUGIN_ID, "Error opening serial port " + PortName, e)); From f486e88f9e68f197e77b7b8ebdfc87c933379c23 Mon Sep 17 00:00:00 2001 From: Konstantin Gredeskoul Date: Fri, 11 Jul 2014 19:52:58 -0700 Subject: [PATCH 2/6] Reformat to match Eclipse coding style --- .../src/it/baeyens/arduino/arduino/Serial.java | 16 ++++++++-------- .../arduino/communication/ArduinoSerial.java | 18 +++++++++--------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/it.baeyens.arduino.common/src/it/baeyens/arduino/arduino/Serial.java b/it.baeyens.arduino.common/src/it/baeyens/arduino/arduino/Serial.java index a3d7c8fb8..4449b4428 100644 --- a/it.baeyens.arduino.common/src/it/baeyens/arduino/arduino/Serial.java +++ b/it.baeyens.arduino.common/src/it/baeyens/arduino/arduino/Serial.java @@ -193,18 +193,18 @@ public void connect() { } catch (PortInUseException e) { String OS = System.getProperty("os.name", "generic").toLowerCase(); boolean isMac, haveVarLock = false; - isMac = ((OS.indexOf("mac") >= 0) || (OS.indexOf("darwin") >= 0)); + isMac = ((OS.indexOf("mac") >= 0) || (OS.indexOf("darwin") >= 0)); if (isMac) { File varLock = new File("/var/lock"); haveVarLock = varLock.exists() && varLock.canWrite(); - } + } if (isMac && !haveVarLock) { - Common.log(new Status(IStatus.ERROR, ArduinoConst.CORE_PLUGIN_ID, "Serial port " + PortName - + " not accessible: please run the following command: 'sudo mkdir -p /var/lock && sudo chmod 777 /var/lock'")); - } else { - Common.log(new Status(IStatus.ERROR, ArduinoConst.CORE_PLUGIN_ID, "Serial port " + PortName - + " already in use. Try quiting any programs that may be using it", e)); - } + Common.log(new Status(IStatus.ERROR, ArduinoConst.CORE_PLUGIN_ID, "Serial port " + PortName + + " not accessible: please run the following command: 'sudo mkdir -p /var/lock && sudo chmod 777 /var/lock'")); + } else { + Common.log(new Status(IStatus.ERROR, ArduinoConst.CORE_PLUGIN_ID, "Serial port " + PortName + + " already in use. Try quiting any programs that may be using it", e)); + } return; } catch (Exception e) { Common.log(new Status(IStatus.ERROR, ArduinoConst.CORE_PLUGIN_ID, "Error opening serial port " + PortName, e)); diff --git a/it.baeyens.arduino.core/src/it/baeyens/arduino/communication/ArduinoSerial.java b/it.baeyens.arduino.core/src/it/baeyens/arduino/communication/ArduinoSerial.java index f015f2b33..fdc39373a 100644 --- a/it.baeyens.arduino.core/src/it/baeyens/arduino/communication/ArduinoSerial.java +++ b/it.baeyens.arduino.core/src/it/baeyens/arduino/communication/ArduinoSerial.java @@ -61,17 +61,17 @@ public static String wait_for_com_Port_to_appear(Vector OriginalPorts, S // wait for port to disappear int NumTries = 0; - int MaxTries = 200; // wait for 2 seconds, leaves us 6secs in case we are not seeing disappearing ports but reset worked - int delayMs = 10; // on faster computers Esplora reconnects *extremely* quickly and we can't catch this + int MaxTries = 200; // wait for 2 seconds, leaves us 6secs in case we are not seeing disappearing ports but reset worked + int delayMs = 10; // on faster computers Esplora reconnects *extremely* quickly and we can't catch this do { - if (NumTries > 0) { - try { - Thread.sleep(delayMs); - } catch (InterruptedException e) {// Jaba is not going to write this - // code - } - } OriginalPortsCopy = new Vector(OriginalPorts); + if (NumTries > 0) { + try { + Thread.sleep(delayMs); + } catch (InterruptedException e) {// Jaba is not going to write this + // code + } + } if (NumTries++ > MaxTries) { Common.log(new Status(IStatus.WARNING, ArduinoConst.CORE_PLUGIN_ID, "Leonardo upload port is not disappearing after reset and " + NumTries + " checks")); return defaultComPort; From 709344291e0660bee0487f12a5039b6dd151787a Mon Sep 17 00:00:00 2001 From: Konstantin Gredeskoul Date: Fri, 11 Jul 2014 21:29:44 -0700 Subject: [PATCH 3/6] Slight update to message text + handle NPE --- .../src/it/baeyens/arduino/arduino/Serial.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/it.baeyens.arduino.common/src/it/baeyens/arduino/arduino/Serial.java b/it.baeyens.arduino.common/src/it/baeyens/arduino/arduino/Serial.java index 4449b4428..3de784f0e 100644 --- a/it.baeyens.arduino.common/src/it/baeyens/arduino/arduino/Serial.java +++ b/it.baeyens.arduino.common/src/it/baeyens/arduino/arduino/Serial.java @@ -200,10 +200,12 @@ public void connect() { } if (isMac && !haveVarLock) { Common.log(new Status(IStatus.ERROR, ArduinoConst.CORE_PLUGIN_ID, "Serial port " + PortName - + " not accessible: please run the following command: 'sudo mkdir -p /var/lock && sudo chmod 777 /var/lock'")); + + " is not accessible or already in use: try to quit all other programs that may be using it." + + " If that doesn't fix it, please run the following command:" + + "\n\nsudo mkdir -p /var/lock && sudo chmod 777 /var/lock\n")); } else { Common.log(new Status(IStatus.ERROR, ArduinoConst.CORE_PLUGIN_ID, "Serial port " + PortName - + " already in use. Try quiting any programs that may be using it", e)); + + " already in use. Try to quit all other programs that may be using it.", e)); } return; } catch (Exception e) { @@ -245,7 +247,9 @@ public void disconnect() { } public void dispose() { - notifyConsumersOfEvent("Disconnect of port " + port.getName() + " executed"); + if (port != null) + notifyConsumersOfEvent("Disconnect of port " + port.getName() + " executed"); + disconnect(); if (fServiceRegistration != null) { From 15892fbd9f93e4e30a337ad9e44db48fe93aa799 Mon Sep 17 00:00:00 2001 From: Konstantin Gredeskoul Date: Fri, 11 Jul 2014 21:32:01 -0700 Subject: [PATCH 4/6] Switch back to ERROR, otherwise how to know? * Since the change was made so long ago I am hoping we can go back to having this useful descriptive error. It's really nice to be reminded when the port setting may have remained from a previous project/setup. --- .../it/baeyens/arduino/arduino/Serial.java | 5 +- .../arduino/communication/ArduinoSerial.java | 237 ++++++++++-------- .../tools/uploaders/arduinoUploader.java | 2 +- 3 files changed, 136 insertions(+), 108 deletions(-) diff --git a/it.baeyens.arduino.common/src/it/baeyens/arduino/arduino/Serial.java b/it.baeyens.arduino.common/src/it/baeyens/arduino/arduino/Serial.java index 3de784f0e..a584b7290 100644 --- a/it.baeyens.arduino.common/src/it/baeyens/arduino/arduino/Serial.java +++ b/it.baeyens.arduino.common/src/it/baeyens/arduino/arduino/Serial.java @@ -214,9 +214,8 @@ public void connect() { } if (port == null) { - // jaba 28 feb 2012. I made the log below a warning for issue #7 - Common.log(new Status(IStatus.WARNING, ArduinoConst.CORE_PLUGIN_ID, "Serial port " + PortName - + " not found. Did you select the right one from the project properties -> Arduino -> Arduino?", null)); + Common.log(new Status(IStatus.ERROR, ArduinoConst.CORE_PLUGIN_ID, "Serial port " + PortName + + " not found. Did you assign proper serial port to your project, in Project Properties → Arduino → Port?", null)); return; } } diff --git a/it.baeyens.arduino.core/src/it/baeyens/arduino/communication/ArduinoSerial.java b/it.baeyens.arduino.core/src/it/baeyens/arduino/communication/ArduinoSerial.java index fdc39373a..8a4ca5f81 100644 --- a/it.baeyens.arduino.core/src/it/baeyens/arduino/communication/ArduinoSerial.java +++ b/it.baeyens.arduino.core/src/it/baeyens/arduino/communication/ArduinoSerial.java @@ -9,6 +9,7 @@ import it.baeyens.arduino.common.ArduinoConst; import it.baeyens.arduino.common.Common; +import java.util.Arrays; import java.util.Vector; import org.eclipse.core.resources.IProject; @@ -16,91 +17,100 @@ import org.eclipse.core.runtime.Status; public class ArduinoSerial { + /** - * This method resets arduino based on setting the baud rate. Used for due, leonardo and others + * This method resets Arduino based on setting the baud rate and disconnecting from the port. + * Used for due, leonardo, esplora, and others. Here is from Esplora documentation: + * + * Rather than requiring a physical press of the reset button before an upload, the Esplora is + * designed in a way that allows it to be reset by software running on a connected computer. + * The reset is triggered when the Esplora's virtual (CDC) serial / COM port is opened at + * 1200 baud and then closed. When this happens, the processor will reset, breaking the USB + * connection to the computer (meaning that the virtual serial / COM port will disappear). + * After the processor resets, the bootloader starts, remaining active for about 8 seconds * - * @param ComPort + * @param comPort * The port to set the baud rate - * @param bautrate + * @param baudRate * The baud rate to set + * @param keepOpenPeriod + * How long to keep the port open (ms) + * * @return true is successful otherwise false */ - public static boolean reset_Arduino_by_baud_rate(String ComPort, int baudrate, long openTime) { + public static boolean resetArduinoByBaudRate (String comPort, int baudRate, long keepOpenPeriod) { Serial serialPort; + try { - serialPort = new Serial(ComPort, baudrate); + serialPort = new Serial(comPort, baudRate); } catch (Exception e) { e.printStackTrace(); - Common.log(new Status(IStatus.WARNING, ArduinoConst.CORE_PLUGIN_ID, "Unable to open Serial port " + ComPort, e)); + Common.log(new Status(IStatus.WARNING, ArduinoConst.CORE_PLUGIN_ID, "Unable to open Serial port " + + comPort + " and baudRate " + baudRate, e)); return false; } - try { - Thread.sleep(openTime); - } catch (InterruptedException e) {// Jaba is not going to write this - // code - } - serialPort.dispose(); + waitFor(keepOpenPeriod); + + if (serialPort != null) + serialPort.dispose(); + return true; } /** * Waits for a serial port to appear. It is assumed that the default comport is not available on the system * - * @param OriginalPorts + * @param originalPorts * The ports available on the system - * @param defaultComPort + * @param comPort * The port to return if no new com port is found * @return the new comport if found else the defaultComPort */ - public static String wait_for_com_Port_to_appear(Vector OriginalPorts, String defaultComPort) { - - Vector NewPorts; - Vector OriginalPortsCopy; - + public static String waitForComPortsToReappear (Vector originalPorts, String comPort, String boardName) { // wait for port to disappear - int NumTries = 0; - int MaxTries = 200; // wait for 2 seconds, leaves us 6secs in case we are not seeing disappearing ports but reset worked - int delayMs = 10; // on faster computers Esplora reconnects *extremely* quickly and we can't catch this - do { - OriginalPortsCopy = new Vector(OriginalPorts); - if (NumTries > 0) { - try { - Thread.sleep(delayMs); - } catch (InterruptedException e) {// Jaba is not going to write this - // code - } - } - if (NumTries++ > MaxTries) { - Common.log(new Status(IStatus.WARNING, ArduinoConst.CORE_PLUGIN_ID, "Leonardo upload port is not disappearing after reset and " + NumTries + " checks")); - return defaultComPort; - } - NewPorts = Serial.list(); - for (int i = 0; i < NewPorts.size(); i++) { - OriginalPortsCopy.remove(NewPorts.get(i)); + int maxAttempts = 200; + int pauseForMs = 5; + int attemptsCount; + + Vector disconnectedPorts = null; + + for (attemptsCount = 0; attemptsCount < maxAttempts; attemptsCount++) { + Vector currentPorts = Serial.list(); + if (currentPorts.size() < originalPorts.size()) { + disconnectedPorts = new Vector(originalPorts); + disconnectedPorts.removeAll(currentPorts); + Common.log(new Status(IStatus.INFO, ArduinoConst.CORE_PLUGIN_ID, + boardName + " port(s) disconnected [" + disconnectedPorts.toString() + "] after " + attemptsCount * pauseForMs +"ms")); + break; } - } while (OriginalPortsCopy.size() != 1); - OriginalPorts.remove(OriginalPortsCopy.get(0)); + if (attemptsCount > 0) + waitFor(pauseForMs); + } - NumTries = 0; - do { - if (NumTries++ > MaxTries) { - Common.log(new Status(IStatus.ERROR, ArduinoConst.CORE_PLUGIN_ID, "Leonardo upload port is not appearing after reset")); - return defaultComPort; - } - NewPorts = Serial.list(); - for (int i = 0; i < OriginalPorts.size(); i++) { - NewPorts.remove(OriginalPorts.get(i)); - } - try { - Thread.sleep(delayMs); - } catch (InterruptedException e) {// Jaba is not going to write this - // code + if (attemptsCount == maxAttempts && (disconnectedPorts == null || disconnectedPorts.isEmpty())) { + Common.log(new Status(IStatus.WARNING, ArduinoConst.CORE_PLUGIN_ID, boardName + " upload port is not disappearing after reset and " + attemptsCount * pauseForMs + "ms")); + return comPort; + } + + for (attemptsCount = 0; attemptsCount < maxAttempts; attemptsCount++) { + if (Serial.list().contains(comPort)) { + Common.log(new Status(IStatus.INFO, ArduinoConst.CORE_PLUGIN_ID, + boardName + " port " + comPort + " reconnected after " + attemptsCount * pauseForMs)); + return comPort; } - } while (NewPorts.size() != 1); - return NewPorts.get(0); + if (attemptsCount > 0) + waitFor(pauseForMs); + } + + if (attemptsCount == maxAttempts) { + Common.log(new Status(IStatus.WARNING, ArduinoConst.CORE_PLUGIN_ID, boardName + " upload port is not appearing after reset")); + + } + + return comPort; } /** @@ -116,11 +126,7 @@ public static boolean ToggleDTR(Serial serialPort, long delay) { serialPort.setDTR(false); serialPort.setRTS(false); - try { - Thread.sleep(delay); - } catch (InterruptedException e) {// Jaba is not going to write this - // code - } + waitFor(delay); serialPort.setDTR(true); serialPort.setRTS(true); @@ -136,16 +142,12 @@ public static boolean ToggleDTR(Serial serialPort, long delay) { public static void flushSerialBuffer(Serial serialPort) { while (serialPort.available() > 0) { serialPort.readBytes(); - try { - Thread.sleep(100); // TOFIX I think this is bad; not to bad as - // readBytes reads all info but - // if the boards sends data at a speed higher - // than 1 ever 100ms we will never get out of - // this loop - } catch (InterruptedException e) { // we can safely ignore all - // errors here as we are throwing - // everything away anyway - } + // TOFIX I think this is bad; not to bad as + // readBytes reads all info but + // if the boards sends data at a speed higher + // than 1 ever 100ms we will never get out of + // this loop + waitFor(100); } } @@ -157,54 +159,58 @@ public static void flushSerialBuffer(Serial serialPort) { * * @param project * The project related to the com port to reset - * @param ComPort + * @param comPort * The name of the com port to reset * @return The com port to upload to */ - public static String makeArduinoUploadready(IProject project, String configName, String ComPort) { + public static String makeArduinoUploadready(IProject project, String configName, String comPort) { if (Common.RXTXDisabled()) - return ComPort; - // ArduinoProperties arduinoProperties = new ArduinoProperties(project); - String use_1200bps_touch = Common.getBuildEnvironmentVariable(project, configName, ArduinoConst.ENV_KEY_upload_use_1200bps_touch, "false"); + return comPort; + + boolean use1200bpsTouch = Common.getBuildEnvironmentVariable(project, configName, ArduinoConst.ENV_KEY_upload_use_1200bps_touch, "false") + .equalsIgnoreCase("true"); boolean bDisableFlushing = Common.getBuildEnvironmentVariable(project, configName, ArduinoConst.ENV_KEY_upload_disable_flushing, "false") - .equalsIgnoreCase("true"); - boolean bwait_for_upload_port = Common.getBuildEnvironmentVariable(project, configName, ArduinoConst.ENV_KEY_wait_for_upload_port, "false") - .equalsIgnoreCase("true"); - String boardName = Common.getBuildEnvironmentVariable(project, configName, ArduinoConst.ENV_KEY_JANTJE_BOARD_NAME, ""); + .equalsIgnoreCase("true"); + boolean bwaitForUploadPort = Common.getBuildEnvironmentVariable(project, configName, ArduinoConst.ENV_KEY_wait_for_upload_port, "false") + .equalsIgnoreCase("true"); - if (boardName.equalsIgnoreCase("Arduino leonardo") || boardName.equalsIgnoreCase("Arduino Micro") - || boardName.equalsIgnoreCase("Arduino Esplora") || boardName.startsWith("Arduino Due") || use_1200bps_touch.equalsIgnoreCase("true")) { - Vector OriginalPorts = Serial.list(); - // OriginalPorts.remove(ComPort); + String boardName = Common.getBuildEnvironmentVariable(project, configName, ArduinoConst.ENV_KEY_JANTJE_BOARD_NAME, ""); - if (!reset_Arduino_by_baud_rate(ComPort, 1200, 100) || boardName.startsWith("Arduino Due") || boardName.startsWith("Digistump DigiX")) { + if (boardRequiresBaudReset(boardName) || use1200bpsTouch) { + Vector serialPorts = Serial.list(); + if (!resetArduinoByBaudRate(comPort, 1200, 0) || boardRequiresResetPause(boardName)) { // Give the DUE/DigiX Atmel SAM-BA bootloader time to switch-in after the reset - try { - Thread.sleep(2000); - } catch (InterruptedException ex) { - // ignore error - } - return ComPort; + waitFor(2000); + return comPort; } - if (boardName.equalsIgnoreCase("Arduino leonardo") || boardName.equalsIgnoreCase("Arduino Micro") - || boardName.equalsIgnoreCase("Arduino Esplora") || bwait_for_upload_port) { - return wait_for_com_Port_to_appear(OriginalPorts, ComPort); + if (boardNeedsToWaitForPorts(boardName) || bwaitForUploadPort) { + return waitForComPortsToReappear(serialPorts, comPort, boardName); } } + reconnectAndFlushSerialPort(comPort, bDisableFlushing); + + return comPort; + } + + + // ____________________________________________________________________________ + // + // private helpers + + + private static void reconnectAndFlushSerialPort (String comPort, boolean bDisableFlushing) { // connect to the serial port - Serial serialPort; + Serial serialPort = null; try { - serialPort = new Serial(ComPort, 9600); + serialPort = new Serial(comPort, 9600); } catch (Exception e) { e.printStackTrace(); - Common.log(new Status(IStatus.WARNING, ArduinoConst.CORE_PLUGIN_ID, "Unable to open Serial port " + ComPort, e)); - return ComPort; - // throw new RunnerException(e.getMessage()); + Common.log(new Status(IStatus.WARNING, ArduinoConst.CORE_PLUGIN_ID, "Unable to open Serial port " + comPort, e)); } - if (!serialPort.IsConnected()) { - Common.log(new Status(IStatus.WARNING, ArduinoConst.CORE_PLUGIN_ID, "Unable to open Serial port " + ComPort, null)); - return ComPort; + + if (serialPort == null || !serialPort.IsConnected()) { + Common.log(new Status(IStatus.WARNING, ArduinoConst.CORE_PLUGIN_ID, "Unable to open Serial port " + comPort, null)); } if (!bDisableFlushing) { @@ -215,9 +221,32 @@ public static String makeArduinoUploadready(IProject project, String configName, } // reset arduino ToggleDTR(serialPort, 100); - serialPort.dispose(); - return ComPort; + } + private static void waitFor(long delayMs) { + try { + Thread.sleep(delayMs); + } catch (InterruptedException e) { + } + } + + private static final String[] BOARDS_RESET_BY_BAUD = {"arduino leonardo", "arduino micro", "arduino esplora", "arduino due"}; + private static final String[] BOARDS_NEEDING_RESET_PAUSE = {"arduino due", "digistump digix"}; + private static final String[] BOARDS_NEEDING_TO_WAIT_FOR_PORTS = {"arduino leonardo", "arduino micro", "arduino esplora"}; + + private static boolean boardRequiresBaudReset(String board) { + return Arrays.asList(BOARDS_RESET_BY_BAUD).contains(board.toLowerCase()); + } + + private static boolean boardRequiresResetPause(String board) { + return Arrays.asList(BOARDS_NEEDING_RESET_PAUSE).contains(board.toLowerCase()); + } + + private static boolean boardNeedsToWaitForPorts(String board) { + return Arrays.asList(BOARDS_NEEDING_TO_WAIT_FOR_PORTS).contains(board.toLowerCase()); } + + + } diff --git a/it.baeyens.arduino.core/src/it/baeyens/arduino/tools/uploaders/arduinoUploader.java b/it.baeyens.arduino.core/src/it/baeyens/arduino/tools/uploaders/arduinoUploader.java index bcdd0faf1..f6b27f95b 100644 --- a/it.baeyens.arduino.core/src/it/baeyens/arduino/tools/uploaders/arduinoUploader.java +++ b/it.baeyens.arduino.core/src/it/baeyens/arduino/tools/uploaders/arduinoUploader.java @@ -46,7 +46,7 @@ public boolean uploadUsingPreferences(IFile hexFile, IProject project, boolean u return false; } if (boardName.startsWith("Arduino Due ")) { - ArduinoSerial.reset_Arduino_by_baud_rate(MComPort, 115200, 100); + ArduinoSerial.resetArduinoByBaudRate(MComPort, 115200, 100); } return true; From fcd7b22f0f38a447d8c2618404e41f8a2b01266d Mon Sep 17 00:00:00 2001 From: Konstantin Gredeskoul Date: Sat, 12 Jul 2014 03:06:59 -0700 Subject: [PATCH 5/6] Adding extra new lines for readability. --- .../src/it/baeyens/arduino/arduino/Serial.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/it.baeyens.arduino.common/src/it/baeyens/arduino/arduino/Serial.java b/it.baeyens.arduino.common/src/it/baeyens/arduino/arduino/Serial.java index a584b7290..e91586762 100644 --- a/it.baeyens.arduino.common/src/it/baeyens/arduino/arduino/Serial.java +++ b/it.baeyens.arduino.common/src/it/baeyens/arduino/arduino/Serial.java @@ -200,8 +200,8 @@ public void connect() { } if (isMac && !haveVarLock) { Common.log(new Status(IStatus.ERROR, ArduinoConst.CORE_PLUGIN_ID, "Serial port " + PortName - + " is not accessible or already in use: try to quit all other programs that may be using it." - + " If that doesn't fix it, please run the following command:" + + " is not accessible or already in use: try quitting all other programs that may be using it." + + "\n\nIf that doesn't fix it, please run the following command:" + "\n\nsudo mkdir -p /var/lock && sudo chmod 777 /var/lock\n")); } else { Common.log(new Status(IStatus.ERROR, ArduinoConst.CORE_PLUGIN_ID, "Serial port " + PortName From a93ee05d4b161b3ed8c84ee261d0635366bf20ab Mon Sep 17 00:00:00 2001 From: Konstantin Gredeskoul Date: Sat, 12 Jul 2014 03:07:44 -0700 Subject: [PATCH 6/6] Revert "Switch back to ERROR, otherwise how to know?" This reverts commit 15892fbd9f93e4e30a337ad9e44db48fe93aa799. --- .../it/baeyens/arduino/arduino/Serial.java | 5 +- .../arduino/communication/ArduinoSerial.java | 237 ++++++++---------- .../tools/uploaders/arduinoUploader.java | 2 +- 3 files changed, 108 insertions(+), 136 deletions(-) diff --git a/it.baeyens.arduino.common/src/it/baeyens/arduino/arduino/Serial.java b/it.baeyens.arduino.common/src/it/baeyens/arduino/arduino/Serial.java index e91586762..f7a772dcd 100644 --- a/it.baeyens.arduino.common/src/it/baeyens/arduino/arduino/Serial.java +++ b/it.baeyens.arduino.common/src/it/baeyens/arduino/arduino/Serial.java @@ -214,8 +214,9 @@ public void connect() { } if (port == null) { - Common.log(new Status(IStatus.ERROR, ArduinoConst.CORE_PLUGIN_ID, "Serial port " + PortName - + " not found. Did you assign proper serial port to your project, in Project Properties → Arduino → Port?", null)); + // jaba 28 feb 2012. I made the log below a warning for issue #7 + Common.log(new Status(IStatus.WARNING, ArduinoConst.CORE_PLUGIN_ID, "Serial port " + PortName + + " not found. Did you select the right one from the project properties -> Arduino -> Arduino?", null)); return; } } diff --git a/it.baeyens.arduino.core/src/it/baeyens/arduino/communication/ArduinoSerial.java b/it.baeyens.arduino.core/src/it/baeyens/arduino/communication/ArduinoSerial.java index 8a4ca5f81..fdc39373a 100644 --- a/it.baeyens.arduino.core/src/it/baeyens/arduino/communication/ArduinoSerial.java +++ b/it.baeyens.arduino.core/src/it/baeyens/arduino/communication/ArduinoSerial.java @@ -9,7 +9,6 @@ import it.baeyens.arduino.common.ArduinoConst; import it.baeyens.arduino.common.Common; -import java.util.Arrays; import java.util.Vector; import org.eclipse.core.resources.IProject; @@ -17,100 +16,91 @@ import org.eclipse.core.runtime.Status; public class ArduinoSerial { - /** - * This method resets Arduino based on setting the baud rate and disconnecting from the port. - * Used for due, leonardo, esplora, and others. Here is from Esplora documentation: - * - * Rather than requiring a physical press of the reset button before an upload, the Esplora is - * designed in a way that allows it to be reset by software running on a connected computer. - * The reset is triggered when the Esplora's virtual (CDC) serial / COM port is opened at - * 1200 baud and then closed. When this happens, the processor will reset, breaking the USB - * connection to the computer (meaning that the virtual serial / COM port will disappear). - * After the processor resets, the bootloader starts, remaining active for about 8 seconds + * This method resets arduino based on setting the baud rate. Used for due, leonardo and others * - * @param comPort + * @param ComPort * The port to set the baud rate - * @param baudRate + * @param bautrate * The baud rate to set - * @param keepOpenPeriod - * How long to keep the port open (ms) - * * @return true is successful otherwise false */ - public static boolean resetArduinoByBaudRate (String comPort, int baudRate, long keepOpenPeriod) { + public static boolean reset_Arduino_by_baud_rate(String ComPort, int baudrate, long openTime) { Serial serialPort; - try { - serialPort = new Serial(comPort, baudRate); + serialPort = new Serial(ComPort, baudrate); } catch (Exception e) { e.printStackTrace(); - Common.log(new Status(IStatus.WARNING, ArduinoConst.CORE_PLUGIN_ID, "Unable to open Serial port " + - comPort + " and baudRate " + baudRate, e)); + Common.log(new Status(IStatus.WARNING, ArduinoConst.CORE_PLUGIN_ID, "Unable to open Serial port " + ComPort, e)); return false; } - waitFor(keepOpenPeriod); - - if (serialPort != null) - serialPort.dispose(); - + try { + Thread.sleep(openTime); + } catch (InterruptedException e) {// Jaba is not going to write this + // code + } + serialPort.dispose(); return true; } /** * Waits for a serial port to appear. It is assumed that the default comport is not available on the system * - * @param originalPorts + * @param OriginalPorts * The ports available on the system - * @param comPort + * @param defaultComPort * The port to return if no new com port is found * @return the new comport if found else the defaultComPort */ - public static String waitForComPortsToReappear (Vector originalPorts, String comPort, String boardName) { + public static String wait_for_com_Port_to_appear(Vector OriginalPorts, String defaultComPort) { - // wait for port to disappear - int maxAttempts = 200; - int pauseForMs = 5; - int attemptsCount; - - Vector disconnectedPorts = null; - - for (attemptsCount = 0; attemptsCount < maxAttempts; attemptsCount++) { - Vector currentPorts = Serial.list(); - if (currentPorts.size() < originalPorts.size()) { - disconnectedPorts = new Vector(originalPorts); - disconnectedPorts.removeAll(currentPorts); - Common.log(new Status(IStatus.INFO, ArduinoConst.CORE_PLUGIN_ID, - boardName + " port(s) disconnected [" + disconnectedPorts.toString() + "] after " + attemptsCount * pauseForMs +"ms")); - break; - } - - if (attemptsCount > 0) - waitFor(pauseForMs); - } + Vector NewPorts; + Vector OriginalPortsCopy; - if (attemptsCount == maxAttempts && (disconnectedPorts == null || disconnectedPorts.isEmpty())) { - Common.log(new Status(IStatus.WARNING, ArduinoConst.CORE_PLUGIN_ID, boardName + " upload port is not disappearing after reset and " + attemptsCount * pauseForMs + "ms")); - return comPort; - } - for (attemptsCount = 0; attemptsCount < maxAttempts; attemptsCount++) { - if (Serial.list().contains(comPort)) { - Common.log(new Status(IStatus.INFO, ArduinoConst.CORE_PLUGIN_ID, - boardName + " port " + comPort + " reconnected after " + attemptsCount * pauseForMs)); - return comPort; + // wait for port to disappear + int NumTries = 0; + int MaxTries = 200; // wait for 2 seconds, leaves us 6secs in case we are not seeing disappearing ports but reset worked + int delayMs = 10; // on faster computers Esplora reconnects *extremely* quickly and we can't catch this + do { + OriginalPortsCopy = new Vector(OriginalPorts); + if (NumTries > 0) { + try { + Thread.sleep(delayMs); + } catch (InterruptedException e) {// Jaba is not going to write this + // code + } + } + if (NumTries++ > MaxTries) { + Common.log(new Status(IStatus.WARNING, ArduinoConst.CORE_PLUGIN_ID, "Leonardo upload port is not disappearing after reset and " + NumTries + " checks")); + return defaultComPort; + } + NewPorts = Serial.list(); + for (int i = 0; i < NewPorts.size(); i++) { + OriginalPortsCopy.remove(NewPorts.get(i)); } - if (attemptsCount > 0) - waitFor(pauseForMs); - } - - if (attemptsCount == maxAttempts) { - Common.log(new Status(IStatus.WARNING, ArduinoConst.CORE_PLUGIN_ID, boardName + " upload port is not appearing after reset")); - } + } while (OriginalPortsCopy.size() != 1); + OriginalPorts.remove(OriginalPortsCopy.get(0)); - return comPort; + NumTries = 0; + do { + if (NumTries++ > MaxTries) { + Common.log(new Status(IStatus.ERROR, ArduinoConst.CORE_PLUGIN_ID, "Leonardo upload port is not appearing after reset")); + return defaultComPort; + } + NewPorts = Serial.list(); + for (int i = 0; i < OriginalPorts.size(); i++) { + NewPorts.remove(OriginalPorts.get(i)); + } + try { + Thread.sleep(delayMs); + } catch (InterruptedException e) {// Jaba is not going to write this + // code + } + } while (NewPorts.size() != 1); + return NewPorts.get(0); } /** @@ -126,7 +116,11 @@ public static boolean ToggleDTR(Serial serialPort, long delay) { serialPort.setDTR(false); serialPort.setRTS(false); - waitFor(delay); + try { + Thread.sleep(delay); + } catch (InterruptedException e) {// Jaba is not going to write this + // code + } serialPort.setDTR(true); serialPort.setRTS(true); @@ -142,12 +136,16 @@ public static boolean ToggleDTR(Serial serialPort, long delay) { public static void flushSerialBuffer(Serial serialPort) { while (serialPort.available() > 0) { serialPort.readBytes(); - // TOFIX I think this is bad; not to bad as - // readBytes reads all info but - // if the boards sends data at a speed higher - // than 1 ever 100ms we will never get out of - // this loop - waitFor(100); + try { + Thread.sleep(100); // TOFIX I think this is bad; not to bad as + // readBytes reads all info but + // if the boards sends data at a speed higher + // than 1 ever 100ms we will never get out of + // this loop + } catch (InterruptedException e) { // we can safely ignore all + // errors here as we are throwing + // everything away anyway + } } } @@ -159,58 +157,54 @@ public static void flushSerialBuffer(Serial serialPort) { * * @param project * The project related to the com port to reset - * @param comPort + * @param ComPort * The name of the com port to reset * @return The com port to upload to */ - public static String makeArduinoUploadready(IProject project, String configName, String comPort) { + public static String makeArduinoUploadready(IProject project, String configName, String ComPort) { if (Common.RXTXDisabled()) - return comPort; - - boolean use1200bpsTouch = Common.getBuildEnvironmentVariable(project, configName, ArduinoConst.ENV_KEY_upload_use_1200bps_touch, "false") - .equalsIgnoreCase("true"); + return ComPort; + // ArduinoProperties arduinoProperties = new ArduinoProperties(project); + String use_1200bps_touch = Common.getBuildEnvironmentVariable(project, configName, ArduinoConst.ENV_KEY_upload_use_1200bps_touch, "false"); boolean bDisableFlushing = Common.getBuildEnvironmentVariable(project, configName, ArduinoConst.ENV_KEY_upload_disable_flushing, "false") - .equalsIgnoreCase("true"); - boolean bwaitForUploadPort = Common.getBuildEnvironmentVariable(project, configName, ArduinoConst.ENV_KEY_wait_for_upload_port, "false") - .equalsIgnoreCase("true"); - + .equalsIgnoreCase("true"); + boolean bwait_for_upload_port = Common.getBuildEnvironmentVariable(project, configName, ArduinoConst.ENV_KEY_wait_for_upload_port, "false") + .equalsIgnoreCase("true"); String boardName = Common.getBuildEnvironmentVariable(project, configName, ArduinoConst.ENV_KEY_JANTJE_BOARD_NAME, ""); - if (boardRequiresBaudReset(boardName) || use1200bpsTouch) { - Vector serialPorts = Serial.list(); - if (!resetArduinoByBaudRate(comPort, 1200, 0) || boardRequiresResetPause(boardName)) { + if (boardName.equalsIgnoreCase("Arduino leonardo") || boardName.equalsIgnoreCase("Arduino Micro") + || boardName.equalsIgnoreCase("Arduino Esplora") || boardName.startsWith("Arduino Due") || use_1200bps_touch.equalsIgnoreCase("true")) { + Vector OriginalPorts = Serial.list(); + // OriginalPorts.remove(ComPort); + + if (!reset_Arduino_by_baud_rate(ComPort, 1200, 100) || boardName.startsWith("Arduino Due") || boardName.startsWith("Digistump DigiX")) { // Give the DUE/DigiX Atmel SAM-BA bootloader time to switch-in after the reset - waitFor(2000); - return comPort; + try { + Thread.sleep(2000); + } catch (InterruptedException ex) { + // ignore error + } + return ComPort; } - if (boardNeedsToWaitForPorts(boardName) || bwaitForUploadPort) { - return waitForComPortsToReappear(serialPorts, comPort, boardName); + if (boardName.equalsIgnoreCase("Arduino leonardo") || boardName.equalsIgnoreCase("Arduino Micro") + || boardName.equalsIgnoreCase("Arduino Esplora") || bwait_for_upload_port) { + return wait_for_com_Port_to_appear(OriginalPorts, ComPort); } } - reconnectAndFlushSerialPort(comPort, bDisableFlushing); - - return comPort; - } - - - // ____________________________________________________________________________ - // - // private helpers - - - private static void reconnectAndFlushSerialPort (String comPort, boolean bDisableFlushing) { // connect to the serial port - Serial serialPort = null; + Serial serialPort; try { - serialPort = new Serial(comPort, 9600); + serialPort = new Serial(ComPort, 9600); } catch (Exception e) { e.printStackTrace(); - Common.log(new Status(IStatus.WARNING, ArduinoConst.CORE_PLUGIN_ID, "Unable to open Serial port " + comPort, e)); + Common.log(new Status(IStatus.WARNING, ArduinoConst.CORE_PLUGIN_ID, "Unable to open Serial port " + ComPort, e)); + return ComPort; + // throw new RunnerException(e.getMessage()); } - - if (serialPort == null || !serialPort.IsConnected()) { - Common.log(new Status(IStatus.WARNING, ArduinoConst.CORE_PLUGIN_ID, "Unable to open Serial port " + comPort, null)); + if (!serialPort.IsConnected()) { + Common.log(new Status(IStatus.WARNING, ArduinoConst.CORE_PLUGIN_ID, "Unable to open Serial port " + ComPort, null)); + return ComPort; } if (!bDisableFlushing) { @@ -221,32 +215,9 @@ private static void reconnectAndFlushSerialPort (String comPort, boolean bDisabl } // reset arduino ToggleDTR(serialPort, 100); - serialPort.dispose(); - } - private static void waitFor(long delayMs) { - try { - Thread.sleep(delayMs); - } catch (InterruptedException e) { - } - } - - private static final String[] BOARDS_RESET_BY_BAUD = {"arduino leonardo", "arduino micro", "arduino esplora", "arduino due"}; - private static final String[] BOARDS_NEEDING_RESET_PAUSE = {"arduino due", "digistump digix"}; - private static final String[] BOARDS_NEEDING_TO_WAIT_FOR_PORTS = {"arduino leonardo", "arduino micro", "arduino esplora"}; - - private static boolean boardRequiresBaudReset(String board) { - return Arrays.asList(BOARDS_RESET_BY_BAUD).contains(board.toLowerCase()); - } - - private static boolean boardRequiresResetPause(String board) { - return Arrays.asList(BOARDS_NEEDING_RESET_PAUSE).contains(board.toLowerCase()); - } + serialPort.dispose(); + return ComPort; - private static boolean boardNeedsToWaitForPorts(String board) { - return Arrays.asList(BOARDS_NEEDING_TO_WAIT_FOR_PORTS).contains(board.toLowerCase()); } - - - } diff --git a/it.baeyens.arduino.core/src/it/baeyens/arduino/tools/uploaders/arduinoUploader.java b/it.baeyens.arduino.core/src/it/baeyens/arduino/tools/uploaders/arduinoUploader.java index f6b27f95b..bcdd0faf1 100644 --- a/it.baeyens.arduino.core/src/it/baeyens/arduino/tools/uploaders/arduinoUploader.java +++ b/it.baeyens.arduino.core/src/it/baeyens/arduino/tools/uploaders/arduinoUploader.java @@ -46,7 +46,7 @@ public boolean uploadUsingPreferences(IFile hexFile, IProject project, boolean u return false; } if (boardName.startsWith("Arduino Due ")) { - ArduinoSerial.resetArduinoByBaudRate(MComPort, 115200, 100); + ArduinoSerial.reset_Arduino_by_baud_rate(MComPort, 115200, 100); } return true;