Не хватает памяти в Nano для получения инфы после GET запроса

Vasa211
Offline
Зарегистрирован: 29.09.2017

Брал скетч ТУТ

#include <SoftwareSerial.h>

String SID = "*****";
String PAS = "*****";
String IP = "sait.ru";

String s = "";
int i=0;
String ii = "";
String GET = "";

SoftwareSerial softserial(10, 11); // RX, TX

void setup() {
  softserial.begin(9600);
  Serial.begin(9600);

  softserial.println("AT");
  sr();

  softserial.println("AT+CWMODE=1");
  sr();
  delay(1000);
  
  softserial.println("AT+CWJAP=\"" + SID + "\",\"" + PAS + "\"");
  sr();
  delay(5000);
  
}

void loop() {
  ii=i+1;
  i=i+1;
   GET = "GET /?test="+ ii +" HTTP/1.1\r\nHost: tceh.artgrain.pro\r\n";
   softserial.println("AT+CIPSTART=\"TCP\",\"" + IP + "\",80");
  sr();
  delay(500);
  
  softserial.print("AT+CIPSEND=");
  softserial.println(GET.length() + 2);
  sr();
  delay(100);
  
   softserial.println(GET);
   sr(); 
 
   delay(10000);
}

void sr() {
  while (softserial.available()) {
    delay(20);
    if (softserial.available() > 0) {
      char c = softserial.read();
      s += c;
    }
  }
  Serial.println(s);
  s = "";
}

 

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

Вот что от сервера приходит

 

+IPD,173:HTTP/1.1 200 OK
Server: nginx
Date: Tue, 10 Oct 2017 21:29:17 GMT
Content-Type: text/html; charse

 

toc
Offline
Зарегистрирован: 09.02.2013

1. не понятно зачем 52 строка. хотя бы уменьшите задержку в 10 раз

2. не накапливайте (55 стр) а сразу выводите в сериал символ

3. от String избавитесь - много памяти освободите

4. Не знаю какая именно у вас нана. Но знайте, что у вас не больше 2048 байт оперативной памяти на всё. А это 2 килобайта или 0,002 мегабайта примерно.

Vasa211
Offline
Зарегистрирован: 29.09.2017

Спасибо. Вечером попробую

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Vasa211 пишет:

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

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

Ну а так, по мелочи, желательно избавиться от String и перенести текстовые константы в PROGMEM.

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

если я правильно понял - вы не видите полный ответ по RX / TX ?

у меня аналогично было при получении ответа от GSM модема по SoftwareSerial,

менял исходники, сейчас попробую найти в каком месте.

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

..........\arduino\avr\libraries\SoftwareSerial\src

SoftwareSerial.h

я увеличивал вот это число:

 

#define _SS_MAX_RX_BUFF 128 // RX buffer size

 

Vasa211
Offline
Зарегистрирован: 29.09.2017

Когда было меньше переменных ответ полный призодил

еще не менял код чтоб проверить

 

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

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

andycat пишет:

.я увеличивал вот это число:

 

#define _SS_MAX_RX_BUFF 128 // RX buffer size

 

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

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

я накапливал сразу в тип String а не в char как у вас, а потом уже парсил полный текст

  if (gsm.available()) {
    while (gsm.available()) {
      val += char(gsm.read());
      delay(50);
    }
    Serial.println(val);
    MainCommand();
    val = "";
  } else {
    delay(50);
  }

задержка можкт и не нужна - зависит от "тормознутости" конкретного устройства

Vasa211
Offline
Зарегистрирован: 29.09.2017

Тоже попробую

а нащет парсить полный текст, как его можно отобрать?

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

andycat пишет:

я накапливал сразу в тип String а не в char как у вас, а потом уже парсил полный текст

  if (gsm.available()) {
    while (gsm.available()) {
      val += char(gsm.read());
      delay(50);
    }
    Serial.println(val);
    MainCommand();
    val = "";
  } else {
    delay(50);
  }

задержка можкт и не нужна - зависит от "тормознутости" конкретного устройства

Задержка на 50мс после каждого символа?!  - не просто не нужна. а скорее убийственна для связи... Удивляюсь, как при ней вы вообще что-то могли принять... У вас только один заголовок HTTP будет приниматься секунд пятнадцать

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

ну например так, но если команд более 5 рекомендуется уже более серьезные алгоритмы

