Sim900 + длинное смс
- Войдите на сайт для отправки комментариев
Была как то давно создана подобная тема и никто ничего не ответил.
Собственно, есть вот такой вот примерчик отсюда http://wiki.amperka.ru/%D0%B1%D0%B5%D1%81%D0%BF%D1%80%D0%BE%D0%B2%D0%BE%D0%B4%D0%BD%D0%B0%D1%8F-%D1%81%D0%B2%D1%8F%D0%B7%D1%8C:gprs-shield
#include <SoftwareSerial.h> SoftwareSerial gprsSerial(7, 8); //для зелёного светодиода будем использовать второй цифровой вход, //а для жёлтого - третий int greenPin = 2; int yellowPin = 3; void setup() { gprsSerial.begin(19200); pinMode(greenPin, OUTPUT); pinMode(yellowPin, OUTPUT); // Настраиваем приём сообщений с других устройств // Между командами даём время на их обработку gprsSerial.print("AT+CMGF=1\r"); delay(300); gprsSerial.print("AT+IFC=1, 1\r"); delay(300); gprsSerial.print("AT+CPBS=\"SM\"\r"); delay(300); gprsSerial.print("AT+CNMI=1,2,2,1,0\r"); delay(500); } String currStr = ""; // Переменная принимает значение True, если текущая строка является сообщением boolean isStringMessage = false; void loop() { if (!gprsSerial.available()) return; char currSymb = gprsSerial.read(); if ('\r' == currSymb) { if (isStringMessage) { //если текущая строка - SMS-сообщение, //отреагируем на него соответствующим образом if (!currStr.compareTo("Green on")) { digitalWrite(greenPin, HIGH); } else if (!currStr.compareTo("Green off")) { digitalWrite(greenPin, LOW); } else if (!currStr.compareTo("Yellow on")) { digitalWrite(yellowPin, HIGH); } else if (!currStr.compareTo("Yellow off")) { digitalWrite(yellowPin, LOW); } isStringMessage = false; } else { if (currStr.startsWith("+CMT")) { //если текущая строка начинается с "+CMT", //то следующая строка является сообщением isStringMessage = true; } } currStr = ""; } else if ('\n' != currSymb) { currStr += String(currSymb); } }
Читаем сериал GSM, собираем строку и отлавливаем по окончании строки флажок - СМС сообщение (+CMT)
Далее читаем продолжение этого самого смс сообщения...Но вот в чем проблема - Когда приходит первая часть смс в виде
+CMT: "+79999999999","NAME","16/01/28,00:36:38+24"
эта самая часть видимо умещается в 64 символа и все бы ничего, если бы вторая часть сообщения умещалась в эти же самые 64 символа. Не знаю почему, но модуль не умеет скорее всего принимать все 160 символов разрешенные на одну смс и пересылает 160 символов частями по 64...
Поэтому запустив данный пример и отослав просто сообщение длинной в 140 символов ничего кроме вышеупомянутой строки в монитере порта я не увидел. Отослав же сообщение длинной в 100 символов мы видим все красиво
+CMT: "+79999999999","NAME","16/01/28,00:36:38+24"
qwerty qwerty qwerty qwerty
Вопрос - каким образом можно собрать строку из этих частей оставшихся, если сообщение больше 64 символов?
Пробовал таким способом, непосредственно с вики
if (gprsSerial.available()) // if date is comming from softwareserial port ==> data is comming from gprs shield { while (gprsSerial.available()) // reading data into char array { bufGsm[countBufGsm++] = gprsSerial.read(); // writing data into array if (countBufGsm == 64) { break; } } Serial.write(buffer, count); clearBufferArray(); // call clearBufferArray function to clear the storaged data from the array countBufGsm = 0; // set counter of while loop to zero }
char bufGsm[64]; // buffer array for data recieve over serial port String inputGsmStr = ""; //входящая строка с gsm модема int countBufGsm = 0; void Manage() { if (gprsSerial.available()) // if date is comming from softwareserial port ==> data is comming from gprs shield { while (gprsSerial.available()) // reading data into char array { bufGsm[countBufGsm++] = gprsSerial.read(); // writing data into array if (countBufGsm == 64) { break; } } inputGsmStr += bufGsm; clearBufferArray(); // call clearBufferArray function to clear the storaged data from the array countBufGsm = 0; // set counter of while loop to zero } } void clearBufferArray() // function to clear buffer array { for (int i = 0; i < countBufGsm; i++) { bufGsm[i] = NULL; } }
Но выходит что каждый раз когда мы отрезаем часть по 64 и дописываем в строку, то в inputGsmStr записываются те самые части по 64, потом 128 и т.д..она растетпостоянно до тех пор пока не получим полную строку. В таком случае функция проверки, что это СМС сообщение запустится столько раз, сколько у нас частей по 64...
Какие идеи?
Отослав же сообщение длинной в 100 символов
Опечатался - не 100, а 60 символов...
Победил проблему, может кому и понадобится...
А смысл вот в чем. Как сказано выше gsm посылает любую смс - будь то одинарная или составная превышающая 160 для латиницы или 64 для кириллицы символов, частями по 64 символа...
Поэтому ваша смс придет в виде - заголовок + основное тело смс.
Основное тело смс может опять же состоять из нескольких строк, если встретился символ конца строки то его надо добавить в строку которую мы собираем и будем дальше анализировать.
Например пришла смс в виде
\r\n +CMT: "+79999999999","NAME","16/01/28,00:36:38+24" \r\n
1234567890 \n
Что произойдет? Сначала я собираю всю строку с заголовком и телом смс.
Далее бегу по каждому символу строки и собираю подстроку. Как только отлавливаю конец строки, дописываю кего в подстроку и получаю подстроку вида
+CMT: "+79999999999","NAME","16/01/28,00:36:38+24" \r\n
Анализирую то что в ней лежит и поднимаю флажок, что дальше будет тело самой СМС..
Бежим дальше по циклу, отловили опять конец строки - собрали новую подстроку вида
1234567890 \n
Соответственно флажок поднят и мы анализируем уже, то что лежит в теле самомй СМС - в моем случае подстрока состояла из нескольких строк, поэтому я внутри уже разбивал данную подстроку на отдельные строки...
Как то так.