1

Проблема

Я отправляю измерения датчиков с Arduino в -> AWS APIGateway -> Lambda -> CloudWatch, который работает, но только на пару минут, затем отображается трассировка стека и программа останавливается.

Запрос

Ищу решения, которые ..

  • избегает трассировки стека
  • восстанавливается из трассировки стека и начинается заново
  • ускорить отправку данных (как можно ближе к раз в секунду!)
  • по-прежнему собирать точки данных во время отправки / получения данных (если я добавлю часть без комментариев во время получения ответа, ничего не происходит) -> Параллельное выполнение?

Пробовал до сих пор

До сих пор я заметил, что это может быть проблема времени, поскольку с большей "задержкой" требуется больше времени, чтобы получить ошибку. Я действительно просто хочу записать данные и, следовательно, раскомментировать часть кода, которая читает ответ APIGateway, таким образом, ошибка возникает раньше. Я уже искал соответствующую проблему на Github, но мою проблему ничего не решило.

Технические характеристики

  • NodeMCU v2, включая ESP8266
  • Датчик шума LM393
  • MacBook для разработки

Голый вывод:

...
Request: { "id": "S3", "noise": 41 , "ip": "192.168.178.20" }

Exception (29):
epc1=0x4020c612 epc2=0x00000000 epc3=0x00000000 excvaddr=0x00000004 depc=0x00000000

ctx: cont 
sp: 3fff0010 end: 3fff0530 offset: 01a0

>>>stack>>>
3fff01b0:  00820000 00000082 3fff57cc 40219652  
3fff01c0:  3ffef4b0 3fff5f44 3fff57cc 4021984c  
3fff01d0:  3fffba7c 00000208 3fffba7c 40100670  
3fff01e0:  00000104 0000b018 00001603 00000042  
3fff01f0:  00000040 00000082 3fff7dd4 40219b65  
3fff0200:  00800000 00000080 00000000 00000041  
3fff0210:  00000040 0000003f 3fff6164 00000041  
3fff0220:  3fffb664 3fff7dd4 3fff6164 3fff6f34  
3fff0230:  3fffbb78 ffffffff 3fff5f44 40204c04  
3fff0240:  00000040 3fff5f44 3fff7dd4 3fff5f44  
3fff0250:  00000040 3fff5f44 3fff7dd4 4021a69f  
3fff0260:  3fff67b4 0000003f a5c6bfaf 00000001  
3fff0270:  3fff5f44 3fff6a04 3fff7dd4 00000001  
3fff0280:  00000010 3fff5f44 0000000f 4021a8f4  
3fff0290:  3fff6164 3fff9b1c 0000000f 00000001  
3fff02a0:  00000001 3fff68bc 3fff3872 402196f8  
3fff02b0:  00000100 3fff96fc 3fff3847 00000000  
3fff02c0:  00000100 3fff96fc 3fff3847 4021ba7d  
3fff02d0:  3fff0300 00000000 000000d0 00000030  
3fff02e0:  b9a842ca 3fff68c8 3fff6170 00000004  
3fff02f0:  3fff3841 3fffa794 3fff3841 40216778  
3fff0300:  eb090303 4fed87e4 8f9aa767 9126663e  
3fff0310:  ea791a25 f4e54d08 e2cb4f3b da7af472  
3fff0320:  3d042744 7d12ab50 1cecee1e 42cab262  
3fff0330:  3fff3841 00000004 3fffa794 40216c0d  
3fff0340:  fa036a52 f16613d1 c13f331a 40213cd0  
3fff0350:  f6658dd1 3fffc6fc 3ffef510 4020f835  
3fff0360:  00000000 00000004 00000004 40203688  
3fff0370:  00000012 00001192 00000064 40204bc4  
3fff0380:  00000050 00000000 00000032 00000004  
3fff0390:  3fff3841 00000004 3fffa794 00000004  
3fff03a0:  3fff3841 00000004 3fffa794 40216580  
3fff03b0:  d7c44818 00000131 00000131 0000002d  
3fff03c0:  00000062 3fff3841 3fffa794 4021695c  
3fff03d0:  00000016 3fff3874 3fffa794 401004d8  
3fff03e0:  3fff0438 0000000e 00000010 3fff3044  
3fff03f0:  4020343c 3fffa794 3fff0430 01000000  
3fff0400:  3fff0438 00029c3d 3fffa794 402166e8  
3fff0410:  3fffa794 3fff13ec 3fff14ec 3fff3044  
3fff0420:  3fff241c 00029c3d 3fff14ec 40203e25  
3fff0430:  3fffa794 3fff13ec 40204b4c 3ffef510  
3fff0440:  00003a98 00003a98 00003a98 4020136f  
3fff0450:  3ffef248 00000000 3fff241c 00000029  
3fff0460:  000001bb 3ffe8a09 3ffef248 40204073  
3fff0470:  000001bb 3ffef248 3ffe8a09 00000029  
3fff0480:  000001bb 3ffef248 3ffe8a09 40204119  
3fff0490:  40107158 ce653134 40107158 ce653134  
3fff04a0:  3ffe8a09 3ffef248 3ffef240 402022d4  
3fff04b0:  40244290 00000004 00000000 4023d5cd  
3fff04c0:  4023d631 60000a00 00000000 3fffdad0  
3fff04d0:  004b004b 004b004b 004b004b 004b004b  
3fff04e0:  00000000 00000026 40238168 3ffef4f4  
3fff04f0:  402013fa 0000001c 00000000 3ffef4fc  
3fff0500:  3fffdad0 3ffef244 3ffef240 4020245c  
3fff0510:  3fffdad0 00000000 3ffef4f4 40204b98  
3fff0520:  feefeffe feefeffe 3ffef510 40100710  
<<<stack<<<
⸮⸮؁⸮

