Using pySerial to connect to a non-COM port - python

In Hyperterminal I am able to connect to a serial port called "X64-CL_iPro_1_Serial_0" where I am able to send/receive ASCII text to a camera. However when I try to connect to the same port with pySerial, it throws an exception:
SerialException: could not open port X64-CL_iPro_1_Serial_0: [Error 2] The system cannot find the file specified.
I don't understand why Hyperterminal can detect the port and communicate with it, but Python can't. I downloaded this script from the pySerial website that displays a list of serial ports, and the only ports it came up with was COM1 and COM2, neither of which I can connect to.
My code is very simple, and looks like this:
import serial
port = "X64-CL_iPro_1_Serial_0"
ser = serial.Serial(port)
Am I doing anything wrong? Is there a way to work around this? Thanks ahead of time.
Edit:
It should also be noted that this port does not show up in the device manager, and neither does COM1 or COM2.

The problem lies in the enumeration code you linked. It is wrong in two regards:
It uses a fixed GUID_CLASS_COMPORT to enumerate. It should instead ask the GUID through SetupDiClassGuidsFromName, passing "Ports" as description of the class for which it is asking for names.
The code insists of asking for the friendly name of the port. But if the only goal is to open the device (instead of displaying to an user), it should directly access the DevicePath element, which is a weird-looking-but-perfectly-valid port name to pass to pySerial. The friendly name might even be totally missing.

aside
I'm not clear the question is about non-serial-port use through pyserial, or serial port that is not a COMX port in enumeration.
This may be a bit OT or too hard code for your use, but here goes first, using some other file in a pyserial object:
foo = serial.Serial()
peer = serial.Serial()
foo.fd, peer.fd = posix.openpty()
try: foo._isOpen = peer._isOpen = True # depending on pyserial version
except: pass
foo._reconfigurePort()
peer.setTimeout(timeout=0.1)
peer._reconfigurePort()
Regarding second, remember that ports beyond COM9 use weird windows notation \\.\COM10, perhaps that's what Hyperterminal does for you. pyserial doesn't do it, so perhaps you need to open the port something like this:
s = serial.Serial("\\\\.\\X64-CL_iPro_1_Serial_0") # also remember to escape backslash

Related

Using Pyserial to read and write data

I am trying to understand how Pyserial is interfacing with my windows machine. I am using this basic code from the pyserial website.
import serial
ser = serial.Serial('COM1') # open serial port
print(ser.name) # check which port was really useds
ser.write(b'hello') # write a string
ser.close() # close port
I am using python 2.7 and IDLE as the IDE for this code, I am wondering should I be able to read the string hello from my console after I run the code? My output as of right now only show COM1, while not printing hello to my console. Is the hello message being sent to my COM1 port? If so, how would I be able to read the message I sent?
Also as a bonus question, I sometimes randomly have this error happen to me.
SerialException: could not open port 'COM1': WindowsError(5, 'Access is denied.'). Sometimes when I re-run the code it goes away, other times I have to restart my computer. I appreciate any help, thanks.
COM1 is not connected to anything currently.
You should open the connection first with ser.open(). You can write the command like you are doing, but to read it, you need to use ser.readlines(). Then you can close the connection. This page has a lot of good info! What is connected to the COM1 port?

Port forwarding in python to allow socket connections

I start a server using sockets and want to allow clients to connect to it.
self.sock.bind(('0.0.0.0',0)) # 0.0.0.0 will allow all connections and port 0 -> os chooses a open port.
stroke_port=self.sock.getsockname()[1]
self.sock.listen(75)
self.open_port_popup(stroke_port)
Now, for other clients to connect I have port forward it manually and it works fine.
I want to do this in automated fashion. -> I try upnp.
import miniupnpc
def open_port(port_no):
'''this function opens a port using upnp'''
upnp = miniupnpc.UPnP()
upnp.discoverdelay = 10
upnp.discover()
upnp.selectigd()
# addportmapping(external-port, protocol, internal-host, internal-port, description, remote-host)
result=upnp.addportmapping(port_no, 'TCP', upnp.lanaddr, port_no, 'testing', '')
return result
It opens a port shown in the image below. But the port-forwarding list shown in the first image is empty. It doesn't work and clients can't connect. How can I fix this? What am I missing?
I think you made a mistake using upnp.lanaddr as internal-host address. upnp.lanaddr is the address of the upnp device which is your router, you want to use the local address of your server.
If needed take a look at Finding local IP addresses using Python's stdlib if you want to get your server local IP dynamically.
I think that we are missing lot of related info to know what's the main problem here. I see so many people guessing.
By the way, just editing that line
result=upnp.addportmapping(port_no, 'TCP', upnp.lanaddr, port_no, 'testing', '') to
result=upnp.addportmapping('7777', 'TCP', '192.168.1.8', '7777', 'testing', '') would tell you if it works at all.
Doing port testing from localhost it's dummy, you're not under the router at all.
Also, remember to use Try/Except blocks to tell you what's wrong on your code.
try:
print "1" + 1
except Exception as e:
print str(e)
Another way, not fashioned is to use html/web automation, even cURL to make those requests instead using uPnp, this way you don't really need to handle it.
Most of the time ISP don't allow port forwarding, and you spend hours on this trying to forward port.
I went for ngrok - it's a lightweight free of cost (for basic usage) program that tunnels the port and give its own tunneled domain which can be accessed everywhere.
this is interesting question.
from what I could summon I think
GUI shows that UPNP port forwarding rules are added.
so Most likely there is issue in UPNPC configuration.
I doubt you are doing this on Router or similar platform with X-WRT or OpenWRT
the issue I think is you can't use upnp for this or it doesn't work for some strange reason.
I suggest you try this library pytables.
I know you wanted to know why and I am working on figuring out the reason.
this is just for you to get going on this project
and for quick solution
Try this
import subprocess
p = subprocess.Popen(["iptables", "-A", "INPUT", "-p", "tcp", "-m", "tcp", "--dport", "22" , "-j", "ACCEPT"], stdout=subprocess.PIPE)
output , err = p.communicate()
print output

