SIM800L mini

cat5130
Offline
Зарегистрирован: 14.02.2017

Хочу внести своии 5 копеек касаемо баланса. В теме не увидел нормального решения и решил предложить свое. Здесь код получения баланса и отправки его в ответном сообщении(вернне часть, все лишнее я убрал). Иногда баланс мне приходит в виде +CUSD:0,"OCTATOK 123.45 p.",72.  "ОСТАТОК" и "р." написаны латиницей. Но чаще баланс приходит  вместе с рекламой на русском языке и как писалось выше, формат сообщения меняется на PDU (+CUSD: 0,004F0043005400410054004F004B0020003100350038...). Каждый символ закодирован двумя байтами, причем латинские буквы, цифры и знаки начинаются с 00, а оставшийся  байт - это символы таблицы ASCII. Русские буквы начинаются с 04 и они нас не интересуют. Нам необходимо выделить строку с балансом из этого хаоса чисел и преобразовать его в строку. Буфер SofrwareSerial я увеличил до 250. Также под строку из буфера я отвел 250 байт для того, чтобы гарантировано поймать \r для дальнейшей обработки строки. Надеюсь кому-нибудь поможет.

//Размер буфера SoftwareSerial необходимо увеличить до 250 байт. 
//В файле C:\Program Files\arduino IDE\hardware\arduino\avr\libraries\SoftwareSerial\src\SoftwareSerial.h в строке
//#define _SS_MAX_RX_BUFF 64 // RX buffer size поменять размер с 64 на 250.
#include <SoftwareSerial.h>
SoftwareSerial serialGSM(7,8);
String str="";
String substr="";
String number;
String substr4="";
int8_t j,z;
char Char[69];
char Char4[5];
int8_t myArray[17];

void setup() {   
  serialGSM.begin(9600);  
  //AT+IFC=1,1; AT+CMGF=1; AT+CLIP=1; AT+CNMI=2,2,0,0,0; AT+CSCS="GSM"; AT+IPR=9600; ATE0 настройки уже в памяти GSM
  delay(300);  
  str.reserve(250);//устанавливаем размер строки 250 байт   
}

void loop() { 
  
  if (!serialGSM.available())//ждем, когда появятся данные
  return;  
    
  char symb=serialGSM.read();    
  
  if (symb=='\r')//если конец строки
  {   
    if (str.startsWith("+CMT"))//если это СМС
    {      
      number=str.substring(6,20);//сохраняем номер для возможного ответного сообщения           
    }    

    else if (str=="balance")
    {
      serialGSM.print("AT+CUSD=1,\"*105#\"\r");//Tele2        
    }
    
    else if (str.startsWith("+CUSD"))
    {      
      if (str.length()>30)//если ответ пришел в виде +CUSD: 0,004F0043005400410054004F004B0020003100350038...
      {
        z=0;     
        substr=str.substring(str.indexOf("004F"),str.indexOf("002004"));//выделяем строку с балансом
        substr.toCharArray(Char,substr.length()+1);//копируем символы строки в буфер Char       
        for (j=0; j<substr.length(); j++)
        {
          substr4=substr4+Char[j];
          if ((j+1)%4==0)//собираем строку из 4-х символов
          {
            substr4.toCharArray(Char4,5);//копируем символы строки в буфер Char4
            int result=strtol(Char4,0,16);//преобразуем строку в шестнадцатиричное число, тем самым отбрасывая два нуля впереди
            myArray[z]=result;//сохраняем число в массиве          
            substr4="";
            z=z+1;          
          }        
        }           
        serialGSM.print("AT+CMGS="+number+"\r");        
        delay(200);      
        for (z=0; z<substr.length()/4; z++)
        {        
          serialGSM.write(myArray[z]);
        }
        delay(200);      
        serialGSM.println((char)26);
        delay(100);
      }
      else//если ответ пришел в виде +CUSD: 0,"OCTATOK 123.45 p."
      {
        substr=str.substring(10,str.indexOf(".\""));
        serialGSM.print("AT+CMGS="+number+"\r");        
        delay(200);    
        serialGSM.print(substr);
        delay(200);      
        serialGSM.println((char)26);
        delay(100); 
      }         
    }
     str="";
  }
  else if (symb!='\n')
  {
    str=str+String(symb);
  }  
}

 

