try: except: else: not acting right at all!!


31 posts   Page 2 of 2   1, 2
by AshPowers » Tue May 09, 2017 10:47 pm
0.5s sleep in main while 1 loop. openConn() call made before main while 1 loop.
It just prints "None" twice a second, LOL. Still no data printed when sending from phone. I know the data is going from the phone to the RPi though - loading one of my other previous scripts does print the data on the screen (the one with all the open/close ropey code in it that would eventually hang up somewhere).

How is the while 1 loop getting the "msg" data from within the comm_mon thread? If I were to guess, the data for "print msg" is coming from the first line of code rather than from within the comm_mon thread function.

Code: Select all
msg = None

def openConn():
   global conn
   
   while True:
      try:
         conn = serial.Serial("/dev/rfcomm0", baudrate=9600)
         return
      except serial.SerialException:
         pass

def comm_mon():
   global conn, msg
   while True:
      try:
         msg = conn.readline().strip("\n")
      except serial.SerialException:
         conn.close()
         time.sleep(0.2)
         openConn()
openConn()         
t = threading.Thread(target=comm_mon)
t.start()

while 1:
   time.sleep(0.5)
   print msg

Posts: 65
Joined: Thu Apr 20, 2017 12:10 am
Location: Ormond Beach, FL
by AshPowers » Tue May 09, 2017 11:21 pm
OK, I think I may be on to something here...

Even when I disconnect the phone from the RPi, the damn rfcomm0 device is still in the /dev folder. It is NOT closing the rfcomm0 when the connection is terminated. What the hell is going on here?
Posts: 65
Joined: Thu Apr 20, 2017 12:10 am
Location: Ormond Beach, FL
by Douglas6 » Tue May 09, 2017 11:36 pm
I noticed that as well during my simple testing. Not sure what's going on, I suspected not cleanly terminating the connection when interrupting the program with ctrl-c. I haven't investigated further.
User avatar
Posts: 3811
Joined: Sat Mar 16, 2013 5:34 am
Location: Chicago, IL
by AshPowers » Tue May 09, 2017 11:43 pm
How can we check in the python script if the rfcomm0 is in /dev? How do we use rfcomm watch in python?


The problem comes from the python script which does not close the serial port after the Android device has disconnected. One can implement a mechanism (doesn't matter how exactly you want to achieve it) that reacts to a Disconnected message received by rfcomm watch. Namely, when the disconnection occurs, you want to

Either close the port in python by calling Serial.close or kill the python process
Wait for the device to reconnect
Reopen the port or restart the python process
In detail

After calling rfcomm listen <dev> or rfcomm watch <dev>, the Pi is effectively waiting for a connection to be established on /dev/rfcomm0.

When the Android device initiates the connection, the endpoint /dev/rfcomm0 is created and will live forever unless the connection is broken by either of the parties.

In this situation, the python script referred in the question opens up the newly created serial interface (/dev/rfcomm0) via the Serial object abstraction.

Now when the Android device breaks the link, /dev/rfcomm0 is indeed removed but the python Serial object still lives in memory and keeps the port open even though the Android device is down. So when the Android device tries to reconnect after some time, rfcomm watch rightfully complains:

Can't create RFCOMM TTY: Address already in use
simply because the port hasn't been properly closed by the python script when the Android device first left.

To circumvent the problem, one can implement a mechanism (does not matter how exactly you want to achieve it) that reacts to a Disconnected message received by rfcomm watch. Namely, when the disconnection occurs, you want to

Either close the port in python or kill the python process
Wait for the device to reconnect
Reopen the port or restart the python process
Posts: 65
Joined: Thu Apr 20, 2017 12:10 am
Location: Ormond Beach, FL
by AshPowers » Wed May 10, 2017 12:52 am
FINALLY figured this out.

What was throwing things off is if there was previously a connection to the phone and the program was ctrl-c halted, the rfcomm would stay open. If the phone's connection to the RPi was disconnected and the program restarted, it would think that there is a connection even though there wasn't.

The solution to it was to simply do this below before the main "while 1:" loop.. Even if the phone was still connected when the program starts, the phone doesn't see the conn.close() so it stays connected. once the openConn() function is run, it starts with rfcomm nonexistent and then the logic works properly.

Code: Select all
if os.path.exists('/dev/rfcomm0/'):
     conn = serial.Serial("/dev/rfcomm0", baudrate=9600)
     conn.close()
Posts: 65
Joined: Thu Apr 20, 2017 12:10 am
Location: Ormond Beach, FL
by paddyg » Wed May 10, 2017 6:53 am
people often eithe use a variable in the while loop so the ptogam can be stopped in a controlled way (as with the pi3d demos) You could do something like while msg != 'stop': or they put the whole loop in a try and tidy up in except keyboardinterrupt.
also https://groups.google.com/forum/?hl=en-GB&fromgroups=#!forum/pi3d
User avatar
Posts: 1835
Joined: Sat Jan 28, 2012 11:57 am