2012-10-22 12 views
14

मुझे एक पायथन प्रोग्राम मिला है जो PySerial मॉड्यूल के माध्यम से एक सीरियल पोर्ट से डेटा पढ़ रहा है। मुझे दो स्थितियों को ध्यान में रखने की आवश्यकता है: मुझे नहीं पता कि डेटा कितना होगा, और मुझे नहीं पता कि डेटा की अपेक्षा कब करें।PySerial का उपयोग करना डेटा के लिए प्रतीक्षा करना संभव है?

इस आधार पर मैं अनुसरण कोड snipets के साथ आया है:

#Code from main loop, spawning thread and waiting for data 
s = serial.Serial(5, timeout=5) # Open COM5, 5 second timeout 
s.baudrate = 19200 

#Code from thread reading serial data 
while 1: 
    tdata = s.read(500) # Read 500 characters or 5 seconds 

    if(tdata.__len__() > 0):  #If we got data 
    if(self.flag_got_data is 0): #If it's the first data we recieved, store it 
     self.data = tdata   
    else:       #if it's not the first, append the data 
     self.data += tdata 
     self.flag_got_data = 1 

तो यह कोड पाश हमेशा के लिए डेटा सीरियल पोर्ट बंद हो रही होगी। हमें 500 वर्णों तक डेटा स्टोर करने में मदद मिलेगी, फिर ध्वज सेट करके मुख्य पाश को चेतावनी दी जाएगी। यदि कोई डेटा मौजूद नहीं है तो हम बस सोने और प्रतीक्षा करेंगे।

कोड काम कर रहा है, लेकिन मुझे 5s टाइमआउट पसंद नहीं है। मुझे इसकी आवश्यकता है क्योंकि मुझे नहीं पता कि कितना डेटा उम्मीद कर सकता है, लेकिन मुझे यह पसंद नहीं है कि यह हर 5 सेकंड में जाग रहा है, भले ही कोई डेटा मौजूद न हो।

क्या read करने से पहले डेटा उपलब्ध होने पर जांचने का कोई तरीका है? मैं लिनक्स में select कमांड की तरह कुछ सोच रहा हूं।

संपादित करें:
बस सोचा था कि मैं ध्यान दें था मैंने पाया कि inWaiting() विधि, लेकिन वास्तव में यह है कि, यह सिर्फ एक सर्वेक्षण के मेरे "नींद" बदल रहा है ताकि नहीं है क्या मैं यहाँ चाहते हैं। मैं बस तब तक सोना चाहता हूं जब तक डेटा आ जाए, फिर इसे प्राप्त करें।

उत्तर

15

ठीक है, मैं वास्तव में एक साथ कुछ है कि मैं इस के लिए पसंद करते हैं। कोई समय समाप्ति के साथ read() का एक संयोजन और inWaiting() पद्धति का उपयोग करना:

#Modified code from main loop: 
s = serial.Serial(5) 

#Modified code from thread reading the serial port 
while 1: 
    tdata = s.read()   # Wait forever for anything 
    time.sleep(1)    # Sleep (or inWaiting() doesn't give the correct value) 
    data_left = s.inWaiting() # Get the number of characters ready to be read 
    tdata += s.read(data_left) # Do the read and combine it with the first character 

    ... #Rest of the code 

यह मुझे लगता है कि कार्यक्षमता के इस प्रकार अजगर

में
+1

'time.sleep (1) 'एक सुंदर बदसूरत हैक जैसा लगता है जो आपके डेटा को प्राप्त करने में देरी का एक गुच्छा जोड़ता है। – TJD

+0

@TJD - ऐसा कोई तर्क नहीं है, ऐसा लगता है कि यह नींद के बिना भी काम करता है, लेकिन 'data_left' बहुत अविश्वसनीय हो जाता है (1 9 वर्णों की एक स्ट्रिंग 3 के रूप में लूप होती है, फिर 10, फिर 6 "बैंक" आते हैं)। तो मैं अभी भी इसके साथ खुश नहीं हूं, लेकिन यह उस चीज़ के करीब है जो मैं सोच रहा था। डेटा तक सो जाओ, फिर डेटा पढ़ें, फिर सोने के लिए वापस जाओ। – Mike

+0

मुझे नहीं लगता कि यह "अविश्वसनीय" कैसे है। वैसे ही बाइट्स आ रहे हैं जैसे आप उन्हें पढ़ रहे हैं।आप 'interCharTimeout' का उपयोग करना चाह सकते हैं, जो आपको यह पता लगाने देता है कि रिसीवर ने किसी भी नए बाइट को देखना बंद कर दिया है। – TJD

10

आप timeout = None सेट कर सकते हैं, तो read कॉल तब तक अवरुद्ध होगा जब तक कि बाइट्स की अनुरोधित संख्या न हो। यदि आप डेटा आने तक प्रतीक्षा करना चाहते हैं, तो बस read(1) टाइमआउट None के साथ करें। यदि आप अवरुद्ध किए बिना डेटा जांचना चाहते हैं, तो read(1) टाइमआउट शून्य के साथ करें, और जांचें कि यह कोई डेटा देता है या नहीं।

(प्रलेखन http://pyserial.sourceforge.net/pyserial_api.html देखें)

+1

लेकिन मैं यह भी लगता है कि वहाँ बिल्कुल एक 5s टाइमआउट उपयोग करने और इसे wakeup और तुरंत पढ़ने के लिए वापस जाने के लिए होने के साथ कुछ भी गलत नहीं है। यह बहुत आसान है और इसमें कोई मापनीय ओवरहेड नहीं होगा। – TJD

+0

जानकारी के लिए धन्यवाद, मैंने पढ़ा प्रलेखन देखा था, यह पता नहीं लगा कि मैं इसे क्या करना चाहता हूं। मैं मानता हूं कि एक टाइमआउट के साथ एक लूप डेस्कटॉप मशीन पर बहुत महंगा नहीं है, लेकिन (एम्बेडेड पृष्ठभूमि से आ रहा है) मुझे – Mike

+0

मतदान के लिए मेरे लिए इतना गलत लगता है (कम से कम मेरी ज़रूरतों के लिए)। साझा करने के लिए धन्यवाद। – Marcel

0
def cmd(cmd,serial): 
    out='';prev='101001011' 
    serial.flushInput();serial.flushOutput() 
    serial.write(cmd+'\r'); 
    while True: 
     out+= str(serial.read(1)) 
     if prev == out: return out 
     prev=out 
    return out 
एक भी विधि के रूप में मौजूद नहीं है परिणाम मैं चाहता था देने के लिए लगता है,

इस तरह इसे कहते:

cmd('ATZ',serial.Serial('/dev/ttyUSB0', timeout=1, baudrate=115000)) 
संबंधित मुद्दे