• Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

Вопрос Что означает сообщение интерпретатора "E:M 1504"

james77

New member
Во время исполнения скрипта при попытке создания ssl подключения интерпретатор выдает строку:
[inline]E:M 1504[/inline]
или:
[inline]E:M 4440[/inline]
и подключение не создается.
Кусок скрипта где создается ssl подключение верный, т.к. если в скрипте оставить только подключение к WiFi и создание ssl подключения, то все работает. Сообщения вылазят только когда к отлаженному, рабочему скрипту (там происходит подключение к WiFi, синхронизация с сервером NTP (используется модуль SNTP), опрос по таймеру RTC на шине i2c) прикручиваю кусок с созданием ssl подключения.
На NodeMCU Documentation описания проблемы не нашел, да и гугл ничего вразумительного не дает...
 

enjoynering

Well-known member
у меня немножко не по теме вопрос - зачем вам RTC, если у вас SNTP поднят? как то очень избыточно.
 

james77

New member
...зачем вам RTC, если у вас SNTP поднят? как то очень избыточно.
Судя из описания внутренний RTC весьма неточен, и требует периодической калибровки с помощью SNTP, особенно после глубокого сна. А ведь нет никакой гарантии, что когда ESP проснется будет доступ к серверу NTP. Поэтому принял решение использовать внешний RTC. Ну а даже с внешним RTC SNTP все еще нужен, во-первых для первоначальной настройки, а во-вторых для периодической калибровки.
Вопрос из первого поста все еще актуален...
 

enjoynering

Well-known member
ааа так вы ESP в сон загоняете.

просто с его потрелением под 300мА и сном, средний срок службы аккумов типа 18650 всего около 3-х месяцев. вобщем большого практического смысла нет. так побаловаться.
 

james77

New member
ааа так вы ESP в сон загоняете.
просто с его потрелением под 300мА и сном, средний срок службы аккумов типа 18650 всего около 3-х месяцев. вобщем большого практического смысла нет. так побаловаться.
Ну спать его укладывать я как раз и не планировал. Просто мне во что бы то ни стало, при любых условиях (нет сети, сам ребутнулся, пропало питание, вспышка на солнце) нужно точное время. Я собственно изначально на внешний RTC и расчитывал, а SNTP модуль удачно подвернулся. Ну не кнопки же с дисплеем или вебморду лепить только лишь ради настройки времени.
 

james77

New member
Странно, если скомпилировать lua скрипт, при выполнении которого выдается
Код:
E:M 1504
и соединение не создается (см. первый пост), то при запуске скомпилированного скрипта ошибки не вылазят и соединение создается. Я явно чего-то не понимаю... А что вообще дает компиляция?
 

enjoynering

Well-known member
понимаете в чем мдело - во всех этих фремвоках куча багов, которые накладываются на баги ESP-го SDK. в итоге получаются вот такие забавные ситуации.

еще забавно смотреть как глючные куски кода копируются из одной библиотеки или проекта в другой и ни у кого не возникает желания посмотреть почему тут эти цифры и что же я отправляю?

вот вам пример - NTP запрос, который вы найдете в любом проекте, и 99.9% в вашем он тоже есть.

Код:
    ntpPacketBuffer[0] = 0b11100011;   // LI, Version, Mode
    ntpPacketBuffer[1] = 0;     // Stratum, or type of clock
    ntpPacketBuffer[2] = 6;     // Polling Interval
    ntpPacketBuffer[3] = 0xEC;  // Peer Clock Precision
                                // 8 bytes of zero for Root Delay & Root Dispersion
    ntpPacketBuffer[12] = 49;
    ntpPacketBuffer[13] = 0x4E;
    ntpPacketBuffer[14] = 49;
    ntpPacketBuffer[15] = 52;
если открыть стандарт на протокол RFC 5905, то становится понятно что некоторые цифры взяты просто с потолка.

и это не единичный случай - это норма с реди ардунщиков тупо скопировать чей-то полурабочий код и вставить в свой проект.
 

james77

New member
Так вот и не хочется уподобляться ардуинщикам в плохом смысле этого слова. Хочется разобраться что я делаю не так и что это за сообщения интерпретатора (или транслятора). Полагаю что это сообщения о нехватки памяти для виртуальной машины (размер скрипта на луа чуть более 10КБ). Косвенно мое предположение подтверждается тем, что прекомпилированный скрипт работает без проблем. Но конечно могу ошибаться.
С ESP8266 имею дело совсем недавно, сразу выбрал NodeMCU. Но уже появляются грешные мысли перейти на ардуино :) Хоть посмотрю что оно такое... Но что-то мне подсказывает и там косяков не меньше...
 

