2016-04-25 23 views
1

私はsim900 gps/gprsモジュールシールドをArduino Unoに接続していますが、私のATコマンドの応答をどのように解析できるでしょうか?または、ATコマンドを送信した後、シリアルに印刷された1行目を削除するにはどうすればいいですか?上記の出力にSIM900 ATコマンド応答解析

AT+CMGL="ALL" 

+CMGL: 1,"REC READ","+XXXXXXXXXX","","16/04/25,15:20:59+32" 
Hilp akp si ralphh the pogi one mmalit mi pizza hehehehehe 

+CMGL: 2,"REC READ","+XXXXXXXXXX","","16/04/25,21:51:33+32" 
Yow!!! 

OK 

たとえば、私はAT + CMGL =「ALL」を取り除き、その後、残っているデータを解析取得したい、

答えて

5

私のATコマンドの応答をどのように解析することができますか?

はい、これは正しい質問です。

ATコマンドを送信した後、シリアルに印刷された1行目を削除するにはどうすればよいですか?

いいえ、エコーがオンかどうかを気にする場合は間違っているので、これは間違った質問です。

次のようにコマンドの出力で解析するための正しい戦略は次のとおりです。

  • (正しく"\r"で終了)、ATコマンドラインを送信します。
  • 完全な行が"\r\n"で終了するまで、モデムから受け取った1文字と1文字を読み取り、その行を解析します。
    • 行が最終結果コードと等しい場合、コマンドラインからのすべての出力が完了します(モデムは新しいコマンドを受信する準備ができています)。これはあなたがテストする最初のものでなければなりません!
    • ATコマンド実行時に、情報テキストの応答行(ほとんどすべてのもの)に接頭辞が付いていれば、その行が開始するかどうかを確認し、そうであれば行を処理します。
    • 実行中のATコマンドに接頭辞が付いていない場合は、最終結果コードが受信されるまですべてを印刷することをお勧めします。これは、ATIのようなレガシーコマンドにのみ適用され、これらの解析ではエコーについて正当な関心があるかもしれません。応答は複数行に分割されているので、それは少しより多くの仕事であるAT+CMGLコマンドの今

最初に、最良の情報源は、製造元固有のATドキュメントであり、次善策は、AT+CMGLコマンドを標準化する公式の3GPP 27.005仕様です。\ rを\あなたは(空白行を読むまで、次のすべての行を ":「+ CMGL」

テキストモードでAT + CMGLの応答は、したがって始まる行を受け取った後

+CMGL: <index>,<stat>,<oa/da>,[<alpha>],[<scts>][,<tooa/toda>, 
<length>]<CR><LF><data>[<CR><LF> 
+CMGL: <index>,<stat>,<da/oa>,[<alpha>],[<scts>][,<tooa/toda>, 
<length>]<CR><LF><data>[...]] 

として指定されていますn ")はこれに属します。

一般的なコード構造とフローについてはthis answerを参照してください。ただし、上記のように応答のマルチラインプロパティはもう少し処理する必要があります。私は、次の(未テストコード)のようなものを使用しているだろう:

enum CMGL_state { 
    CMGL_NONE, 
    CMGL_PREFIX, 
    CMGL_DATA 
}; 

// Extra prototype needed because of Arduino's auto-prototype generation which often breaks compilation when enums are used. 
enum CMGL_state parse_CMGL(enum CMGL_state state, String line); 
enum CMGL_state parse_CMGL(enum CMGL_state state, String line) 
{ 
    if (line.equals("\r\n") { 
     return CMGL_NONE; 
    } 
    if (line.startsWith("+CMGL: ") { 
     return CMGL_PREFIX; 
    } 
    if (state == CMGL_PREFIX || state == CMGL_DATA) { 
     return CMGL_DATA; 
    } 
    return CMGL_NONE; 
} 

... 

write_to_modem("AT+CMGL=\"ALL\"\r"); 
CMGL_state = CMGL_NONE; 
goto start; 
do { 
    CMGL_state = parse_CMGL(CMGL_state, line); 
    switch (CMGL_state) { 
    case CMGL_PREFIX: 
     process_prefix(line); // or whatever you want to do with this line 
     break; 
    case CMGL_DATA: 
     process_data(line); // or whatever you want to do with this line 
     break; 
    case CMGL_NONE: 
    default: 
     break; 
    } 
start: 
    line = read_line_from_modem(); 
} while (! is_final_result_code(line)) 
+0

これは多くのことを吸収するためのものです。この便利な情報に感謝しています。私はこれを完全に実装する能力に疑念を抱いています。私は初めてATコマンドと構文解析を扱っています。少し混乱しています..ありがとう! – Ralph

2

を解析における最良の方法何である最初の行AT+CMGL="ALL"は思わエコーになるこれを無効にするには、setup機能でモジュールにATE0を送信します。

残りのデータはすべて同じ形式です。さまざまな文字列操作関数を使用してパーサを簡単に書くことができます。

+0

神様ありがとうございます!私はすでに数日間、これらのエコーを削除する方法を探していたが、まだ私はデータを解析する方法を知らない、あなたは私に使用できる簡単な例を教えてくれますか? – Ralph

+0

@Ralphあなたはすでに2時間前に[Arduinoサイトで]あなたに与えた回答のようなものですか?(http://arduino.stackexchange.com/questions/23575/split-string-into-an-array-of-文字列)? – frarugi87

+0

@ frarugi87はい私は関数を呼び出すとき、パラメータは何なのか、なぜint 1を返すのか、文字の配列にシリアルを格納しようとすると、ランダムな文字が返されます。 'if(mySerial。 (バイトi = 0; i <99; i ++){ str [i] = mySerial.read(); Serial.print(str [i]); } } ' – Ralph

1

あなたがarduinoを使用している場合、私は良いライブラリを使用することをお勧めします!あなたはこれらのことに対処する必要はありません。試してくださいhttp://www.gsmlib.org/またはあなたのような他のあなたを見つけることができます。

ここに1つの例を示します。

#include "SIM900.h" 
#include <SoftwareSerial.h> 
//If not used, is better to exclude the HTTP library, 
//for RAM saving. 
//If your sketch reboots itself proprably you have finished, 
//your memory available. 
//#include "inetGSM.h" 

//If you want to use the Arduino functions to manage SMS, uncomment the lines below. 
#include "sms.h" 
SMSGSM sms; 

//To change pins for Software Serial, use the two lines in GSM.cpp. 

//GSM Shield for Arduino 
//www.open-electronics.org 
//this code is based on the example of Arduino Labs. 

//Simple sketch to send and receive SMS. 

int numdata; 
boolean started=false; 
char smsbuffer[160]; 
char n[20]; 

void setup() 
{ 
    //Serial connection. 
    Serial.begin(9600); 
    Serial.println("GSM Shield testing."); 
    //Start configuration of shield with baudrate. 
    //For http uses is raccomanded to use 4800 or slower. 
    if (gsm.begin(2400)){ 
    Serial.println("\nstatus=READY"); 
    started=true; 
    } 
    else Serial.println("\nstatus=IDLE"); 

    if(started){ 
    //Enable this two lines if you want to send an SMS. 
    //if (sms.SendSMS("3471234567", "Arduino SMS")) 
     //Serial.println("\nSMS sent OK"); 
    } 

}; 

void loop() 
{ 
    if(started){ 
    //Read if there are messages on SIM card and print them. 
    if(gsm.readSMS(smsbuffer, 160, n, 20)) 
    { 
     Serial.println(n); 
     Serial.println(smsbuffer); 
    } 
    delay(1000); 
    } 
};