इतना समय पहले नहीं, एक मित्र ने मुझे एक माइक्रोकंट्रोलर के लिए फर्मवेयर बनाने से संबंधित नौकरी की पेशकश की, जिसे
SIM900D GSM मॉड्यूल का उपयोग करके सर्वर के साथ संवाद करना था। इससे पहले, मेरे पास प्रोग्रामिंग माइक्रोकंट्रोलर्स के साथ कोई व्यवसाय नहीं था, और मैंने अपने छात्र दिनों में आखिरी बार सी में प्रोग्राम किया था, लेकिन मेरी जिज्ञासा बढ़ गई और मैंने काम करना शुरू कर दिया। लोहे के इस टुकड़े पर प्रलेखन इंटरनेट पर
मौजूद है , हालांकि, कोड में टीसीपी / आईपी के साथ काम करने के अच्छे उदाहरण नहीं मिल सके। प्रलेखन में शामिल होने, सिगरेट और चाय पर स्टॉक करने और रेक के बीच पैंतरेबाज़ी करने के लिए कुछ भी नहीं बचा था। एक रेक बहुत था। दरअसल, इसीलिए मैंने यह लेख लिखा है - दूसरों के लिए इसे आसान बनाने के लिए।
बहुत सारे AT कमांड होंगे, बहुत ज्यादा कोड नहीं, और बहुत सारे अक्षर।
क्या जरूरत थी
यह एक कोड लिखने के लिए आवश्यक था जो जीएसएम मॉड्यूल को इनिशियलाइज़ कर सके, सर्वर के साथ एक कनेक्शन स्थापित कर सके, मनमाना डेटा प्राप्त कर सके और कनेक्शन की स्थिति की जाँच कर सके और बिना किसी असफलता के काम कर सके। और माइक्रोकंट्रोलर की सीमित मेमोरी में फिट होने के लिए भी पर्याप्त कॉम्पैक्ट होना चाहिए और मुख्य कार्यक्षमता के लिए कमरे को छोड़ देना चाहिए और रिजर्व में थोड़ा अधिक होना चाहिए।
नतीजा क्या हुआ
परिणाम एक सी कोड है जो कुछ भी वह कर सकता है। कॉम्पैक्टनेस की आवश्यकताओं के कारण, उत्तरों को पार्स करना और अपने स्वयं के कोड का उपयोग करके तार उत्पन्न करना आवश्यक था, जो ईमानदार लोगों को दिखाने के लिए भी शर्म की बात है। इसलिए, मैं सभी को इन उद्देश्यों के लिए नियमित अभिव्यक्ति का उपयोग करने की सलाह देता हूं। मैं अपने कोड को एक हल्के नियमित अभिव्यक्ति इंजन में स्थानांतरित करने जा रहा हूं, लेकिन पूरी तरह कार्यात्मक फर्मवेयर बनाने के बाद।
कोड को सीरियल पोर्ट के साथ काम करने के लिए फ़ंक्शन / मैक्रोज़ की आवश्यकता होती है, साथ ही साथ मेमसेट और मेमसीपी कार्यों की उपस्थिति भी होती है। तो यह रास्ते में पुस्तकालयों के एक झुंड को हुक किए बिना किसी अन्य प्लेटफॉर्म पर सापेक्ष आसानी से स्थानांतरित किया जा सकता है।
और यह कैसा दिखता है?
विंडोज 7 के तहत प्रोग्रामिंग और परीक्षण किया गया था। परिणामस्वरूप कोड इस लेख के लिए मुख्य सामग्री बन गया। मैं कोड को पूरी तरह से उद्धृत नहीं करूंगा और उस पर टिप्पणी नहीं करूंगा, बल्कि इसके बजाय मैं जीएसएम मॉड्यूल के साथ स्थापित करने और काम करने के लिए एल्गोरिदम दिखाऊंगा।
कोड द्वारा आवश्यक कार्य:
uint16_t init_serial_port(char *port_name)
यह फ़ंक्शन निर्दिष्ट सीरियल पोर्ट को कॉन्फ़िगर करता है। विंडोज के तहत।uint16_t puts_serial(uint8_t *buffer, uint16_t size)
और यह एक इस बंदरगाह को बाइट्स की एक स्ट्रिंग लिखता है।gets_serial(uint8_t *buffer, uint16_t size)
यह क्रमशः, सीरियल पोर्ट से बाइट्स के एक स्ट्रिंग को पढ़ता है।
कोड प्रदान करता है कि कार्य हैं:
init_gprs() & stop_gprs()
क्रमशः प्रारंभ और जीएसएम मॉड्यूल नीचे कटौती।uint16_t connect_gprs(uint8_t index, uint8_t mode, char *address, char *port)
सर्वर के साथ एक कनेक्शन स्थापित करता है। यह ध्यान देने योग्य है कि मॉड्यूल टीसीपी और यूडीपी प्रोटोकॉल के साथ क्लाइंट के रूप में और क्लाइंट के रूप में काम कर सकता है। अधिकतम 8 युगपत कनेक्शन समर्थित हैं।uint16_t close_gprs(uint8_t index)
निर्दिष्ट कनेक्शन को बंद कर देता है।uint16_t send_gprs(uint8_t index, uint8_t *buffer, uint16_t size)
निर्दिष्ट कनेक्शन के माध्यम से एक संदेश भेजता है।uint16_t recv_gprs(uint8_t index, uint8_t *buffer, uint16_t size)
एक संदेश प्राप्त करें। एक गैर-अवरुद्ध फ़ंक्शन, जिसका अर्थ है कि यह डेटा स्ट्रीम में प्रदर्शित होने के लिए इंतजार नहीं करेगा, लेकिन अगर कुछ भी प्राप्त नहीं करना है तो नियंत्रण वापस कर देगा। यह ध्यान दिया जाना चाहिए कि यह व्यवहार अवरुद्ध करने की तुलना में लागू करना आसान है।
सीरियल पोर्ट के साथ कैसे काम करें
यह काफी सरल है। लक्ष्य माइक्रोकंट्रोलर के तहत
USART के माध्यम से डेटा भेजने / प्राप्त करने के लिए मैक्रो हैं, लेकिन चूंकि यह एक स्थिर कंप्यूटर से इस तरह के कोड को डीबग करना आसान है, इसलिए मुझे USB <-> USART एडाप्टर और जीएसएम मॉड्यूल के साथ प्रदान किया गया था। यह केवल विंडोज के तहत सीरियल पोर्ट के साथ काम करने का तरीका जानने के लिए बना रहा। यह सरल निकला। संक्षेप में, सीरियल पोर्ट ओएस में एक नियमित फ़ाइल के रूप में दिखाई देता है, जानकारी
ReadFile और
WriteFile फ़ंक्शन द्वारा प्रेषित की जाती है। आपको केवल
SetCommTimeouts और
SetCommState फ़ंक्शन का उपयोग करके कुछ पैरामीटर सेट करने की आवश्यकता है।
यहाँ पोर्ट इनिशियलाइज़ेशन फंक्शन कैसा दिखता है:
uint16_t init_serial_port(char *port_name) { COMMTIMEOUTS timeouts; DCB parameters; int result; serial_port_handle = CreateFile(port_name,
जीएसएम मॉड्यूल के साथ संचार कैसे होता है
सीरियल पोर्ट कॉन्फ़िगर होने के बाद, एटी कमांड्स को भेजा जा सकता है। पहला कमांड अनुक्रम
"AT\r"
होना चाहिए, जिससे मॉड्यूल सीरियल पोर्ट पर बॉड दर को स्वचालित रूप से कॉन्फ़िगर कर सके। इसके बाद पोर्ट से प्राप्त किया जा सकने वाला उत्तर
"AT\r\r\nOK\r\n"
जैसा दिखेगा।
आदेश ASCII वर्णों का एक सरल स्ट्रिंग है। आदेश को स्वीकार करने के लिए मॉड्यूल के लिए, इसके अंत में एक गाड़ी वापसी चरित्र
"\r"
डालें। प्रतिक्रिया में, मॉड्यूल दो भागों से मिलकर एक चरित्र स्ट्रिंग भेजेगा - एक कमांड जिसके लिए मॉड्यूल वर्णों द्वारा अलग किए गए प्रतिक्रिया के साथ प्रतिक्रिया करता है "\ r \ r \ n" अक्षर
"\r\n"
साथ समाप्त होता है। उत्तरों को पार्स करना आसान बनाने के लिए, मैंने एक मैक्रो बनाया जो प्राप्त बफर में प्रतिक्रिया की शुरुआत के लिए एक संकेतक सेट करता है। यदि आप कंसोल में उत्तर प्रदर्शित करना चाहते हैं, तो आपको प्राप्त संदेश के अंत में एक अशक्त चरित्र जोड़ना होगा।
void at_send(char *cmd, uint16_t size) { uint16_t result; cmd[size - 1] = '\r'; result = puts_serial(cmd, size); return; } uint16_t at_recv(uint8_t *buffer, uint16_t size) { uint16_t result; result = gets_serial(buffer, size); return result; }
कमांड भेजने और प्रतिक्रिया प्राप्त करने के लिए सहायक कार्य कुछ इस तरह दिखते हैं।
मॉड्यूल प्रारंभिक
मॉड्यूल को स्थापित करने के लिए कोड में सबसे बड़ा कार्य जिम्मेदार है। प्रारंभ में कई एटी कमांड्स भेजे जाते हैं। मैं मॉड्यूल को भेजे गए आदेश में उनका वर्णन करूंगा। मैं विशेष रूप से तर्कों और उत्तर विकल्पों का विस्तार से वर्णन नहीं करता हूं, क्योंकि वे प्रलेखन में पाए जा सकते हैं।
"AT+CPIN=pin-code"
जैसा कि आप अनुमान लगा सकते हैं, यह कमांड पिन कोड दर्ज करके सिम कार्ड को अनलॉक करता है। यह जानने के लिए कि क्या पिन कोड की आवश्यकता है, आप "AT+CPIN?"
कमांड का उपयोग कर सकते हैं "AT+CPIN?"
।"AT+CREG?"
यह कमांड नेटवर्क में मॉड्यूल की पंजीकरण स्थिति देता है। मॉड्यूल के जवाब देने तक इसे निष्पादित करना आवश्यक है जो नेटवर्क में पंजीकृत है।"AT+CGATT=1"
जीपीआरएस से कनेक्ट करने के लिए मॉड्यूल को "AT+CGATT=1"
। आप जाँच कर सकते हैं कि क्या यह "AT+CGATT?"
कमांड का उपयोग करके जुड़ा हुआ है "AT+CGATT?"
।"AT+CIPRXGET=1"
मैन्युअल रूप से कनेक्शन के माध्यम से प्रेषित डेटा प्राप्त करने में सक्षम करता है। डिफ़ॉल्ट रूप से, यह पैरामीटर अक्षम है और रसीद पर तुरंत सीरियल पोर्ट पर डेटा प्रसारित होता है। यह बहुत सुविधाजनक नहीं है, हालांकि महत्वपूर्ण नहीं है - आप मॉड्यूल को कॉन्फ़िगर कर सकते हैं ताकि डेटा के साथ यह आईपी हेडर भी भेजता है, जिसके द्वारा आप यह निर्धारित कर सकते हैं कि पैकेट किससे प्राप्त किया गया था। मैंने तय किया कि मैन्युअल रूप से डेटा प्राप्त करना आसान है और गलत नहीं है। जैसा कि मैं इसे समझता हूं, यह कमांड केवल SIM.COM जीएसएम-मॉड्यूल द्वारा स्वीकार किया जाता है।"AT+CIPMUX=1"
डिफ़ॉल्ट रूप से, मॉड्यूल केवल एक कनेक्शन स्थापित कर सकता है। यह विकल्प कई कनेक्शन बनाने की क्षमता को सक्षम करता है। डेटा भेजना और प्राप्त करना केवल एक पैरामीटर से अलग होगा - कनेक्शन सूचकांक।"AT+CSTT="internet""
एपीएन - एक्सेस प्वाइंट नाम, जीपीआरएस के लिए एक्सेस प्वाइंट नाम। यह मेरे प्रदाता के लिए बिल्कुल वैसा ही दिखता है।"AT+CIICR"
एक वायरलेस जीपीआरएस कनेक्शन स्थापित करता है। इसमें कुछ समय लग सकता है, इसलिए इसे लूप में चलाने और प्रतिक्रिया की जांच करने की आवश्यकता है।"AT+CIFSR"
मॉड्यूल का IP पता लौटाता है। मैं यह जांचने के लिए उपयोग करता हूं कि मॉड्यूल इंटरनेट से जुड़ा है या नहीं।"AT+CDNSCFG="8.8.8.8","8.8.4.4""
यह कमांड DNS सर्वरों को स्थापित करता है जो मॉड्यूल उपयोग करेगा।"AT+CIPSTATUS"
कनेक्शन स्थिति डेटा के अलावा, यह कमांड इस बात की जानकारी देता है कि क्या मॉड्यूल कनेक्शन स्थापित करने के लिए तैयार है। इसलिए आपको उसका उत्तर जांचने की आवश्यकता है।
इन आदेशों को निष्पादित करने के बाद, मॉड्यूल ऑपरेशन के लिए तैयार हो जाएगा। अच्छी तरह से या नहीं। यहाँ यह कितना भाग्यशाली है
स्थापना और वियोग
कनेक्शन
"AT+CIPSTART=index,"mode","address","port""
कमांड
"AT+CIPSTART=index,"mode","address","port""
।
index
कनेक्शन की क्रम संख्या को इंगित करता है; यह 0 से 7 तक मान ले सकता है।mode
प्रोटोकॉल को परिभाषित करता है जो कनेक्शन का उपयोग करेगा। यह "टीसीपी" या "यूडीपी" हो सकता है।address
सर्वर का address
सेट करता है। यदि आपने कॉन्फ़िगरेशन के दौरान DNS सर्वर निर्दिष्ट किए हैं, तो आप एक आईपी पते और डोमेन नाम दोनों का उपयोग कर सकते हैं।port
सर्वर के पोर्ट को निर्दिष्ट करता है जिसके साथ कनेक्शन स्थापित किया जाएगा।
ध्यान दें कि UDP प्रोटोकॉल का उपयोग करते समय, डिफ़ॉल्ट रूप से, डेटाग्राम को केवल एक पते से भेजा और प्राप्त किया जाएगा। UDP को पूर्ण रूप से उपयोग करने और किसी भी पते से डेटा भेजने / प्राप्त करने के लिए, आप
"AT+CIPUDPMODE"
कमांड द्वारा कॉन्फ़िगर किए गए तथाकथित उन्नत UDP मोड का उपयोग कर सकते हैं। विवरण के लिए, प्रलेखन देखें।
कमांड के जवाब में, आप कई उत्तर प्राप्त कर सकते हैं। यदि सब कुछ ठीक है, तो मानक
"OK"
बाद
"OK"
थोड़े समय के बाद, आप तीन में से एक उत्तर प्राप्त कर सकते हैं:
"index,ALREADY CONNECT"
इसका मतलब है कि दिए गए सूचकांक के साथ एक संबंध पहले ही स्थापित हो चुका है और यह इसके लायक है।"index,CONNECT OK"
सब कुछ यहाँ स्पष्ट है।"index,CONNECT FAIL"
अर्थ है कि कनेक्शन स्थापित करने में समस्याएं हैं।
आप
"AT+CIPCLOSE=index"
कमांड के साथ कनेक्शन समाप्त कर सकते हैं। आप
"AT+CIPSHUT"
का उपयोग करके सभी कनेक्शनों को डिस्कनेक्ट कर सकते हैं और GPRS इंटरफ़ेस को निष्क्रिय कर सकते हैं।
डेटा ट्रांसफर
डेटा को
"AT+CIPSEND=index,length"
कमांड के साथ प्रेषित किया जाता है, जहां
index
उस कनेक्शन को इंगित करता है जिसके माध्यम से डेटा प्रेषित किया जाना चाहिए, और
length
डेटा पैकेट की
length
निर्धारित करती है। वैसे, आप
"AT+CIPSEND=?"
कमांड का उपयोग करके प्रत्येक कनेक्शन के लिए
MTU का पता लगा सकते हैं। ।
यदि सब कुछ ठीक है, तो कमांड के जवाब में मॉड्यूल
">"
शीघ्र जारी करेगा, जिसके बाद सीरियल पोर्ट पर डेटा भेजा जाना चाहिए। जैसे ही मॉड्यूल
length
बराबर बाइट्स की संख्या प्राप्त करता है, यह
"index,SEND OK"
जैसे कुछ कहेगा। सामान्य तौर पर, आप
length
पैरामीटर का उपयोग नहीं कर सकते हैं, हालांकि, इस मामले में, डेटा पैकेट के अंत में
0x1A
चरित्र का उपयोग करके संकेत दिया जाना चाहिए, टर्मिनल में संयोजन Ctrl + Z। मनमाने डेटा के हस्तांतरण के लिए, यह विकल्प स्पष्ट रूप से उपयुक्त नहीं है।
जैसा कि आप देख सकते हैं, डेटा ट्रांसफर बहुत जटिल प्रक्रिया नहीं है। इसलिए, हम सबसे दिलचस्प - डेटा रिसेप्शन की ओर मुड़ते हैं।
डेटा का स्वागत
जैसे ही जीएसएम मॉड्यूल डेटा प्राप्त करता है, यह सीरियल पोर्ट को
"+CIPRXGET:1,index\r\n"
के रूप में
"+CIPRXGET:1,index\r\n"
। मुझे ईमानदारी से पता नहीं है कि यूनिट का क्या मतलब है, क्योंकि मॉड्यूल का यह फ़ंक्शन खराब रूप से प्रलेखित है, लेकिन यह मेरे सभी संदेशों में एक पैकेट प्राप्त करने के बारे में दिखाई देता है।
मैं इस सोच से खुश नहीं था कि मुझे एक या दूसरे तरीके से मॉड्यूल संदेशों की निगरानी करनी होगी। हालांकि, डिबगर के साथ थोड़ा खेलने के बाद, मुझे पता चला कि मॉड्यूल किसी अन्य अतुल्यकालिक संदेश नहीं भेजता है, और यह भी कि किसी भी एटी-कमांड को निष्पादित करने के बाद यह संदेश बफर की शुरुआत में दिखाई देता है। चूँकि मैंने एक मैक्रो को
"\r\r\n"
लिए खोज कर कमांड से प्रतिक्रिया को अलग करने के लिए संकलित किया, इससे किसी भी तरह से मुझे प्रभावित नहीं हुआ। इसलिए डेटा प्राप्त करने का कार्य काफी सरलता से लागू किया गया था।
तो, आप
"AT+CIPRXGET=2,index,length"
कमांड के साथ डेटा प्राप्त कर सकते हैं। दो मतलब रिसेप्शन मोड, इस मामले में, बाइट्स केवल सीरियल पोर्ट में डाले जाते हैं।
प्रोग्रामेटिक फ्लो कंट्रोल के साथ टकराव को रोकने के लिए, आप एक हेक्स पाठ के रूप में डेटा प्राप्त करने के लिए भी सेट कर सकते हैं। मुझे इसकी आवश्यकता नहीं थी, क्योंकि मैं प्रवाह नियंत्रण का उपयोग बिल्कुल नहीं करता हूं।
length
पैरामीटर उस डेटा पैकेट का आकार निर्धारित करता है जिसे हम एक बार में प्राप्त करना चाहते हैं।
जवाब में, हमें
"+CIPRXGET:2,index,received,excess\r\n__DATA__\r\nOK\r\n"
जैसा कुछ मिलता है।
received
फ़ील्ड में
__DATA__
डेटा
__DATA__
में बाइट्स की संख्या शामिल होगी, और
excess
फ़ील्ड में मॉड्यूल बफ़र में अपनी बारी की प्रतीक्षा में बाइट्स की संख्या शामिल होगी। इसलिए यदि
received
क्षेत्र शून्य है, तो आप ईमानदारी से घोषणा कर सकते हैं कि प्राप्त करने के लिए कुछ भी नहीं है। दरअसल, इसका उपयोग करते हुए, मैंने डेटा प्राप्त करने के लिए एक गैर-अवरुद्ध फ़ंक्शन लागू किया।
निष्कर्ष में
मैं दृढ़ता से अनुशंसा करता हूं कि आपको कोड लिखने से पहले
PuTTY के साथ एटी कमांड की आदत हो, जो सीरियल पोर्ट के साथ बहुत अच्छा काम करता है।
मुझे उम्मीद है कि इस लेख में दी गई जानकारी से किसी को अपने SIM900 के लिए कोड लिखने में मदद मिलेगी। यह संभव है कि ऊपर वर्णित जीएसएम मॉड्यूल के साथ काम करने के सिद्धांत, अन्य मॉडलों के मॉड्यूल पर लागू किए जा सकते हैं, और, संभवतः, निर्माता।