Вкусняшки от Наташки, или - посылаем/принимает SMS на русском

Тема в разделе "Arduino & Shields", создана пользователем DIYMan, 28 июл 2016.

  1. DIYMan

    DIYMan Guest

    (голосом КВН-щика) Короче-еее! Здравствуйте-ееее!

    Многие балуются всякими непотребностями, типа GSM-модемов из двух враждебных сицилийских кланов с фамилиями Neoway и SIM. Многие же - парятся, как раскодировать SMS, пришедшее на русском языке. Некоторые - хотят послать всех "на", и - тоже на русском.

    Короче-еее! Как переводить GSM-модем в режим работы в кодировке PDU - есть в даташитах, а я вам дам другое: кодировщик/декодировщик в/из PDU/UTF-8. Т.е. можно классу скормить текст в UTF-8, например, "Привет, сосед!", и он вернёт закодированное сообщение со всей необходимой информацией, которую уже можно будет скормить GSM-модему по команде AT+CMGS. Соответственно, может и в обратку - раскодировать, причём уже есть поддержка разрешённого номера.

    Из недостатков: не поддерживает склейку SMS, т.е. вы сами должны следить, чтобы SMS не превышало максимальное кол-во символов, отведённых на 1 (прописью - одну) штуку. Решение - не готовое, а часть большого проекта, но выпиливается оттуда без шума и пыли.

    Код:
    https://github.com/Porokhnya/GreenhouseProject/blob/master/Main/PDUClasses.h
    https://github.com/Porokhnya/GreenhouseProject/blob/master/Main/PDUClasses.cpp

    Использование:
    Код (C++):

    // раскодируем
    PDUIncomingMessage m = PDU.Decode("закодированное SMS", "+79181112233"); // вторым параметром - мастер-номер
    if(m.IsDecodingSucceed)
    {
    Serial.println(m.SenderNumber);
    Serial.println(m.Message);
    }

    //закодируем
    PDUOutgoingMessage o = PDU.Encode("+79182223344", "Привет, сосед!",true); // третий параметр - сообщение сразу на экране или нет (FLASH)

    // отправляем
    gsmSerial.println("AT+CMGS=" + String(o.MessageLength));
    gsmSerial.print(o.Message);

     
    Ещё раз хочу заметить - работа идёт в кодировке UTF-8, т.е. исходное сообщение, если оно на русском - должно быть в этой кодировке. В общем, если что - задавайте вопросы, желательно не сильно сложные и ставящие в тупик своей непосредственностью, а то я нервный :D:eek:
     
    rico, ostrov, ИгорьК и ещё 1-му нравится это.
  2. ИгорьК

    ИгорьК Гуру

    Я купил в Амперке ардуино уно и GSM шилд. Мне надо отправлять и принимать смс на русском языке. Как мне это сделать? Спасибо заранее.
    UPD. Да ладно. Прикалываюсь :) Спасибо!
     
    DIYMan нравится это.
  3. AlexVS

    AlexVS Гик

    А где, собственно, Наташка? И кто она воще такая? Или под ником DIYMan скрывается симпатяшка Наташка??? ;)
     
  4. Airbus

    Airbus Радиохулиган Модератор

    Не впечатлило.Вот хоть убейте не впечатлило.Пару лет назад (а может больше)выкладывал свой (а не с github.com) скетч как отправлять СМС в PDU на русском.Безо всяких ненужных gsmSerial .Можно и короче и оптимальнее.
     
    РусНекромант нравится это.
  5. DIYMan

    DIYMan Guest

    Про gsmSerial - это как бэ псевдокод, вообще-то. Для примера, чтобы не спрашивали, как юзать. Через какой Serial работать - классам фиолетово, если честно.

    Вы, наверное, Мандельштама не читали, да? ;)

    З.Ы. Дык и выложили бы свой код сюда, для комплекта. И да - ссылки с гитхаба приведены с моего аккаунта, если что.
     
  6. Airbus

    Airbus Радиохулиган Модератор

    Хех!Не собираюсь с Вами спорить просто хотел сказать что можно проще в разы. 1способ собираем PDU пакет здесь-как обьяснять не буду и так понятно.Есть ещё програмки в несколько Кб для компа-тоже можно.Далее пишем простой скетч.Компилим шьём отправляем.
    Код (C++):
    // Передача СМС в режиме PDU
    int buttonPin = 5; // номер входа, подключенный к кнопке
    Serial.begin(9600);  //скорость 9600 бод
    delay(1000); //на 1 сек пусть ловит сеть
    }
    void loop(){
    if (digitalRead(buttonPin)==HIGH){
    delay(100); //если на кнопке "плюс"(PIN 5 не на минусе т.е разомкнут)
    Serial.println("AT+CMGF=0\r"); // выставляем режим сообщений PDU
    delay(300);
    Serial.println("AT+CMGS=35"); //передали
    Serial.print((char)13); // символ <cr>
    delay(300);
    Serial.print("07919721680780F301000B919721512494F6000816041F044004380432043504420020041204300441044F"); // Пишем PDU пакет Привет Мир
    delay(300);
    Serial.print((char)26); // Отправляем Ctrl+Z, обозначая, что сообщение готово
    Serial.print((char)13); // символ <cr>
    delay(10000);
          }
       }
     
    Есть способ ещё проще-если отправлять одно и то же СМС на один и тот же телефон (а ля GSM сигнализация) Пишем "Русское СМС" отправляем его на "нужный" телефон и сохраняем в отправленых. Смотрим под каким номером оно у нас сохранилось.Потом пуляем его оттуда GSM командой "AT+CMGS=1\r" где 1 это номер сохранённого СМС.Можно написать хоть 50 СМС на 50 разных номеров либо на один и тот же и пулять их по разным событиям.Скетч писать не буду и так понятно как?Вот как то так ))))
    Про gsmSerial и так всё понял просто меня всегда передёргивает когда его используют усложняя и увеличивая код а так да всё равно как. Про Мандельштама не понял хотя не очень его люблю. А так респект Вам DIY Man что ищете думаете и имеете аккаунт на github.com. Просто хотел сказать что всё гораздо проще. GSM команды-наше всё!Они делают код проще!
     
  7. DIYMan

    DIYMan Guest

    Вы опять не поняли ничего, к сожалению. Собрать PDU-пакет можно, не вопрос. Разобрать его как, если пришло СМС на русском? Я предлагаю универсальный способ, который может работать как на передачу, так и на приём СМС в формате PDU. Это решение делает за вас всю чёрную работу по кодированию/раскодированию СМС.

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

    И это хорошо, когда есть несколько решений проблемы.

    З.Ы. И да: простота - понятие обманчивое. И неблагодарное. Это всё из жизненного опыта. Порой решение, основанное на поддержании формата, пусть и частичном - потом оказывается более применимым, чем простое решение в лоб. Скажем, изначально у меня в проекте не было поддержки кастомных СМС, и только благодаря написанным ранее классам для перегона в PDU и обратно такое решение прикрутилось на раз-два ;)
     
  8. mvn77

    mvn77 Нерд

    Попытался откомпилить
    Код (C++):

    #include <PDUClasses.h>
    void setup() {
    Serial.begin(9600);
    Serial3.begin(9600);
    delay(2000);
      Serial3.println("AT");

      //закодируем
    PDUOutgoingMessage o = PDU.Encode("+79182223344", "Привет, сосед!",true); // третий параметр - сообщение сразу на экране или нет (FLASH)
    }
    void loop() {
      if (Serial3.available())
        Serial.write(Serial3.read());
      if (Serial.available())
        Serial3.write(Serial.read());
    }[/code
     
    выдает
     
    Последнее редактирование: 25 янв 2019
  9. Tomasina

    Tomasina Сушитель лампочек Модератор

    В пути к файлу русские буквы.
    Не надо.
     
  10. ZAZ-965

    ZAZ-965 Гуру

    @mvn77, автор библиотеки изменил количество параметров функции Encode
    Код (C++):
    PDUOutgoingMessage Encode(const String& recipientPhoneNum, const String& utf8Message, bool isFlash, String* outBuffer, bool incomingMessageInUCS2Format=false); // кодирует сообщение из UTF-8 в UCS2
    Нужно или исправить тестовый скетч или взять с гитхаба срез с предыдущей версией библиотеки.
     
    DIYMan нравится это.
  11. DIYMan

    DIYMan Guest

    Именно так: там давно уже несколько поменяно всё. Либо брать срез со старого коммита, либо вызывать по новому, навскидку:
    Код (C++):
    String result;
    PDUOutgoingMessage message = PDU.Encode(F("+79180000000"), F("Превед!"), false,&result);
    Переделки были связаны с тем, что возникла необходимость переправлять смс-ки, которые уже в UCS2.