HTTP-запросы с использованием Arduino

Я использую этот простой HTTP-запрос Post для публикации некоторых значений в моем API из Arduino с помощью Switch. Каждый раз, когда я нажимаю переключатель, он отправляет разные значения в API.

void switch_led() {
bool SwitchReading = digitalRead(SWITCH);
if (SwitchReading == HIGH) {
Serial.println("Now pressed....");
state = state + 1;
if (state % 2 != 0) {
  digitalWrite(LED, HIGH);
  char data1[] = "{""LDRValue"": 88888888}";
  Serial.println("\nStarting connection to led server...");
  if (client.connect(server, 8040)) {
    Serial.println("connected to post server");
    client.println("POST /api/sensor HTTP/1.1");
    client.println("Host: 192.168.2.116:8040");
    client.println("Content-Type: application/json");
    client.print("Content-Length: ");
    client.println(sizeof(data1));
    client.println();
    client.print(data1);
    Serial.println("1.finish");
  }
  Serial.println("2.finish");
}
else {
  digitalWrite(LED, LOW);
  char data2[] = "{""LDRValue"": 1111111111}";
  Serial.println("\nStarting connection to led server...");
  if (client.connect(server, 8040)) {
    Serial.println("connected to post server");
    client.println("POST /api/sensor HTTP/1.1");
    client.println("Host: 192.168.2.116:8040");
    client.println("Content-Type: application/json");
    client.print("Content-Length: ");
    client.println(sizeof(data2));
    client.println();
    client.print(data2);
    Serial.println("3.finish");
  }
  Serial.println("4.finish");
}
delay(500);
   }
}

Это отлично работает для первого и второго постов как в Arduino, так и в API, но в третьем посте все работает отлично на Arduino, но на API требуется много времени (около 2 минут, чтобы получить пост). Четвертый и пятый посты тоже работают нормально, но шестой такой же, как третий. Зная, что мой API на 100% работает с Raspberry Pi и не имеет ошибок.

То же самое для PUT и GET.

После издания: После того, как я удалил номер порта из строки хоста и использовал strlen(data) вместо sizeof(data), запрос POST работает, но только для первых 7 постов. Вывод последовательного монитора на Arduino такой:

Attempting to connect to WPA SSID: WiFi-Repeater1

WiFi connected
SSID: WiFi-Repeater1
IP Address: 192.168.2.149
signal strength (RSSI):-66 dBm

Starting connection to post server...
connected to post server

Starting connection to post server...
connected to post server

Starting connection to post server...
connected to post server

Starting connection to post server...
connected to post server

Starting connection to post server...
connected to post server

Starting connection to post server...
connected to post server

Starting connection to post server...
connected to post server

Starting connection to post server...

Starting connection to post server...

Starting connection to post server...

До редактирования он всегда выдавал мне сообщение «подключено к почтовому серверу» и всегда отправлял сообщения, но, как я уже говорил, это занимает много времени на 3-м, 6-м, 9-м, 12-м постах... Теперь после 7-го поста сообщения не отправляются.

, 👍2

Обсуждение

Экранируйте кавычки в строках. Не включайте номер порта в заголовок HTTP-хоста. Используйте strlen() вместо sizeof()., @SoreDakeNoKoto

@TisteAndii какие цитаты выбрать?, @Bilal Sehwail

@TisteAndii, пожалуйста, посмотрите вывод в вопросе, @Bilal Sehwail


4 ответа


Лучший ответ:

0

Я понял, в чем проблема.

Для решения проблемы сеанс между Arduino и сервером должен завершаться после каждой публикации с помощью client.stop();

