GSM сигнализация M590+Arduino

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

pasha413 пишет:
не могу разбить строку на количество n -строк, в зависимости от кол-ва пришедших +CPBF

Как всегда в вопросе не сказао какого типа ситорка, которую надо парсить. Вот хрен Вас знает, она у Вас String или char *. Если первое, то гуглите indexOf, если второе то ищите пример strstr или strtok

pasha413
Offline
Зарегистрирован: 27.11.2016

допустим имеется код:

String val =   // пришла строка с sim с номерами:
"+CPBF: 1,""\"79111234567""\",129,""\"number""\"\n"
" +CPBF: 2,""\"79112345678""\",129,""\"main""\"\n"
" +CPBF: 3,""\"79113456789""\",129,""\"911""\"\n"
" +CPBF: 4,""\"79114567890""\",129,""\"\"\n";


void setup() {
Serial.begin(9600);
Serial.println(val);

}

void loop() {

  
}

вот надо разбить эту строку val на n - количество строк (в зависимости от кол-ва номеров). 

строка из  модема приходит в виде: 

+CPBF: 1,"79111234567",129,"number"  

где 1 - номер ячейки памяти,

7911.... - номер телефона,

остальное не важно.

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

Ну, я же сказал, смотрите indexOf. Вам что, ссылку в документации найти?

pasha413
Offline
Зарегистрирован: 27.11.2016

по indexOf конечно нашел пример, не совсем уж я тупой :)

void setup() {
  // Инициализируем последовательную передачу данных и ждем открытия порта:
  Serial.begin(9600);
 
  // Отсылаем вступительную часть:
  Serial.println("\n\nString indexOf() and lastIndexOf()  functions:");
  Serial.println();
}

void loop() {
  // Функция indexOf() возвращает самую первую позицию (т.е. индекс) определенного символа, находящегося в строке.
  // Ее можно использовать, например, при анализе HTML-тегов:
  String stringOne = "<HTML><HEAD><BODY>";
  int firstClosingBracket = stringOne.indexOf('>');
  Serial.println("The index of > in the string " + stringOne + " is " + firstClosingBracket);
 
  stringOne = "<HTML><HEAD><BODY>";
  int secondOpeningBracket = firstClosingBracket + 1;
  int secondClosingBracket = stringOne.indexOf('>', secondOpeningBracket );
  Serial.println("The index of  the second > in the string " + stringOne + " is " + secondClosingBracket);
  while(true);
}

но вот как его применить в моем случае с неизвестным количеством позиций? 

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

pasha413 пишет:

но вот как его применить в моем случае с неизвестным количеством позиций? 

Цикл "пока найдено" делать "что надо". 

Разберитесь что возващает indexOf в случае, если ничего не нашёл и сделайте цикл "пока нашлось".

pasha413
Offline
Зарегистрирован: 27.11.2016

так сообшение то одно приходит, а не несколько. еслиб приходило несколькими сообщениями то я запросто справился бы.

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

Ничего не понял. В одной строке несколько сообщений, так? Ну и делайте цикл поиска этих сообщений "пока найдено"

pasha413
Offline
Зарегистрирован: 27.11.2016

у меня на первой строке останавливается и выводит полное сообщение.

напишите пример. цикла поиска сообщений?

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

Да, нет, это Вы напишите, а я посмотрю.

Если хотите, чтобы Вам писали, то для этого есть специальный раздел.

Short Circuit
Short Circuit аватар
Offline
Зарегистрирован: 17.05.2015

Umka пишет:

Конечно можно и даже нужно. Зачем же пины аппаратного прерывания под порт занимать? Я бы и датчики посоветовал на прерывания пересадить. Так удобнее, чем постоянно состояние пина проверять.

 

 под приемник нужно выделять отдельный проц и не морочить себе голову...

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

будут постоянные коллизии.

Umka
Umka аватар
Offline
Зарегистрирован: 19.10.2012

Приемник чего? Тут про внешнее прерывание и сигналку говорил. Будет работать отлично. Uart с буфером, его хватает вполне. Задачи у контроллера более чем простые.

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

