Conditioning the sketch on finding the COM port trouble

I have a sketch that talks to an Arduino. I would like it to stop and warn me when the arduino is not present so I tried:

void setup() {
  size(1900, 950, JAVA2D);


  printArray(Serial.list());

  if (Serial.list().length > 0)
  {
    serialConnect =true;
    myPort = new Serial(this, Serial.list()[0], 115200);
    myPort.bufferUntil(lf); 
    //myPort = new Serial (this, "/dev/tty.wchusbserial5d10", 115200);
    myPort.clear();
    IncomingSTR= "";
  } else
  { 
    textSize(26); 
    text ("CONNECT RECEIVER"+"\n", 10, 40);
  
    delay (3000);
    exit();
    
  }

When the Arduino is connected the sketch is fine.
When there is no ardu, I am still finding a COM port and the sketch gives me a bare screen and no warnings.
In the print bottom I get

=======================================================
[0] ā€œCOM27ā€
RuntimeException: Error opening serial port COM27: Port not found

In device manager, the ā€œPorts COM and LPTā€ is not even thereā€¦ when there is no Arduino.
So where the heck is processing finding a port?

Thanks
Mitch

Iā€™m not sure in your case but some drivers create a virtual com port so maybe thatā€™s what it is trying to open. If you connect an arduino, does it appear as COM27 or show up as another port?

A potential ā€œfixā€ can be to use try/catch and see if you can actually open the port

import processing.serial.*;

void setup() {
  size(1900, 950, JAVA2D);
  printArray(Serial.list());

  try {
    Serial myPort = new Serial(this, "COM27", 115200);
    myPort.clear();
  } catch (Exception e) { 
    e.printStackTrace();
    delay (3000);
    exit();
  }
}

ps could you add all the imports and variable declarations when you post something like this, so we can run the sketch without editing? :slight_smile:

1 Like

Thanks a lot friend. Yes the ardu goes on COM27 when connected.

Its my first time playing with ā€œtryā€ and I tried

import processing.serial.*;
Serial myPort;

int lf = 10; 

void setup() {
  size(1900, 950, JAVA2D);
  printArray(Serial.list());

  try {
    Serial myPort = new Serial(this, "COM27", 115200);
    myPort.clear();
  } catch (Exception e) { 
    e.printStackTrace();
    delay (3000);
    println("NoPORT");
    //exit();
  }
}


void draw() { 
  background(0);


    if (myPort.available() > 0) {
      String IncomingSTR = myPort.readStringUntil(lf);
      println (IncomingSTR);
    }
    
}

I am getting a null pointer when the Ardu is connected and when is not.

When is not I do get the printout println(ā€œNoPORTā€); but not the one above.

I would want not to get a null pointer and give the user a chance to connect the Ardu.

but the first problem, first:
When the Ardu is connected, I get a null pointer and it gets stuck on
if (myPort.available() > 0) { line

The situation is quite messy because of windows. I found in device manager several ā€œGhostsā€ comm ports that get picked occasionally by processing as real portsā€¦

ghost_Ports

To be concise: I would love to write a condition in Setup that will connect the sketch to the only active port in windows. (This time Com27) and would ignore the rest.

Sometimes I get in the (Serial.list()) ports that are greyed out but still indexed as [0] and oneā€¦ halting the sketch. Then I delete them in device manager and re-boot and then I pick the [0] in the sketch and it works fineā€¦

Any advice, thank you,
Mitch

Thanks
Mitch

Hello,

There are many solutions to cleaning this up and starting fresh.

This is just one.

I used to run a script to do this.

:)

Itā€™s because try - catch failed and myPort remained empty. By the way I couldnā€™t get what you mean, but does the code run if the Arduino is connected, and crashes when itā€™s not connected?

If you want to give time for the user to connect USB, I suggest moving the initialization part to draw instead. Pseudo code would be

boolean isConnected = false;
void draw() {
  if(isConnected == false) {
    try {
      // serial connection
      ...
      if(success) {
        isConnected = true;
      }
      else {
        // delay
        ...
      }
    } catch (e) {
      // delay
      ...
    }
  }
  else {
    // do the usual process of serial communication and drawing
    ...
  }
}

and this gives flexibility to go back to the connection process once the Arduino is accidentally disconnected (in theory. I donā€™t know if it actually works like that, though). Also for where I wrote delay, it would be even better if you avoid delay function and check the elapsed time and say

if(currentTime - lastTime > 5000) {
  // do something after 5 sec passed
}

so that there is no interruption in the animation frame (you can display, like ā€œreconnecting in 2 secā€

I was saying I am getting a null pointer even when the Ardu was connected.

OK, I tried your code, but ā€˜successā€™ is not defined. Should we make a bool just for that?

Here

import processing.serial.*;
Serial myPort;
boolean isConnected = false;
int lf = 10; 

void setup() {
  size(1900, 950, JAVA2D);
  printArray(Serial.list());
  
}


void draw() { 
  background(0);

  if (isConnected == false) 
  {
    try {
      Serial myPort = new Serial(this, Serial.list()[0], 115200);
      myPort.clear();
      if (success) {
        isConnected = true;
      } else {
        delay (3000);
        println("NoPORT");
      }
    } 
    catch (Exception e) {
      delay (3000);
      println("NoPORT");
    }
  } else {
    if (myPort.available() > 0) {
      String IncomingSTR = myPort.readStringUntil(lf);
      println (IncomingSTR);
    }
  }
}

Change above to:

myPort = new Serial(this, Serial.list()[0], 115200);

Reference:
Variable Scope / Examples / Processing.org

Hi @laptophead , Have you noticed that with the ch340 driver and chip the port number depends on which USB socket on the PC you have connected to? (The ftdi chip gives you the same number for the same Arduino whatever usb socket.) I know itā€™s annoying to adjust your actions to suit the equipment, but you could simplify things by always using the same usb socket.

Yes, Richard,
Here is what I did,

Went in the device manager and made the Arduino COM port the lowest number among other devices.
This way the [0] in serial list always gets picked.
I rebooted several times and windows seems to keep my COM assignments.

Good enough. Keep life simple