I want to open the serial device exclusively by pyserial in ubuntu 20.04. I tried the following two approaches.
To use the exclusive flag in pyserial.
ser = Serial(port=serialdevice, baudrate=115200, bytesize=8, timeout=2, exclusive=True)
To use fcntl as below.
try:
ser = Serial(port=serialdevice, baudrate=115200, bytesize=8, timeout=2)
if ser.isOpen():
try:
fcntl.flock(ser.fileno(), fcntl.LOCK_EX | fcntl.LOCK_NB)
except Exception as e:
print(e)
except Exception a e:
print(e)
Both approaches do not work. There is no any lock file generated under /var/lock.
Finally, I can only created the lock file manually under /var/lock as below.
try:
device_name = serialdevice.split("/")[2]
lock_file_name = "/var/lock/LCK.."+device_name
ser = Serial(port=serialdevice, baudrate=115200, bytesize=8, timeout=2)
if ser.isOpen():
open(lock_file_name, 'w').write(str(os.getpid()))
else:
print("port not open")
except Exception as e:
print("Failed to open serial port exclusively. Pls check if the serial port is already used by other tools")
print(e)
return
May I ask what could be wrong in the first two approaches? Is the manual method used generally in opening the serial port exclusively? Do I need to delete the lock file manually when the python script quit?
Thanks!
Related
I was hoping to find out how to check if there are any serial ports opened before they are established and if so then close them
comlist= serial.tools.list_ports.comports()
for i in comlist:
connected.append(i.device)
if i.device == isOpen()
i.device.close
where i.device is the serial port being identified because if I use
try:
ser = serial.Serial(port = i.device)
if ser.isOpen:
ser.close()
except
pass
because then the serial I want to close cannot be accessed as ser, it fails because ser = serial.Serial(port = i.device) will raise a PermissionError. Let me know if I can explain this further.
Im newbie for python and serial port. I want to monitor serial port continuously. If port not opened or access denied, need to run the python script without stop.
I had done something, But that script has stopped when the PORT not opened or access denied. kindly, help someone to close this issue.
import serial
z1baudrate = 9600
z1port = 'COM4'
z1serial = serial.Serial(port=z1port, baudrate=z1baudrate,timeout=1)
try:
if z1serial.is_open:
while True:
size = z1serial.inWaiting()
if size:
data = z1serial.read(size)
res= data.decode("utf-8")
print(res)
else:
print("Data not reading")
time.sleep(1)
else:
z1serial.close()
print('z1serial not open or Already in use')
except serial.SerialException as e:
z1serial.close()
print('COM4 not open')
You need to include the z1serial assignment inside the try block as
import serial
import time
z1baudrate = 9600
z1port = 'COM4'
while True:
try:
z1serial = serial.Serial(port=z1port, baudrate=z1baudrate,timeout=1)
if z1serial.is_open:
while True:
size = z1serial.inWaiting()
if size:
data = z1serial.read(size)
res= data.decode("utf-8")
print(res)
else:
print("Data not reading")
time.sleep(1)
else:
z1serial.close()
print('z1serial not open or Already in use')
except serial.SerialException:
print('COM4 not open')
time.sleep(1)
This worked for me, running on Python 3.7
I am trying to open a serial port via Python, write the incoming data stream into a file and close the file when the data stream stops.
My program is unable to detect that the port is no longer receiving any data. So the file remains open. What do I do?
import serial
ser = serial.Serial(port='COM8', baudrate=9600, bytesize=8, parity='N', stopbits=1, timeout=None, xonxoff=0, rtscts=0)
print("Connected to Audio(COM8) port")
try:
f = open('C:\Users\user\Desktop\final.raw', 'w')
while 1:
ser_bytes = ser.readline()
if ser_bytes:
f.write(ser_bytes)
else:
break
finally:
f.close()
print("output file closed")
ser.close()
Specify timeout while using ser.readline()
I am trying to send this command ":01050801FF00F2" over serial in python 2.7 , with no success.
The code that i use is :
import serial, sys ,socket
from time import sleep
port = "COM9"
baudRate = 9600
try:
ser = serial.Serial(port, baudRate, timeout=1)
if not ser.isOpen():
ser.open()
except Exception, e:
print("Error opening com port. Quitting."+str(e))
sys.exit(0)
print("Opening " + ser.portstr)
#this is few ways i am trying to send with
c = '01050801FF00F2'
ser.write(c.encode('utf-8'))
sleep(3)
ser.flushInput() #flush input buffer, discarding all its contents
ser.flushOutput()#flush output buffer, aborting current output
#and discard all that is in buffer
c = ':01050801FF00F2'
ser.write(c.encode('hex'))
sleep(3)
ser.write(':01050801FF00F2')
If those are hex values, this should work:
c = '\x01\x05\x08\x01\xFF\x00\xF2'
ser.write(c)
Have you tried sending the command using bytearray?
Perhaps you could try:
ser.write(b':01050801FF00F2')
or
ser.write(':01050801FF00F2'.encode())
I have a question about Python and PySerial.
On my Raspberry Pi i want to read a serial port from a device. I got 2 types of devices i want to read from. They both got different settings:
ser = serial.Serial()
ser.baudrate = 9600
ser.bytesize=serial.SEVENBITS
ser.parity=serial.PARITY_EVEN
ser.stopbits=serial.STOPBITS_ONE
ser.xonxoff=0
ser.rtscts=0
ser.timeout=20
ser.port="/dev/ttyUSB0
and:
ser = serial.Serial()
ser.baudrate = 115200
ser.bytesize=serial.EIGHTBITS
ser.parity=serial.PARITY_NONE
ser.stopbits=serial.STOPBITS_ONE
ser.xonxoff=1
ser.rtscts=0
ser.timeout=20
ser.port="/dev/ttyUSB0
This is the code to read the serial port:
try:
ser.open()
except:
sys.exit ("Error opening %s." % ser.name)
t_count = 0
while t_count < 20:
t_line = ''
try:
t_raw = ser.readline()
except serial.SerialException:
sys.exit ("Serial port %s could not be read." % ser.name )
t_str = str(t_raw)
t_line = t_str.strip()
print (t_line)
t_count += 1
try:
ser.close()
except:
sys.exit ("Oops %s. Program aborted. Could not close serial port." % ser.name )
So when i connect to a device with 115200 but the device runs 9600, i get timeouts ofcourse. But in my program it will just time out twenty times (times the for loop will run), and no exception to be thrown. Not even just before the program exits after looping 20 times. No error message nothing.
What i want to achieve is the following, i want to make the python script self detecting what he is connected to. When the readline() times out 20 times it should change settings. (by running another function or something).
I cant check if the readline returns something empty, because there are empty lines in the serial message.
Is there any way to get the right exception? Or any other smart way to solve this?
(By the way, i am sure the settings work. As i tested them both and run fine.)
Thanks in advance.
Cheers!
Easiest way would be to create a handshake function,
send something with one serial handler that you know the device will respond to correctly. If the answer is jibberish then change the handler and try the other one until you succceed.