pasha413 пишет:

у меня на первой строке останавливается и выводит полное сообщение.

Ну блин, Паша, что за тупизм?

Ищете в начальной строке "+CPBF:", к найденной позиции добавляете 6 знакомест (длину +CPBF:) и снова ищете эту строку. Если нашли - строку между двумя +CPBF: вырезаете, если не наншли - значит это последнее +CPBF: в строке... И так в цикле.

Банальный алгоритм же, что тут думать?

pasha413
Offline
Зарегистрирован: 27.11.2016

b707, точно! спасибо, попробую.

Short Circuit
Short Circuit аватар
Offline
Зарегистрирован: 17.05.2015

Umka пишет:
Приемник чего? Тут про внешнее прерывание и сигналку говорил. Будет работать отлично. Uart с буфером, его хватает вполне. Задачи у контроллера более чем простые.

на 2 или на 3 вывод радиоприемник датчиков предполагается вешать?

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

програма будет постоянно там останавливаться, намного чаще чем нам хотелось бы. верно?

вот именно для этого на приемник ставят отдельный проц, чтобы разгрузить от этой рутины основной проц.

иначе думаю даже прием от гсм по юарту тоже будет постоянно прерываться, со всеми вытекающими.

TrampSRV
Offline
Зарегистрирован: 10.09.2017

Не пинайте сильно. Я не могу понять, как работает проверка баланса. Может кто разжует мне?

pasha413
Offline
Зарегистрирован: 27.11.2016

TrampSRV, на каком модеме? Про А6 я писал здесь проверку баланса

TrampSRV
Offline
Зарегистрирован: 10.09.2017

У меня М590, на запрос типа ATD#102#, Билайн отвечает Vash balans 100.00 r.   

pasha413
Offline
Зарегистрирован: 27.11.2016

TrampSRV. Тогда там все элементарно

kvolk
Offline
Зарегистрирован: 12.06.2017

TrampSRV пишет:

Не пинайте сильно. Я не могу понять, как работает проверка баланса. Может кто разжует мне?

Есть функция void balance(), когда она выполняется - оператору посылается команда запроса баланса. 
Оператор присылает ответ который начинается со строки "+CUSD:". Так же в коде есть проверка на получение от модема строки "+CUSD:" и если модем передаёт эту строку, то считаем что это инфо о балансе, парсим и оправляем ответ тому, кто выполнил void balance(). У меня задумка была именно такая, тут практически аналогично.
Umka
Umka аватар
Offline
Зарегистрирован: 19.10.2012

Если void balance(), то ничего не возвращает функция :)

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

Umka, ваши шутки для здесь слишком заумные :)

 

TrampSRV
Offline
Зарегистрирован: 10.09.2017

Собрал отдельный скетч проверки баланса,(правда пока на Мегафон, т.к. нет карты Билайна под рукой) у меня пока он не заработал, что я делаю не так?


//#include <SoftwareSerial.h>
gprsSerial = Serial;


String currStr = "";




void balance () {
  gprsSerial.println("ATD#100#");  //запрос баланса
  delay(300);
  Serial.println("zapros balansa");
}



void setup()
{
  Serial.begin(9600);
  gprsSerial.begin(9600);
  //   Настраиваем приём сообщений 
  //   Между командами даём время на их обработку
  
  gprsSerial.println("AT+CMGF=1"); //устанавливает текстовый режим смс-сообщения
  delay(300);

  gprsSerial.println("AT+IFC=1,1"); //устанавливает программный контроль потоком передачи данных 
  delay(300);

  gprsSerial.print("AT+CPBS=");//открывает доступ к данным телефонной книги
  gprsSerial.print((char)34);
  gprsSerial.print("SM"); // SIM-карты
  gprsSerial.print((char)34);
  gprsSerial.println("");
  //    gprsSerial.print((char)13);
  delay(300);

  gprsSerial.println("AT+CNMI=1,2,2,1,0");//включает оповещение о новых сообщениях, 
  //новые сообщения приходят в следующем формате:
  // +CMT: "<номер телефона>", "", "<дата, время>", 
  //а на следующей строчке с первого символа идёт содержимое сообщения
  delay(300);
  
  while(1){                             // ждем подключение модема к сети
        gprsSerial.println("AT+COPS?");
        if (gprsSerial.find("+COPS: 0")) break;
       
    }
Serial.println("GSM find ok");

  balance();
}