energokom
Offline
Зарегистрирован: 31.07.2016

obuhanoe пишет:

Добрый день, никто не сталкивался при запросе NTP времени (пока юзал www.ntp-servers.net) командой AT+CNTP("AT+CNTP=\"88.147.254.227\",12") - иногда(редко) время синхронизируется неверно, например +4 или +5 часов к моему. Причем синхронизируется через минуту и все нормально. С указанного сайта я использовал ip 1 яруса, перешел на ip 2 яруса - пока не замечал глюков.

P.S. - на 2 ярусе тоже была обнаружена ошибка синхронизации - 07.02.2017 20:50:11(время до синхронизации) |  08.02.2017 01:49:47 (время после синхронизации)

Ни у кого нет мыслей почему так происходит?

Потестирую на www.time.nist.gov - отпишусь позже.


День добрый.
У меня время вообще не хочет синхронизироваться
Не AT+CLTS=1
Не AT+CNTP, выдает + CNTP: 64.
Перепробовал несколько серверов.
Инет работает, данны отправляются, принимаются, а синхронизация с сервером времени не происходит.

В чем может быть проблема?

energokom
Offline
Зарегистрирован: 31.07.2016

команда AT+CNTP синхронизации с сервером врмени.
AT+CNTP ="сервер времени", time zone

obuhanoe
Offline
Зарегистрирован: 18.05.2016

покажите код синхронизации и настройки сервера NTP, у вас sim800l?

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

а не проще время из GSM сети брать?   или нужно ну оочень точное время?

energokom
Offline
Зарегистрирован: 31.07.2016

Short Circuit пишет:

а не проще время из GSM сети брать?   или нужно ну оочень точное время?


AT+CLTS=1 из сети тоже не берет.
Или есть другой способ?

obuhanoe
Offline
Зарегистрирован: 18.05.2016

Short Circuit пишет:

а не проще время из GSM сети брать?   или нужно ну оочень точное время?

у меня данные передаются на сервер по GPRS, почему и не получать время в раз сутки по NTP

zalias7
Offline
Зарегистрирован: 18.03.2015

energokom пишет:
Short Circuit пишет:

а не проще время из GSM сети брать?   или нужно ну оочень точное время?

AT+CLTS=1 из сети тоже не берет. Или есть другой способ?

 

AT+CLTS=1
AT&W
и после  перезагруски будет показывать

obuhanoe
Offline
Зарегистрирован: 18.05.2016

energokom пишет:
Short Circuit пишет:

а не проще время из GSM сети брать?   или нужно ну оочень точное время?

AT+CLTS=1 из сети тоже не берет. Или есть другой способ?

 

https://forums.adafruit.com/viewtopic.php?f=19&t=58002#p294235

energokom
Offline
Зарегистрирован: 31.07.2016

zalias7 пишет:

energokom пишет:
Short Circuit пишет:

а не проще время из GSM сети брать?   или нужно ну оочень точное время?

AT+CLTS=1 из сети тоже не берет. Или есть другой способ?

 

AT+CLTS=1
AT&W
и после  перезагруски будет показывать


Дело в операторе.
На МТС приходит время сети, на мегафон не приходит.
Испробовал 3 симки от Мегафон.

Кто-нибудь синхронизировал время с симкой мегафон?

obuhanoe
Offline
Зарегистрирован: 18.05.2016

energokom пишет:
zalias7 пишет:

energokom пишет:
Short Circuit пишет:

а не проще время из GSM сети брать?   или нужно ну оочень точное время?

