3

我正在使用 Arduino 来控制 SM5100B GSM 设备,一切正常,除非我想在收到另一个短信后发送短信。我明白了,

错误代码:

OK > + CMGS:2 5 OK + CMEERROR:4

我处理上述收到的短信的代码:

     #include <SoftwareSerial.h>  //Include the NewSoftSerial library to send serial commands to the cellular module. 
        char inchar;                //Will hold the incoming character from the Serial Port. 
        SoftwareSerial cell(2,3); 
        char mobilenumber[] = "0597010129";
        void setup() { 
        //GSM
        Serial.begin(9600); // opens serial port, sets data rate to 9600 bps
        Serial.println("Initialize GSM module serial port for communication.");                       
        cell.begin(9600); 
        delay(35000); // give time for GSM module to register on network etc. 
        Serial.println("delay off");
        cell.println("AT+CMGF=1"); // set SMS mode to text 
        delay(200); 
        cell.println("AT+CNMI=3,3,0,0"); // set module to send SMS data to serial out upon receipt 
        delay(200); 
        } 



        void loop() {   

         if(cell.available() >0)//If a character comes in, from the cellular module
         { 
         inchar=cell.read(); 
         Serial.println(inchar); 
         if (inchar=='#'){ // OK - the start of our command 

           delay(10); 
           inchar=cell.read();
           Serial.println(inchar);  

             if (inchar=='a'){ 

               delay(10); 
               Serial.println("The folowing SMS : \n");
               inchar=cell.read();
               Serial.println(inchar); 

               if (inchar=='0'){ //sequance = #a0

                 Serial.println("#a0 was received"); 

             }
             else if (inchar=='1'){//sequance = #a1

                Serial.println("#a1 was received ");
                sendSms();

             }
         }
         cell.println("AT+CMGD=1,4");// AT command to delete all msgs
         Serial.println(" delete all SMS"); 
          } 
        }//end of  if(cell.available() >0) {...}
        }

        void sendSms(){
        //cell.println("AT+CMGF=1"); // set SMS mode to text 
        cell.print("AT+CMGS=");  // now send message... 
        cell.print((char)34); // ASCII equivalent of " 
        cell.print(mobilenumber); 
        cell.println((char)34);  // ASCII equivalent of " 
        delay(500); // give the module some thinking time 
        cell.print(":D hello m3alleg :D");   // our message to send 
        cell.println((char)26);  // ASCII equivalent of Ctrl-Z 
        delay(20000);
}
4

2 回答 2

16

关于处理 AT 命令的一般说明。

不不不!这种方法永远不会可靠地工作。在发送“要发送的文本”之前,您必须 等待接收到字符。>或者实际上不仅仅是>字符,它是四个字符。引自3GPP 规范 27.005

  • TA 应 <CR><LF><greater_than><space> 在命令行以 ; 终止后发送一个四字符序列(IRA 13、10、62、32)<CR>;之后,文本可以从 TE 输入到 ME/TA。

(这里的TA(终端适配器)是调制解调器,TE(终端设备)是AT命令的发送者)

对于任何可中止的 AT 命令(以及 27.005 明确说明 AT+CMGS This command should be abortable.),发送任何字符都将中止命令的操作。引用ITU V.250

5.6.1 中止命令

...

命令的中止是通过从 DTE 向 DCE 传输任何字符来完成的。

(这里的DCE(数据通信设备)是指调制解调器,DTE(数据终端设备)是AT命令的发送者)

这意味着当您在调制解调器发送“\r\n>”之前发送“要发送的文本”时,该命令将被中止。没有办法等待“足够长的时间”来期待响应被发送。您必须阅读并解析从调制解调器返回的响应文本。

这同样适用于每个命令之后的最终结果代码(例如OK, ERRORCME ERROR)。例如发送“AT+CMGF=1”然后发送下一个命令而不先等待OK是在乞求问题。所以总是在发送 AT 命令时,您必须等待最终结果代码,然后再发送下一个命令。

请永远,永远不要用于delay等待任何 AT 命令响应。它就像踢狗一样有用,以使它们移动。是的,它有时可能确实有效,但在某些时候你会为采取这种方法而感到抱歉......

回答你的问题。

根据您收到的回复,我可以看出您的问题不是命令中止(尽管您的解析存在如上所述的严重问题,您应该修复),CME ERROR 是您最好的线索。从 27.007 中的“9.2.1 一般错误”部分,它给出operation not supported了值 4 的描述。

27.005 指出:

如果在网络中发送失败或 ME 错误,则返回最终结果代码 +CMS ERROR:。

请注意,这是 +CMS ERROR 而不是 +CME ERROR,但它是适用的,见下文。

我猜想动作顺序如下:

SM100B GSM 调制解调器的 AT 命令处理部分接受短信数据并将其格式化为适当的格式,并将其发送到与 GSM 网络通信的调制解调器部分。它成功地将短信数据发送到网络,并将其报告回 AT 命令处理部分,然后打印+CMGS: 25和最终结果代码OK。然而,在很短的时间后,网络会发回一条拒绝短信的消息,然后作为 +CME ERROR 响应给出。

如果我上面的猜测是正确的,那么响应是否应该以 +CMS ERROR 的形式传递?不,因为 AT+CMGS 命令的最终响应已经给出(OK),并且不应该为一个命令返回多个最终结果代码(除非错误(注 1))。虽然+CME ERROR 可以替换ERROR 最终结果代码,但它不仅仅是最终结果代码。来自 AT+CMEE 命令说明:

设置命令禁用或启用结果代码 +CME ERROR:作为与 MT 功能相关的错误的指示。启用后,与 MT 相关的错误会导致 +CME ERROR: final result code 而不是常规的 ERROR 最终结果代码。当错误与语法、无效参数或 TA 功能有关时,通常会返回 ERROR。

因此,+CME ERROR 既可以是最终结果代码,也可以是未经请求的结果代码(也可能是中间结果代码)。

但是AT+CMGS命令不能等待收到网络拒绝并返回+CMS ERROR吗?可能不是。如果不了解短信发送的网络详细信息,今天的拒绝可能会比以前晚得多。这种变化有时会成为与 GSM 相关的 AT 命令的问题,这些 AT 命令具有最初与 GSM 行为紧密相关的旧传统,随着技术转向 GPRS、UMTS、LTE 等,这种行为有时变得越来越不真实。

注1:

我的一位前同事曾经抱怨标准指定语音呼叫处理的方式,因为在 ATD1234 之后;命令你首先得到最终结果代码 OK,然后当调用结束时你得到一个新的最终结果代码 NO CARRIER。这种糟糕的设计,呼叫结束指示应该是特定的主动响应,而不是最终响应。

所以总结一下

您的短信似乎被网络拒绝了。尝试找出原因。你的 AT 命令处理也有一些严重的问题,你应该修复;如果不从调制解调器读取和解析响应文本,就无法处理 AT 命令。

于 2013-03-23T20:25:41.377 回答
0
cell.println("AT+CNMI=3,3,0,0"); // set module to send SMS data to
serial out upon receipt

对于正在寻找相同问题的答案的任何人:

我试图通过发送短信将 gsm 模块从睡眠模式中唤醒,但它没有立即工作。电话直接发送到 UART,但对于短信,您必须使用此命令设置模块在收到短信数据时将短信数据发送到串口。

AT+CNMI=3,3,0,0

于 2016-07-13T20:09:41.727 回答