Циклы выходят из строя через ~ 5 минут при выполнении двух вызовов API каждые 10 секунд с использованием клиента WiFi.

wifi spi time mkr1000

У меня возникла проблема с вызовом цикла на Arduino MKR1000. Я попробовал решения, предложенные в этом вопросе, и обычно они работают в течение 5 минут, а затем рушатся. Я пытаюсь делать два вызова к разным API каждые 10 секунд и соответствующим образом обновлять что-то на Arduino, но циклы, похоже, теряют синхронизацию через несколько минут. Вот код - я пытался его сократить...

#include <Time.h>
#include <SPI.h>
#include <WiFi101.h>
#include "arduino_secrets.h"

// поместите сюда информацию о вашем локальном Wi-Fi
const char* ssid     = SECRET_SSID;
const char* password = SECRET_PASS;

const char* host = "bustime.mta.info";

void setup() {
  Serial.begin(9600);
  delay(10);
 // подключение к сети Wi-Fi
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(300);
    Serial.print(". ");
  }    
}

void loop() {
  Serial.println("START THE LOOP");
  // Используем класс WiFiclient для создания TCP-соединений
  WiFiClient client;
  WiFiClient client2;
  char * serviceDeliveryString = new char[40]();
  strcpy(serviceDeliveryString, "/ServiceDelivery");
  char * responseTimestampString = new char[40]();
  strcpy(responseTimestampString, "<ResponseTimestamp>");  
  char * TString = new char[40]();
  strcpy(TString, "T");

  if (!client.connect(host, 80)) {
    lcd.clear();
    lcd.gotoXY(0, 0);
    lcd.string(connectionFailed);
    delay(2000);
    return;
  }

  //подключаемся к данным расписания
  if (!client2.connect(host, 80)) {
    lcd.clear();
    lcd.gotoXY(0, 0);
    lcd.string(connectionFailed);
    delay(2000);
    return;
  }

  char * req1full = new char [100]();
  strcat(req1full, "GET /api/siri/stop-monitoring.xml?key=KEY&OperatorRef=MTA");
  strcat(req1full, " HTTP/1.1");
  client.println(req1full);
  client.println("Host: bustime.mta.info");
  client.println("Connection: close\r\n");

  char * req2full = new char [100]();
  strcat(req2full, "GET /api/where/schedule-for-stop/MTA_");
  strcat(req2full, stopNum);
  strcat(req2full, ".xml?");
  strcat(req2full, "key=KEY HTTP/1.1");
  Serial.println(req2full);
  client2.println(req2full);
  client2.println("Host: bustime.mta.info");
  client2.println("Connection: close\r\n");

  //Пауза достаточно долго, чтобы произошло соединение. Сделайте это дольше, если у вас есть проблемы.
  delay(1000);

  while(client.available()){
    if (client.findUntil(responseTimestampString, serviceDeliveryString)){
      Serial.println("inside client...");
      client.findUntil(TString, serviceDeliveryString);
      String mtaTime = client.readStringUntil('.');
      Serial.println(mtaTime);   
    }
    delay(10);
  }


  while(client2.available()){
    if (client2.findUntil("<currentTime>", "/data")){
      Serial.println("inside client2...");
      String mtaTime2 = client2.readStringUntil('<');
      Serial.println(mtaTime2);   
    }
    delay(10);
  }

  client.stop();
  client2.stop();
  delay(9000);

}

Вывод выглядит хорошо:

START THE LOOP
GET /api/where/schedule-for-stop/MTA_306762.xml?key=KEY HTTP/1.1
inside client...
22:13:38
inside client...
22:13:38
inside client2...
1541211218146
START THE LOOP
GET /api/where/schedule-for-stop/MTA_306762.xml?key=KEY HTTP/1.1
inside client...
22:13:51
inside client...
22:13:51
inside client2...
1541211231815
START THE LOOP
GET /api/where/schedule-for-stop/MTA_306762.xml?key=KEY HTTP/1.1
inside client...
22:14:04
inside client...
22:14:04
inside client2...
1541211244465

Но в конце концов что-то происходит с циклами, и это окончательный результат, когда он должен продолжать работать:

inside client...
22:19:02
inside client...
22:19:02
START THE LOOP
GET /api/where/schedule-for-stop/MTA_306762.xml?key=KEY HTTP/1.1
START THE LOOP
GET /api/where/schedule-for-stop/MTA_306762.xml?key=KEY HTTP/1.1
START THE LOOP

Есть предложения, как это исправить?

, 👍0

Обсуждение

есть ли ограничение на частоту или количество вызовов API bustime.mta.info?, @jsotola

Нет, я так не думаю., @garson

Подсказка: Возможна утечка памяти. Много «новых», но мало «удаленных» (malloc/free)., @Mikael Patel

спасибо @MikaelPatel, я вырезал «новое», и, похоже, оно работает нормально., @garson


1 ответ


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

1

Вы продолжаете вызывать new для выделения памяти, но никогда не освобождаете ее. Это утечка памяти, и в конце концов вы закончите. Вместо того, чтобы постоянно создавать новые массивы, почему бы вам не сделать их глобальными или статическими. Или даже просто локальные массивы, если они вам не нужны. На микроконтроллере вы действительно не хотите использовать new без крайней необходимости.

,

Я использовал «новый», чтобы все записи были инициализированы как отсутствующие. Однако я мог бы переместить все объявления массива перед циклом(). Или, может быть, в настройке()? СПАСИБО за ответ!, @garson

Что вы подразумеваете под «инициализировано как отсутствующее». Для меня эта фраза не имеет никакого смысла., @Delta_G

Если вы поместите определения массива в настройку, они будут локальными для настройки, и вы не сможете использовать их в цикле., @Delta_G

Если вы хотите использовать подобное «динамическое» распределение, рассмотрите возможность использования alloca(), поскольку он выделяет пространство в стеке и автоматически освобождает его после завершения функции., @Majenko