AT+CLTS=1 из сети тоже не берет. Или есть другой способ?

 

AT+CLTS=1
AT&W
и после  перезагруски будет показывать

Дело в операторе. На МТС приходит время сети, на мегафон не приходит. Испробовал 3 симки от Мегафон. Кто-нибудь синхронизировал время с симкой мегафон?

у меня симка мегафон, чуть позже попробую и отпишусь

zalias7
Offline
Зарегистрирован: 18.03.2015

Как вариант: посылаеш себе смс и получив, берёш время

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

zalias7 пишет:

Как вариант: посылаеш себе смс и получив, берёш время

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

energokom
Offline
Зарегистрирован: 31.07.2016

zalias7 пишет:

Как вариант: посылаеш себе смс и получив, берёш время


Всё же хотелось бы разобраться с синхронизацией по серверу времени.
AT+CNTP.
Но почему-то ответ +CNTP: 64

obuhanoe
Offline
Зарегистрирован: 18.05.2016

obuhanoe пишет:

energokom пишет:
zalias7 пишет:

energokom пишет:
Short Circuit пишет:

а не проще время из GSM сети брать?   или нужно ну оочень точное время?

AT+CLTS=1 из сети тоже не берет. Или есть другой способ?

 

AT+CLTS=1
AT&W
и после  перезагруски будет показывать

Дело в операторе. На МТС приходит время сети, на мегафон не приходит. Испробовал 3 симки от Мегафон. Кто-нибудь синхронизировал время с симкой мегафон?

у меня симка мегафон, чуть позже попробую и отпишусь

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

Как бы мегафон победить, без отправок СМС?

obuhanoe
Offline
Зарегистрирован: 18.05.2016
// NTP
  Serial3.println("AT+CNTPCID=1");
  delay(100);
  Serial3.println("AT+CNTP=\"216.229.0.179\",12"); // www.time.nist.gov 216.229.0.179 88.147.254.227
  delay(100);

Serial3.println("AT+CNTP");
        delay(100);

Serial3.println("AT+CCLK?");
           delay(100);

energokom В такой последоватльности у тебя?

dioxin
Offline
Зарегистрирован: 02.11.2016

Модуль часов стоит 40 рублей.. Точности хватит лет на 10.

Я себе вот такой купил: https://ru.aliexpress.com/item/DS3231-AT24C32-IIC-Module-Precision-Clock-Module-DS3231SN-for-Arduino-Memory-module-Free-Shipping/32418233172.html?spm=2114.13010708.0.0.Bp65BU

obuhanoe
Offline
Зарегистрирован: 18.05.2016

dioxin пишет:

Модуль часов стоит 40 рублей.. Точности хватит лет на 10.

Я себе вот такой купил: https://ru.aliexpress.com/item/DS3231-AT24C32-IIC-Module-Precision-Clock-Module-DS3231SN-for-Arduino-Memory-module-Free-Shipping/32418233172.html?spm=2114.13010708.0.0.Bp65BU

а у меня вот такой шилд https://ru.aliexpress.com/item/Data-logger-shield-for-Arduino-MicroSD-card-RTC-Assembled/32530882474.html, и на нем к сожалению DS1307 - и синхронизация необходима.

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

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

obuhanoe
Offline
Зарегистрирован: 18.05.2016

на просторах али - кто-нибудь встречал шилды не DS1307?

sinner82
Offline
Зарегистрирован: 12.01.2017

obuhanoe пишет:

на просторах али - кто-нибудь встречал шилды не DS1307?

пост 467

obuhanoe
Offline
Зарегистрирован: 18.05.2016

sinner82 пишет:

obuhanoe пишет:

на просторах али - кто-нибудь встречал шилды не DS1307?

пост 467

разве это шилд?

вот это шилд с RTC и SD на борту https://ru.aliexpress.com/item/Data-logger-shield-for-Arduino-MicroSD-card-RTC-Assembled/32530882474.html