void MainCommand() {
  val.toLowerCase();
  String cmd;
  if ((val.indexOf("+cmgr: ") > -1)) {
    String vt = val.substring((val.indexOf("+cmgr: ") + 7), val.length());
    if ((vt.indexOf("rec unread") > -1)) {
      if ((vt.indexOf(AlarmNumber) > -1)) {
        val = vt.substring((vt.indexOf(AlarmNumber) + 15), vt.length());
        //case command
        SMSCommand();
        //---
        val = "";
      }
    }
  } else {
    //--other command
    if ((val.indexOf("reset") > -1)) {
      timerResetModem = 0;
      timerGetTemp = 0;
      curr_temp = 0;
      ResetModem();
    }
    if ((val.indexOf("smson") > -1)) {
      SMSoff = false;
    }
    if ((val.indexOf("+cusd: 2,") > -1)) {
      String vt = val.substring((val.indexOf("+cusd: 2,") + 10), val.length());
      vt.toUpperCase();
      boolean ft = true;
      for (int i = 0; i <= 3 ; ++i) {
        int ti = int(vt[i]);
        if (!(((ti >= 48) && (ti <= 57)) || ((ti >= 65) && (ti <= 70)))) {
          ft = false;
        }
      }
      if (ft) {
        String vo = "";
        for (int i = 0; i <= vt.length(); i += 4) {
          int tf = StrHtoInt(vt.substring(i, (i + 4)));
          if (tf <= 127) {
            vo += char(tf);
          }
        }
        SendSMS(vo);
      } else {
        if (vt.indexOf('"') > -1) {
          vt = vt.substring(0, vt.indexOf('"'));
        }
        SendSMS(vt);
      }
    }
    if ((val.indexOf("smsoff") > -1)) {
      SMSoff = true;
    }
    if ((val.indexOf("balancetele2") > -1)) {
      // get balance phone
      cmd = "ATD"; cmd += BalanceNumberTele2; cmd += ";";
      gsm.println(cmd);
      delay(500);
    }
    if ((val.indexOf("balancemegafon") > -1)) {
      // get balance phone
      cmd = "ATD"; cmd += BalanceNumberMegafon; cmd += ";";
      gsm.println(cmd);
      delay(500);
    }
    if ((val.indexOf("delete") > -1)) {
      for (int i = 1; i <= 8; ++i) {
        cmd = "AT+CMGD="; cmd +=  String(i);
        gsm.println(cmd);
        delay(500);
      }
    }
    if ((val.indexOf("gettemp") > -1)) {
      SendSMS("");
    }
    if ((val.indexOf("+cmti: ") > -1)) {
      String vt = val.substring((val.indexOf("+cmti: ") + 12), val.length());
      cmd = "AT+CMGR="; cmd += vt;
      gsm.println(cmd);
      delay(500);
    }
    if ((val.indexOf("+csq: ") > -1)) {
      String vt = val.substring((val.indexOf("+csq: ") + 6), val.length());
      if (vt.indexOf(",") > -1) {
        vt = vt.substring(0, (vt.indexOf(",")));
      }
      vt.trim();
      int vl = vt.length();
      if (vl <= 0) {
        HardStatus = 226;
        ShowStatus;
        return;
      }
      if (vl == 1 ) {
        HardStatus = (int(vt[0])) - 48;
      }
      if (vl == 2 ) {
        int d1 = (int(vt[0])) - 48;
        d1 *= 16;
        HardStatus = d1 + (int(vt[1])) - 48;
      }
      ShowStatus();
    }
    //-- end other command
  }
}

 

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

b707 пишет:

andycat пишет:

жкт и не нужна - зависит от "тормознутости" конкретного устройства

Задержка на 50мс после каждого символа?!  - не просто не нужна. а скорее убийственна для связи... Удивляюсь, как при ней вы вообще что-то могли принять... У вас только один заголовок HTTP будет приниматься секунд пятнадцать

э... вы меня с ТС перепутали, я максимум SMS принимаю символов из 10 а не HTTP

Deamon
Offline
Зарегистрирован: 21.09.2017

А зачем использовать софтварный порт? Аппаратный занят?

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

andycat пишет:

э... вы меня с ТС перепутали, я максимум SMS принимаю символов из 10 а не HTTP

для СМС тоже задержка в 50мс не нужна. Хотя при длине в 10 символов это не так критично :)

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

Deamon пишет:

А зачем использовать софтварный порт? Аппаратный занят?

это был мой первый проект и я пошел по наипростейшему пути

 

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

Deamon пишет:

А зачем использовать софтварный порт? Аппаратный занят?

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

Jeka_M
Jeka_M аватар
Offline
Зарегистрирован: 06.07.2014

andycat пишет:

Deamon пишет:

А зачем использовать софтварный порт? Аппаратный занят?

это был мой первый проект и я пошел по наипростейшему пути

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

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

Jeka_M пишет:

andycat пишет:

Deamon пишет:

А зачем использовать софтварный порт? Аппаратный занят?

это был мой первый проект и я пошел по наипростейшему пути

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

да :) я не знал (дя и сейчас не знаю, т.к. пока не требуется, мне кажется это невозможно) как одновременно использовать консоль для тестирования и работать с COM портом модема

 

fogary
Offline
Зарегистрирован: 05.03.2016

Цитата:

int i=0;
String ii = "";
...
void loop() {
  ii=i+1;
...

Что и вот так то же можно?

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

откуда этот код?

fogary
Offline
Зарегистрирован: 05.03.2016

b707 пишет:

откуда этот код?

Из первого поста, строка 32.