खोज…


परिचय

सीरियल पोर्ट बाहरी सेंसर या एम्बेडेड सिस्टम जैसे कि Arduinos के साथ संचार करने के लिए एक सामान्य इंटरफ़ेस है। आधुनिक धारावाहिक संचार अक्सर यूएसबी-सीरियल एडेप्टर का उपयोग करके यूएसबी कनेक्शन पर लागू किया जाता है। MATLAB RS-232 और RS-485 प्रोटोकॉल सहित धारावाहिक संचार के लिए अंतर्निहित कार्य प्रदान करता है। इन कार्यों का उपयोग हार्डवेयर सीरियल पोर्ट या "वर्चुअल" यूएसबी-सीरियल कनेक्शन के लिए किया जा सकता है। यहां के उदाहरण MATLAB में धारावाहिक संचार को चित्रित करते हैं।

पैरामीटर

सीरियल पोर्ट पैरामीटर यह क्या करता है
BaudRate बॉड्रेट सेट करता है। सबसे आम आज 57600 है, लेकिन 4800, 9600, और 115200 अक्सर भी देखे जाते हैं
InputBufferSize स्मृति में रखे बाइट्स की संख्या। मतलाब में एक FIFO है, जिसका अर्थ है कि नए बाइट्स को छोड़ दिया जाएगा। डिफ़ॉल्ट 512 बाइट्स है, लेकिन इसे आसानी से 20 एमबी पर सेट किया जा सकता है। केवल कुछ किनारे मामले हैं जहां उपयोगकर्ता यह चाहते हैं कि यह छोटा हो
BytesAvailable पढ़ने के लिए प्रतीक्षा कर रहे बाइट्स की संख्या
ValuesSent पोर्ट खोले जाने के बाद से भेजे गए बाइट्स की संख्या
ValuesReceived पोर्ट खोले जाने के बाद से बाइट्स की संख्या पढ़ी गई
BytesAvailableFcn इनपुट बफ़र में निर्दिष्ट बाइट्स उपलब्ध होने पर कॉलबैक फ़ंक्शन को निष्पादित करने के लिए निर्दिष्ट करें, या एक टर्मिनेटर पढ़ा जाता है
BytesAvailableFcnCount bytes-available ईवेंट उत्पन्न करने के लिए इनपुट बफ़र में उपलब्ध बाइट्स की संख्या निर्दिष्ट करें
BytesAvailableFcnMode निर्दिष्ट करें कि bytes-available ईवेंट इनपुट बफ़र में उपलब्ध बाइट्स की संख्या के बाद उत्पन्न होता है, या एक टर्मिनेटर पढ़ने के बाद

मैक / लिनक्स / विंडोज पर एक सीरियल पोर्ट बनाना

% Define serial port with a baud rate of 115200
rate = 115200;
if ispc
    s = serial('COM1', 'BaudRate',rate);
elseif ismac
    % Note that on OSX the serial device is uniquely enumerated. You will
    % have to look at /dev/tty.* to discover the exact signature of your
    % serial device
    s = serial('/dev/tty.usbserial-A104VFT7', 'BaudRate',rate);
elseif isunix
    s = serial('/dev/ttyusb0', 'BaudRate',rate);
end

% Set the input buffer size to 1,000,000 bytes (default: 512 bytes).
s.InputBufferSize = 1000000;    

% Open serial port    
fopen(s);

सीरियल पोर्ट से पढ़ना

आप यह मानते हुए सीरियल पोर्ट वस्तु बनाया s के रूप में इस उदाहरण है, तो

% Read one byte
data = fread(s, 1);

% Read all the bytes, version 1
data = fread(s);

% Read all the bytes, version 2
data = fread(s, s.BytesAvailable);

% Close the serial port
fclose(s);

खो जाने, मिटाने या अधिलेखित होने पर भी सीरियल पोर्ट बंद करना

मान लिया जाये कि आपके द्वारा बनाए गए सीरियल पोर्ट वस्तु s के रूप में इस उदाहरण है, तो यह बंद करने के लिए

fclose(s)

हालांकि, कभी-कभी आप गलती से पोर्ट खो सकते हैं (उदाहरण के लिए स्पष्ट, अधिलेखित, परिवर्तन गुंजाइश, आदि ...), और fclose(s) अब काम नहीं करेंगे। समाधान आसान है

fclose(instrfindall)