energokom
Offline
Зарегистрирован: 31.07.2016

obuhanoe пишет:

// NTP
  Serial3.println("AT+CNTPCID=1");
  delay(100);
  Serial3.println("AT+CNTP=\"216.229.0.179\",12"); // www.time.nist.gov 216.229.0.179 88.147.254.227
  delay(100);

Serial3.println("AT+CNTP");
        delay(100);

Serial3.println("AT+CCLK?");
           delay(100);

energokom В такой последоватльности у тебя?

Да, только я прям в мониторе порта тестирую.
Предворительно подключаюсь к GPRS.

obuhanoe
Offline
Зарегистрирован: 18.05.2016

а знаете я тоже такую ошибку кажется получал, GPRS   был активным (диод мигает часто), а на балансе было 0 рублей и получал или 61 или 64 ответ.

покажите ответы на каждую команду 

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

obuhanoe пишет:

// NTP
  Serial3.println("AT+CNTPCID=1");
  delay(100);
  Serial3.println("AT+CNTP=\"216.229.0.179\",12"); // www.time.nist.gov 216.229.0.179 88.147.254.227
  delay(100);

Serial3.println("AT+CNTP");
        delay(100);

Serial3.println("AT+CCLK?");
           delay(100);

energokom В такой последоватльности у тебя?

проверил, в терминалке у меня этот код работает

 

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

кстати, вот вам еще один способ вытянуть у сим800 время из "интернета"  

AT+CIPGSMLOC=2,1

ответ
+CIPGSMLOC: 0,2017/02/26,18:28:45

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

Блин.. надо будет подкинуть идею программмистам а симкоме - для сим800 сделать в команде параметр AT+CIPGSMLOC=?

+CIPGSMLOC: (1,2),(1-3)
+CIPGSMLOC: (1,2,3),(1-3) - добавить параметр 3, чтобы автоматом меняло 
в  команде:
AT+CCLK?
+CCLK: "04/01/01,00:25:38+00"
 
а то сейчас не меняет, итого хочешь - через сервер, а хочешь - через более простую команду.
 
Хотя в программе потом нужно всеравно вытягивать время, верно?  Ее можно и из 
AT+CIPGSMLOC=2,1
+CIPGSMLOC: 0,2017/02/26,18:48:11
вытянуть, без разницы, может из второго показания даже проще, там уже запятыми разделили все.

 

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

alfik777 пишет:

dr.lmg пишет:

AT команды я вообще не использую.

А как же Вы управляете модулем ,как отправляете СМС?

 

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

obuhanoe
Offline
Зарегистрирован: 18.05.2016

Подскажите по такому вопросу - когда принимаешь сообщение с помощью АТ команд, приходится использовать переменную (String например) и так как она заполняется в цикле, ее нужно сделать либо глобальной либо static, а это отжирает память на объем входящего СМС. Никак не могу сообразить как считать данные внутри одной функции, чтобы переменная была локальной.

небольшой пример ниже.

void read_buffer_SIM800L(){

    static boolean isStringMessage = false;
    static String currStr = "";
    static String currStr_head_at = "";  
  
    if (!Serial3.available())
       return;

    char currSymb = Serial3.read();    
    if ('\r' == currSymb) {
        if (isStringMessage) {
            //если текущая строка - SMS-сообщение или график с сайта,
            //отреагируем на него соответствующим образом
            isStringMessage = false; 
           // что-то делаем

        } else {
        
            if (currStr.startsWith("+CMT")) {
                //если текущая строка начинается с "+CMT",
                //то следующая строка является сообщением
                isStringMessage = true;
                currStr_head_at = currStr;        
                
            } 
          }         
        
      currStr = "";
          
    } else if ('\n' != currSymb) {
        currStr += String(currSymb);
      }    
    
}


void loop() {

   // вычитываем буфер 
  read_buffer_SIM800L(); 
}

Спасибо.

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

что значит либо глоабльн либо статик??  

