Работа со строками и переменными

snowscape
snowscape аватар
Offline
Зарегистрирован: 15.10.2016

Третий день ломаю голову над отрывком кода из примера Arduino WebServer:

...
    boolean currentLineIsBlank = true;
    //char buf[150];                     
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();         //проблема здесь
        //buf[i]=c;
        if (c == '\n' && currentLineIsBlank) {         
          client.println("HTTP/1.1 200 OK");
          //if(strncmp("GET",buf,3)==0)   //или здесь
....

Если переменную "char c" заменить на "char buff[i]" все работает только до тех пор, пока не применяется строковая функция, например strcpy(buff, buff2). Как только используем строковую функцию (strcpy, strcat,strncmp,....) программа просто перестает работать.

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

Кто сталкивался!!! с подобной проблемой или знает!!! в чем причина, помогите, пока мозг себе не сломал!

snowscape
snowscape аватар
Offline
Зарегистрирован: 15.10.2016

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

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

Ну, по этому кусочку ничего не скажешь. Нужен код полнсотью. Лучше отдельно работающий и отдельно неработающий. А также информация, что у Вас за ардуина.

snowscape
snowscape аватар
Offline
Зарегистрирован: 15.10.2016

Данный кусочек со стандартного примера Ардуино Ide с небольшими изменениями:

#include <Ethernet.h>
byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
char buf[150];
IPAddress ip(192, 168, 1, 177);
EthernetServer server(80);
void setup() {
  Ethernet.begin(mac, ip);
  server.begin();}
void loop() {
  EthernetClient client = server.available();
  if (client) {
    boolean currentLineIsBlank = true;
    uint8_t ind=0;
    while (client.connected()) {
      if (client.available()) {
        buf[ind] = client.read();
        if ( buf[ind] == '\n' && currentLineIsBlank) {
          client.println("HTTP/1.1 200 OK");
          client.println...и т.д.
          ...
          client.println("</html>");
          //строковая функция, например strcpy
          strcpy(buf,"это небольшой пример"); 
          break;
        }
        if ( buf[ind]== '\n') {
          currentLineIsBlank = true;
        } else if ( buf[ind] != '\r') {
          currentLineIsBlank = false;
        }
      ind++;
      }
    }
    delay(1);
    client.stop();
  }
}

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

Рабочий код ничем не отличается от нерабочего. Два дня работало, сегодня в ходе доработки перестало. К сожалению код разобрал на винтики и как такого рабочий вариант не остался.

Ардуинка - promini (atmega328p).

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

Поставьте после 31 строки печать переменной ind в Serial. Мне кажется. что она у Вас растёт неуправляемо, переходит за 149 (и продолжает расти) и тогда строка 16 начинает гадить в произвольные места пмяти, затирая всё. что там было. 

Она может работать при коротких сеансах связи (когда не успевает вырасти до 150 - клиент раньше отконнектится), а при долгих - перерастает и распахивает память

snowscape
snowscape аватар
Offline
Зарегистрирован: 15.10.2016

Завтра попробую поставить ограничение наподобие

...
if (ind>149)
   ind=0;
...

но мне кажется это не поможет, т.к. сеансы одни и те же и длина одинаковая (в данном коде обрабатывается первая строка http запроса длина которого в моем случае не превышает 20 символов). Такое ощущение что я что то не учитываю, может библеотеку надо подключить дополнительную, может данные функции (strcpy, ...) ардуино на дух не переносит... как будто кодировка символов меняется при использовании данных функций. В общем раз 10 переписывал код в итоге вернулся к истокам, т.е. к пратически голому примеру. Возможно с классом String проблемы не будет, но очень уж не хочется переписывать весь код.

snowscape
snowscape аватар
Offline
Зарегистрирован: 15.10.2016

Всем доброго дня. С проблемой разобрался. Оказывается, конструкция:

      ....
     if ( buf[ind] == '\n' && currentLineIsBlank) {
18     .......
   
25     }
26 if ( buf[ind]== '\n'
27           currentLineIsBlank = true;
28  else if ( buf[ind] != '\r'
29           currentLineIsBlank = false;
30 ....

считывает не по строкам, а весь пакет целиком и соответственно буффер размером в 150 символов переполнялся. Необольшое изменение кода и все стало на свои места:

26 if ( buf[ind]== '\r'
27           currentLineIsBlank = true;
28  else 
29           currentLineIsBlank = false;
30

Спасибо Жень за "пинок" в нужное направление))). Проблема решена!