void loop()
{

  //  toSerial();
  if (gprsSerial.available()){
    char currSymb = gprsSerial.read();
    if ('\r' == currSymb) {  //если символ перевод каретки
      if  (currStr.startsWith("+CUSD: 0,")) {
        int zzz = currStr.indexOf('UAH');
        String balance=currStr.substring(10,zzz-3); //баланс на сим карте
        
        Serial.println("balans:");
        Serial.print(balance);
      }
      currStr = "";
    } 
    else if ('\n' != currSymb) { //если символ НЕ новая строка
      currStr += String(currSymb);
    }          
  }

}



Это то что в мониторе порта


AT+CMGF=1
AT+IFC=1,1
AT+CPBS="SM"
AT+CNMI=1,2,2,1,0
AT+COPS?
GSM find ok
ATD#100#
zapros balansa

 

Umka
Umka аватар
Offline
Зарегистрирован: 19.10.2012

И что сие означает?

gprsSerial = Serial;

 

TrampSRV
Offline
Зарегистрирован: 10.09.2017

Мусор) Наверное так #define gprsSerial Serial

kvolk
Offline
Зарегистрирован: 12.06.2017

TrampSRV пишет:

Собрал отдельный скетч проверки баланса,(правда пока на Мегафон, т.к. нет карты Билайна под рукой) у меня пока он не заработал, что я делаю не так?

Вместо ATD#100# используйте  AT+CUSD=1,"#100#",15

Здесь ещё в ветке про баланс было, посмотрите https://mysku.ru/blog/ebay/43282.html#comment2025632

kvolk
Offline
Зарегистрирован: 12.06.2017

pasha413 пишет:

допустим имеется код:

String val =   // пришла строка с sim с номерами:
"+CPBF: 1,""\"79111234567""\",129,""\"number""\"\n"
" +CPBF: 2,""\"79112345678""\",129,""\"main""\"\n"
" +CPBF: 3,""\"79113456789""\",129,""\"911""\"\n"
" +CPBF: 4,""\"79114567890""\",129,""\"\"\n";

С большой вероятностью у ардуины не хватит оперативной память на обработку этих данных, при том функционале который уже реализован.

Umka
Umka аватар
Offline
Зарегистрирован: 19.10.2012

Serial зарезервировано системой под аппаратный uart. А Вы программному экземпляру порта это имя присваиваете.

TrampSRV
Offline
Зарегистрирован: 10.09.2017

Umka пишет:
Serial зарезервировано системой под аппаратный uart. А Вы программному экземпляру порта это имя присваиваете.

У меня М590 подключен к Ардуино надо к аппаратному уарту (к 30 и 31 ножке) . Подскажите, как тогда правельнее?

Umka
Umka аватар
Offline
Зарегистрирован: 19.10.2012

Ну, софтовый сериал удобнее использовать, если надо результаты в обычный порт выводить. Хотя можно и наоборот, а то модем с ума сойдет. Хотя я с аппаратным тоже работаю с SIM800L и нормально. Тогда зачем вообще его переименовывать? Совет - начните таки с софтового с выводом статистики в аппаратный. Вам там 2 строчки добавить.

pasha413
Offline
Зарегистрирован: 27.11.2016

Мой запрос баланса на М590 :
void balance() {
mySerial.println(F("AT+CUSD=1"));
delay(200);
mySerial.println(String(F("ATD#100#")));
delay(1000);
}

Gienekb
Offline
Зарегистрирован: 29.08.2017

