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"), он должен начать работать для каждого сообщения.

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

,

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" включительно.

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

,