sim900 отправка больших СМС на русском в PDU формате

volodya3d
Offline
Зарегистрирован: 09.09.2020
Приветсвую. 
Приобрел модуль SIM900. Хочу отправлять смс с ардуино на русском языке. Причем возможно будут очень большие СМС.
подключил все по этой схеме. 
 
запитал от БП 5В 3А
 
В основном отталкивался от статьи https://codius.ru/articles/GSM_модуль_SIM800L_часть_3
 
приведу часть кода 
для сообщения на номер 79209996677, сообщение "Здравстуй. Я помню чудное мнгоновенье передо мной явилась ты, как 1234".
 
void sendSMSinPDU()
{
  String PDUPack = "0001000B919702996976F700088C041704340440043004320441044204430439002E0020042F0020043F043E043C043D044E0020044704430434043D043E04350020043C043D0433043E043D043E04320435043D044C04350020043F0435044004350434043E0020043C043D043E04390020044F04320438043B04300441044C00200442044B002C0020043A0430043A00200031003200330034" + (String)((char)26); // После PDU-пакета отправляем Ctrl+Z
  
  sendATCommand("AT+CMGF=0", true);               // Включаем PDU-режим
  sendATCommand("AT+CMGS=153", true);             // Отправляем длину PDU-пакета
  sendATCommand(PDUPack, true);      
}
 
При этом при таком длинном сообщении - оно никак не отправляется, а сам модуль sim900 наглухо зависает и не отвечает ни на какие команда например даже на "АТ"
 
 -- если же отправить что нибудь маленькое например
 
для сообщения на номер 79209996677, сообщение "Здравстуй.".
void sendSMSinPDU()
{
  String PDUPack = "0001000B919702996976F7000814041704340440043004320441044204430439002E" + (String)((char)26); // После PDU-пакета отправляем Ctrl+Z
  
  sendATCommand("AT+CMGF=0", true);               // Включаем PDU-режим
  sendATCommand("AT+CMGS=33", true);             // Отправляем длину PDU-пакета
  sendATCommand(PDUPack, true);      
}
 -- Все прекрасно отправляется и доставляется.
 
Ниже привел часть кода с спомощью которого отправляются АТ команды в Сим900 опять же скопипастенные из статьи
String sendATCommand(String cmd, bool waiting) {
  String _resp = "";                            // Переменная для хранения результата
  //Serial.println(cmd);                          // Дублируем команду в монитор порта
  SIM900.println(cmd);                          // Отправляем команду модулю
  if (waiting) {                                // Если необходимо дождаться ответа...
    _resp = waitResponse();                     // ... ждем, когда будет передан ответ
    // Если Echo Mode выключен (ATE0), то эти 3 строки можно закомментировать
    if (_resp.startsWith(cmd)) {                // Убираем из ответа дублирующуюся команду
      _resp = _resp.substring(_resp.indexOf("\r", cmd.length()) + 2);
    }
    Serial.println(_resp);                      // Дублируем ответ в монитор порта
  }
  return _resp;                                 // Возвращаем результат. Пусто, если проблема
}

String waitResponse() {                         // Функция ожидания ответа и возврата полученного результата
  String _resp = "";                            // Переменная для хранения результата
  long _timeout = millis() + 10000;             // Переменная для отслеживания таймаута (10 секунд)
  while (!SIM900.available() && millis() < _timeout)  {}; // Ждем ответа 10 секунд, если пришел ответ или наступил таймаут, то...
  if (SIM900.available()) {                     // Если есть, что считывать...
    _resp = SIM900.readString();                // ... считываем и запоминаем
  }
  else {                                        // Если пришел таймаут, то...
    Serial.println("Timeout...");               // ... оповещаем об этом и...
  }
  return _resp;                                 // ... возвращаем результат. Пусто, если проблема
}
 
Сам я грешу либо на скороть обмена с модулем сим 900, либо на питание модуля сим 900, либо на неисправность самой платы. 
 
Подскажите пожалуйста - как думаете вы - а почему не отправляюстя большие смс ? в каком направлении капать ? 
b707
Offline
Зарегистрирован: 26.05.2017

ваще-то по стандарту максимальная длина СМС - 140 символов, а у вас 153

volodya3d пишет:

Сам я грешу либо на скороть обмена с модулем сим 900, либо на питание модуля сим 900, либо на неисправность самой платы.

интересно мыслите. Какая из этих трех причин может обьяснить. что короткие СМС уходят, а длинные нет? :) скорость обмена? - really??

volodya3d
Offline
Зарегистрирован: 09.09.2020

b707 пишет:
интересно мыслите. Какая из этих трех причин может обьяснить. что короткие СМС уходят, а длинные нет? :) скорость обмена? - really??

- Я подумал что типа не справляется буфер обмена или сам контроллер модуля - то есть ему сложно переварить много информации ... Каюсь был не прав ... плохо знаю мат часть ... каюсь ...

b707 пишет:
140 символов

- как я понял это длина pdu пакета в байтах - без претензий и понтов книжного червя - просто чтобы быть точным. 

b707 пишет:
ваще-то по стандарту максимальная длина СМС - 140 символов, а у вас 153

- просто я на другом языке в примере видел как передавали 154 символа/байта (модему правда а не модулю сим 900). поэтому подумал что здесь так же - типа это стандарт - подумал я.

--- (и главный вопрос который хотел задать в теме но не подношел к нему)