Декодированная трассировка стека:

Decoding 36 results
0x40219652: more_comps at crypto/bigint.c line 672
0x4021984c: alloc at crypto/bigint.c line 672
0x40100670: _umm_realloc at /Users/lony/Library/Arduino15/packages/esp8266/hardware/esp8266/2.4.1/cores/esp8266/umm_malloc/umm_malloc.c line 1641
:  (inlined by) realloc at /Users/lony/Library/Arduino15/packages/esp8266/hardware/esp8266/2.4.1/cores/esp8266/umm_malloc/umm_malloc.c line 1715
0x40219b65: regular_multiply at crypto/bigint.c line 672
0x40204c04: optimistic_yield at /Users/lony/Library/Arduino15/packages/esp8266/hardware/esp8266/2.4.1/cores/esp8266/core_esp8266_main.cpp line 57
0x4021a69f: bi_barrett at crypto/bigint.c line 1289
0x4021a8f4: bi_mod_power at crypto/bigint.c line 1414
0x402196f8: trim at crypto/bigint.c line 672
0x4021ba7d: RSA_public at crypto/rsa.c line 254
:  (inlined by) RSA_encrypt at crypto/rsa.c line 288
0x40216778: send_client_key_xchg at ssl/tls1_clnt.c line 409
0x40216c0d: do_clnt_handshake at ssl/tls1_clnt.c line 123
0x40213cd0: mem_free at /local/users/gauchard/arduino/arduino_esp8266/origin/tools/sdk/lwip2/builder/lwip2-src/src/core/mem.c line 152
0x4020f835: pbuf_free_LWIP2 at /local/users/gauchard/arduino/arduino_esp8266/origin/tools/sdk/lwip2/builder/lwip2-src/src/core/pbuf.c line 1306
0x40203688: ClientContext::_consume(unsigned int) at /Users/lony/Library/Arduino15/packages/esp8266/hardware/esp8266/2.4.1/libraries/ESP8266WiFi/src/WiFiClientSecure.cpp line 310 (discriminator 1)
:  (inlined by) ClientContext::read(char*, unsigned int) at /Users/lony/Library/Arduino15/packages/esp8266/hardware/esp8266/2.4.1/libraries/ESP8266WiFi/src/include/ClientContext.h line 253 (discriminator 1)
0x40204bc4: __yield at /Users/lony/Library/Arduino15/packages/esp8266/hardware/esp8266/2.4.1/cores/esp8266/core_esp8266_main.cpp line 57
0x40216580: do_handshake at ssl/tls1.c line 2007
:  (inlined by) basic_read at ssl/tls1.c line 1483
0x4021695c: do_client_connect at ssl/tls1_clnt.c line 168
0x401004d8: malloc at /Users/lony/Library/Arduino15/packages/esp8266/hardware/esp8266/2.4.1/cores/esp8266/umm_malloc/umm_malloc.c line 1668
0x4020343c: SSLContext::_delete_shared_SSL(SSL_*) at /Users/lony/Library/Arduino15/packages/esp8266/hardware/esp8266/2.4.1/libraries/ESP8266WiFi/src/WiFiClientSecure.cpp line 310 (discriminator 1)
0x402166e8: ssl_read at ssl/tls1.c line 2007
0x40203e25: SSLContext::connect(ClientContext*, char const*, unsigned int) at /Users/lony/Library/Arduino15/packages/esp8266/hardware/esp8266/2.4.1/libraries/ESP8266WiFi/src/WiFiClientSecure.cpp line 310 (discriminator 1)
0x40204b4c: esp_yield at /Users/lony/Library/Arduino15/packages/esp8266/hardware/esp8266/2.4.1/cores/esp8266/core_esp8266_main.cpp line 57
0x4020136f: delay at /Users/lony/Library/Arduino15/packages/esp8266/hardware/esp8266/2.4.1/cores/esp8266/core_esp8266_wiring.c line 51
0x40204073: WiFiClientSecure::_connectSSL(char const*) at /Users/lony/Library/Arduino15/packages/esp8266/hardware/esp8266/2.4.1/libraries/ESP8266WiFi/src/WiFiClientSecure.cpp line 310 (discriminator 1)
0x40204119: WiFiClientSecure::connect(char const*, unsigned short) at /Users/lony/Library/Arduino15/packages/esp8266/hardware/esp8266/2.4.1/libraries/ESP8266WiFi/src/WiFiClientSecure.cpp line 310 (discriminator 1)
0x40107158: sntp_get_current_timestamp at ?? line ?
0x40107158: sntp_get_current_timestamp at ?? line ?
0x402022d4: loop_send_post(int) at /var/folders/ld/dws59xv93p15208nvrw7tt9w0000gn/T/arduino_modified_sketch_158237/HTTPSRequest.ino line 86
0x40244290: pm_wakeup_init at ?? line ?
0x4023d5cd: test_tout at ?? line ?
0x4023d631: test_tout at ?? line ?
0x40238168: system_adc_read at ?? line ?
0x402013fa: __analogRead at /Users/lony/Library/Arduino15/packages/esp8266/hardware/esp8266/2.4.1/cores/esp8266/core_esp8266_wiring_analog.c line 33
0x4020245c: loop at /var/folders/ld/dws59xv93p15208nvrw7tt9w0000gn/T/arduino_modified_sketch_158237/HTTPSRequest.ino line 52
0x40204b98: loop_wrapper at /Users/lony/Library/Arduino15/packages/esp8266/hardware/esp8266/2.4.1/cores/esp8266/core_esp8266_main.cpp line 57
0x40100710: cont_norm at /Users/lony/Library/Arduino15/packages/esp8266/hardware/esp8266/2.4.1/cores/esp8266/cont.S line 109

