2013-02-03 19 views
10

मैं एक ऐसे एप्लिकेशन पर काम कर रहा हूं जो दो चीजों में से एक के लिए जीएसएम मॉडेम का उपयोग करता है; सर्वर पर GET अनुरोध भेजकर, या सर्वर (डेटा यूडीपी का उपयोग करके) भेजकर निर्मित HTTP स्टैक में निर्मित स्थिति का उपयोग करके इसकी स्थिति जांचें। मैंने इसे यथासंभव विश्वसनीय रखने के लिए कई अलग-अलग तरीकों की कोशिश की है, और मैं आखिरकार सहायता मांगने के लिए तैयार हूं।एक जीएसएम मोडेम ड्राइवर लिखना?

मेरा आवेदन SIMCOM908 मॉड्यूल और पीआईसी 18 मंच (मैं विकास के लिए एक पीआईसी 18 एक्सप्लोरर का उपयोग कर रहा हूं) के लिए लिखा गया है।

तो समस्या कभी-कभी मॉडेम कुछ करने में व्यस्त होती है, और एक आदेश याद करती है। एक इंसान के रूप में, मैं उसे देखता हूं और बस आदेश भेजता हूं। मेरे एमसीयू के लिए टाइमआउट और रिजेंड के लिए एक सुविधा जोड़ना कोई मुद्दा नहीं है।

समस्या यह है कि मॉडेम विभिन्न घटनाओं के बाद अनचाहे प्रतिक्रिया भेजता है। जब मॉडेम पंजीकरण स्थिति बदलता है (सेल टावर के साथ) तो यह +CGREG: 1, ... या जब जीपीएस तैयार हो जाएगा GPS Ready के साथ जवाब देगा। ये प्रतिक्रिया किसी भी समय हो सकती है, जिसमें कमांड के बीच (जैसे आईपी कनेक्शन बनाना) शामिल है।

यह एक समस्या है, क्योंकि मैंने इस से निपटने का कोई तरीका नहीं सोचा है। मेरे एप्लिकेशन को एक कमांड भेजने की आवश्यकता है (उदाहरण के लिए सर्वर से कनेक्ट करने के लिए, AT+CIPSTART="UDP","example.com",5000) यह आदेश 'ओके' के साथ प्रतिक्रिया देगा, और फिर जब आदेश 'कनेक्ट ठीक है' समाप्त हो गया है। हालांकि, मुझे कई अन्य संभावित प्रतिक्रियाओं पर प्रतिक्रिया करने में सक्षम होना चाहिए, और मुझे ऐसा करने का कोई तरीका नहीं पता है। मुझे अपने कोड के साथ क्या करने की ज़रूरत है; मॉडेम से प्रतिक्रिया के लिए प्रतीक्षा करें, प्रतिक्रिया की जांच करें, उस प्रतिक्रिया के आधार पर एक कार्रवाई करें?

मैं कोड सीमित हूं (8-बिट माइक्रोकंट्रोलर होने के नाते!) और न्यूनतम पुनरावृत्ति को रखना चाहूंगा। मैं एक प्रतिक्रिया फ़ंक्शन कैसे लिख सकता हूं जो जीएसएम मॉड्यूल (अनुरोधित या अब) से प्रतिक्रिया लेगा और फिर मेरे बाकी कार्यक्रम को पता चलेगा कि क्या हो रहा है?