james77

New member
вот вам пример - NTP запрос, который вы найдете в любом проекте, и 99.9% в вашем он тоже есть.
И кстати нет в моем проекте такого куска кода. Это вообще-то из Arduino-проекта кусок. Я конечно в первом посте не уточнил, что мой скрипт на lua и прошивка NodeMCU, но раз уж тема в разделе прошивок NodeMCU, то подумал что уточнять такие подробности будет лишним. А ведь мне пришлось перерыть исходники прошивки NodeMCU в поисках приведенного Вами, enjoynering, куска кода (разобраться ведь нужно) и не найдя его, долго недоумевать откуда же он может быть в моем проекте.
 

enjoynering

Well-known member
да в NodeMCU все грамотно сделанно. они даже отправляют свое время на сервер, для последующего определения Jitter (задержку которая возникает при приеме/передачи пакетов и потом учитваю эту погрешнось). молодцы!!! вот бы товарищам из ардуино у них поучиться, как правильно NTP запросы писать.

Код:
sntp_initialize_request(struct sntp_msg *req)
{
  os_memset(req, 0, SNTP_MSG_LEN);
  req->li_vn_mode = SNTP_LI_NO_WARNING | SNTP_VERSION | SNTP_MODE_CLIENT;

#if SNTP_CHECK_RESPONSE >= 2
  {
    u32_t sntp_time_sec, sntp_time_us;
    /* fill in transmit timestamp and save it in 'sntp_last_timestamp_sent' */
    SNTP_GET_SYSTEM_TIME(sntp_time_sec, sntp_time_us);
    sntp_last_timestamp_sent[0] = htonl(sntp_time_sec + DIFF_SEC_1900_1970);
    req->transmit_timestamp[0] = sntp_last_timestamp_sent[0];
    /* we send/save us instead of fraction to be faster... */
    sntp_last_timestamp_sent[1] = htonl(sntp_time_us);
    req->transmit_timestamp[1] = sntp_last_timestamp_sent[1];
  }
#endif /* SNTP_CHECK_RESPONSE >= 2 */
}
 
Последнее редактирование:

dave_scream

New member
Я тоже недавно с NodeMCU и у меня тоже HTTPS (бот на telegram) - я так понял, что это правда сообщение о нехватке памяти. Опытным путем выяснил, что https get запрос требует наличия 28кб свободной памяти print(node.heap()) если её меньше, то памяти не хватает и модуль перезагружается. Причем такой большой объем требуется и в случае использования библиотеки http так и в случае использования net.createConnection с флагом secure.

Я думаю, что столько много памяти требуется только из-за того, что запрос не http, https с шифрованием, и именно модуль шифрования TLS/SSL жрет столько оперативной памяти.

В интернете совет - разбивать программу на модули (подзадачи) и выполнять их отдельно dofile("init.lua") dofile("main.lua") dofile("check.lua") dofile("telegrambot.lua") однако мне это не помогло. Я ещё не совсем разобрался, но скорее всего глобальные переменные, объявленные в предыдущих модулях, при вызове следующего остаются в памяти и врезультате на https запрос не остается нужного объема озу.

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

Waik

New member
Здравствуйте. Поделитесь рабочим вариантов отправки GET запросы по HTTPS и получение ответа. Модуль HTTP, модуль net/TLS не работают.
Тестирую код - не работает.
Код:
function testHTTPS(host, path)
  local url = "https://" .. host .. path;
  http.get(url, nil, function(code, data)
    if (code < 0) then
      print("HTTP request to " .. url .. " failed")
    else
      print("HTTP request to " .. url .. " succeeded")
    end
  end)
  local srv = tls.createConnection(net.TCP, 0)
  srv:on("receive", function(sck, c) print("net/TLS to " .. url .. " succeeded") end)
  srv:on("connection", function(sck, c)
    sck:send("GET " .. path .. " HTTP/1.1\r\nHost: " .. host .. "\r\nConnection: keep-alive\r\nAccept: */*\r\n\r\n")
  end)
  srv:connect(443, host)