--- подскажите пожалуйста - а как тогда быть если если длина всего сообщения больше 140 символа/байта - разделить все сообщение так чтобы был один полный pdu пакет на 140 cимволов/байт - а в оставшийся запихнуть остаток сообщения ? так ? просто как модуль поймет что это все одно сообщение - и не пошлет 2а разных сообщения ??? есть какой то спец знак ??? 

--- Объясните пожалуйста буду очень благодарен !!!

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

Откройте уже в поисковике PDU формат, там все расписано почему именно столько букв за раз можно отправлять.

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

Фраза понравилась в одной из статей :)
PDU-режим придумали извращенцы-мозгофилы.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

volodya3d пишет:

--- подскажите пожалуйста - а как тогда быть если если длина всего сообщения больше 140 символа/байта - разделить все сообщение так чтобы был один полный pdu пакет на 140 cимволов/байт - а в оставшийся запихнуть остаток сообщения ? так ? просто как модуль поймет что это все одно сообщение - и не пошлет 2а разных сообщения ??? есть какой то спец знак ??? 

--- Объясните пожалуйста буду очень благодарен !!!

Формат PDU имеет специальные средства для отправки смсок из кусков. Принимающая сторона их склеит (если правильно формат PDU обрабатывает). Читайте описание формата - оно много где описано.

Также можете посмотреть готовую программу чтения русских и длинных смс от нашего коллеги (не ленились бы поиск жамкнуть - сами нашли бы).

volodya3d
Offline
Зарегистрирован: 09.09.2020

andycat пишет:
Фраза понравилась в одной из статей :) PDU-режим придумали извращенцы-мозгофилы.

- Бл... это точно, я себе весь мозг вынес ...

ЕвгенийП пишет:
Формат PDU имеет специальные средства для отправки смсок из кусков. Принимающая сторона их склеит (если правильно формат PDU обрабатывает). Читайте описание формата - оно много где описано.

Также можете посмотреть готовую программу чтения русских и длинных смс от нашего коллеги (не ленились бы поиск жамкнуть - сами нашли бы).

- Да я посмотрел и в целом принцып склейки сообщения понял. Я не ленюсь, честно не нашел. Сильно не пинайте - я же новичек (не газ конечно). Хотел бы все же сам разобраться в чем я не прав …

andycat пишет:
Откройте уже в поисковике PDU формат, там все расписано почему именно столько букв за раз можно отправлять.

- читал здесь далее буду ссылаться на этот источник ...

http://hardisoft.ru/soft/samodelkin-soft/otpravka-dlinnyx-sms-soobshhenij-v-formate-pdu/

b707 пишет:
ваще-то по стандарту максимальная длина СМС - 140 символов, а у вас 153

еще раз возвращусь к коментарию Комрада выше. Мне все же удалось отправить сообщение длиной pdu пакета 141 байт.

отправлял сообщение свой телефон, в примере +79209996677 - текст "ААААААААААббббббббббВВВВВВВВВВггггггггггДДДДДДДДДДЕЕЕЕЕЕЕЕЕЕжжжж" - блоки по 10 букв. жжжж – 4, соощение успешно пришло

ПДУ пакет

0001000B919702996976F70008800410041004100410041004100410041004100410043104310431043104310431043104310431043104120412041204120412041204120412041204120433043304330433043304330433043304330433041404140414041404140414041404140414041404150415041504150415041504150415041504150436043604360436

вот код


  String PDUPack = "0001000B919702996976F70008800410041004100410041004100410041004100410043104310431043104310431043104310431043104120412041204120412041204120412041204120433043304330433043304330433043304330433041404140414041404140414041404140414041404150415041504150415041504150415041504150436043604360436" + (String)((char)26); // После PDU-пакета отправляем Ctrl+Z
  
  sendATCommand("AT+CMGF=0", true);                        // Включаем PDU-режим
  sendATCommand("AT+CMGS=141", true);             // Отправляем длину PDU-пакета
  sendATCommand(PDUPack, true);

в статье которую я привел написано

На текст сообщения отводится всего 140 байт. Соответственно, в ASCII кодировке мы можем отправить всего 160 символов (за счет 7-битной кодировки), а в USC-2 всего 70

Подскажите пожалуйста

--- правильно ли я понимаю что я могу разбить смс сообщение не обязательно на максимально большие PDU пакеты – То есть я могу части сообщения уходили и PDU пакетом 120 байт например – ГЛАВНОЕ чтобы соблюдался принцып построения PDU пакета. Все верно ???

Для того же примера что и выше "ААААААААААббббббббббВВВВВВВВВВггггггггггДДДДДДДДДДЕЕЕЕЕЕЕЕЕЕжжжж" я создал 2 PDU пакета

1ый раз 140 и 26 байт

0041000B919702996976F700087F050003FF020104100410041004100410041004100410041004100431043104310431043104310431043104310431041204120412041204120412041204120412041204330433043304330433043304330433043304330414041404140414041404140414041404140414041504150415041504150415041504150415041504

И

0041010B919702996976F700080D050003FF020236043604360436

Код использовал вот такой

  sendATCommand("AT+CMGF=0", true);                        // Включаем PDU-режим
  sendATCommand("AT+CMGS=140", true);             // Отправляем длину PDU-пакета
  sendATCommand(PDUPack1, true);
  AnalizeResponseSMS();  // 
  sendATCommand("AT+CMGS=26", true);             // Отправляем длину PDU-пакета
  sendATCommand(PDUPack2, true);

- Процедура AnalizeResponseSMS  ждет ответа о отправке смс вида (+CMGS: 99) и только затем выполняем команды ниже.

