• Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

Вычитать длинную страницу по SoftwareSerial

Junkie

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

Код:
void getsend() {
  String ans = "";
  String send_text = "GET /index.php?time HTTP/1.0\n\n";
  ans = set("AT+CIPMUX=1\nAT+CIPSTART=0,\"TCP\",\"192.168.0.104\",80");
  ans = set("AT+CIPSEND=0,"+String(send_text.length(),DEC));
  ans = set(send_text);
  Serial.println(ans);
  String ans_time = ans.substring(ans.indexOf("<time>")+6,ans.indexOf("</time>"));
  String ans_user = ans.substring(ans.indexOf("<user>")+6,ans.indexOf("</user>"));
  Serial.println(ans_time);
  Serial.println(ans_user);
  lcd.setCursor(0,0); lcd.print(ans_time);
  delay(5000);
}

String set(String cmd){
  String inData = "";
  mySerial.println(cmd);
  while ( mySerial.available() ) {
      inData = mySerial.readString();
  }
  return inData;
}
Вобщем то вот сами две простых функции. в getsend я отсылаю команды и вырезаю ответы, в set соответственно шлю команды.

Проблема в том что страница вычитывается не полностью, а обрывается не дойдя до конца, так же пробовал выводить mySerial.available() чтобы посмотреть сколько знаков доступно, по началу их 500 потом уменьшается до 400 и потом резко 150 и дальше вниз, это когда я их убавлял по одному с помощью Serial.read().

Сам код страницы незамысловатый
PHP:
echo '<time>'.$result1[0]['time'].'</time>'.PHP_EOL;
    echo '<user>'.encode_cyr($result2[0]['user']).'</user>'.PHP_EOL;
    echo '<trash>'.PHP_EOL; for($i=1;$i<901;$i++) { echo chr(65+floor($i/100)); if(($i%50)==0) echo " ".str_pad($i,4,"0",STR_PAD_LEFT)." ".PHP_EOL; } echo '</trash>';
просто выводит в тегах пользователя и время, еще для теста 900 случайных символов.

Так вот если я просто напишу в ардуине
Код:
if (mySerial.available()) { Serial.write(mySerial.read()); } if (Serial.available())   { mySerial.write(Serial.read()); }
соеденение напрямую ком порта с софтварным, то с помощью ESplorer можно хоть 5000 символов вычитать, и все приходит.

Как сделать чтобы ардуина не спотыкалась при чтении?
 

Junkie

Member
Очень похоже, потому что когда я вызываю еще какую-нибудь функцию, то ответ с сервера еще больше укорачивается, наверное как раз оперативка кончается, там в скетче пишет свободно 500 байт для локальных переменных. Спасибо за ответ. попробую похитрить с памятью, допустим всегда делать буфер на 5 символов, если в нем попадется слово <time>, читаем остальные символы пока снова не встретитя скобка
 

Junkie

Member
Кстати, может знаете способ как откинуть все заголовки из файла ответа
а то там в начале идет куча лишнего, вот бы только HTTP200OK и мои данные и всё
Код:
HTTP/1.1 200 OK
Date: Wed, 05 Oct 2016 17:21:58 GMT
Server: Apache/2.2.22 (Win32) mod_ssl/2.2.22 OpenSSL/1.0.1c PHP/5.3.13
X-Powered-By: PHP/5.3.13
Content-Length: 1146
Connection: close
Content-Type: text/html; charset=utf-8
 

Сергей_Ф

Moderator
Команда форума
@Junkie я бы эту обработку переложил на esp - у него памяти несравненно больше и 5000 байт он может обработать легко. Или перешел на работу с потоком (stream), там и буфер нужен только для полезных данных.
 

nikolz

Well-known member
Кстати, может знаете способ как откинуть все заголовки из файла ответа
а то там в начале идет куча лишнего, вот бы только HTTP200OK и мои данные и всё
Код:
HTTP/1.1 200 OK
Date: Wed, 05 Oct 2016 17:21:58 GMT
Server: Apache/2.2.22 (Win32) mod_ssl/2.2.22 OpenSSL/1.0.1c PHP/5.3.13
X-Powered-By: PHP/5.3.13
Content-Length: 1146
Connection: close
Content-Type: text/html; charset=utf-8
1) По ключевым словам или символам
2) По знакоместу полезной инфы
 

Junkie

Member
Еще небольшой вопрос.
Почему если я для вырезки тегов создам отдельную функцию, ну или просто отправлю строку с ответом в функцию.
Код:
void test(Strigh txt) { Serial.println(txt); }
ans = set(send_text);
//если я сделаю
test(ans);
//то ничего не напечатается, потому что в функции окажется пустая строка
 

Сергей_Ф

Moderator
Команда форума
@Junkie потому, что вы возвращаетесь ууазатель на локальную строку. К моменту печати, там может быть что угодно. Сразу после выхода указатель обычно указывает в правильное место, но делать так не стоит. Лучше работать с переменной определенной до вызова функции и передавать указатель на переменную как аргумент функции. Или использовать глобальные переменные.
 

Junkie

Member
Боль менее все отладил, в самой еспшке прошивка 0.9.2.2 AT, но вот беда при попытке частой отправки запросов постоянно вываливаются сообщения busy p..., busy s..., может посоветуете стабильную прошивку чтобы не зависала и работала на 9600. пробовал даже на сервере выставлять keep alive в 120 секунд чтобы один раз соединится и спамить запрсоами, все равно подвисает на этих busy а потом пишет unlink и привет :(
 

Andrey_w

New member
Кстати, может знаете способ как откинуть все заголовки из файла ответа
а то там в начале идет куча лишнего, вот бы только HTTP200OK и мои данные и всё
Код:
HTTP/1.1 200 OK
Date: Wed, 05 Oct 2016 17:21:58 GMT
Server: Apache/2.2.22 (Win32) mod_ssl/2.2.22 OpenSSL/1.0.1c PHP/5.3.13
X-Powered-By: PHP/5.3.13
Content-Length: 1146
Connection: close
Content-Type: text/html; charset=utf-8
Используйте header_remove();
и потом header('Status: 200 Ok');
А данные лучше в формате JSON и проще с ними работать будет.
 
Сверху Снизу