Чтение СМС с GSM A6
- Войдите на сайт для отправки комментариев
Вс, 11/11/2018 - 19:46
// код предназначен для работы с модулем 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 } }
Всем доброго времени суток!
стал счастливым обладателем модуля A6, к сожалению рабочих, готовых библиотек найти не удалось
основываясь на теме http://arduino.ru/forum/programmirovanie/problema-s-softwareserial-i-gsm-modulem-a6?page=1 написал код чтения СМС вроде как все работает
в програмировании я новичок буду сильно благодарен, если ткнете меня носиком в мои ошибки
ps код работает, до тех пор пока не переполнится память сообщений смс чистить надо вручную AT коммандой так же как и давать запрос на чтение смс
Всем доброго времени суток!
стал счастливым обладателем модуля A6, к сожалению рабочих, готовых библиотек найти не удалось
для А6 библиотек не встречал, зато их полно для SIM800/900 . Поскольку АТ-команды для разных модемов практически совпадают, то можно взять готовую библиотеку для SIM и чуть подправить. Думаю, это будет проще, чем писать свое совсем с нуля.