end
testHTTPS("api.ethermine.org", "/poolStats")
Вывод получаю:
Код:
HTTP client: Disconnected with error: -114
HTTP client: Connection timeout
HTTP request to https://api.ethermine.org/poolStats failed
Код:
NodeMCU custom build by frightanic.com
    branch: master
    commit: 2e67ff5a639a13260fd4fb3c3b627ccdc2845616
    SSL: true
    modules: file,gpio,http,net,node,tmr,uart,wifi,tls
build     built on: 2017-10-14 17:00
powered by Lua 5.1.4 on SDK 2.1.0(116b762)
 
Последнее редактирование:

dave_scream

New member
Здравствуйте. Поделитесь рабочим вариантов отправки GET запросы по HTTPS и получение ответа. Модуль HTTP, модуль net/TLS не работают.
Тестирую код - не работает.
Код:
function testHTTPS(host, path)
  local url = "https://" .. host .. path;
  http.get(url, nil, function(code, data)
    if (code < 0) then
      print("HTTP request to " .. url .. " failed")
    else
      print("HTTP request to " .. url .. " succeeded")
    end
  end)
  local srv = tls.createConnection(net.TCP, 0)
  srv:on("receive", function(sck, c) print("net/TLS to " .. url .. " succeeded") end)
  srv:on("connection", function(sck, c)
    sck:send("GET " .. path .. " HTTP/1.1\r\nHost: " .. host .. "\r\nConnection: keep-alive\r\nAccept: */*\r\n\r\n")
  end)
  srv:connect(443, host)
end
testHTTPS("api.ethermine.org", "/poolStats")
Вывод получаю:
Код:
HTTP client: Disconnected with error: -114
HTTP client: Connection timeout
HTTP request to https://api.ethermine.org/poolStats failed
Код:
NodeMCU custom build by frightanic.com
    branch: master
    commit: 2e67ff5a639a13260fd4fb3c3b627ccdc2845616
    SSL: true
    modules: file,gpio,http,net,node,tmr,uart,wifi,tls
build     built on: 2017-10-14 17:00
powered by Lua 5.1.4 on SDK 2.1.0(116b762)
Сам не могу заставить работать https. Оно работает с полпинка на sdk 1.5.1 сам билд с модулями нудно переделать под старый сдк.

Минус в том что старый сдк оставляет меньше озу для пользователя, а http.get видтмо изза шифрования жрет 28000байт врезультате не хватает памяти.

Если сможешь запустить https на сдк выше 1.5.1 маякни сюда плз
 

Waik

New member
Проблему HTTPS и GET запросами решил следующим способом:
1. Создаем на своем на хостинге файл, допустим redirect.php.
Код:
PHP:
<?php
  $ch = curl_init();
  curl_setopt($ch, CURLOPT_URL, $_SERVER['QUERY_STRING']);
  curl_setopt($ch, CURLOPT_HEADER, false);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
  curl_setopt($ch, CURLOPT_USERAGENT, 'NodeMcu');
  $data = curl_exec($ch);
  curl_close($ch);
  echo $data
?>
2. На всякий случай пишем robots.txt
HTML:
User-agent: *
Disallow: /redirect.php
теперь в NodeMcu Используем модуль http, но уже ссылаемся на наш файл а в параметры передаем полный адрес до нужно https сервера.
Например: http://вашсайт.com/redirect.php?https://сайтсшттпс.com/парметры
Redirect.php возьмет целиком строку что мы ему передали, в наше случае https://сайтсшттпс.com/парметры и выполнит get запрос и через обычное echo выдаст ответ.
 

enjoynering

Well-known member
многи роботы игнорируют коменду Disallow: /redirect.php
помнню открыл php сервер во внешний мир и начал отлиживать запросы с помощью wireshark. Смотрю куча запросов повалило с неизвесных IP. оказались роботы. не прошло и 10 минут!!!
 

enjoynering

Well-known member
теперь в NodeMcu Используем модуль http, но уже ссылаемся на наш файл а в параметры передаем полный адрес до нужно https сервера.
Например: http://вашсайт.com/redirect.php?https://сайтсшттпс.com/парметры
Redirect.php возьмет целиком строку что мы ему передали, в наше случае https://сайтсшттпс.com/парметры и выполнит get запрос и через обычное echo выдаст ответ.
какой замечательный идусский костыль.
 
Сверху Снизу