I'm currently trying to set up communication between an Arduino UNO and a PC via a serial/USB connection using Python on a Windows PC.
The goal is to start a video on a laptop when the Arduino tells it to.
I found a guide online which lead me to the code below but Visual Studio 2017 is just showing errors seemingly at random everywhere. A lot of it seemed to come from the imports and VS's IntelliSense messing up (which I believe is fixed now).
So currently when I'm running the program it's getting stuck at the ser = serial.Serial(port, 9600, timerout=0) Line with the error that "name 'port' is not defined" Any idea why that is happening?
I'm unsure if that is the core issue since every time I'm making changes a lot of "unexpected token" and "indent" errors appear for port, newline, print and ser (completely at random)
import serial, os, time, serial.tools.list_ports
cmd = '"C:\\Users\\Josef\\Desktop\\PYTHON_PlayVideo\\PYTHON_PlayVideo\\Video1.mp4" -f --fullscreen --play-and-exit'
for p in serial.tools.list_ports.comports():
sp = str(p)
#if (sp.find('COM5') != -1):
if (sp.find('Arduino') != -1):
flds = sp.split()
port = flds[0]
print(port)
ser = serial.Serial(port, 9600, timeout=0)
while 1:
try:
line = ser.readline()
if (line):
print (cmd)
os.system(cmd)
except:
pass
time.sleep(1)
It seems that you donĀ“t find any COM port, so port is never defined.
I rework your code and this version works for me (replace USB with your keyword).
import serial, os, time, serial.tools.list_ports
# Get the COM port
Ports = serial.tools.list_ports.comports()
if(len(Ports) == 0):
print("[ERROR] No COM ports found!")
exit()
TargetPort = None
for Port in Ports:
StringPort = str(Port)
print("[INFO] Port: {}".format(StringPort))
if("USB" in StringPort):
TargetPort = StringPort.split(" ")[0]
print("[INFO] Use {}...".format(TargetPort))
if(TargetPort is None):
print("[ERROR] No target COM port found!")
exit()
# Open the COM port
ser = serial.Serial(TargetPort, 9600, timeout = 0)
if(ser.isOpen() == False):
ser.open()
while(True):
try:
line = ser.readline()
if (line):
print (cmd)
#os.system(cmd)
except:
pass
time.sleep(1)
Related
In my project, there's a Raspberry Pi Zero W, linked with Arduino Pro Micro over the serial TX/RX lines (through 5 - 3.3V logic level converter). At power-on, the Arduino starts sending "are you there" command over the serial, until Pi has finished booting and launched a python program that listens on serial port, and it replies with "yes". Then Arduino proceeds with sending regular updates with sensor data.
For some reason not yet understood, the Arduino can disconnect and reboot, while the Pi is still running. And, for some reason, the connection on the Python end is severed in a way that does not raise exception if connection.in_waiting is read.
import serial
import time
ser = serial.Serial('/dev/serial0')
ser.baudrate = 9600
cmd = b''
while True:
time.sleep(1)
print(ser.is_open)
while ser.in_waiting:
ch = ser.read()
if ch == b'\n':
print('New command:', cmd)
cmd = b''
ser.write(b'OK\n')
continue
else:
cmd = cmd + ch
I have tested with this simple code, but in my tests, if I disconnect the Arduino and connect it back, the ser.is_open never is False, and the old connection works just fine also with reconnected Arduino. So, unfortunately I can not exactly replicate the loss of connection scenario when the data stop coming after disconnection. However, in order to investigate further, I'd like to add some monitoring code that would log serial disconnection incidents in file. But is there a way? If connection.is_open is always true, even without Arduino connected, then how one can detect if there is no connection?
The port remains open if there's a disconnection so your example code will loop continuously.
import serial
def connect(port):
return serial.Serial(port, baudrate=9600, timeout=1)
ser = connect('/dev/serial0')
buf = bytearray()
while True:
i = buf.find(b'\n')
if i >= 0:
buf = buf[i + 1:]
ser.write('OK\n')
num_bytes = max(1, min(1024, ser.in_waiting))
data = ser.read(num_bytes)
if data:
buf.extend(data)
else:
# no data to read aka disconnection has occurred
ser = connect('/dev/serial0')
if ser.isOpen():
continue
else:
# could not reconnect
break
EDIT: It seems like the issue might have to do with Python 3. I tried executing the script in a Anaconda Environment of Python 2.7.15 and was able to get it to work. Thinking it might be just Anaconda, I tried running it in a Anaconda Environment of Python 3.6.5 and ran into the same error. To remove the variable of Anaconda, I tried running Python 2.7.15 from a fresh install without Anaconda and was again able to get the script running properly. Note that my original problem came up when running through a non-Anaconda Python3 environment. I do not think this really answers the question but is somewhat of a solution for anyone running into the same issue.
Windows 10. Python 3.6.5
I am trying to establish/open a connection with a connected COM port through pyserial. I am able to do this just fine through a Python shell started in cmd, but receive an exception when running it through a script. The exception chain is this:
File "C:\Python\Python36-32\lib\site-packages\serial\serialwin32.py", line 62, in open
raise SerialException("could not open port {!r}: {!r}".format(self.portstr, ctypes.WinError()))
serial.serialutil.SerialException: could not open port 'COM8': OSError(22, 'Element not found.', None, 1168)
The script is this:
import serial.tools.list_ports
import time
import sys
SERIAL_CONNECTION_ATTEMPTS = 3
ports = list(serial.tools.list_ports.comports())
bluetoothPorts = []
for p in ports:
if 'Bluetooth' in p.description:
bluetoothPorts.append(p)
print("Found: ", p)
selectedPort = bluetoothPorts[0]
print("selected port: ", selectedPort.device)
ser = serial.Serial()
ser.baudrate = 9600
ser.timeout = 120
ser.port = selectedPort.device
for i in range(0, SERIAL_CONNECTION_ATTEMPTS):
try:
ser.open()
time.sleep(5)
if ser.is_open():
break
except:
print(sys.exc_info())
if i == SERIAL_CONNECTION_ATTEMPTS-1:
print("Failed to connect. Will stop trying now.")
exit()
print("Failed to connect. Retrying...")
ser.close()
time.sleep(5)
print(ser.read(32))
print("Closing out now..")
ser.close()
Successful connections using the interactive shell follow the script exactly, excluding the use of the try-except block.
One thing I have noticed is that the target device seems to recognize a connection attempt for a very brief moment. I am able to make this guess because the target device has an LED to indicate an established serial connection. When the script runs to the ser.open(), this LED flashes for a moment before quickly turning off. On the other hand, when ser.open() is attempted in the interactive shell, the shell blocks until the connection is made and the LED stays lit.
Please let me know if any additional information would help.
well you know Bluetooth, it doesn't work from the first attempt, just give it a try, one and two and three ...
def getSerialOrNone(port, conn_att):
connec_attempts = 0
ser = None
while ser is None:
try:
connec_attempts+=1
print('connect attempts to %s num %d' % (port , (connec_attempts)))
ser = serial.Serial(port, 9600,timeout=1.5, parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE, bytesize=serial.EIGHTBITS)
if connec_attempts == conn_att:
print('Serial connection error',
'Failed to commect to port ', self.port )
return None
#time.sleep(2)
except Exception as e:
print('Serial connection error',
'Error sending message "%s" to controller:\n%s' %
(port, e))
return ser
I am trying to read from serial port using python 2.5 in windows CE 5.0.
What is happening is It gets connected to serial port but nothing gets read from the port.
Below is my Code
import ceserial
from time import sleep
ser = ceserial.Serial(port="COM1:",baudrate=9600,bytesize=8,stopbits=ceserial.STOPBITS_ONE,parity=ceserial.PARITY_EVEN,
timeout=0)
ser.open()
print("connected to: " + ser.portstr)
while True:
data = ser.read(size=50)
if len(data) > 0:
print 'Got:', data
sleep(0.5)
ser.close()
I'm trying to use PySerial to accept inputs from an RFID Reader. As per the answers here: I've tried using WinObj and found something odd: there is no COM3 port in the GLOBAL??? folder pointing to something "more driver specific." However, when I run the command python -m serial.tools.list_ports, it does throw up COM3. When I try a simple program like:
import serial
ser = serial.Serial()
ser.port = 2
print(ser)
ser.open()
I get the following output:
Serial<id=0x45e8198, open=False>(port='COM3', baudrate=9600, bytesize=8, parity='N', stopbits=1, timeout=None, xonxoff=False, rtscts=False, dsrdtr=False)
serial.serialutil.SerialException: could not open port 'COM3': FileNotFoundError(2, 'The system cannot find the file specified.', None, 2)
So, I know that PySerial is looking for my reader in the right place, and, according to two different sources (the device manager and the command line), the device is registering. And yet I'm still getting this error. What is going on? I'm using Python 3.3 on Windows 8.1.
EDIT: That error is actually what I get from python's command line. The one I get from making and running a program like the one above is:
AttributeError: 'function' object has no attribute 'Serial.'
I'd appreciate thoughts on that too.
First thing I would check is what you have for com ports attached and what's currently in use:
import serial.tools.list_ports
import sys
list = serial.tools.list_ports.comports()
connected = []
for element in list:
connected.append(element.device)
print("Connected COM ports: " + str(connected))
# compliments of https://stackoverflow.com/questions/12090503/listing-available-com-ports-with-python#14224477
""" Lists serial port names
:raises EnvironmentError:
On unsupported or unknown platforms
:returns:
A list of the serial ports available on the system
"""
if sys.platform.startswith('win'):
# !attention assumes pyserial 3.x
ports = ['COM%s' % (i + 1) for i in range(256)]
elif sys.platform.startswith('linux') or sys.platform.startswith('cygwin'):
# this excludes your current terminal "/dev/tty"
ports = glob.glob('/dev/tty[A-Za-z]*')
elif sys.platform.startswith('darwin'):
ports = glob.glob('/dev/tty.*')
else:
raise EnvironmentError('Unsupported platform')
result = []
for port in ports:
try:
s = serial.Serial(port)
s.close()
result.append(port)
except (OSError, serial.SerialException):
pass
print("Availible COM Ports: " + str(result))
Then, make sure you are calling the serial port constructor with the parameters you want:
ser = serial.Serial(
port="com2", # assumes pyserial 3.x, for 2.x use integer values
baudrate=19200,
bytesize=8,
parity="E", # options are: {N,E,O,S,M}
stopbits=1,
timeout=0.05)
When you call "serial.Serial()" without any parameters and then add the port ID, I'm not entirely sure what it's going to do, I've always explicitly referenced the port I want to use there.
Your issue lies in the fact that the serial object is looking for a string "COMXX" or else it won't work. I don't know if it need to be capitalized or not.
make sure you configure it like this.
serial.Serial(port = "COM2")
I've read the documentation, but can't seem to find a straight answer on this.
I have a list of all COM Ports in use by Modems connected to the computer. From this list, I try to open it, send it a command, and if it says anything back, add it to another list. I'm not entirely sure I'm using pyserial's read and write functions properly.
i=0
for modem in PortList:
for port in modem:
try:
ser = serial.Serial(port, 9600, timeout=1)
ser.close()
ser.open()
ser.write("ati")
time.sleep(3)
print ser.read(64)
if ser.read(64) is not '':
print port
except serial.SerialException:
continue
i+=1
I'm not getting anything out of ser.read(). I'm always getting blank strings.
a piece of code who work with python to read rs232
just in case somedoby else need it
ser = serial.Serial('/dev/tty.usbserial', 9600, timeout=0.5)
ser.write('*99C\r\n')
time.sleep(0.1)
ser.close()
ser.read(64) should be ser.read(size=64); ser.read uses keyword arguments, not positional.
Also, you're reading from the port twice; what you probably want to do is this:
i=0
for modem in PortList:
for port in modem:
try:
ser = serial.Serial(port, 9600, timeout=1)
ser.close()
ser.open()
ser.write("ati")
time.sleep(3)
read_val = ser.read(size=64)
print read_val
if read_val is not '':
print port
except serial.SerialException:
continue
i+=1