Разбор ответов SIM-команд AT

Я использую экран модуля sim900 gps/gprs, подключенный к Arduino Uno, как я смогу проанализировать реакцию моих AT-команд? Или как я смогу удалить первую строку, напечатанную в сериале после отправки команды 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", а затем проанализировать оставшиеся данные, что является лучшим способом разбора

3 ответа

Решение

Как я смогу проанализировать ответ моих AT-команд?

Да, это правильный вопрос.

Как я смогу удалить первую строку, напечатанную в сериале после отправки AT-команды?

Нет, это неправильный вопрос, потому что, если вас волнует, включено ли эхо или нет, вы делаете это неправильно.

Правильная стратегия разбора выходных данных AT-команды следующая:

  • Отправить командную строку AT (правильно завершается с "\r").
  • Читайте один и один символ, полученный от модема, пока не закончите полную строку, оканчивающуюся на "\r\n" а затем разобрать эту строку.
    • Если строка равна окончательному коду результата, тогда весь вывод из командной строки завершен (и модем готов к приему новых команд). Это должно быть первое, что вы проверяете!
    • Если выполняющаяся AT-команда имеет префикс для своих информационных текстовых строк ответа (почти у всех есть), проверьте, начинается ли строка с этого, и, если это так, обработайте строку, иначе проигнорируйте ее.
    • Если запущенная AT-команда не имеет префикса, вы, вероятно, захотите распечатать все, пока не будет получен окончательный код результата. Это относится только к устаревшим командам, таким как ATI и для их анализа вы можете по праву заботиться об эхо или нет.

Теперь для AT+CMGL Команда это немного больше работы, так как ответы разбиты на несколько строк.

Во-первых, лучшим источником информации должна быть документация AT, относящаяся к конкретному производителю, а вторым - официальная спецификация 3GPP 27.005, которая стандартизирует AT+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>[...]]

следовательно, после получения строки, начинающейся с "+CMGL: ", все строки, следующие до тех пор, пока вы не прочитаете пустую строку ("\r\n"), принадлежат этому.

Посмотрите этот ответ об общей структуре кода и потоке, хотя, как написано выше, многострочное свойство ответа требует немного большей обработки. Я бы использовал что-то вроде следующего (непроверенный код):

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))

Первая строка AT+CMGL="ALL" похоже на эхо. Вы можете отключить его, отправив ATE0 к вашему модулю в вашем setup функция.

Что касается остальных данных, все они имеют одинаковый формат. Вы можете легко написать свой парсер, используя различные функции манипуляции со строками.

Если вы используете arduino Я бы порекомендовал использовать хорошую библиотеку! Вам не нужно разбираться с этими вещами. Попробуйте http://www.gsmlib.org/ или вы можете найти любой другой, который вам нравится.

Я приведу один пример здесь.

#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);
  }
};
Другие вопросы по тегам