"Ключевое слово static используется для создания переменных, которые будут видны только одной функции. Однако, в отличие от локальных переменных, которые создаются и уничтожаются при каждом вызове функции, переменные static сохраняют свое значение между вызовами."

между вызовами просто сохраняет свое значение и все! и в вашем лупе похоже она не видна, нужно все в леп засунуть, весь код.

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

делл

alfik777
alfik777 аватар
Offline
Зарегистрирован: 29.06.2015

Short Circuit пишет:

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

Что-то я не  помню ...Может это не я был?:-)

obuhanoe
Offline
Зарегистрирован: 18.05.2016

Short Circuit пишет:

что значит либо глоабльн либо статик??  

"Ключевое слово static используется для создания переменных, которые будут видны только одной функции. Однако, в отличие от локальных переменных, которые создаются и уничтожаются при каждом вызове функции, переменные static сохраняют свое значение между вызовами."

между вызовами просто сохраняет свое значение и все! и в вашем лупе похоже она не видна, нужно все в леп засунуть, весь код.

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

Я хочу реализовать read_buffer_SIM800L так, чтобы вычитать буфер за раз, и тогда переменную currStr можно было объявить как локальную.

Пробывал добавить цикл в read_buffer_SIM800L, но не удачно, возможно нужно добавить что-то еще в условия while

void read_buffer_SIM800L(){

    /*static*/ boolean isStringMessage = false;
    /*static*/ String currStr = "";
    /*static*/ String currStr_head_at = "";  
  
    if (!Serial3.available())
       return;

  while (Serial3.available()) { // ПРОБУЮ Вычитать за раз 
    char currSymb = Serial3.read();    
    if ('\r' == currSymb) {
        if (isStringMessage) {
            //если текущая строка - SMS-сообщение или график с сайта,
            //отреагируем на него соответствующим образом
            isStringMessage = false; 
           // что-то делаем

        } else {
        
            if (currStr.startsWith("+CMT")) {
                //если текущая строка начинается с "+CMT",
                //то следующая строка является сообщением
                isStringMessage = true;
                currStr_head_at = currStr;        
                
            } 
          }         
        
      currStr = "";
          
    } else if ('\n' != currSymb) {
        currStr += String(currSymb);
      }    
  }  
}

 

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

obuhanoe пишет:

 

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

так она видна толкьо внутри вашего рид-буфера, а в лупе насколько я понимаю - неа.. 

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

alfik777 пишет:

Short Circuit пишет:

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

Что-то я не  помню ...Может это не я был?:-)

 

давали пример еще из вашей сигнализации,  там в буфер были собраны  сообщения для тревожных смс..

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

obuhanoe
Offline
Зарегистрирован: 18.05.2016

Short Circuit пишет:

obuhanoe пишет:

 

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

так она видна толкьо внутри вашего рид-буфера, а в лупе насколько я понимаю - неа.. 

мне в loop это переменная и не нужна, в строке 17 // что-то делаем

я вызовую функцию и передам в нее значение вот так.  И переменная больше не нужна. А так она отожрала память на размер входящего СМС.

listen_sms(currStr_head_at, currStr); 

void listen_sms(const String & head_at, const String & data_sms) 

общий вид.



void listen_sms(const String & head_at, const String & data_sms) {
	
	// получили СМС
}

void read_buffer_SIM800L(){

    /*static*/ boolean isStringMessage = false;
    /*static*/ String currStr = "";
    /*static*/ String currStr_head_at = "";  
  
    if (!Serial3.available())
       return;

  while (Serial3.available()) {
    char currSymb = Serial3.read();    
    if ('\r' == currSymb) {
        if (isStringMessage) {
            //если текущая строка - SMS-сообщение или график с сайта,
            //отреагируем на него соответствующим образом
            isStringMessage = false; 
           // что-то делаем
		   listen_sms(currStr_head_at, currStr); 

        } else {
        
            if (currStr.startsWith("+CMT")) {
                //если текущая строка начинается с "+CMT",
                //то следующая строка является сообщением
                isStringMessage = true;
                currStr_head_at = currStr;        
                
            } 
          }         
        
      currStr = "";
          
    } else if ('\n' != currSymb) {
        currStr += String(currSymb);
      }    
  }  
}