locating unused ports in python without binding them

Firstly i know that you can use the socket constructor with port = 0 to find an unused port, but this isn't my question.
I'm using a python script as an intermediate code between two applications, i want the python script to locate a free port for both applications so that they can communicate, i haven't found a graceful way to locate unused ports in python without binding them to a socket, is it possible without binding? or am i forced to do so?
This is a code that does so, by binding the port and closing it asap but i still don't feel that this is good practice
import socket
s = socket.socket()
s.bind(('localhost',0))
addr,port = s.getsockname()
s.close()
print(addr)
print(port)
the connection is going to be temporary between the apps and many instances could occur
I'm literally looking for pointers on good practice of doing so, and i wanna know if what I'm doing is correct or I'm heading the wrong way

Python Pyserial Windows No Port Found

I have just tried to connect to usb mobile to send sms through it using AT commands. But when i use pyserial to connect to it in a windows os, i get error could not open port, the file specified cannot be found.
>>> import serial
>>> ser = serial.Serial(0) # open first serial port
>>> print ser.name # check which port was really used
>>> ser.write("hello") # write a string
>>> ser.close()
even if i replace the 0 with any other value, like 0 -10 or 'com0','com1' etc, i still get error file specified not found, port cannot be open.
There is a command listed in pyserial documentation which lists ports or allows you to open a port
python -m serial.tools.miniterm
This command is supposed to list all serial ports. But it shows none.
I have 3 usb ports on my system. What is causing this issue.
Pyserial is not guaranteed to detect all ports. This depends on how the device and the OS communicate and if pyserial is designed to pick up on this. For Example, pyserial could not detect a LabJack U3-LV or a EPSOM-POS receipt printer I plugged in in a Win8 session (both could be detected using a linux session).
Try serial.tools.list_ports.comports() and see what it gives you.
You could also look at the pyusb module for usb connections.
Also: I recommend being careful when using numbers for ports, as the mapping may not be "common-sense" logical (i.e. 0 may not map to COM0). Use explicit string names instead.
I found the solution myself. Its pretty simple and uses the same code in the question.. I was getting blocked error because there was no modem(nokia phone) in my device manager. although i had plugged in my phone into the usb, there was no nokia pc suite installed. Once you install nokia pc suite and connect your nokia phone, in device manager -> modems your phone will appear. Just check its properties->modem and you will find the com5 or whichever number. Then use that id to connect. If you dont know this, just iterate till you find the right one.
Thanks everyone who tried to help

Identifying serial/usb device python

The solution to this problem is probably pretty simple, but I am new to interfacing with a device dynamically. What I'm doing is I am making a python executable code, so the user doesn't have to have Idle on their computer or any kind of python interpreter, which means I don't know which USB port the device will be plugged in to. The program needs to be able to open a connection to a device that is connected through a serial to usb converter. How can I determine which connected device is the correct device to open a port to? I am using pySerial to interact with the device. Any help would be greatly appreciated.
No matter how you configure your device, at some point you're probably going to have to ask the user where the port is, or poll all serial devices for a known response. (Polling has it's pitfalls though, so read on!). Unlike USB devices, there is no vendor/device ID that is made known to the OS when you attach a plain-old serial device.
First you need to find the serial ports. Here's a question that might help: What is the cross-platform method of enumerating serial ports in Python (including virtual ports)?.
Once you have a list of serial ports, you could ask the user whether they know which one to use. If they do, problem solved!
If they don't, you could offer to poll ALL serial devices with some data that you know will yield a certain response from your device. Keep in mind though that if the user has other serial devices attached, your string of "hello" bytes might actually be the self-destruct sequence for some other device! Hence, you should warn the user that polling may interfere with other devices, and always prompt them before you do so.
Without knowing more about your code (eg. what comms framework, if any, you're using; are you doing this in the console or are you using a GUI toolkit, etc), it's impossible to say what the best way to code this might be. In the simplest case, you could just loop over all of your serial devices, send the greeting and check for a response. (You could also do this in parallel: loop once for the greeting, and loop again to check what's in the buffer. If you're going to get more fancy than that, use a proper library.)
Side note: You might be able to get around this if you have a built-in converter that you can set the vendor/device ID for, but the converter will still be automatically detected by any modern OS and enumerated as a serial port; you won't get to talk to it directly as a USB device. It could be possible to figure out which port goes with which ID, but I've never tried to do that. But this approach is useless if you're not the one who gets to pick the converter (eg. if it's a user-supplied cable).
This is the way that I used for identify Serial-USB conveter device like Arduino.
It checks 'USB' String of device description.
import serial as ser
import serial.tools.list_ports as prtlst
global COMs
COMs=[]
def getCOMs():
global COMs
pts= prtlst.comports()
for pt in pts:
if 'USB' in pt[1]: #check 'USB' string in device description
COMs.append(pt[0])
The only way I can think to get around the problem with probing unknown devices is to have the device send unsolicited "hello" responses continually. That was you can just connect to all serial devices and listen for the "hellos". Connecting and listening to a serial device shouldn't ever mess it up.
The downside is you have these messages cluttering up your serial stream. You could have a "I'm here now, stfu" command but then you can only connect to it once.
FTDI chips have a method of identification but you have to use their library to access the data.

Categories