pasha413 пожалуйста сообщите, почему этот код (с сообщения#216) не работает с модемом M590E, a с модемом sim300DZ работает очень хорошо.

pasha413
Offline
Зарегистрирован: 27.11.2016

Скорее всего из-за небольших отличий в АТ командах. Подправьте их и все будет работать

Baks
Baks аватар
Offline
Зарегистрирован: 11.01.2016

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

kvolk
Offline
Зарегистрирован: 12.06.2017

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

Прикалываетесь? :)  В оригинальном проекте изначально это реализовано (иначе какой смысл в такой охранной системе), 60 часов автономность на одном литиевом аккумуляторе 18650. Сигнализация работает от аккума только при отсутствии внешнего питания. Тут почитать https://mysku.ru/blog/ebay/44545.html и тут https://mysku.ru/blog/ebay/43282.html

Вот тут ещё https://mysku.ru/blog/ebay/43282.html#comment1930875

Baks
Baks аватар
Offline
Зарегистрирован: 11.01.2016

Спасибо схему понял и что докупить надо тоже понял. Спасибо за совет. Вот только один вопрос остался, не испортится ли акамулятор из за того что он всегда будет под зарядкой?

Umka
Umka аватар
Offline
Зарегистрирован: 19.10.2012

Контроллер заряда лития стоит рублей 30 если не меньше. Или 100р за пяток. Или взять корпус павербэнка с контроллером за те же 100р. Тоже мне проблема.

kvolk
Offline
Зарегистрирован: 12.06.2017

Umka пишет:
Контроллер заряда лития стоит рублей 30 если не меньше. Или 100р за пяток. Или взять корпус павербэнка с контроллером за те же 100р. Тоже мне проблема.

Не всё так просто, если взять тупо контроллеры заряда-разряда для лития, то аккум будет циклически "заряжаться-разряжаться" раз по 10 в сутки и долго не протянет. Контроллер от дешевого павербанка не умеет работать в режиме источника бесперебойного питания (сам заряжаться и питать устройство), сяомишные павербанки это могут, но цена у них не три копейки.

Umka
Umka аватар
Offline
Зарегистрирован: 19.10.2012

Умеют.

kvolk
Offline
Зарегистрирован: 12.06.2017

Umka пишет:
Умеют.

Можно пруфы?

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

например такой - у него вход-выход 5в напрямую

http://www.ebay.com/itm/5x-5V-Step-Up-Module-Boost-Converter-Battery-Cha...

Umka
Umka аватар
Offline
Зарегистрирован: 19.10.2012

Я покажу как домой попаду. Сейсас в разъездах. Проще всего сделать развязку на 2 диодах Шоттки и питать банку и Ардуину от 5В источника.

kvolk
Offline
Зарегистрирован: 12.06.2017

b707 пишет:

например такой - у него вход-выход 5в напрямую

http://www.ebay.com/itm/5x-5V-Step-Up-Module-Boost-Converter-Battery-Cha...

Будет тоже самое: 

Цитата:

...аккум будет циклически "заряжаться-разряжаться" раз по 10 в сутки и долго не протянет.

 А так же появится ещё проблема со стартом устройства и регистрацией в GSM сети при автономном питании, так как модуль не сможет отдать кратковременно  необходимые 1,5 - 2А. Прийдётся ещё конденсаторов минимум на 3000 мкф ставить.

kvolk
Offline
Зарегистрирован: 12.06.2017

Umka пишет:
...Проще всего сделать развязку на 2 диодах Шоттки и питать банку и Ардуину от 5В источника.

Можно подробнее?

TrampSRV
Offline
Зарегистрирован: 10.09.2017

Как то так   www.youtube.com/watch?v=rZYRJSVIz1o

TrampSRV
Offline
Зарегистрирован: 10.09.2017

Я так и не могу заставить скетч проверки баланса работать. Кто ни будь может его допилить?

smesharik
Offline
Зарегистрирован: 31.01.2016

TrampSRV пишет:

Я так и не могу заставить скетч проверки баланса работать. Кто ни будь может его допилить?

а что хоть происходит?!

TrampSRV
Offline
Зарегистрирован: 10.09.2017