अधिक जानकारी instrfindall()

सीरियल पोर्ट के लिए लेखन

आप यह मानते हुए सीरियल पोर्ट वस्तु बनाया s के रूप में इस उदाहरण है, तो

% Write one byte
fwrite(s, 255);

% Write one 16-bit signed integer
fwrite(s, 32767, 'int16');

% Write an array of unsigned 8-bit integers
fwrite(s,[48 49 50],'uchar');

% Close the serial port
fclose(s);

अपने संचार मोड को चुनना

मतलब सीरियल पोर्ट के साथ सिंक्रोनस और एसिंक्रोनस संचार का समर्थन करता है। सही संचार मोड को चुनना महत्वपूर्ण है। चुनाव इस पर निर्भर करेगा:

  • आप किस प्रकार का साधन व्यवहार कर रहे हैं।
  • आपके मुख्य कार्यक्रम (या GUI) के अन्य कार्यों को सीरियल पोर्ट को प्रबंधित करने से अलग क्या करना होगा।

मैं वर्णन करने के लिए 3 अलग-अलग मामलों को परिभाषित करूँगा, सबसे सरल से सबसे अधिक मांग तक। 3 उदाहरणों के लिए, मैं जिस उपकरण से जुड़ रहा हूं, वह एक इनक्लिनोमीटर के साथ एक सर्किट बोर्ड है, जो नीचे वर्णित 3 मोड में काम कर सकता है।


मोड 1: सिंक्रोनस (मास्टर / दास)

यह विधा सबसे सरल है। यह उस मामले के अनुरूप है जहां पीसी मास्टर है और साधन दास है । साधन सीरियल पोर्ट के लिए कुछ भी नहीं भेजता है पर यह खुद, यह केवल एक जवाब उत्तर है उसका नाम से किया जा रहा मास्टर (पीसी, अपने कार्यक्रम) द्वारा एक सवाल / आदेश के लिए कहा। उदाहरण के लिए:

  • पीसी एक आदेश भेजता है: "मुझे अब एक माप दें"
  • साधन कमांड प्राप्त करते हैं, माप लेते हैं फिर माप मान को सीरियल लाइन पर भेजते हैं: "इनक्लिनोमीटर मूल्य XXX है"।

या

  • पीसी एक कमांड भेजता है: "मोड एक्स से मोड वाई में बदलें"
  • साधन कमांड प्राप्त करता है, इसे निष्पादित करता है, फिर एक पुष्टिकरण संदेश वापस सीरियल लाइन पर भेजें: " कमांड निष्पादित " (या " कमांड निष्पादित नहीं किया गया ")। इसे आमतौर पर ACK / NACK उत्तर ("Acknowledge (d)" / "Not Acknowledged" के लिए) कहा जाता है।

सारांश: इस मोड में, साधन ( स्लेव ) केवल पीसी ( मास्टर ) द्वारा पूछे जाने के तुरंत बाद सीरियल लाइन में डेटा भेजते हैं

समकालिक चित्रण


मोड 2: अतुल्यकालिक

अब मान लीजिए कि मैंने अपना यंत्र शुरू कर दिया है, लेकिन यह सिर्फ एक गूंगा सेंसर से अधिक है। यह लगातार निगरानी करता है कि यह स्वयं का झुकाव है और जब तक यह लंबवत है (एक सहिष्णुता के भीतर, चलो +/- 15 डिग्री कहते हैं), यह चुप रहता है। यदि डिवाइस 15 डिग्री से अधिक झुका हुआ है और क्षैतिज के करीब है, तो यह धारावाहिक रेखा को एक अलार्म संदेश भेजता है, जिसके तुरंत बाद झुकाव की एक रीडिंग होती है। जब तक झुकाव थ्रेसहोल्ड से ऊपर है, तब तक यह हर 5s में एक झुकाव पढ़ने भेजना जारी रखता है।

