Чтение СМС с GSM A6

dima744
dima744 аватар
Offline
Зарегистрирован: 27.09.2018

// код предназначен для работы с модулем A6 GSM
// код скопирован отсэда: http://arduino.ru/forum/programmirovanie/problema-s-softwareserial-i-gsm...
// вернее часть инициализации модема и первичного анализа-чтения содержимого смс
// Для правильной работы в компьютере выставляем скорость 9600 бод и NL&CR 
// запуск окна терминала ctrl+shift+m
#include <SoftwareSerial.h>

SoftwareSerial mySerial(7, 8); // RX, TX 7 нога ардуино подключена к U_TXD a6, 8 нога ардуины к U_RXD
boolean ok=false;
String str="";
//знаю слишком много памяти отжирают
String msg=""; 
String msg1="";
String msg2="";
//String msg2="";
//String SmsRecieveLong="";
int SmsRecieveLongInt=0;
String SmsRecieveNumber="";
String SmsRecieveMessege="";
char ch="";
int i=0;
int j=0;
//int a1=0;// a1-a3 в них будем писать цифры длины сообщения
//int a2=0;
//int a3=0;
//String ResponseA6="";
void setup() {
// пытаемся достучаться до модема на скорости 115200
Serial.begin(9600); // открываем порт для общения с компом
do{
  mySerial.begin(115200); // включаем myserial на скорости 115200
  delay(100);
  mySerial.println(F("ATZ+IPR=9600")); // команда модему о понижении скорости
  delay(500);
  mySerial.end(); // закрываем соединение
  delay(100);
  mySerial.begin(9600); // включаем myserial на скорости 9600
  delay(100);
  mySerial.println(F("ATE 0"));//отключаем эхо
  delay(100);
  mySerial.println(F("AT")); // проверка связи
  delay(100);
  str="";
  while(mySerial.available())
  {
    ch=mySerial.read(); //считываем ответ модема
    str+=ch;
    delay(10);
  }  
  if(str.indexOf(F("OK"))>-1) //молимся
    {
      ok=true;
      Serial.println(F("Получилось перевести скорость a6 на 9600")); // получилось
    }
else{
  mySerial.end();delay(500);ok=false;
  Serial.println(F("НЕ ПОЛУЧИЛОСЬ перевести скорость a6 на 9600"));}
}while(!ok);

// поперли настройки смс
 //AT+CMGF=1\r\n - установка текстового режима.
Serial.println(F("AT+CMGF=1 r n - установка текстового режима."));
mySerial.println(F("AT+CMGF=1"));     
delay(200);
//    str="";
    while(mySerial.available())
      {
        ch=mySerial.read();
        Serial.write(ch);
//        str+=ch;
        delay(5);
      }
//Serial.write(str);

  //AT+CNMI=2,1\r\n - разрешить индикацию получения SMS без вывода их содержимого.
Serial.println(F("AT+CNMI=2,1\r\n - разрешить индикацию получения SMS без вывода их содержимого."));
mySerial.println(F("AT+CNMI=2,1"));     
delay(200);
//    str="";

     while(mySerial.available())
      {
        ch=mySerial.read();
        Serial.write(ch);
//        str+=ch;
        delay(5);
      }

//AT+CPMS="SM","SM","SM"\r\n - память SIM для просмотра, написания и получения SMS.
// мой ответ от модема +CPMS: 3,15,3,15,3,15
// из мануала
// Response Success +CPMS: <used1>,<total1>,<used2>,<total2>,<used3>,<total3>
// mem1 memory from which messages are read and deleted
// mem2 memory to which writing and sending operations are made
// mem3 memory to which received SMs are preferred to be stored
Serial.println(F("AT+CPMS=SM,SM,SM r n - память SIM для просмотра, написания и получения SMS."));
mySerial.println(F("AT+CPMS=\"SM\",\"SM\",\"SM\""));   
delay(200);
while(mySerial.available())
      {
        ch=mySerial.read();
        Serial.write(ch);
//        str+=ch;
        delay(5);
      }

//AT+CSDH=1\r\n - разрешить отображение заголовков SMS сообщений (не обязательно).
Serial.println(F("AT+CSDH=1 r n - разрешить отображение заголовков SMS сообщений (не обязательно)."));
mySerial.println(F("AT+CSDH=1"));     
delay(200);
//    str="";
    while(mySerial.available())
      {
        ch=mySerial.read();
        Serial.write(ch);
//        str+=ch;
        delay(5);
      }


// проверка качества связи AT+CSQ
/* результат два числа, через запятую.
Первое число - уровень сигнала от 0 (менее -113 дБм) до 31 (более -51 дБм).
Второе число - частота появления ошибок от 0 до 7 (GSM 05.08).
Значение 99 означает что указанный параметр неизвестен или не определяется.
пример ответа
------------
20:13:17.030 -> +CSQ: 17,99
20:13:17.030 -> 
20:13:17.030 -> OK
------------
*/
Serial.println(F("Запрос уровня сигнала GSM сети  AT+CSQ пример ответа +CSQ: 17,99 где цифра 17 показывает уровень сигнала от 0 до 31"));
mySerial.println(F("AT+CSQ"));
delay(100);
i=0;
str="";
Serial.println(F("для чтения 1-ой смс надо ввести AT+CMGR=1 "));
}

