उपलब्ध कॉम बंदरगाहों को पायथन के साथ सूचीबद्ध करना


86

मैं पीसी पर सभी उपलब्ध कॉम पोर्ट को सूचीबद्ध करने के लिए एक सरल विधि की खोज कर रहा हूं।

मुझे यह तरीका मिल गया है, लेकिन यह विंडोज-विशिष्ट है: विंडोज पर लिस्टिंग सीरियल (COM) पोर्ट?

मैं एक विंडोज 7 पीसी पर अजगर के साथ पायथन 3 का उपयोग कर रहा हूं।

मुझे pySerial API ( http://pyserial.sourceforge.net/pyserial_api.html ) एक फ़ंक्शन मिला है serial.tools.list_ports.comports()जो कॉम पोर्ट को सूचीबद्ध करता है (वास्तव में मुझे जो चाहिए)।

import serial.tools.list_ports
print(list(serial.tools.list_ports.comports()))

लेकिन ऐसा लगता है कि यह काम नहीं करता है। जब मेरा USB से COM गेटवे पीसी से जुड़ा होता है (मैं डिवाइस मैनेजर में COM5 देखता हूं), यह COM पोर्ट द्वारा दी गई सूची में शामिल नहीं है list_ports.comports()। इसके बजाय मुझे केवल COM4 मिलता है जो एक मॉडेम से जुड़ा हुआ लगता है (मैं इसे डिवाइस मैनेजर के COM और LPT अनुभाग में नहीं देखता)!

क्या आप जानते हैं कि यह काम क्यों नहीं करता है? क्या आपको एक और समाधान मिला है जो सिस्टम विशिष्ट नहीं है?


21
नए पाठकों: ध्यान दें कि यह प्रश्न पूछे जाने के बाद से पांच साल से अधिक हो गए हैं, और comports()इस प्रश्न में वर्णित व्याकरणिक समारोह में बग बग (इसे पुन: पेश करने के बारे में सटीक जानकारी के बिना) शायद तय हो गया है। कोशिश करके शुरू करें import serial.tools.list_ports; print([comport.device for comport in serial.tools.list_ports.comports()])। केवल अगर आपके लिए यह काम नहीं करता है तो आपके लिए प्रासंगिक नीचे दिए गए किसी भी उत्तर हैं।
मार्क एमी

नए पाठकों के लिए भी: जाहिरा तौर पर पीयर्सियल में बदलाव के कारण, ओपी द्वारा वर्णित कोड (और कुछ जवाब) अब COM पोर्ट नामों की सूची नहीं बनाते हैं, चाहे पूर्ण या अपूर्ण। इसके बजाय, यह ऑब्जेक्ट्स के लिए ऑब्जेक्ट संदर्भों की एक सूची बनाता है ListPortInfo। सूची बनाते समय नाम या अन्य जानकारी प्राप्त करने के लिए आपको इन वस्तुओं के गुणों का उपयोग करना चाहिए। देखें: pythonhosted.org/pyserial/…
JDM

जवाबों:


155

यह मेरे द्वारा उपयोग किया जाने वाला कोड है।

सफलतापूर्वक विंडोज 8.1 x64, विंडोज 10 x64, मैक ओएस एक्स 10.9.x / 10.10.x / 10.11.x और Ubuntu 14.04 / 14.10 / 15.04 / 15.10 पर दोनों पायथन 2 और पायथन 3 के साथ परीक्षण किया गया।

import sys
import glob
import serial


def serial_ports():
    """ 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'):
        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
    return result


if __name__ == '__main__':
    print(serial_ports())

मैं इसमें कुछ सिस्टम संस्करण का पता लगा सकता हूं और इसे एक दिन कह सकता हूं। मुझे पता नहीं है कि "सभी सिस्टम" उस पोर्ट के बराबर हैं जो आपके OS के आधार पर अलग-अलग तरीके से हासिल किए गए हैं। मैं बस OS संस्करण का पता लगाऊंगा, फिर उसके आधार पर विभिन्न मामलों के लिए एक स्विच उपलब्ध होगा।
jml

1
except OSError: passOSX पर परीक्षण करते समय मुझे भी जोड़ना था ।
नवलिक

4
यदि पोर्ट पहले से ही खोला गया है तो क्या होगा? यह एक त्रुटि सही लौटेगा? लेकिन पोर्ट अभी भी उपलब्ध होगा। मैं बस सोच रहा हूं कि अजगर के साथ खिड़कियों पर एक व्यवहार्य COM पोर्ट डिकॉन्फेक्शन कैसे बनाया जाए।
15:42 पर Manny42

@ Manny42 मुझे समझ नहीं आ रहा है कि आप क्या हासिल करने की कोशिश कर रहे हैं, लेकिन अगर एक पोर्ट पहले से ही खोला गया है तो यह निश्चित रूप से अन्य कार्यक्रमों के लिए उपलब्ध नहीं है और serial_ports()फ़ंक्शन द्वारा सूचीबद्ध नहीं किया जाएगा (और अपवाद नहीं बढ़ाएगा)। आप close()COM-पोर्ट को डिस्कनेक्ट करने के लिए pyserial द्वारा प्रदान किए गए फ़ंक्शन का उपयोग क्यों नहीं करते हैं ?
tfeldmann

@Thomas - क्या पोर्ट अस्वेल का कुछ वर्णन प्राप्त करने का एक तरीका है? मुझे विवरण के आधार पर अपनी पसंद का पोर्ट चुनने की आवश्यकता है

25

आप उपयोग कर सकते हैं:

python -c "import serial.tools.list_ports;print serial.tools.list_ports.comports()"

पता पोर्ट द्वारा फ़िल्टर करें: python -c "import serial.tools.list_ports;print [port for port in serial.tools.list_ports.comports() if port[2] != 'n/a']"

अधिक जानकारी यहां देखें: https://pyserial.readthedocs.org/en/latest/tools.html#module-serial.tools.list_ports


यह अजगर 2.7.11 के साथ OSX 10.11.5 पर बहुत अच्छा काम करता है और थॉमस से समाधान की तुलना में बहुत तेज लगता है। अजगर 3.4.4 के साथ OSX 10.11.5 पर यह एक खाली सरणी देता है, इसलिए यह निश्चित रूप से कुछ कॉम बंदरगाहों को याद कर रहा है।
doizuc

विंडोज 7 और पायथन 2.7 के साथ बढ़िया काम करता है। बहुत उपयोगी है, यह इस तरह से एक टपल ('COM114', 'USB Serial Port (COM114)', 'FTDIBUS\\VID_0403+PID_6001+7&2A8DEF85&0&2\\0000')देता है : जो आपको वेंडर यूएसबी पीआईडी ​​/ वीआईडी ​​द्वारा फ़िल्टर करने की अनुमति देता है, जो कि वास्तव में मैं था।
रिचर्ड एपलिन

बस लिनक्स बोर्ड (डेबियन, 3.4 कर्नेल) पर परीक्षण किया गया, समान रूप से अच्छे परिणाम, इस बार यूएसबी डिवाइस सीरियल नंबर ('/dev/ttyACM1', 'ttyACM1', 'USB VID:PID=0483:5752 SNR=8D7B179D5354')ग्रेट समाधान सहित। धन्यवाद!
रिचर्ड एपलिन

यहाँ एक बहुत ही समान उत्तर है: stackoverflow.com/questions/24214643/…
ग्लेडफेल

2
-1; ओपी ने पहले ही उल्लेख किया serial.tools.list_ports.comports()और समझाया कि यह पूछने वाले के मंच पर सही ढंग से काम नहीं करता है। आप कोई ऐसी जानकारी नहीं जोड़ रहे हैं जो प्रश्न में नहीं थी।
मार्क एमी

16

मूल रूप से पाइसरियल डॉक्यूमेंटेशन में इसका उल्लेख https://pyserial.readthedocs.io/en/latest/tools.html#module-serial.tools.list_ports

import serial.tools.list_ports
ports = serial.tools.list_ports.comports()

for port, desc, hwid in sorted(ports):
        print("{}: {} [{}]".format(port, desc, hwid))

परिणाम :

COM1: संचार पोर्ट (COM1) [ACPI \ PNP0501 \ 1]

COM7: मीडियाटेक USB पोर्ट (COM7) [USB VID: PID = 0E8D: 0003 SER = 6 LOCATION = 1-2.1]


11

थॉमस के उत्कृष्ट उत्तर के लिए एक संभावित शोधन के लिए लिनक्स है और संभवतः OSX भी बंदरगाहों को खोलने और केवल उन्हीं को वापस करने की कोशिश करता है जिन्हें खोला जा सकता था। ऐसा इसलिए है क्योंकि लिनक्स, कम से कम, बंदरगाहों की एक नाव को / dev / में फ़ाइलों के रूप में सूचीबद्ध करता है जो किसी भी चीज़ से जुड़े नहीं हैं। यदि आप किसी टर्मिनल में चल रहे हैं, / dev / tty वह टर्मिनल है जिसमें आप काम कर रहे हैं और इसे खोल रहे हैं और बंद कर रहे हैं, तो यह आपकी कमांड लाइन को समाप्त कर सकता है, इसलिए ग्लोब को ऐसा नहीं करने के लिए डिज़ाइन किया गया है। कोड:

    # ... Windows code unchanged ...

    elif sys.platform.startswith ('linux'):
        temp_list = glob.glob ('/dev/tty[A-Za-z]*')

    result = []
    for a_port in temp_list:

        try:
            s = serial.Serial(a_port)
            s.close()
            result.append(a_port)
        except serial.SerialException:
            pass

    return result

थॉमस के कोड में इस संशोधन को केवल उबंटू 14.04 पर परीक्षण किया गया है।


8

moylop260 के उत्तर पर परिशोधन :

import serial.tools.list_ports
comlist = serial.tools.list_ports.comports()
connected = []
for element in comlist:
    connected.append(element.device)
print("Connected COM ports: " + str(connected))

यह उन बंदरगाहों को सूचीबद्ध करता है जो हार्डवेयर में मौजूद होते हैं, जिनमें वे भी शामिल हैं जो उपयोग में हैं। सूची में पूरी तरह से बहुत अधिक जानकारी मौजूद है, जो कि पीयर्सियल टूल डॉक्यूमेंटेशन के अनुसार है


3
-1 कम से कम कुछ कारणों के लिए: यह बिलिन के नामों को ओवरराइड करने के लिए बुरा अभ्यास है list, और आपके चार-बयान निर्माण को connectedकाफी अधिक सफलतापूर्वक लिखा जा सकता है connected = [port.device for port in serial.tools.list_ports.comports()]
मार्क अमेरी

5
उस लड़के के लिए जिसने 1/2 का कैरियर एम्बेडेड C में बिताया है, मैं सिंगल लाइन के लिए एक नहीं हूं, यहां सब कुछ स्टाइल करता हूं। आप निश्चित रूप से यह सब एक लाइन पर कर सकते हैं। मैंने 'सूची' अशुद्ध पेस को ठीक किया है, मुझे यकीन नहीं है कि मैं इस तरह से कुछ याद कर रहा हूं। चीयर्स।
ग्रैम्बो

3
@ मर्क अमेरी क्या आपको वास्तव में लगता है कि वन-लाइनर्स एक प्रश्न और उत्तर साइट के लिए एक अच्छा विचार है?
क्रेस्टूटन

@cstrutton मुझे आपका सवाल समझ नहीं आ रहा है।
मार्क अमेरी

2
@ मर्क एवरी। वन-लाइनर्स नौसिखिए उपयोगकर्ताओं से प्रमुख अवधारणाओं को अस्पष्ट करते हैं। उदाहरण के लिए, यदि आप एक सरल अवधारणा को प्रदर्शित करने के लिए सूची समझ का उपयोग करते हैं, तो एक नौसिखिया सूची समझ में खो सकता है और आधार अवधारणा को याद कर सकता है। यदि सूची बोध इसे करने का सबसे अच्छा तरीका है, तो पहले लंबे संस्करण को दिखाएं, फिर इसे छोटा कैसे करें। आप अपनी बात सिखाते हैं और एक ही समय में सूची COMP को सुदृढ़ करते हैं।
क्रस्टूटन


2

कृपया, इस कोड की कोशिश करें:

import serial
ports = serial.tools.list_ports.comports(include_links=False)
for port in ports :
    print(port.device)

सबसे पहले, आपको सीरियल पोर्ट संचार के लिए पैकेज आयात करने की आवश्यकता है, इसलिए:

import serial

तब आप वर्तमान में उपलब्ध सभी सीरियल पोर्ट की सूची बनाते हैं:

ports = serial.tools.list_ports.comports(include_links=False)

और फिर, पूरी सूची के साथ चलते हुए, आप उदाहरण के लिए पोर्ट नाम प्रिंट कर सकते हैं:

for port in ports :
    print(port.device)

यह केवल एक उदाहरण है कि बंदरगाहों की सूची कैसे प्राप्त करें और उनके नाम कैसे प्रिंट करें, लेकिन कुछ अन्य विकल्प हैं जो आप इस डेटा के साथ कर सकते हैं। बस इसके बाद अलग-अलग वेरिएंट प्रिंट करने की कोशिश करें

बंदरगाह।


मुझे लगता है कि आपको सीरीयल आयात करने की जरूरत है ।ools.list_ports, या कम से कम यही है जो मुझे Pytherial 3.4 के साथ Python 3.7 पर धारावाहिक के मेरे संस्करण पर करने की आवश्यकता है
टॉम Myddeltyn

0

कई विकल्प उपलब्ध हैं:

सभी DOS उपकरणों को सूचीबद्ध करने के लिए NULL lpDeviceName के साथ QueryDosDevice को कॉल करें । फिर CreateFile और GetCommConfig का उपयोग प्रत्येक डिवाइस के नाम के साथ यह जानने के लिए करें कि क्या यह एक सीरियल पोर्ट है।

GUID_DEVINTERFACE_COMPORT के ClassGuid के साथ SetupDiGetClassDevs को कॉल करें ।

WMI C / C ++ प्रोग्राम के लिए भी उपलब्ध है

Win32 न्यूज़ग्रुप और एक कोडप्रोजेक्ट, एर, प्रोजेक्ट पर कुछ बातचीत हुई है ।


3
-1; यह एक प्लेटिनम-अज्ञेय समाधान के लिए पूछने वाला पायथन सवाल था, और आपने एक जवाब के साथ जवाब दिया है जो कि विंडोज-विशिष्ट है और विशेष रूप से पायथन में इस में से कोई भी करने का कोई संकेत नहीं देता है। यह थोड़ा अलग सवाल का एक शानदार जवाब हो सकता है, लेकिन यहां से बाहर है।
मार्क एमी

0

इस कोड को आज़माएं

import serial.tools.list_ports
for i in serial.tools.list_ports.comports():
    print(i) 

यह लौट आता है

COM1 - Port de communication (COM1)
COM5 - USB-SERIAL CH340 (COM5)

यदि आप छूट COM1 के लिए पोर्ट के नाम को अभ्यस्त कर रहे हैं

import serial.tools.list_ports
for i in serial.tools.list_ports.comports():
    print(str(i).split(" ")[0])

यह लौट आता है

COM1
COM5

जैसा कि मेरे मामले में py 3.7 64 बिट्स है


0

केवल विंडोज पर काम करता है:

import winreg
import itertools

def serial_ports() -> list:
    path = 'HARDWARE\\DEVICEMAP\\SERIALCOMM'
    key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, path)

    ports = []
    for i in itertools.count():
        try:
            ports.append(winreg.EnumValue(key, i)[1])
        except EnvironmentError:
            break

    return ports

if __name__ == "__main__":
    ports = serial_ports()
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.