Скетч / код, который я использую:

#include <ESP8266WiFi.h>
#include <WiFiClientSecure.h>

static const String         SYSTEM_NAME = "S3";

static const char*          WIFI_SSID = "SSID...";
static const char*          WIFI_PASSWORD = "PW...";
static String               local_ip;

static const char*          TARGET_HOST = "host.com";
static const int            TARGET_PORT = 443;
static const String         TARGET_URL = "/v1/noise-data-receiver";
static const char*          TARGET_SSL_SHA1_FINGERPRINT = "8D ....2"; // To retrieve use web browser

static const int            BAUD_RATE = 9600;
static const int            PIN_SENSOR = A0;
static const int            PIN_LED = LED_BUILTIN;

static WiFiClientSecure     client;

static const int            THRESHOLD_NOISE = 100;
static int                  level = 0;

static const unsigned long  REFRESH_INTERVAL = 1000; // ms
static unsigned long        lastRefreshTime = 0;

void setup() {

  pinMode(PIN_LED, OUTPUT);
  Serial.begin(BAUD_RATE);  
  setup_wifi();
}

void loop() {

  // Fetch noise level
  digitalWrite(PIN_LED, LOW);
  level = analogRead(PIN_SENSOR);
  digitalWrite(PIN_LED, HIGH);   

  // Send HTTP POST request (every s)
  if(millis() - lastRefreshTime >= REFRESH_INTERVAL) {  
    // Send request
    loop_send_post(level);

    lastRefreshTime += REFRESH_INTERVAL;
  }
}