आदर्श रूप में, मैं उन प्रतिक्रियाओं के साथ कुछ करना चाहता हूं। जैसा एक आंतरिक स्थिति रखने के (जब मैं GPS Ready सुना है, मैं जानता हूँ कि मैं जीपीएस आदि संचालित कर सकती हैं

हो सकता है कि वहाँ कुछ चीजें मैं बारे में सोचना चाहिए, या हो सकता है एक खुला स्रोत परियोजना है कि पहले से ही इस समस्या का हल नहीं है कर रहे हैं?

यहाँ मैं अब तक है:।

/* Command responses */ 
enum { 
    // Common 
    OK = 0, 
    ERROR, 
    TIMEOUT, 
    OTHER, 
    // CGREG 
    NOT_REGISTERED, 
    // CGATT 
    NOT_ATTACHED, 
    // Network Status 
    NO_NETWORK, 
    // GPRS status 
    NO_ADDRESS, 
    // HTTP ACTION 
    NETWORK_ERROR, 
    // IP Stack State 
    IP_INITIAL, 
    IP_STATUS, 
    IP_CONFIG, 
    UDP_CLOSING, 
    UDP_CLOSED, 
    UDP_CONNECTING 
} gsmResponse; 

int gsm_sendCommand(const char * cmd) { 
    unsigned long timeout = timer_getCurrentTime() + 5000; 

    uart_clearb(GSM_UART); // Clear the input buffer 
    uart_puts(GSM_UART, cmd); // Send the command to the module 
    while (strstr(bf2, "\r") == NULL) { // Keep waiting for a response from the module 
     if (timeout < timer_getCurrentTime()) { // Check we haven't timed out yet 
      printf("Command timed out: %s\r\n", cmd); 
      return TIMEOUT; 
     } 
    } 
    timer_delay(100); // Let the rest of the response be received. 

    return OK; 
} 

int gsm_simpleCommand(const char * cmd) { 
    if (gsm_sendCommand(cmd) == TIMEOUT) 
     return TIMEOUT; 

    // Getting an ERROR response is quick, so if there is a response, this will be there 
    if (strstr(bf2, "ERROR") != NULL) 
     return ERROR; 

    // Sometimes the OK (meaning the command ran) can take a while 
    // As long as there wasn't an error, we can wait for the OK 
    while (strstr(bf2, "OK") == NULL); 
    return OK; 
} 

एक साधारण आदेश आदेश है कि विशेष रूप से जवाब में OK या ERROR की तलाश में है पर किसी भी AT तरह है लेकिन, मैं भी यह और अधिक उन्नत कमांड के लिए AT+CPIN? की तरह उपयोग करें, क्योंकि यह एम ईन्स मैं पूरी प्रतिक्रिया पर कब्जा कर लिया होगा, और आगे +CPIN: READY खोज सकते हैं। हालांकि, इनमें से कोई भी वास्तव में अनचाहे प्रतिक्रियाओं का जवाब नहीं देता है। वास्तव में, gsm_sendCommand() फ़ंक्शन प्रारंभिक रूप से वापस आ जाएगा जब अनचाहे प्रतिक्रिया प्राप्त होती है।

जटिल, कभी-कभी अनचाहे, स्थिति संदेश जैसे प्रबंधन का एक अच्छा तरीका क्या है? कृपया ध्यान दें कि यह एप्लिकेशन सी में लिखा गया है, और 8 बिट माइक्रोकंट्रोलर पर चलता है!

+1

आपको शायद एक राज्य मशीन (एफएसएम) लागू करना होगा: 'newstate = oldstate [message]', और हो सकता है कि दूसरे छोर को राज्य मशीन भी माना जाए। – wildplasser

+0

यह मेरा हिस्सा होगा जो मुझे लगता है। हालांकि, इस मामले में एक पूर्ण एफएसएम सबसे अच्छा विकल्प नहीं लगता है। मुझे एक सिस्टम के कई राज्यों की बजाय कुछ अलग अनचाहे कोडों की बाइनरी स्थिति को ट्रैक करने की आवश्यकता है। ट्रैक रखने के लिए मेरे पास बस कुछ वैश्विक बूलियन प्रकार होंगे। – dantheman

उत्तर

2

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

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

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

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

+0

यह जाने के लिए वास्तव में एक शानदार तरीका लगता है। मुझे इस मॉड्यूल के साथ पता है कि द्वितीयक सीरियल पोर्ट कमांड भेजने के लिए अच्छा नहीं है। अब तक, मैंने वास्तव में केवल 'जीपीएस तैयार' और '+ CGREG: 1' संदेश देखे हैं। मुझे पता है कि आप CGREG को अक्षम कर सकते हैं। मेरा पुराना कोड मतदान के लिए प्रयोग किया जाता था, और यह अच्छा था क्योंकि इसका मतलब था कि अगर मुझे अनचाहे प्रतिक्रिया याद आती है, तो मेरा कोड अभी भी इसके लिए इंतजार नहीं करेगा। – dantheman

+1

इसलिए जब मैं एक कतार को लागू करने के विचार पर उत्सुक नहीं हूं (जैसे कि काफी स्मृति सीमित अनुप्रयोग होने के कारण) अनचाहे प्रतिक्रियाओं को अक्षम करना पूरी तरह से संभव नहीं है। मैं बाधा डालने की संभावना के कारण सभी कमांड फ़ंक्शंस को प्रोसेसिंग क्षमता जोड़ने के विचार को नापसंद करता हूं ताकि कतार बहुत अधिक समझ में आती है। आपके उत्तर के लिए धन्यवाद! – dantheman

+1

@ डांथेमैन उम्मीद है कि आपकी कतार छोटी हो सकती है। यदि आप अपने 'gsm_sendCommand' को 'char * buf' और' size_t bufLen' के लिए अतिरिक्त पैरामीटर लेते हैं, तो आप शायद कतार में होने के लिए कतार की व्यवस्था कर सकते हैं। जिन कार्यों को 'gsm_sendCommand' कहते हैं, वे स्टैक पर एक अस्थायी बफर आवंटित कर सकते हैं, और' gsm_sendCommand' वापस लौटने के बाद, कतार को संसाधित करें। ऐसा करने के कई तरीके। –

संबंधित मुद्दे