checking if Arduino is connected (serial USB) to a PC?

I want to change a boolean variable when the Arduino is connected (serial USB connection, not just powered by USB) or disconnected from the PC (if connected set to 1, if disconnected set to 0).

I'd like to know if this is the right way to do it. English is not my first language and the manual page got me a bit confused.

bool var = 0

void setup() {
}

void loop() {
    if (Serial) {
       var = 0;
    } else {
       var = 1;
    }
}

For normal serial:-

The only way to tell if there is anything on the other end of the serial connection is to send a message and see if you get a reply!

Serial still exists and works even if there is nothing connected to it.

If you are using a Leo or one of the other chips with hardware USB then you can check the connection.

Mark

holmes4: For normal serial:-

The only way to tell if there is anything on the other end

So you're saying even if you quit the OS (only the power rails working) Arduino will still send data, it just won't be received? Did I understand?

send a message and see if you get a reply!

More info please. I don't know what you mean by this.

If you are using a Leo or one of the other chips with hardware USB then you can check the connection.

What do you mean by checking the connection? I'm using the Nano.

o you’re saying even if you quit the OS (only the power rails working) Arduino will still send data, it just won’t be received? Did I understand?

Yes. What do you mean OS?

More info please. I don’t know what you mean by this.

You send a message via serial. you have software on the other end that replies. You write the software.

What do you mean by checking the connection? I’m using the Nano.

Then you can’t check the connection by looking at the Arduino hardware.

Mark

holmes4: Yes. What do you mean OS?

When PC provides power via USB but is not booted.

You send a message via serial. you have software on the other end that replies.

Sorry, but this is not clear.

Send from where to where? I do have a program which communicates with the Arduino via USB btw, but your explanation is not clear to me. If my PC is turned off, the program cannot send anything to the Arduino because it is not running, same way Arduino cant send anything to it as it wont recieve it. So I dont understand what you mean by sending a message via serial to check if there is a connection. If you mean something else, please explain. Code (Arduino end) would be nice too.

ghosttrain: If my PC is turned off, the program cannot send anything to the Arduino because it is not running, same way Arduino cant send anything to it as it wont recieve it.

So you believe that not listening makes other people stop talking?

If nobody will listen to the Arduino, how will Arduino know it is not being listened, or more correctly, how can Arduino know there is no PC USB communication going on? That's what I have asked from the beginning. Look,

holmes4: send a message and see if you get a reply

How can Arduino know it hasn't gotten a reply when it won't?

ghosttrain: Look,How can Arduino know it hasn't gotten a reply when it won't?

Because it wont.

Send a message, timeout on waiting for reply, set flag.

Whandall: Send a message, timeout on waiting for reply, set flag.

Example code please. I don't understand how that will translate to code.

Brain gets trained by using it. Same holds true for any skills.

bool stillChecking = true;
bool notConnected;
unsigned long sentMs;

void setup() {
  pinMode(13, OUTPUT);
  digitalWrite(13, LOW);
  Serial.begin(115200);
  Serial.println("Answer!");
  sentMs = millis();
}

void loop() {
  if (stillChecking) {
    if (millis() - sentMs > 10000) {
      if (!Serial.available()) {
        notConnected = true;
        digitalWrite(13, HIGH);
      } else {
        Serial.println("I see you.");
      }
      stillChecking = false;
    }
  }
}

So !Serial.available() is the key? API doc only said Serial.available() "returns the number of bytes available to read".

!Serial.available() is a shortform for Serial.available()==0.

And yes, in detecting a response, no response shows that nobody answered (it does not mean that nobody is attached).

The key is still 'Send a message, timeout on waiting for reply, set flag.'

This seems like a great solution, but there's one problem. Heres a simple code.

if (Serial.available()) {
        digitalWrite(7, HIGH);
} else {
        digitalWrite(7, LOW);
}

When I use the Arduino Serial Monitor or my Python program, the LED turns on, just what I need. But when I exit either, it doesn't turn off. What else do I have to do?

Do the test again?

If you dont read the bytes comming from Serial, available will stay != 0.

Your 'simple code' fails in that case, as well if you use the incomming bytes.

You need to send a message and save the value of millis() wheh it is sent and also set a variable that records that you are waiting for a reply

Then you need continuously to check

if (waitingForReply == true) {
     if (millis() - savedMillis >= timeoutMillis) {
         // there has been no reply in the alotted time
     }
}

so that you will know that there has been no reply.

If you get a reply then change waitingForReply to false.

The demo Several Things at a Time illustrates the use of millis() for timing.

And Serial Input Basics may have some useful ideas.

...R

Whandall: If you dont read the bytes comming from Serial, available will stay != 0.

You mean in my program, or Arduino code? My Python program does read the bytes and prints in the console.

Do you have a Serial.available() on your Pi?

Of course in the Arduino code, you want your detection going on there, don’t you?

I showed you how to detect a (non)communication to a cooperating (answering) partner.

To keep it as simple as possible, I left the answer in the buffer (of Serial).

Write an areYouThere() routine, if you want to check it more than once.

I just don't understand some parts of your code, that's where my confusion comes . Not everyone is as experienced as you.

In your code you have this part:

if (millis() - sentMs > 10000)

From what I read about millis(), it is the time since Arduino started running. So from what I understand, you're making the program loop for 10 seconds. Do I understand , or no? If yes, I don't see how it's any way different to few lines of code I posted, which is in a loop function itself, except of only looping for 10 seconds and also printing text.

It is not looping for ten seconds, it loops forever.

When 10 seconds have expired after sending the request to the partner, it looks for an answer and decides after that, whether sombody is connected.

The stillChecking flag blocks that part of the program after the decision was made.

Is that clearer?

I did not see any detection code posted by you, where is it?