SIM800L и нечитаемые символы

Тема в разделе "Arduino & Shields", создана пользователем obuhanoe, 9 авг 2016.

  1. sys

    sys Злобный Буратино Модератор

    А как быть с тем что пока не получен ответ на команду следующую отправлять не следует?
     
  2. DIYMan

    DIYMan Guest

    Вводить автоматное состояние, и всё. В минимале - флаг, что текущая команда обрабатывается, т.е. на неё ждётся ответ, и очередь команд на обработку, при этом следующая не посылается модему, пока не получен ответ с предыдущей. Выше я приводил ссылку на свои исходники работы с M590 - там как раз конечный автомат подобного рода.
     
  3. sys

    sys Злобный Буратино Модератор

    Я так и думал про очередь. Упустил как-то я пост со ссылочкой, а код там интересный, спасибо.
     
  4. obuhanoe

    obuhanoe Гик

    Правильно ли я понял в что переменной incomingBuffer будет содержаться первая строка ответа от модуля, а если нужно прочитать и сам текст(SMS), нужно тогда читать ответ модуля до конца, а не до '\n' ?

    Что-то не получается получить текст СМС, как его получить?
     
    Последнее редактирование: 24 авг 2016
  5. sys

    sys Злобный Буратино Модератор

    Собственно обработать следующую строку, если это не +CMTI
     
  6. obuhanoe

    obuhanoe Гик

    Если не затруднит, покажите как это сделать, у меня не получается почему-то
     
  7. sys

    sys Злобный Буратино Модератор

    Самый простой способ - добавьте флаг. И обрабатывайте его первым: если выставлен - значит строка из буфера содержит текст сообщения, обрабатываете, снимаете флаг; иначе - идем дальше к распознаванию.
    Соответственно при распознавании +CMT: выставляете флаг.
     
  8. obuhanoe

    obuhanoe Гик

    sys - А если СМС состоит из многих строчек, типа
    Код (C++):
    [conf1]
    ss=1
    ee=2
    Как определить где конец сообщения?
     
  9. DIYMan

    DIYMan Guest

    А вы читали описание +CMT ?
     
  10. sys

    sys Злобный Буратино Модератор

    http://wiki.amperka.ru/беспроводная-связь:gprs-shield

    Если точнее то http://wiki.amperka.ru/беспроводная-связь:gprs-shield#управление_светодиодами_с_помощью_sms

    Код там для вас не самый подходящий, но если описание поможет вам, то приложить знания к коду предложенному уважаемым DIYMan не должно составить труда.

    И неплохо бы было, чтоб вы пообщались с модемом напрямую в терминале/консоле/мониторе с помощью комманд и посмотрели как выглядят ответы вживую.
     
    Последнее редактирование: 25 авг 2016
  11. obuhanoe

    obuhanoe Гик

    Смотрю в SIM800 Series_AT Command Manual_V1.10
    команду AT+CMGR (AT+CMGR=1) и не вижу почему то у Response +CMT
    Я что не там смотрю?
     
  12. sys

    sys Злобный Буратино Модератор

    Потому что, это другое. То что вы посмотрели это команда прочтения СМС, и ответ у нее свой. А +CMT это ответ модема на факт прихода сообщения и вид его может отличаться в зависимости от настроек. Включите поиск по pdf там найдете форматы его.
     
  13. obuhanoe

    obuhanoe Гик

    Вроде бы нашел
    Код (C++):
    +CMT:
    <oa>,<scts>[,<tooa>,<fo>,<pi
    d>,<dcs>,<sca>,<tosca>,
    <length>]<CR><LF><data>
    <data> - это само СМС, а как понять что закончилось?
     
  14. sys

    sys Злобный Буратино Модератор

    В самом начале даташита описан формат ответа
    <CR><LF>RESPONSE<CR><LF>
     
  15. DIYMan

    DIYMan Guest

    А вам <length> ни о чём не намекает?
     
  16. DIYMan

    DIYMan Guest

    Так, давайте уже разберёмся с этими СМС. Есть два вида оповещения входящего СМС: сразу в порт (настраивается командой CNMI) и прочтение ранее сохранённого. Если сообщение по приходу кидается сразу в порт и не сохраняется, то в порту появляются строки вида +CMT....\r\nТутданные СМС. Строка, начинающаяся с +CMT, может содержать в себе длину сообщения, что идёт следом. Можно опираться на эту длину, можно - не опираться, например, если кодировка при работе с СМС - PDU, то достаточно тупо вычитать вторую строку, т.е. до символов \r\n, т.к. переводы строк в PDU тоже кодируются октетами.

    Если сообщение запрашивается из ранее сохранённых - надо смотреть формат ответа на эту команду у модема. В общем случае, подчеркну, в общем - достаточно вычитать две строки, в первой - ответ модема, во второй - само СМС. Если в СМС есть переводы строки - надо читать даташит, что он говорит по этому поводу. Мне это не особо актуально, т.к. юзаю исключительно PDU-кодировку.
     
    sys нравится это.
  17. sys

    sys Злобный Буратино Модератор

    Опыт - критерий истины. Ради эксперимента создайте массив и сохраняйте строки из буфера в него, затем пошлите себе смс и посмотрите что и как приходит.

    А так вроде выше DIYMan уже все разжевал.
     
  18. obuhanoe

    obuhanoe Гик

    Согласен, но когда ты сидишь на какой то проблемой и в упор не понимаешь почему не получается, это начинает раздражать.
    Вот смотрите - про СМС разжевали рассказали, показали - вот что получилось
    Код (C++):

    void ProcessIncomingBuffer()
    {
         
        if(head_at.startsWith("+CMT"))
        {
            // пришло СМС
            debug_log("InComing SMS");
            listen_sms();
        }
        else
        if(head_at.startsWith("+SAPBR: 1,3,\"0.0.0.0\""))
        {
            // пришёл статус соединения по GPRS    
            debug_log("ReConnecr GPRS");    
            init_gprs();
        }
       
       
        incomingBuffer = ""; // очищаем буфер, он нам не нужен больше
        head_at = "";
    }


    void read_buffer2(){  

         if (!Serial3.available())
            return;

        char currSymb = Serial3.read();  
        if ('\r' == currSymb) {
            if (isStringMessage) {
                //если текущая строка - SMS-сообщение,
                //отреагируем на него соответствующим образом
                incomingBuffer = currStr;
                ProcessIncomingBuffer();        
                isStringMessage = false;
            } else {
                if (currStr.startsWith("+CMT")) {
                    //если текущая строка начинается с "+CMT",
                    //то следующая строка является сообщением
                    isStringMessage = true;
                    head_at = currStr;
               
                 
                }
            }
       currStr = "";
         
        } else if ('\n' != currSymb) {
            currStr += String(currSymb);
        }
    }
    Тело и заголовок получается получать, но есть НО это СМС само падает в порт мне даже нигде его вызывать не надо, жду и вычитываю в loop.
    А если нужно в другом месте программе, сделать проверки и если нет соединения gprs - вызвать команду АТ - но в порт само уже не упадет, так как я это вызываю не loop, а в какой то другой функции.
    Сам работаю с БД(с различными) и проблем с представлением реализации почти никогда не бывает, а тут просто ступор. Расстраивает это (((.
     
  19. sys

    sys Злобный Буратино Модератор

    Ответы вы получаете в тот же буфер или я чегото не допонимаю... вам просто нужно будет ввести новые флаги и проверки. Выше DIYMan столько кода по ссылке выкатил с комментариями, что можно было бы и подглядеть ... Да и пост его повыше про обработку команд в очереди прочтите
     
    Последнее редактирование: 26 авг 2016
  20. obuhanoe

    obuhanoe Гик

    Согласен с Вами.
    Вроде переосмыслил Ваши слова и sys - вроде бы картина стала вырисовываться, нарисовал блок схему и хочу спросить правильно ли я Вас понял:
    и так в блоке loop крутится вычитывание буфера Sim800L и передается в ProcessIncomingBuffer, в котором у меня проверяется команды +CMT и +SAPBR.
    Если пришло СМС, то запускаю свою функцию которая записывает на СД пришедшее СМС и сразу посылает в порт проверку активности GPRS(+SAPBR), чтобы отправить лог действия на сайт и вываливается обратно в loop.
    Затем вычитываю +SAPBR (активно - ок, неактивно - поднимаю соединение ) и вызываю функцию отправки данных и обратно попадаю в loop.
    Правильный ход мыслей или опять не туда?

    Спасибо за терпение.:(