AT+CMGF=1
AT+IFC=1,1
AT+CPBS="SM"
AT+CNMI=1,2,2,1,0
AT+COPS?
GSM find ok
ATD#100#
zapros balansa

И тишина..... Пробывал менять номер на AT+CUSD=1,"#100#",15, выдает ошибку. Второй день бьюсь над этим скетчем и все в пустую

сам код таков

#define gprsSerial Serial;


String currStr = "";




void balance () {
  gprsSerial.println("ATD#100#");  //запрос баланса
  delay(300);
  Serial.println("zapros balansa");
}



void setup()
{
  Serial.begin(9600);
  gprsSerial.begin(9600);
  //   Настраиваем приём сообщений 
  //   Между командами даём время на их обработку
  
  gprsSerial.println("AT+CMGF=1"); //устанавливает текстовый режим смс-сообщения
  delay(300);

  gprsSerial.println("AT+IFC=1,1"); //устанавливает программный контроль потоком передачи данных 
  delay(300);

  gprsSerial.print("AT+CPBS=");//открывает доступ к данным телефонной книги
  gprsSerial.print((char)34);
  gprsSerial.print("SM"); // SIM-карты
  gprsSerial.print((char)34);
  gprsSerial.println("");
  //    gprsSerial.print((char)13);
  delay(300);

  gprsSerial.println("AT+CNMI=1,2,2,1,0");//включает оповещение о новых сообщениях, 
  //новые сообщения приходят в следующем формате:
  // +CMT: "<номер телефона>", "", "<дата, время>", 
  //а на следующей строчке с первого символа идёт содержимое сообщения
  delay(300);
  
  while(1){                             // ждем подключение модема к сети
        gprsSerial.println("AT+COPS?");
        if (gprsSerial.find("+COPS: 0")) break;
       
    }
Serial.println("GSM find ok");

  balance();
}


void loop()
{

  //  toSerial();
  if (gprsSerial.available()){
    char currSymb = gprsSerial.read();
    if ('\r' == currSymb) {  //если символ перевод каретки
      if  (currStr.startsWith("+CUSD: 0,")) {
        int zzz = currStr.indexOf('UAH');
        String balance=currStr.substring(10,zzz-3); //баланс на сим карте
        
        Serial.println("balans:");
        Serial.print(balance);
      }
      currStr = "";
    } 
    else if ('\n' != currSymb) { //если символ НЕ новая строка
      currStr += String(currSymb);
    }          
  }

 

pasha413
Offline
Зарегистрирован: 27.11.2016

Попробуйте сначала команду
AT+CUSD=1
Затем
ATD#100#
___________________
Попробуйте проверку баланса из моего кода, сейчас нет возможности проверить ваш код.
Либо вообще подключите модем через конвертор к компу, и пробуйте отсылать команду проверки баланса, что модем пришлет в ответ? Либо через ардуинку https://istarik.ru/blog/arduino/68.html

Baks
Baks аватар
Offline
Зарегистрирован: 11.01.2016

TrampSRV пишет:

Как то так   www.youtube.com/watch?v=rZYRJSVIz1o


Ссылка битая. Я всё-таки так и не понял что со схемой резервного питания делать. Можно ли так сделать как в образце и будет ли это правильно и надёжно?

TrampSRV
Offline
Зарегистрирован: 10.09.2017

Ардуино молчит, а вот если ручками набирать это через USB TTL конвектор, то выкидывает это

at
OK
AT+CMGF=1
OK
AT+IFC=1,1
OK
AT+CPBS=SM
ERROR
AT+CPBS?
ERROR
AT+CNMI=1,2,2,1,0
OK
AT+CUSD=1
OK
ATD#100#
+CUSD: 0,"0032003800320440002E003004310430043B002E04280430043D0441043E043D00200022041D0435002004420440043E0433043004390020043E04410435043D044C00220020043D04300020043304430434043E043A002004370430002000340440002F04340021002000300037003700370034",72

OK

И почему ругается на симку? AT+CPBS=SM     Error