void loop() {

   // вычитываем буфер 
  read_buffer_SIM800L(); 
}

 

obuhanoe
Offline
Зарегистрирован: 18.05.2016

Проблему решил, забыл добавить delay(10) при чтении из буфера.

void listen_sms(const String & head_at, const String & data_sms) {
	
	// получили СМС
}

void read_buffer_SIM800L(){

    /*static*/ boolean isStringMessage = false;
    /*static*/ String currStr = "";
    /*static*/ String currStr_head_at = "";  
  
    if (!Serial3.available())
       return;

  while (Serial3.available()) {
    char currSymb = Serial3.read();    
    if ('\r' == currSymb) {
        if (isStringMessage) {
            //если текущая строка - SMS-сообщение или график с сайта,
            //отреагируем на него соответствующим образом
            isStringMessage = false; 
           // что-то делаем
		   listen_sms(currStr_head_at, currStr); 

        } else {
        
            if (currStr.startsWith("+CMT")) {
                //если текущая строка начинается с "+CMT",
                //то следующая строка является сообщением
                isStringMessage = true;
                currStr_head_at = currStr;        
                
            } 
          }         
        
      currStr = "";
          
    } else if ('\n' != currSymb) {
        currStr += String(currSymb);
      }  
  delay(10); // Тут добавил

  }  

}


void loop() {

   // вычитываем буфер 
  read_buffer_SIM800L(); 
}

 

alfik777
alfik777 аватар
Offline
Зарегистрирован: 29.06.2015

Short Circuit пишет:

давали пример еще из вашей сигнализации,  там в буфер были собраны  сообщения для тревожных смс..

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

Я+удачно скомпоновано?? Не, точно не я:-))) А если серьезно, в том проекте что я делал, сообщения формировались непосредственно в соответсвующих функциях. Да и тревожная только одна смс была, остальные информационные для  отправки  или конфигурационные входящие. Так что точно не я.

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

Может и кто другой.. давно было блин.

Смотрю пора учится рптимизировать код  передачи ат команд на модуль. а то блин жрет столько что  под конеч написания всех хотелок в код - можно застрелится. Не помещается в память, режет смс, да и вообще может  в итоге очень нестабильно работать. Тем более в интернет уже хочется чтото передавать...

sinner82
Offline
Зарегистрирован: 12.01.2017

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


const String str[] = {" ",":","---","!","ALARM","ON","OFF","SMS"};

void setup() 
{
 Serial.begin(9600);
 Serial.println(str[4] + str[0] + str[5] + str[3] + str[3] + str[3]);
 delay(500);
 Serial.println(str[2] + str[0] + str[7] + str[1] + str[0] + str[2]);
 delay(500);
 Serial.println(str[4] + str[0] + str[6] + str[3] + str[3] + str[3]);
}

void loop(){}

Надеюсь, поможет.

obuhanoe
Offline
Зарегистрирован: 18.05.2016

Short Circuit пишет:

Может и кто другой.. давно было блин.

Смотрю пора учится рптимизировать код  передачи ат команд на модуль. а то блин жрет столько что  под конеч написания всех хотелок в код - можно застрелится. Не помещается в память, режет смс, да и вообще может  в итоге очень нестабильно работать. Тем более в интернет уже хочется чтото передавать...

из-за чего жрет? Вам не хвататет 8кб под переменные?

у меня общение с sim800L только по АТ командам: SMS(прием смс), NTP(синхронизация времени), GPRS(отправка на сайт и скачивание с сайта) - могу помочь.

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

sinner82 пишет:

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


const String str[] = {" ",":","---","!","ALARM","ON","OFF","SMS"};