यदि आपका मुख्य कार्यक्रम (या GUI) सीरियल लाइन पर पहुंचने वाले संदेश के लिए लगातार "प्रतीक्षा" कर रहा है, तो वह यह अच्छी तरह से कर सकता है ... लेकिन यह इस बीच कुछ और नहीं कर सकता है। यदि मुख्य कार्यक्रम एक जीयूआई है, तो जीयूआई प्रतीत होता है कि "जमे हुए" होना बहुत निराशाजनक है क्योंकि यह उपयोगकर्ता से किसी भी इनपुट को स्वीकार नहीं करेगा। अनिवार्य रूप से, यह दास बन गया और साधन मास्टर है । जब तक आपके पास साधन से अपने जीयूआई को नियंत्रित करने का एक फैंसी तरीका नहीं है, यह बचने के लिए कुछ है। सौभाग्य से, अतुल्यकालिक संचार मोड आपको देगा:

  • एक अलग फ़ंक्शन परिभाषित करें जो आपके प्रोग्राम को बताता है कि संदेश प्राप्त होने पर क्या करना है
  • इस फ़ंक्शन को एक कोने में रखें, यह केवल तब बुलाया और निष्पादित किया जाएगा जब कोई संदेश धारावाहिक लाइन पर आता है । बाकी समय जीयूआई किसी अन्य कोड को चला सकता है जो उसे चलाना है।

सारांश: इस मोड में, इंस्ट्रूमेंट किसी भी समय धारावाहिक लाइन को संदेश भेज सकता है (लेकिन जरूरी नहीं कि हर समय)। संदेश संसाधित करने के लिए PC स्थायी रूप से प्रतीक्षा नहीं करता है। इसे किसी अन्य कोड को चलाने की अनुमति है। जब कोई संदेश आता है, तो यह एक फ़ंक्शन को सक्रिय करता है जो तब इस संदेश को पढ़ेगा और संसाधित करेगा।

यहाँ छवि विवरण दर्ज करें


मोड 3: स्ट्रीमिंग ( वास्तविक समय )