/*
 * LIBS 
 */

void setup_wifi() {

  Serial.println();
  Serial.println();
  Serial.print("Connecting system [" + SYSTEM_NAME + "] to WIFI ");
  Serial.print(WIFI_SSID);

  WiFi.mode(WIFI_STA);
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);

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

  local_ip = WiFi.localIP().toString();
  Serial.print("IP address: ");
  Serial.print(local_ip);
  Serial.println();
}

void loop_send_post(int level) {

  // Connect 
  if (!client.connect(TARGET_HOST, TARGET_PORT)) {
    Serial.println("connection failed");
    return;
  }

  // Speed up sending
  client.setNoDelay(true);

  // Verify TLS
  if (!client.verify(TARGET_SSL_SHA1_FINGERPRINT, TARGET_HOST)) {
    Serial.println("certificate doesn't match");
    return;
  }

  // Send
  String body_json = "{ \"id\": \"" + SYSTEM_NAME + "\", \"noise\": " + String(level) + " , \"ip\": \"" + local_ip + "\" }";
  client.print("POST " + TARGET_URL + " HTTP/1.1\r\n" +
               "Host: " + TARGET_HOST + "\r\n" +
               "Connection: close\r\n" + 
               "User-Agent: ESP8266\r\n" +
               "x-api-key: GEeGwazU1Ia2h6rZH6e0y4jwlxhjVurT9OWbOed4\r\n" +
               "Cache-Control: no-cache\r\n" +
               "Content-Type: application/json\r\n" +
               "Content-Length: " + body_json.length() + "\r\n" +
               "\r\n" +
               body_json);
  Serial.println();
  Serial.println();
  Serial.println("Request: " + body_json);

//  // Wait for response
//  unsigned long timeout = millis();  
//  while (client.available() == 0) {
//    
//    if (millis() - timeout > 5000) {
//      Serial.println(">>> Client Timeout !");
//      client.stop();
//      return;
//    }
//  }
//
//  Serial.println("Response: ");
//  while(client.available()){
//    String line = client.readStringUntil('\r');
//    Serial.print(line);
//  }
}
Share a link to this question
CC BY-SA 3.0
| улучшить этот вопрос | |
  • 1
    Не могли бы вы переместить объявление your WiFiClientSecure clientв своей loop_send_postфункции, чтобы принудительно уничтожить этот объект в конце функции? Похоже, у вашего клиента утечка памяти, потому что сеанс никогда не закрывается должным образом ... Может, попробуйте позвонить и client.stop()после отправки запроса? Максимилиан Герхардт 16 марта '18 в 9:50
  • Он уже работает стабильнее, спасибо. По-прежнему есть задержки в исполнении. Вы знаете, есть ли инструмент для более детального анализа утечек памяти? lony 16 марта '18 в 22: 142018-03-16 19:14
  • 1
    1 секунда на рукопожатие TLS с огромными сертификатами RSA - это довольно сложно для вашего ESP8266, поэтому я не ожидал, что новые сеансы будут установлены так быстро. Если вам нужна меньшая задержка, вы должны .connect()один раз Connection: keep-aliveвыполнить настройку и использовать POST столько р