void setup() 
{
 Serial.begin(9600);
 Serial.println(str[4] + str[0] + str[5] + str[3] + str[3] + str[3]);
 delay(500);
 Serial.println(str[2] + str[0] + str[7] + str[1] + str[0] + str[2]);
 delay(500);
 Serial.println(str[4] + str[0] + str[6] + str[3] + str[3] + str[3]);
}

void loop(){}

Надеюсь, поможет.

 

да, этот вариант очень даже мне нравится. А еще  есть примеры? const String str[]  сохраняет в флешпамять? str   начинается с str[0] ? 

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

взял переписал инициализацию модема  добавив в скетч - const String strAT[] = {"ATE0","AT+CPBR=1","AT+CSCS=\"GSM\"","AT+CLIP=1","AT+CPBS=\"SM\"","AT+IFC=1,1","AT+CMGF=1",

"AT+CNMI=1,2,2,1,0","AT+DDET=1,0,1"}; и естественно вместо АТ команд вписал уже  (strAT[1]) и ит.д...  вышло +6% !! динамической памяти в сообщении компилятора.

то есть мой первый вариант хавал на 6% динамической памяти меньше! как же так?  Как же тогда экономить динамическую память в проце?

sinner82
Offline
Зарегистрирован: 12.01.2017

попробуйте так:

const String str[] = {"AT","+","="};

Serial.println(str[0] + str[1] + "CPBR" + str[2] + "1"); //"AT+CPBR=1"

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

А уменьшить флеш память получится только правильным использованием формата переменных, именно поэтому я почти никогда не использую int. Так же присмотритесь к define#.

Если какие-то куски кода повторяются в программе(например активация каналов), запихните их в отдельный void, это экономит очень много памяти.

obuhanoe
Offline
Зарегистрирован: 18.05.2016

Short Circuit пишет:

взял переписал инициализацию модема  добавив в скетч - const String strAT[] = {"ATE0","AT+CPBR=1","AT+CSCS=\"GSM\"","AT+CLIP=1","AT+CPBS=\"SM\"","AT+IFC=1,1","AT+CMGF=1",

"AT+CNMI=1,2,2,1,0","AT+DDET=1,0,1"}; и естественно вместо АТ команд вписал уже  (strAT[1]) и ит.д...  вышло +6% !! динамической памяти в сообщении компилятора.

то есть мой первый вариант хавал на 6% динамической памяти меньше! как же так?  Как же тогда экономить динамическую память в проце?

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

Если Вы раньше использовали инициализацию модема и команыд были только внутри ф-ии, то память под них выделялась  в момент вызова ф-ии и  уничтожалась при выходе из нее. А переписав на  const String strAT[]  память выделилась сразу, так объявлена как глобальная перменная.

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

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

obuhanoe
Offline
Зарегистрирован: 18.05.2016

Short Circuit пишет:

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

Поделитесь с нами )

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

http://arduino.ru/forum/obshchii/neoway-m590#comment-267372

 

испытал на паре переделанных скетчей, люблю я много разных сообщений выводить в сериал или в смс. уменьшить занятость памяти в 3-4 раза! - давно так ничему не удивлялся. И главное все как часы работает, хотя думаю подводные камни таки должны быть, хз.. но пока все как часы.

obuhanoe
Offline
Зарегистрирован: 18.05.2016

Short Circuit пишет:

http://arduino.ru/forum/obshchii/neoway-m590#comment-267372

 

испытал на паре переделанных скетчей, люблю я много разных сообщений выводить в сериал или в смс. уменьшить занятость памяти в 3-4 раза! - давно так ничему не удивлялся. И главное все как часы работает, хотя думаю подводные камни таки должны быть, хз.. но пока все как часы.

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

String str="123";
Serial.println(F(str));
//или
Serial.println(F(str + "qwerty"));

У меня получилось только так - 

Serial.println(F("123"));

 

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

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