अब आइए अपने साधन की पूरी शक्ति को उजागर करें। मैंने इसे एक मोड में रखा जहां यह लगातार सीरियल लाइन पर माप भेजेगा। मेरा कार्यक्रम इन पैकेटों को प्राप्त करना चाहता है और प्रदर्शित करता है कि एक वक्र या एक डिजिटल डिस्प्ले पर। यदि यह केवल प्रत्येक 5s को ऊपर के रूप में मान भेजता है, तो कोई समस्या नहीं है, उपरोक्त मोड को रखें। लेकिन फुल व्हेक पर मेरा इंस्ट्रूमेंट 1000Hz पर सीरियल लाइन को एक डेटा पॉइंट भेजता है, यानी यह हर एक मिलीसेकंड पर एक नया मूल्य भेजता है। यदि मैं ऊपर वर्णित अतुल्यकालिक मोड में रहता हूं, तो एक उच्च जोखिम है (वास्तव में एक निश्चित निश्चितता) जो कि हर नए पैकेट को संसाधित करने के लिए हमने जिस विशेष फ़ंक्शन को परिभाषित किया है उसे निष्पादित करने के लिए 1ms से अधिक समय लगेगा (यदि आप मूल्य को प्लॉट करना या प्रदर्शित करना चाहते हैं। ग्राफिक फ़ंक्शंस काफी धीमी हैं, फ़िल्टरिंग या सिग्नल को FFT'ing करने पर भी नहीं)। इसका मतलब है कि फ़ंक्शन निष्पादित करना शुरू कर देगा, लेकिन इससे पहले कि यह खत्म हो जाए, एक नया पैकेट आ जाएगा और फ़ंक्शन को फिर से ट्रिगर करेगा। दूसरे फ़ंक्शन को निष्पादन के लिए एक कतार में रखा गया है, और केवल तभी शुरू होगा जब पहले एक किया जाता है ... लेकिन इस समय तक कुछ नए पैकेट आ गए और प्रत्येक ने कतार में निष्पादित करने के लिए एक फ़ंक्शन रखा। आप जल्दी से परिणाम का पूर्वाभास कर सकते हैं: जब तक मैं 5 वें अंक की साजिश रच रहा हूं, तब तक मेरे पास पहले से ही सैकड़ों प्लॉट होने की प्रतीक्षा है ... गुई धीमा कर देती है, अंततः जमा देता है, ढेर बढ़ता है, जब तक कि कुछ नहीं देता। आखिरकार आप पूरी तरह से जमे हुए कार्यक्रम या बस दुर्घटनाग्रस्त होने से बचे हैं।

इसे दूर करने के लिए, हम पीसी और इंस्ट्रूमेंट के बीच सिंक्रनाइज़ेशन लिंक को और भी डिस्कनेक्ट कर देंगे। हम प्रत्येक पैकेट आगमन पर एक फ़ंक्शन को ट्रिगर किए बिना, इंस्ट्रूमेंट को अपनी गति से डेटा भेजने देंगे। सीरियल पोर्ट बफर सिर्फ प्राप्त पैकेट को संचित करेगा। पीसी केवल बफर में डेटा एकत्र कर सकता है एक गति पर जो इसे प्रबंधित कर सकता है (एक नियमित अंतराल, पीसी की तरफ स्थापित), इसके साथ कुछ करें (जबकि बफर साधन द्वारा रिफिल हो रहा है), फिर एक नया बैच इकट्ठा करें बफर से डेटा ... और इतने पर।

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

यहाँ छवि विवरण दर्ज करें


सीरियल पोर्ट से प्राप्त डेटा को स्वचालित रूप से संसाधित करना

एक सीरियल पोर्ट के माध्यम से जुड़े कुछ डिवाइस आपके प्रोग्राम को निरंतर दर (स्ट्रीमिंग डेटा) पर डेटा भेजते हैं या अप्रत्याशित अंतराल पर डेटा भेजते हैं। जब भी यह आता है तो डेटा को संभालने के लिए आप किसी फ़ंक्शन को स्वचालित रूप से निष्पादित करने के लिए सीरियल पोर्ट को कॉन्फ़िगर कर सकते हैं। इसे सीरियल पोर्ट ऑब्जेक्ट के लिए "कॉलबैक फ़ंक्शन" कहा जाता है।

सीरियल पोर्ट के दो गुण हैं जिन्हें इस सुविधा का उपयोग करने के लिए सेट किया जाना चाहिए: कॉलबैक के लिए इच्छित फ़ंक्शन का नाम ( BytesAvailableFcn ), और वह शर्त जो कॉलबैक फ़ंक्शन ( BytesAvailableFcnMode ) को निष्पादित करने के लिए ट्रिगर होनी चाहिए।

कॉलबैक फ़ंक्शन को ट्रिगर करने के दो तरीके हैं:

  1. जब सीरियल पोर्ट पर एक निश्चित संख्या में बाइट्स प्राप्त हुए हैं (आमतौर पर बाइनरी डेटा के लिए उपयोग किया जाता है)
  2. जब सीरियल पोर्ट पर एक निश्चित चरित्र प्राप्त होता है (आमतौर पर पाठ या ASCII डेटा के लिए उपयोग किया जाता है)

कॉलबैक फ़ंक्शंस में दो आवश्यक इनपुट तर्क हैं, जिन्हें obj और event कहा जाता है। obj सीरियल पोर्ट है। उदाहरण के लिए, यदि आप सीरियल पोर्ट से प्राप्त डेटा को प्रिंट करना चाहते हैं, तो newdata नामक डेटा को प्रिंट करने के लिए एक फ़ंक्शन को परिभाषित करें:

function newdata(obj,event)
    [d,c] = fread(obj);  % get the data from the serial port
    % Note: for ASCII data, use fscanf(obj) to return characters instead of binary values
    fprintf(1,'Received %d bytes\n',c);
    disp(d)
end

उदाहरण के लिए, जब भी 64 बाइट्स के डेटा newdata , तो newdata फ़ंक्शन को निष्पादित करने के लिए, इस तरह सीरियल पोर्ट को कॉन्फ़िगर करें:

s = serial(port_name);
s.BytesAvailableFcnMode = 'byte';
s.BytesAvailableFcnCount = 64;
s.BytesAvailableFcn = @newdata;

पाठ या ASCII डेटा के साथ, डेटा को आमतौर पर "टर्मिनेटर वर्ण" के साथ लाइनों में विभाजित किया जाता है, जैसे पृष्ठ पर पाठ। जब भी गाड़ी का रिटर्न कैरेक्टर मिलता है, तो newdata फ़ंक्शन को निष्पादित करने के लिए, इस तरह सीरियल पोर्ट को कॉन्फ़िगर करें:

s = serial(port_name);
s.BytesAvailableFcnMode = 'terminator';
s.Terminator = 'CR';  % the carriage return, ASCII code 13
s.BytesAvailableFcn = @newdata;


Modified text is an extract of the original Stack Overflow Documentation
के तहत लाइसेंस प्राप्त है CC BY-SA 3.0
से संबद्ध नहीं है Stack Overflow