2

Using python code for a serial port connection to an arduino, it sends a value to the arduino, which then starts printing values to serial. The python code will print the value on the first or second run (if run soon enough after), but after that it won't read what's from Serial.println again. To get it to read again (whether I wait some time or not, like for the while loop to finish), the arduino has to be unplugged and plugged in again, why is that different than the serial port connection being closed by python? Here is the arduino code used,

int measured;
int counter = 0;
int maxnum = 10;

void setup()
{
Serial.begin(9600);
}

void loop()
{
  if(Serial.available() > 0)
  {
    while(counter < maxnum)
    {

        Serial.println("V");
        counter++;
        delay(100);

    }
  }
}

I know the value sent from python can be read because I added in code that reads from serial after checking if it's available and changed an output pin value, which works, even if the serial println is not read.

Edit: Since the answer is there shouldn't be a significant difference and the arduino script should be reset if the serial port was closed, the issue should be with the python code.

1 Answers1

2

We cannot know, if your python code also has a problem. But your Arduino code will send the series of "V" only once.

You are using this while loop:

while(counter < maxnum)

in there you are incrementing the variable counter. But after you left the while loop, you are never resetting counter to zero. So the next time, counter is still equal to maxnum. Thus the while loop will not run again. To solve that, insert

counter = 0;

directly after your while loop. Though, for such loops its normally easier to just use a for loop.


Also you might have a second problem. Currently the code waits for Serial data to be received. When something is received, the code will enter the

if(Serial.available() > 0)

statement. But this will stay true, unless you are actually reading the data. Currently the code inside the if statement will be executed on every loop() interation forever. So if you are applying the above fix to the first problem, the code will send "V" forever after you send the first byte to the Arduino. To actually only react to data being received, you need to read the data from the buffer - even if you are throwing the data away:

Serial.read();

What is the difference when an arduino has been unplugged vs when a serial port connection was closed?

For the Arduino itself? Nearly none. Reopening the serial connection will cause the Arduino to reset. The code then starts again from its beginning. Thats also what happens, when you power cycle (replugging) the Arduino. I think there are some little details, where both differ, but that certainly is not the problem here.

For the computer, replugging means, that the USB device (the USB-to-Serial chip on the Arduino to be precise) gets disconnected and again connected. That can lead to the OS allocating a different com-port/device-file for it, than before. Though that doesn't directly do something with the Arduino code (apart from the mentioned power cycle with reset).

For resetting (preserved from comment of OP):

I found that by setting DTR to 0 then 1, then 0 again, right before closing the port, the arduino resets.

chrisl
  • 15,197
  • 2
  • 16
  • 26
  • Ok, yes I had taken out some code to make the simplest example, but in either case, it should read 'V' at least once when starting. When I use pyserial it would read again after rerunning the script, but with pyqt5 it would not read again. So maybe it's an issue with certain python code not closing the serial port properly, if unplugging and closing the serial port should give the same results. [Here](https://stackoverflow.com/questions/66789407/why-would-qtserialport-not-read-after-running-more-than-once-or-twice) is the pyqt5 python version that won't read again. – user14094230 Mar 25 '21 at 17:09
  • Though yes, when I put ```if(Serial.available() > 0) { int counter = 0;``` instead of having the counter initialized at the start, it does read each time. So again, it sounds like the python code was not resetting the arduino code with a new serial port connection. – user14094230 Mar 25 '21 at 17:11
  • I'm no expert in pyqt5 serial, but wouldn't that code just exit, when it received one (or a few) line? And the program just exits without reopening the serial port. So when exactly did you think, that the port should be reopened? – chrisl Mar 25 '21 at 17:15
  • It would be reopened when I run the script again. Yes it just reads one line, but if have the python code read 10 lines like the arduino prints, it still doesn't seem to reset the arduino code when restarting the script. I was just trying to have the simplest script here. – user14094230 Mar 25 '21 at 17:17
  • Mhh, as written above, we are no experts in pyqt5 serial. The Arduino will reset on signals on the DTR or RTS lines ([reference question](https://arduino.stackexchange.com/questions/439/why-does-starting-the-serial-monitor-restart-the-sketch)). Maybe the pyqt5 implementation does not do this by default. You can look into the options of pyqt5 serial. For us that is out of scope. If you need help with that, you can try asking at stackoverflow. That might get you better results, than here. – chrisl Mar 25 '21 at 17:26
  • Yes I have altered the stack overflow question to ask about how pyqt5 opens and closes. Maybe it is an issue with that, pyqt5 has options to set DTR and RTS. Thanks. – user14094230 Mar 25 '21 at 17:30
  • Do you know if this would be related to why the python code would sometimes receive and print out a bytes object b'V' instead of a string object V? This could be for another question and could be an issue with the python code again though. – user14094230 Mar 25 '21 at 17:44
  • 1
    Thats totally on the python side. The serial interface doesn't know the difference between the string V and the byte object b'V'. I would consider it normal, if the python code gave me a byte object as serial data (since serial data isn't necessarily string data; could also be real binary) – chrisl Mar 25 '21 at 18:07
  • 1
    I found that by setting DTR to 0 then 1, then 0 again, right before closing the port, the arduino resets. – user14094230 Mar 26 '21 at 16:37
  • @user14094230 Great! I have preserved that at the end of my answer, since the comments are temporary and this might help others with the same problem. – chrisl Mar 26 '21 at 17:09