void loop() {
 /* смс с ячейки 1 по запросу AT+CMGR=1 с компьютера
-------------------------------
    AT+CMGR=1
13:53:02.364 -> +CMGR: "REC READ","+79778032045",,"2018/11/09,06:47:15+03",145,17,0,0,"+79043490000",145,7 - 1я строка её впоследствии введем в msg1
13:53:02.411 -> Test145  2я строка её впоследствии введем в msg2
13:53:02.411 -> 
13:53:02.411 -> OK

-------------------------------
+79778032045 отправитель СМС
1-я строка последняя цифра 7 - это длина сообщения
2-я строка текст "Test145" это текст сообщения
 приход смс
 -------------------------------
13:55:17.261 -> +CIEV: "MESSAGE",1
13:55:17.261 -> 
13:55:17.261 -> +CMTI: "SM",3
-------------------------------
  */

    // чтение СМС из ячейки 1 происходит при отправке комманды  AT+CMGR=1 с компьютера

     //  чтение инфы с компа

    
    if (Serial.available())                 //  чтение инфы с компа
    mySerial.write(Serial.read());       // и передача в a6 через softwareserial

    //Начало анализа ответа a6
    while (mySerial.available())              //чтение инфы от A6
      {
        delay(2);  //маленькая задержка иначе не вся строка собирается
        ch=mySerial.read();
        str +=char(ch);
      }
      Serial.print(str); // печатаем для проверки на экран компа целиком строку ответа a6

      // это первоначальная проверка если отправить смс с левого телефона
      // в тексте которого будет указан номер телефона владельца, то проверка прокатит
      // думайте сами решайте сами
      //а не смс ли это?
      if (str.indexOf("CMGR") > -1)  //проверим СМС ли это, если СМС пишем её в переменную msg
        {
          
     
          Serial.println(F("sms")); //точно sms

 //          упрошенная проверка от кого sms
 //         if (str.indexOf("+79778032045") > -1)
 //          {
 //             Serial.println("sms from me"); //sms-ка то от меня
              //Serial.print(str);
              msg=str; // копирование строки в переменную msg для дальнейшего анализа
              str="";  // чистим str иначе беда будет при дальнейшей работе в loop         
//           }
   
       }
       
       str="";   // чистим str иначе беда будет при дальнейшей работе в loop хотя и сделал это строкой выше отладка млять

//       msg=str; // удалить эту строку при упрощенной проверке sms
//       }
       
       //анализ строки msg на предмет текста смс и уточнения номера писателя
       //стараюсь определить на каком месте стоит   символ перевода каретки
        if (msg!="")
          {
           // Serial.println("сообщение msg целиком");
           // Serial.println(msg);
            i=msg.indexOf('\n',2); //ищем первый от начала перевод строки
        
            //Serial.print("номер позиции в которой стоит символ перевода строки ");
            //Serial.println(i);
            msg1="";
              //делаем msg1 состояший из первых i символов msg те 1-я строка смс ниже пример строки
              // где +79778032045 номер отправителя
              //13:53:02.364 -> +CMGR: "REC READ","+79778032045",,"2018/11/09,06:47:15+03",145,17,0,0,"+79043490000",145,7
                for (j=2; j < (i-1); j++)
                  {
                  msg1+=msg.charAt(j);
                  }
           //   Serial.print("msg1=");
           //   Serial.println(msg1);
                  //делаем msg2 это 2-я строка смс и текст sms

                  //msg2 это текст sms
              msg2="";
              //Serial.print("номер ПОСЛЕДНЕЙ позиции в которой стоит символ перевода строки ");
              //Serial.println(msg.lastIndexOf('\n'));
              //формируем строку текста (msg2) смс из текста между первым и последним переводом каретки
              for (j=i+1; j < (msg.lastIndexOf('\n')-1); j++)
                {
                msg2+=msg.charAt(j);  
                }  
              msg2.replace('OK \n',' ');
              //Serial.print("msg2=");
              //Serial.println(msg2);
              // работаем с текстом msg1: ищем отправителя и длину сообщения
              //Вычленяем из msg номер отправителя и кол-во символов в сообщении
              // пишем в переменные:
              // String SmsRecieveLong="";
              //int SmsRecieveLongInt=0;
              //String SmsRecieveNumber="";
              
              // для начала определим номер отправителя для чего найдем в сообщении номер символа "+7"
              i=msg1.indexOf("+7",2);
              //Serial.print("номер символа после которого стоит +7 =");
              //Serial.println(i);
              
              SmsRecieveNumber="";
              for (j=i+2; j < (i+2+12); j++)
                {
                SmsRecieveNumber+=msg.charAt(j);
                }  
              Serial.print("номер телефона отправителя sms вида string");
              Serial.print(SmsRecieveNumber); 
              Serial.println("-");
              
              // определим длину сообщения это последние 1,2 или 3 цифры в сообщении
              j=msg1.lastIndexOf(",")+1;
              //Serial.print("номер символа где стоит длина сообщения=");
              //Serial.println(j);
              //Serial.print("обшая длина сообщая длина сообщения=");
              //Serial.println(msg1.length());
            
              if (msg1.length()<=(j+3)) {i=3;}    //то длина сообщения от 100 символов соответственно SmsRecieveLongInt это сотни
              if (msg1.length()<=(j+2)) {i=2;}    //то длина сообщения от 10 до 100 символов соответственно SmsRecieveLongInt1 это десятки
              if (msg1.length()<=(j+1)) {i=1;}    //то длина сообщения от 0 до 9 символов соответственно SmsRecieveLongInt это единицы
              //Serial.print("i=");Serial.println(i);
              // str.toInt(); переводит string в число, но корректно у меня получилось только если в числе один знак
              switch (i) {
                          case 1:
                          //SmsRecieveLongInt=atoi(msg1.charAt(j));
                          str=msg1.charAt(j);
                 //         Serial.println(str.toInt());
                          SmsRecieveLongInt=str.toInt();
                //          Serial.println("case 1");
                          break;
                          case 2:
                          str=msg1.charAt(j);
                          SmsRecieveLongInt=10*str.toInt();
                          str=msg1.charAt(j+1);
                          SmsRecieveLongInt=SmsRecieveLongInt+str.toInt();
                          //Serial.println("case 2");
                          break;
                          case 3:
                          str=msg1.charAt(j);
                          SmsRecieveLongInt=100*str.toInt();
                          str=msg1.charAt(j+1);
                          SmsRecieveLongInt=SmsRecieveLongInt+10*str.toInt();
                          str=msg1.charAt(j+2);
                          SmsRecieveLongInt=SmsRecieveLongInt+str.toInt();
                         // Serial.println("case 3");
                          break;
                          }
              Serial.print("Длина текста сообщения SmsRecieveLongInt=");
              Serial.println(SmsRecieveLongInt);
              //Serial.print("Str=");
              //поместим текст сообщения в переменную SmsRecieveMessege
              /*
              Serial.print("Текст СМС(msg2)=");
              Serial.print(msg2);
              Serial.println("-");
              */
              SmsRecieveMessege="";
                for (i=0; i<(SmsRecieveLongInt+1); i++)            
                {
                 SmsRecieveMessege=SmsRecieveMessege+msg2.charAt(i);
                }
               Serial.print("Текст СМС(SmsRecieveMessege)=");
               Serial.print(SmsRecieveMessege);
               Serial.println("-");
            msg="";
            msg2="";
            msg1="";
            str="";
            SmsRecieveLongInt=0; 
            i=0; 
            j=0;
            //почистить переменные
            // данные на выходе SmsRecieveMessege SmsRecieveMessege
           }
           
                
           
          
}

 

dima744
dima744 аватар
Offline
Зарегистрирован: 27.09.2018

Всем доброго времени суток!

стал счастливым обладателем модуля A6, к сожалению рабочих, готовых библиотек найти не удалось

основываясь на теме http://arduino.ru/forum/programmirovanie/problema-s-softwareserial-i-gsm-modulem-a6?page=1 написал код чтения СМС вроде как все работает

в програмировании я новичок буду сильно благодарен, если ткнете меня носиком в мои ошибки

 

ps код работает, до тех пор пока не переполнится память сообщений смс чистить надо вручную AT коммандой так же как и давать запрос на чтение смс

 

b707
Offline
Зарегистрирован: 26.05.2017

dima744 пишет:

Всем доброго времени суток!

стал счастливым обладателем модуля A6, к сожалению рабочих, готовых библиотек найти не удалось

 

для А6 библиотек не встречал, зато их полно для SIM800/900 . Поскольку АТ-команды для разных модемов практически совпадают, то можно взять готовую библиотеку для SIM и чуть подправить. Думаю, это будет проще, чем писать свое совсем с нуля.