void switch_led() {
      bool SwitchReading = digitalRead(SWITCH);
      if (SwitchReading == HIGH) {
        state = state + 1;
        if (state % 2 != 0) {
          digitalWrite(LED, HIGH);
          char data1[] = "{""LDRValue"": 88888888}";
          Serial.println("\nStarting connection to post server...");
          if (client.connect(server, 8040)) {
            Serial.println("connected to post server");
            client.println("POST /api/sensor HTTP/1.1");
            client.println("Host: 192.168.2.116");
            client.println("Content-Type: application/json");
            client.print("Content-Length: ");
            client.println(strlen(data1));
            client.println();
            client.print(data1);
          }
          client.stop();
        }
        else {
          digitalWrite(LED, LOW);
          char data2[] = "{""LDRValue"": 11111111111}";
          Serial.println("\nStarting connection to post server...");
          if (client.connect(server, 8040)) {
            Serial.println("connected to post server");
            client.println("POST /api/sensor HTTP/1.1");
            client.println("Host: 192.168.2.116");
            client.println("Content-Type: application/json");
            client.print("Content-Length: ");
            client.println(strlen(data2));
            client.println();
            client.print(data2);
          }
          client.stop();
        }
       }
,

0

Я ДУМАЮ, что проблема может быть в операторе client.println(). Я считаю, что сообщения REST должны завершаться \r\n, и я думаю, что println просто делает \n. Так что если вы измените его на client.println("\r"), он должен начать работать для каждого сообщения.

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

,

Это не работает., @Bilal Sehwail

Нет, не значит, потому что должно быть client. println(sizeof(data2)); client.println(); client.print(data2); client.println("\r"); Я неправильно понял, что вы не добавили новую строку в конце сообщения., @Code Gorilla

Работает, но проблема та же. Первые 2 поста работают нормально, 3-му нужно много времени, 4-му и 5-му тоже, 6-й такой же, как 3-й., @Bilal Sehwail

3-й, 6-й, 9-й, .......и т.д. не работают как надо. Но все остальные посты работают на 100%, @Bilal Sehwail

Происходящая закономерность звучит так, как будто это какая-то утечка или нехватка ресурсов. Утечки памяти нет. Нужно ли вам отключиться или вызвать функцию, чтобы отметить, что вы закончили? Может быть, значения data1 и data2 требуют завершающего Null и дополнительного пространства, чтобы это учесть? Что на самом деле возвращает sizeof (data2), правильно ли это, будет ли лучше strlen(data2)? Ваш сервер ожидает 8-байтовые символы или UTF-16, следует ли вам определить это в сообщении?, @Code Gorilla

Пожалуйста, смотрите вывод в вопросе., @Bilal Sehwail

Итак, вопрос был таким: «Нужно ли вам отключиться или вызвать функцию, чтобы отметить завершение работы?» Рад, что проблема решена. :), @Code Gorilla


0

Возможно, вы захотите сделать больше, чем просто client.stop:

// убедитесь, что клиент чист
while (client.connected()) { while (client.available()) client.flush(); }
client.stop();

Кроме того, если вы используете WiFi Shield, вам, возможно, захочется взглянуть на известную проблему, при которой при неудачном подключении сокет не освобождается. Для безупречной работы требуется простой патч:

https://github.com/arduino-libraries/WiFi/issues/5

,

-1

Я заметил, что практически каждый пример веб-сервера Arduino, размещенный в сети, не соответствует стандарту HTTP. При получении запроса "GET" сервер должен проанализировать атрибут "Content-Length: xxx", чтобы получить "xxx", а затем прочитать xxx символов. При отправке веб-страницы клиенту следует вычислить длину запроса, опустив заголовки HTTP (все до тега "html"), а атрибут "Content-Length: xxx" следует включить в заголовок, где xxx — длина ответа от тега "html" до тега "/html" включительно.

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

,

Как это отвечает на вопрос? В коде в вопросе не отсутствует заголовок Content-Length. Если вы комментируете код в вопросе как решение своей проблемы, то это, очевидно, не ответ на вопрос., @gre_gor

Он подчеркивает, что автор делает правильно, на что оригинальный пост не обратил особого внимания. Я просто потратил много времени, чтобы разобраться в этом сам, и подумал, что выделение правильного использования Content-Length здесь может быть полезным для других., @Mr. Mxyxptlik