В результате СМС не отправилась. (((

2ой раз 114 и 52 байта

0041000B919702996976F7000865050003FF02010410041004100410041004100410041004100410043104310431043104310431043104310431043104120412041204120412041204120412041204120433043304330433043304330433043304330433041404140414041404140414041404

0041010B919702996976F7000827050003FF0202140414041404150415041504150415041504150415041504150436043604360436

При этом на первую смс получил заветную +CMGS, на вторую ничего не получил, смс не отпрвавилась.

 

Для первых PDU пакетов

0041000B919702996976F7000865050003FF0201

41 — PDU-Type, 00 – TP-MR (так было сказано в статье, для второго было сказано бери 01 итд), 65— TP-UDL (посчитал программно),

050003FF0201   – UDH: 05 – общая длина UDH, 0003 – идентификатор и длина IE, FF – случайный reference number, 02 – всего 2 сообщения, 01 – это первое сообщение.

Что я делаю неправильно подскажите пожалуйста ???

Если есть возможность дайте пример 2ух pdu пакетов которые написаны верно (прошу пожалуйста без поля VP Времени жизни СМС, и прошу пожалуйста напишите в текстовом формате полное сообщение) - я думаю я бы сразу разобрался как отправлять если скинете ...

Спасибо если поможете.

 

 

 

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

ну очень не хочется опять вникать в эту белиберду :(

попробуйте разобраться в этой функции отправки. Входная строка smsmsg в кодировке WIN1251 должна быть. Длинные СМС не поддерживаются, если я правильно понял - просто в каком то служебном поле отсылается сколько частей длинной СМС и какая это конкретная часть отправляется.

void sendSMS() {
  // convert msg to pdu format
  byte lenTextByChar = strlen(smsmsg);
  // move text to end buf
  byte i, j;
  for (i = 0; i < lenTextByChar; ++i) {
    smsmsg[max_len_sms - lenTextByChar + i] = smsmsg[i];
  }
  byte curr_pos_pdu = 0;
  smsmsg[curr_pos_pdu] = '0'; ++curr_pos_pdu; smsmsg[curr_pos_pdu] = '0'; ++curr_pos_pdu; // SCA field
  smsmsg[curr_pos_pdu] = '0'; ++curr_pos_pdu; smsmsg[curr_pos_pdu] = '1'; ++curr_pos_pdu; // PDU type
  smsmsg[curr_pos_pdu] = '0'; ++curr_pos_pdu; smsmsg[curr_pos_pdu] = '0'; ++curr_pos_pdu; // MR
  byte lenSenderPhone = strlen(sender);
  if (lenSenderPhone != 12) return;
  smsmsg[curr_pos_pdu] = '0'; ++curr_pos_pdu; smsmsg[curr_pos_pdu] = 'B'; ++curr_pos_pdu; // DA-PL
  smsmsg[curr_pos_pdu] = '9'; ++curr_pos_pdu; smsmsg[curr_pos_pdu] = '1'; ++curr_pos_pdu; // DA-PT
  // convert sender number
  for (i = 0; i < lenSenderPhone; ++i) {
    sender[i] = sender[i + 1];
  }
  sender[lenSenderPhone - 1] = 'F'; sender[lenSenderPhone] = 0;
  for (i = 0; i < lenSenderPhone; i += 2) {
    j = sender[i + 1];
    sender[i + 1] = sender[i];
    sender[i] = j;
  }
  for (i = 0; i < lenSenderPhone; ++i) { // DA-RP
    smsmsg[curr_pos_pdu] = sender[i];
    ++curr_pos_pdu;
  }
  smsmsg[curr_pos_pdu] = '0'; ++curr_pos_pdu; smsmsg[curr_pos_pdu] = '0'; ++curr_pos_pdu; // PID field
  smsmsg[curr_pos_pdu] = '0'; ++curr_pos_pdu; smsmsg[curr_pos_pdu] = '8'; ++curr_pos_pdu; // DCS field
  lenTextByChar *= 2; // UDL
  byte bb = lenTextByChar / 16;
  if (bb < 10) {
    smsmsg[curr_pos_pdu] = (bb + '0'); ++curr_pos_pdu;
  } else {
    smsmsg[curr_pos_pdu] = (bb + '0' + 7); ++curr_pos_pdu;
  }
  bb = lenTextByChar % 16;
  if (bb < 10) {
    smsmsg[curr_pos_pdu] = (bb + '0'); ++curr_pos_pdu;
  } else {
    smsmsg[curr_pos_pdu] = (bb + '0' + 7); ++curr_pos_pdu;
  }
  // UD - text by UCS2
  for (i = 0; i < (lenTextByChar / 2); ++i) {
    bb = smsmsg[max_len_sms - (lenTextByChar / 2) + i];
    if (bb < 0x7F) {
      smsmsg[curr_pos_pdu] = '0'; ++curr_pos_pdu; smsmsg[curr_pos_pdu] = '0'; ++curr_pos_pdu;
      // convert to hex
      j = bb / 16;
      if (j < 10) {
        smsmsg[curr_pos_pdu] = (j + '0'); ++curr_pos_pdu;
      } else {
        smsmsg[curr_pos_pdu] = (j + '0' + 7); ++curr_pos_pdu;
      }
      j = bb % 16;
      if (j < 10) {
        smsmsg[curr_pos_pdu] = (j + '0'); ++curr_pos_pdu;
      } else {
        smsmsg[curr_pos_pdu] = (j + '0' + 7); ++curr_pos_pdu;
      }
    } else {
      switch (bb) {
        case 168: {
            smsmsg[curr_pos_pdu] = '0'; ++curr_pos_pdu; smsmsg[curr_pos_pdu] = '4'; ++curr_pos_pdu;
            smsmsg[curr_pos_pdu] = '0'; ++curr_pos_pdu; smsmsg[curr_pos_pdu] = '1'; ++curr_pos_pdu;
            break;
          }
        case 184: {
            smsmsg[curr_pos_pdu] = '0'; ++curr_pos_pdu; smsmsg[curr_pos_pdu] = '4'; ++curr_pos_pdu;
            smsmsg[curr_pos_pdu] = '5'; ++curr_pos_pdu; smsmsg[curr_pos_pdu] = '1'; ++curr_pos_pdu;
            break;
          }
        default: {
            if (bb < 192) {
              smsmsg[curr_pos_pdu] = '0'; ++curr_pos_pdu; smsmsg[curr_pos_pdu] = '0'; ++curr_pos_pdu;
              // convert to hex
              j = bb / 16;
              if (j < 10) {
                smsmsg[curr_pos_pdu] = (j + '0'); ++curr_pos_pdu;
              } else {
                smsmsg[curr_pos_pdu] = (j + '0' + 7); ++curr_pos_pdu;
              }
              j = bb % 16;
              if (j < 10) {
                smsmsg[curr_pos_pdu] = (j + '0'); ++curr_pos_pdu;
              } else {
                smsmsg[curr_pos_pdu] = (j + '0' + 7); ++curr_pos_pdu;
              }
            } else {
              smsmsg[curr_pos_pdu] = '0'; ++curr_pos_pdu; smsmsg[curr_pos_pdu] = '4'; ++curr_pos_pdu;
              // convert to hex
              j = (bb - 176) / 16;
              if (j < 10) {
                smsmsg[curr_pos_pdu] = (j + '0'); ++curr_pos_pdu;
              } else {
                smsmsg[curr_pos_pdu] = (j + '0' + 7); ++curr_pos_pdu;
              }
              j = (bb - 176) % 16;
              if (j < 10) {
                smsmsg[curr_pos_pdu] = (j + '0'); ++curr_pos_pdu;
              } else {
                smsmsg[curr_pos_pdu] = (j + '0' + 7); ++curr_pos_pdu;
              }
            }
          }
      }
    }
  }
  // -
  smsmsg[curr_pos_pdu] = 26;
  smsmsg[curr_pos_pdu + 1] = 0;
  char strcmd[] = "AT+CMGS=";
  i = 0;
  while ((sender[i] = strcmd[i]) != 0) ++i;
  sender[i] = ((curr_pos_pdu / 2 - 1) / 10) + '0'; ++i;
  sender[i] = ((curr_pos_pdu / 2 - 1) % 10) + '0'; ++i;
  sender[i] = 0;
  a6sendcmd(sender, ">", "", "");
  gsmmode = 3; submode = 0;
}

 

volodya3d
Offline
Зарегистрирован: 09.09.2020
andycat пишет:
просто в каком то служебном поле отсылается сколько частей длинной СМС и какая это конкретная часть отправляется.
 
- вы имеете ввиду что скетч режет смс на несколько маленьких ? если так то - это то в данный момент не проблема ... хочется все же длинное смс на кирилице отправить. 
 
Я пробовал отправлять длинные смс другой программой через USB модем (разбитые на PDU пакеты 154 бита и меньше) - и все прекрасно отправляется, теже самые PDU (если надо могу написать) шлю в СИМ 900 - СИМ 900 не отправляет. (((
 
он вообще может длинные смс на кирилице отправлять? может там все же какой отдельный знак нужно подать сим 900 что это длинная смс ???
 
 
понимаю что будет вопрос - а зачем тебе тогда вообще ардуино? - с модемом проблема бывает что он пропускает смс - и ничего в ответ не сообщает ... а ардуино может сообщить в компорт что все ОК или НЕ ОК ... и это нужно мне контролировать отправку смс ...
 
 
andycat пишет:
попробуйте разобраться в этой функции отправки.
- честно говоря не осилил.
 
 
Кто нибудь кто отправлял длинные смс из СИМ 900
 
Если есть возможность дайте пример 2ух pdu пакетов которые написаны верно (прошу пожалуйста без поля VP Времени жизни СМС, и прошу пожалуйста напишите в текстовом формате полное сообщение) - я думаю я бы сразу разобрался как отправлять если скинете ...
 
Спасибо за любую помощь.
andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

volodya3d , вы не с того начинаете, хоть одну СМС научитесь отправлять динамически, а не набором абстрактных байт, потом уже будете переходить на длинные. P.S. С SIM900 конкретно не работал, но учитывая что на A6 и SIM800 работало однотипно, сомневаюсь что дело в модеме - разбирайтесь досконально в протоколе, только так добьетесь результата.

Update: ну вот же в первой попавшейся статье из интернета:

Отправка длинных SMS-сообщений в формате PDU | Хард / Софт (hardisoft.ru)

PDU-Type – Поле флагов. Для отправки простого сообщения туда нужно было поставить “01”. В нашем случае, для отправки длинного сообщения в этом поле должно быть “41”. Т.е. если смотреть по битам, должен быть установлен бит TP-UDHI, который дает понять телефону, что сообщение содержит блок UDH (User Data Header), тот самый дополнительный информационный блок, в котором будет содержаться информация о частях сообщения.

и вот это же поле в моем коде

  smsmsg[curr_pos_pdu] = '0'; ++curr_pos_pdu; smsmsg[curr_pos_pdu] = '1'; ++curr_pos_pdu; // PDU type

 

volodya3d
Offline
Зарегистрирован: 09.09.2020
andycat пишет:
volodya3d , вы не с того начинаете, хоть одну СМС научитесь отправлять динамически, а не набором абстрактных байт, потом уже будете переходить на длинные. P.S. С SIM900 конкретно не работал, но учитывая что на A6 и SIM800 работало однотипно, сомневаюсь что дело в модеме - разбирайтесь досконально в протоколе, только так добьетесь результата.
 
- Это я сделал. Я отправляю через ком порт S1_PDUПакет - и смс уходит,
то есть S - Это СМС. 1 - 1 пду пакет, затем пакет. Нет сложности отправить в ардуино программно пду пакеты. Пду пакеты я сформирую в другой программе (не в ардуино) - с этим сложности нет. Есть сложность с пониманием какие именно пакеты нужны ардуино. 
Если очень надо могу скинуть полный скетч.
 
  while (Serial.available()) {
    char inChar = Serial.read();
    if (inChar != '\n') inStringCommand += inChar; 
      String StringCommand = ""; 
      StringCommand = inStringCommand.substring(0,1); 
........................... ........................... 
	if (StringCommand == "S") //и далее код

 

у меня нету проблемы отправить 1 смс из 1ого PDU пакета программно ... проблема в том чтобы отправить длинную смс.
 
Я специально упростил вопрос - мне просто бы пример 2ух pdu пакетов и я сразу разобрался бы ... Ведь кто нибудь что нибудь писал для отправки длинных СМС ???
 
как я писал ранее 
volodya3d пишет:
Я пробовал отправлять длинные смс другой программой через USB модем (разбитые на PDU пакеты 154 бита и меньше) - и все прекрасно отправляется, теже самые PDU (если надо могу написать) шлю в СИМ 900 - СИМ 900 не отправляет. (((
 
то есть аналогичные пду пакеты модем отправляет - сим 900 не отправляет, как мне кажется есть какая то доп команда для СИМ 900 чтобы отправить смс ...
 
Прошу по возможножности 
кто когда нибудь отправлял длинные смс из СИМ 900. - В мониторинг порта вывести 2а пду пакета - скопировать и прислать мне их ... и прислать текст который отправляли ... и я сразу разберусь - тема будет закрыта тогда ...
 
заранее спасибо !!!
 
andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

volodya3d пишет:

Пду пакеты я сформирую в другой программе (не в ардуино) - с этим сложности нет. Есть сложность с пониманием какие именно пакеты нужны ардуино. 
 

во.....вместо того чтоб разобраться в протоколе вы бездумно шлете в порт какие то данные и надеетесь на чудо :(

никакой доп команды в модемах нет - им че дашь то они и шлют. 

Возьмите любой русское слово, на его основе ручками!!! нарисуйте на бумаге весь текст СМС, разберитесь , отправьте, если удастся -  переходите к длинному тексту. Никто тут на форуме готовую программу вам не выложит - учитесь самостоятельно.

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

volodya3d пишет:

. Нет сложности отправить в ардуино программно пду пакеты. Пду пакеты я сформирую в другой программе (не в ардуино) - с этим сложности нет. Есть сложность с пониманием какие именно пакеты нужны ардуино.

именно поэтому у вас "сложность с пониманием", что реально вы не разобрались с форматом PDU, а берете готовые PDU пакеты "из другой программы".
 
Это читерство :) Вы давайте сами, с нуля, напишите программу для формирования PDU СМС из кириллического текста - тогда и понимание придет. "какие пакеты нужны ардуине".
volodya3d
Offline
Зарегистрирован: 09.09.2020
andycat пишет:
во.....вместо того чтоб разобраться в протоколе вы бездумно шлете в порт какие то данные и надеетесь на чудо :(
- дак нет я и пытаюсь разобраться как должны формироваться PDU пакеты для отправки длинного СМС.
 
b707 пишет:
Вы давайте сами, с нуля, напишите программу для формирования PDU
- мне бы для начала отправить правильные PDU пакеты длинного смс - чтобы понять какие они должны быть чтобы СИМ900 их правильно отправил ...
 
b707 пишет:
именно поэтому у вас "сложность с пониманием", что реально вы не разобрались с форматом PDU, а берете готовые PDU пакеты "из другой программы".
- нет ниже и выше я расписал как формируются PDU пакеты для коротких СМС. 
 
andycat пишет:
Возьмите любой русское слово, на его основе ручками!!! нарисуйте на бумаге весь текст СМС, разберитесь , отправьте, если удастся
 
- без проблем
ориентируюсь на статью http://codius.ru/articles/GSM_модуль_SIM800L_часть_3
 
----------------------------------------------------------------------------------------------------
Например для сообщения "АААААббббб" 5 букв А и 5 Букв б на телефон +79209996677
 
само пду сообщение будет
0001000B919702996976F70008140410041004100410041004310431043104310431
 
00 - SCA Номер телефона Центра SMS (Зашит в сим карте)
01 - PDU-type (MTI 01 отправляемое сообщение)
00 - MR Порядковый номер сообщения 
0B - PL количество цифр в номере телефона получателя 
91 - PT тип номера получателя международный формат телефона
9702996976F7 - RP телефон
00 - PID Идентификатор протокола
08 - DCS Кодировка сообщения (для отправки обычных сообщений)
"" - VP Время жизни сообщения
14 - UDL Длина поля UD в байтах 10 символов х 2 = 20 переводим в 16ричную систему.
0410041004100410041004310431043104310431 - само сообщение где 0410 - "А", 0431 - "б"
 
длина TPDU (PDU без поля SCA) сообщения будет 33 байта = 66 символов / 2
то есть перед отправкой смс будет вводится команда AT+CMGS=33,
а затем уже PDU пакет описаный выше с введенным символом контрол зед
----------------------------------------------------------------------------------------------------
 
при этом описанном PDU все прекрасно уходит и доставляется 
 
ниже вопрос - Вопрос который на который я так и не получил ответ 
 
--- правильно ли я понимаю что я могу разбить смс сообщение не обязательно на максимально большие PDU пакеты – То есть я могу части сообщения уходили и PDU пакетом 120 байт например – ГЛАВНОЕ чтобы соблюдался принцып построения PDU пакета. Все верно ??? 
andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

Лично я не знаю. Думаю нет. Разбивка нужна именно после 140 символов текста.
ЗЫ. Нахрена разбивать смс размером 100 знаков?

volodya3d
Offline
Зарегистрирован: 09.09.2020
все что я пишу ниже опирается на статью 
 
andycat пишет:
Лично я не знаю. Думаю нет. Разбивка нужна именно после 140 символов текста.
- как я понял вы имеете ввиду именно 140 байт. а не символов Русскоязычних символов. И 140 байт это длина поля UDH.
если оставить только буквы то получается 67 букв - как и описано в статье выше.
 
Главный вопрос. 
 
для отправки сообщение "ААААААААААббббббббббВВВВВВВВВВггггггггггДДДДДДДДДДЕЕЕЕЕЕЕЕЕЕжжжжжжжжжжИИИИИИИИИИ" каждой буквы по 10 шт. всего 80 штук.
На телефон +79209996677
 
 
получется будет 2а сообщения 
"ААААААААААббббббббббВВВВВВВВВВггггггггггДДДДДДДДДДЕЕЕЕЕЕЕЕЕЕжжжжжжж" - 67 символов.
и 
"жжжИИИИИИИИИИ" - 13 символов.
 
мы получим 2а PDU сообщения
 
0041000B919702996976F700088C050003FF02010410041004100410041004100410041004100410043104310431043104310431043104310431043104120412041204120412041204120412041204120433043304330433043304330433043304330433041404140414041404140414041404140414041404150415041504150415041504150415041504150436043604360436043604360436
 
00 - SCA Номер телефона Центра SMS (Зашит в сим карте)
41 - PDU-type (Отправка длинного сообщения VP - отсутвует)
00 - MR Порядковый номер сообщения 
0B - PL количество цифр в номере телефона получателя 
91 - PT тип номера получателя международный формат телефона
9702996976F7 - RP телефон (цыфры телефона в перемешку + F - если надо могу расписать)
00 - PID Идентификатор протокола
08 - DCS Кодировка сообщения (для отправки обычных сообщений)
"" - VP Время жизни сообщения
 
8C - TP-UDL длина поля UDH - те самые 140 байт про которые вы говорили. то есть это длина поля ниже и текста.
 
050003FF0201 - UDH поле которое содержит информацию о частях сообщения
__ 05 - общая длина поля UDH - 5 байт
__ 00 - IEI так как IED1 занимает в нашем сообщении 1 байт (как я понял 2 байта это если вообще огоромно сообщение)
__ 03 - IEDL Длина данных информационного элемента - 3 байта
__ FF - IED1 Номер-ссылка (Типа идендификатор сообщения) - должен быть рандомный
__ 02 - Количество частей в сообщении - 2
__ 01 - Порядковый номер части сообщения - 1 - это первая часть сообщения
 
04100410 ... - и затем пошли буквы где 0410 - "А", 0431 - "б" и тд.
 
длина TPDU (PDU без поля SCA) сообщения будет 153 байта = 306 / 2
 
второе PDU 0041010B919702566352F6000820050003FF02020436043604360418041804180418041804180418041804180418

TPDU 45
 
номер затер так как это мой реальный номер ...
 
отправляю первую часть СМС AT+CMGF=0, AT+CMGS=153 затем шлю PDU пакет описанный выше.
жду ответа от СИМ 900 вида "+CUSD:" - не получю его ... ну и на отправку второй части смс Сим900 питет - (+CMS ERROR: operation not allowed)
 
 
подскажите пожалуйста - В чем проблема на ваш взгляд ??? в каком месте PDU пакет сформирован не правильно ???
Делаю как вы и говорили расписываю СМС сообщение на части по буквам ручками ... 
 
andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

из любопытства решил попробовать длинную СМС закодировать, постратил два часа, понял что с наскока не решить.....

выше уже писали - ваш путь отправки готовых наборов байт - путь в никуда, ничего не получиться.

Ниже тестовый код который я начал писать "на коленке", вам достаточно поле UDH рассчитать и заполнить. Но все таки советую разобраться и написать все самостоятельно.

#define GSM_RX 3 // пин RX на модуле подключаем к указаному пину на Ардуино TX
#define GSM_TX 2 // пин TX на модуле подключаем к указаному пину на Ардуино RX
#include <SoftwareSerial.h>
SoftwareSerial SIM800(GSM_TX, GSM_RX); // установка контактовGSM_TX->RX и GSM_RX->TX для программного порта

void waitResponse(unsigned long countWait) {
  unsigned long startMillis = millis();
  while ((millis() - startMillis) < countWait) {
    if (SIM800.available())           // Ожидаем прихода данных (ответа) от модема...
      Serial.write(SIM800.read());    // ...и выводим их в Serial
  }
}

char sender[24];
#define max_len_sms 250
char smsmsg[max_len_sms];

void sendSMS(byte modeSMS) { // 0 - просто смс, 1 - первая часть длинного, 2 - вторая часть длинного
  // convert msg to pdu format
  byte lenTextByChar = strlen(smsmsg);
  // move text to end buf
  byte i, j;
  for (i = 0; i < lenTextByChar; ++i) {
    smsmsg[max_len_sms - lenTextByChar + i] = smsmsg[i];
  }
  byte curr_pos_pdu = 0;
  smsmsg[curr_pos_pdu] = '0'; ++curr_pos_pdu; smsmsg[curr_pos_pdu] = '0'; ++curr_pos_pdu; // SCA field
  switch (modeSMS) {
    case 0: {
      smsmsg[curr_pos_pdu] = '0'; ++curr_pos_pdu; smsmsg[curr_pos_pdu] = '1'; ++curr_pos_pdu; // PDU type
      break;
    }
    default:{
      smsmsg[curr_pos_pdu] = '4'; ++curr_pos_pdu; smsmsg[curr_pos_pdu] = '1'; ++curr_pos_pdu; // PDU type
      }
  }
  if (modeSMS == 2) {
    smsmsg[curr_pos_pdu] = '0'; ++curr_pos_pdu; smsmsg[curr_pos_pdu] = '1'; ++curr_pos_pdu; // MR
  } else {
    smsmsg[curr_pos_pdu] = '0'; ++curr_pos_pdu; smsmsg[curr_pos_pdu] = '0'; ++curr_pos_pdu; // MR
  }
  byte lenSenderPhone = strlen(sender);
  if (lenSenderPhone != 12) return;
  smsmsg[curr_pos_pdu] = '0'; ++curr_pos_pdu; smsmsg[curr_pos_pdu] = 'B'; ++curr_pos_pdu; // DA-PL
  smsmsg[curr_pos_pdu] = '9'; ++curr_pos_pdu; smsmsg[curr_pos_pdu] = '1'; ++curr_pos_pdu; // DA-PT
  // convert sender number
  for (i = 0; i < lenSenderPhone; ++i) {
    sender[i] = sender[i + 1];
  }
  sender[lenSenderPhone - 1] = 'F'; sender[lenSenderPhone] = 0;
  for (i = 0; i < lenSenderPhone; i += 2) {
    j = sender[i + 1];
    sender[i + 1] = sender[i];
    sender[i] = j;
  }
  for (i = 0; i < lenSenderPhone; ++i) { // DA-RP
    smsmsg[curr_pos_pdu] = sender[i];
    ++curr_pos_pdu;
  }
  smsmsg[curr_pos_pdu] = '0'; ++curr_pos_pdu; smsmsg[curr_pos_pdu] = '0'; ++curr_pos_pdu; // PID field
  smsmsg[curr_pos_pdu] = '0'; ++curr_pos_pdu; smsmsg[curr_pos_pdu] = '8'; ++curr_pos_pdu; // DCS field
  lenTextByChar *= 2; // UDL
  byte bb = lenTextByChar / 16;
  if (bb < 10) {
    smsmsg[curr_pos_pdu] = (bb + '0'); ++curr_pos_pdu;
  } else {
    smsmsg[curr_pos_pdu] = (bb + '0' + 7); ++curr_pos_pdu;
  }
  bb = lenTextByChar % 16;
  if (bb < 10) {
    smsmsg[curr_pos_pdu] = (bb + '0'); ++curr_pos_pdu;
  } else {
    smsmsg[curr_pos_pdu] = (bb + '0' + 7); ++curr_pos_pdu;
  }
  // UDH
  if (modeSMS) { // use UDH
    
  }
  // UD - text by UCS2
  for (i = 0; i < (lenTextByChar / 2); ++i) {
    bb = smsmsg[max_len_sms - (lenTextByChar / 2) + i];
    if (bb < 0x7F) {
      smsmsg[curr_pos_pdu] = '0'; ++curr_pos_pdu; smsmsg[curr_pos_pdu] = '0'; ++curr_pos_pdu;
      // convert to hex
      j = bb / 16;
      if (j < 10) {
        smsmsg[curr_pos_pdu] = (j + '0'); ++curr_pos_pdu;
      } else {
        smsmsg[curr_pos_pdu] = (j + '0' + 7); ++curr_pos_pdu;
      }
      j = bb % 16;
      if (j < 10) {
        smsmsg[curr_pos_pdu] = (j + '0'); ++curr_pos_pdu;
      } else {
        smsmsg[curr_pos_pdu] = (j + '0' + 7); ++curr_pos_pdu;
      }
    } else {
      switch (bb) {
        case 168: {
            smsmsg[curr_pos_pdu] = '0'; ++curr_pos_pdu; smsmsg[curr_pos_pdu] = '4'; ++curr_pos_pdu;
            smsmsg[curr_pos_pdu] = '0'; ++curr_pos_pdu; smsmsg[curr_pos_pdu] = '1'; ++curr_pos_pdu;
            break;
          }
        case 184: {
            smsmsg[curr_pos_pdu] = '0'; ++curr_pos_pdu; smsmsg[curr_pos_pdu] = '4'; ++curr_pos_pdu;
            smsmsg[curr_pos_pdu] = '5'; ++curr_pos_pdu; smsmsg[curr_pos_pdu] = '1'; ++curr_pos_pdu;
            break;
          }
        default: {
            if (bb < 192) {
              smsmsg[curr_pos_pdu] = '0'; ++curr_pos_pdu; smsmsg[curr_pos_pdu] = '0'; ++curr_pos_pdu;
              // convert to hex
              j = bb / 16;
              if (j < 10) {
                smsmsg[curr_pos_pdu] = (j + '0'); ++curr_pos_pdu;
              } else {
                smsmsg[curr_pos_pdu] = (j + '0' + 7); ++curr_pos_pdu;
              }
              j = bb % 16;
              if (j < 10) {
                smsmsg[curr_pos_pdu] = (j + '0'); ++curr_pos_pdu;
              } else {
                smsmsg[curr_pos_pdu] = (j + '0' + 7); ++curr_pos_pdu;
              }
            } else {
              smsmsg[curr_pos_pdu] = '0'; ++curr_pos_pdu; smsmsg[curr_pos_pdu] = '4'; ++curr_pos_pdu;
              // convert to hex
              j = (bb - 176) / 16;
              if (j < 10) {
                smsmsg[curr_pos_pdu] = (j + '0'); ++curr_pos_pdu;
              } else {
                smsmsg[curr_pos_pdu] = (j + '0' + 7); ++curr_pos_pdu;
              }
              j = (bb - 176) % 16;
              if (j < 10) {
                smsmsg[curr_pos_pdu] = (j + '0'); ++curr_pos_pdu;
              } else {
                smsmsg[curr_pos_pdu] = (j + '0' + 7); ++curr_pos_pdu;
              }
            }
          }
      }
    }
  }
  // -
  smsmsg[curr_pos_pdu] = 26;
  smsmsg[curr_pos_pdu + 1] = 0;
  char strcmd[] = "AT+CMGS=";
  i = 0;
  while ((sender[i] = strcmd[i]) != 0) ++i;
  sender[i] = ((curr_pos_pdu / 2 - 1) / 10) + '0'; ++i;
  sender[i] = ((curr_pos_pdu / 2 - 1) % 10) + '0'; ++i;
  sender[i] = 0;
  SIM800.print(sender); SIM800.write('\r'); waitResponse(500UL);
  SIM800.print(smsmsg);
}

void setup() {
  Serial.begin(9600);               // Скорость обмена данными с компьютером
  SIM800.begin(9600);               // Скорость обмена данными с модемом
  SIM800.print("AT\r"); waitResponse(500UL);
  SIM800.print("AT+CIPSHUT\r"); waitResponse(500UL);
  SIM800.print("AT+DDET=0\r"); waitResponse(500UL);
  SIM800.print("ATE1\r"); waitResponse(500UL);
  SIM800.print("AT+CLIP=0\r"); waitResponse(500UL);
  SIM800.print("ATS0=0\r"); waitResponse(500UL);
  SIM800.print("ATV1\r"); waitResponse(500UL);
  SIM800.print("AT+CMEE=2\r"); waitResponse(500UL);
  SIM800.print("AT+CMGF=0\r"); waitResponse(500UL);
  SIM800.print("AT+CSCLK=0\r"); waitResponse(500UL);
  /*strcpy(sender, "+79009698478");
  smsmsg[0] = 210; smsmsg[1] = 229; smsmsg[2] = 241; smsmsg[3] = 242; smsmsg[4] = 0; // слово Тест
  sendSMS(0); waitResponse(5000UL);*/
  strcpy(sender, "+79009698478");
  smsmsg[0] = 196; smsmsg[1] = 235; smsmsg[2] = 232; smsmsg[3] = 237; smsmsg[4] = 237; smsmsg[5] = 251; smsmsg[6] = 233; smsmsg[7] = 0; // слово Длинный
  sendSMS(1); waitResponse(40000UL); // ждем OK перед отправкой след части
  strcpy(sender, "+79009698478");
  smsmsg[0] = 32; smsmsg[1] = 242; smsmsg[2] = 229; smsmsg[3] = 234; smsmsg[4] = 241; smsmsg[5] = 242; smsmsg[6] = 0; // слово текст
  sendSMS(2);
}

void loop() {
  if (SIM800.available())           // Ожидаем прихода данных (ответа) от модема...
    Serial.write(SIM800.read());    // ...и выводим их в Serial
  if (Serial.available())           // Ожидаем команды по Serial...
    SIM800.write(Serial.read());    // ...и отправляем полученную команду модему
}

 

volodya3d
Offline
Зарегистрирован: 09.09.2020
Уважаемый andycat спасибо вам за пример. Я до конца пока не понял как, но с помощью вашего примера мне удалось отправить длинную смс. Я этому очень рад. Я постараюсь разобраться. Большое спасибо !!!
 

00 - MR Порядковый номер сообщения - должен быть всегда 00 (прочитал я на другом форуме).

Я отпишусь получится ли у меня отправлять программно смс ... Еще раз спасибо !!!
 
Я не вкурсе - этично не этично как у вас на форуме принято - если как то нужно отблагодарить - то я без проблем ...
andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

MR с каждой частью должен увеличиваться. Какие то не правильные форумы вы читаете.

volodya3d
Offline
Зарегистрирован: 09.09.2020

Добрый день.

прочитала вот здесь

https://www.cyberforum.ru/csharp-net/thread269949.html